<commit_before>module Carnival
  module Presenters
    class AdvancedSearchParser

      def initialize(klass_service)
        @klass_service = klass_service
      end
       def get_advanced_search_fields fields
          advanced_search_fields = {}
          fields.each do |key, field|
            advanced_search_fields[key] = field if field.advanced_searchable?
          end
          advanced_search_fields
       end

       def parse_advanced_search fields, records, search_syntax
          search = search_syntax
          search.each do |key, value|
            search_field = key
            #search_field = key.split(".").last if key.include?(".")
            search_field = search_field.gsub("_id", "") if search_field.ends_with?("_id")
            next if !fields.keys.include? search_field.to_sym
            field = fields[search_field.to_sym]
            if field.advanced_searchable? && value.present? && value.size > 0
              field_param = {"operator" => field.advanced_search_operator.to_s, "value" => "#{value}"}
              records =  parse_advanced_search_field(search_field, field_param, records)
            end
          end
          records
       end

      private
        def parse_advanced_search_field search_field, field_param, records
          return records if not field_param["value"].present?
          return records if field_param["value"] == ""

          if search_field.is_a?(String) && search_field.include?('.')
            search_field_params = search_field.split('.')
            search_field = search_field_params[0]
            column = search_field_params[1]
          end

          if @klass_service.relation? search_field.to_sym
            if @klass_service.is_a_one_to_one_relation?(search_field.to_sym)
              records = records.joins(search_field.split("/").last.to_sym)
            else
              records = records.joins(search_field.split("/").last.pluralize.to_sym)
            end
            table = @klass_service.get_related_class(search_field.to_sym).table_name
            column = "id" if column.nil?
          else
            table = @klass_service.table_name
            column = search_field
          end
          full_column_query = "#{table}.#{column}"
          where_clause = nil

          case field_param["operator"]
            when "equal"
              if field_param["value"] == "nil"
                where_clause = "#{full_column_query} is null"
              elsif field_param["value"].match(/^\d+$/)
                where_clause = "#{full_column_query} = #{field_param["value"]}"
              else
                where_clause = "lower(#{full_column_query}) = '#{advanced_search_field_value_for_query(field_param["value"])}'"
              end
            when "like"
              where_clause = "lower(#{full_column_query}) like '%#{field_param["value"].downcase}%'"
            when "greater_than"
              where_clause = "#{full_column_query} >= '#{field_param["value"]}'"
            when "less_than"
              where_clause = "#{full_column_query} <= '#{field_param["value"]}'"
            when "between"
              where_clause = "#{full_column_query} between '#{field_param["value"]}' and '#{field_param["value2"]}'"
            else
              where_clause = "#{full_column_query} = #{advanced_search_field_value_for_query(field_param["value"])}"
          end
          records = records.where(where_clause) if where_clause.present?
          records
        end

        def advanced_search_field_value_for_query(value)
          if "true" == value.downcase
            return "'t'"
          elsif "false" == value.downcase
            return "'f'"
          else
            "#{value.downcase}"
          end
        end


    end
  end
end<commit_msg>Fixes in advanced_search_parser<commit_after>module Carnival
  module Presenters
    class AdvancedSearchParser

      def initialize(klass_service)
        @klass_service = klass_service
      end
       def get_advanced_search_fields fields
          advanced_search_fields = {}
          fields.each do |key, field|
            advanced_search_fields[key] = field if field.advanced_searchable?
          end
          advanced_search_fields
       end

       def parse_advanced_search fields, records, search_syntax
          search = search_syntax
          search.each do |key, value|
            search_field = key
            #search_field = key.split(".").last if key.include?(".")
            search_field = search_field.gsub("_id", "") if search_field.ends_with?("_id")
            next if !fields.keys.include? search_field.to_sym
            field = fields[search_field.to_sym]
            if field.advanced_searchable? && value.present? && value.size > 0
              field_param = {"operator" => field.advanced_search_operator.to_s, "value" => "#{value}"}
              records =  parse_advanced_search_field(search_field, field_param, records)
            end
          end
          records
       end

      private
        def parse_advanced_search_field search_field, field_param, records
          return records if not field_param["value"].present?
          return records if field_param["value"] == ""

          if search_field.is_a?(String) && search_field.include?('.')
            search_field_params = search_field.split('.')
            search_field = search_field_params[0]
            column = search_field_params[1]
          end

          if @klass_service.relation? search_field.to_sym
            if @klass_service.is_a_one_to_one_relation?(search_field.to_sym)
              records = records.joins(search_field.split("/").last.to_sym)
            else
              records = records.joins(search_field.split("/").last.pluralize.to_sym)
            end
            table = @klass_service.get_related_class(search_field.to_sym).table_name
            column = "id" if column.nil?
          else
            table = @klass_service.table_name
            column = search_field
          end
          
          records.where(where_clause(field_param, column))
        end

        def where_clause(field_param, column)
          arel_table = @klass_service.klass.arel_table
          operator = field_param['operator']
          value = field_param['value']
          value2 = field_param['value2']
          case operator
          when 'equal'
            if value == 'nil'
              arel_table[column].eq(nil)
            elsif value.match(/^\d+$/)
              arel_table[column].eq(value)
            else
              arel_table.lower(arel_table[column]).eq("#{advanced_search_field_value_for_query(value)}")
            end
          when 'like'
            arel_table.lower(arel_table[column]).matches("%#{value.downcase}%")
          when 'greater_than'
            arel_table[column].gteq(value)
          when 'less_than'
            arel_table[column].lteq(value)
          when 'between'
            Arel::Nodes::Between.new(
              arel_table[column], Arel::Nodes::And.new([value, value2])
            )
          else
            arel_table[column].eq("#{advanced_search_field_value_for_query(value)}")
          end
        end

        def advanced_search_field_value_for_query(value)
          if "true" == value.downcase
            return "'t'"
          elsif "false" == value.downcase
            return "'f'"
          end

          value.downcase
        end
    end
  end
end
{'fraction_non_alphanumeric': 0.10147849462365591, 'fraction_numerical': 0.0013440860215053765, 'mean_word_length': 2.063400576368876, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2011660', 'n_tokens_mistral': 2105, 'n_tokens_neox': 2071, 'n_words': 383}