<commit_before>module ActiveScaffold
  module Finder
    module ClassMethods
      # Takes a collection of search terms (the tokens) and creates SQL that
      # searches all specified ActiveScaffold columns. A row will match if each
      # token is found in at least one of the columns.
      def create_conditions_for_columns(tokens, columns, like_pattern = '%?%')
        # if there aren't any columns, then just return a nil condition
        return unless columns.length > 0

        tokens = [tokens] if tokens.is_a? String

        where_clauses = []
        columns.each do |column|
          where_clauses << ((column.column.nil? || column.column.text?) ? "LOWER(#{column.search_sql}) LIKE ?" : "#{column.search_sql} = ?")
        end
        phrase = "(#{where_clauses.join(' OR ')})"

        sql = ([phrase] * tokens.length).join(' AND ')
        tokens = tokens.collect do |value|
          columns.collect {|column| (column.column.nil? || column.column.text?) ? like_pattern.sub('?', value.downcase) : column.column.type_cast(value)}
        end.flatten

        [sql, *tokens]
      end

      # Generates an SQL condition for the given ActiveScaffold column based on
      # that column's database type (or form_ui ... for virtual columns?).
      # TODO: this should reside on the column, not the controller
      def condition_for_column(column, value, like_pattern = '%?%')
        # we must check false or not blank because we want to search for false but false is blank
        return unless column and column.search_sql and (not value.blank?)
        return if (value.is_a?(Array) and value.join.blank?)
        search_ui = column.search_ui || column.column.type
        if self.respond_to?("condition_for_#{column.name}_column")
          self.send("condition_for_#{column.name}_column", column, value, like_pattern)
        elsif self.respond_to?("condition_for_#{search_ui}_type")
          self.send("condition_for_#{search_ui}_type", column, value, like_pattern)
        else
          case search_ui
            when :boolean, :checkbox
            ["#{column.search_sql} = ?", column.column.type_cast(value)]
            when :select
            ["#{column.search_sql} = ?", value[:id]] unless value[:id].blank?
            when :multi_select
            ["#{column.search_sql} in (?)", value.values.collect{|hash| hash[:id]}]
            else
              if column.column.nil? || column.column.text?
                ["LOWER(#{column.search_sql}) LIKE ?", like_pattern.sub('?', value.downcase)]
              else
                ["#{column.search_sql} = ?", column.column.type_cast(value)]
              end
          end
        end
      end

      def condition_for_integer_type(column, value, like_pattern = nil)
        if value['from'].blank? or not ActiveScaffold::Finder::NumericComparators.include?(value['opt'])
          nil
        elsif value['opt'] == 'BETWEEN'
          ["#{column.search_sql} BETWEEN ? AND ?", value['from'].to_f, value['to'].to_f]
        else
          ["#{column.search_sql} #{value['opt']} ?", value['from'].to_f]
        end
      end
      alias_method :condition_for_decimal_type, :condition_for_integer_type
      alias_method :condition_for_float_type, :condition_for_integer_type
      alias_method :condition_for_usa_money_type, :condition_for_integer_type

      def condition_for_string_type(column, value, like_pattern = '%?%')
        if !value.is_a?(Hash)
          ["LOWER(#{column.search_sql}) LIKE ?", like_pattern.sub('?', value.downcase)]
        elsif value['from'].blank? or not ActiveScaffold::Finder::StringComparators.flatten.include?(value['opt'])
          nil
        elsif value['opt'] == 'BETWEEN'
          ["#{column.search_sql} BETWEEN ? AND ?", value['from'], value['to']]
        elsif value['opt'].include?('?')
          ["#{column.search_sql} LIKE ?", value['opt'].sub('?', value['from'].downcase)]
        else
          ["#{column.search_sql} #{value['opt']} ?", value['from']]
        end
      end
      alias_method :condition_for_email_type, :condition_for_string_type
      alias_method :condition_for_text_type, :condition_for_string_type

      def condition_for_datetime_type(column, value, like_pattern = nil)
        conversion = value['from']['hour'].blank? && value['to']['hour'].blank? ? 'to_date' : 'to_time'
        from_value, to_value = ['from', 'to'].collect do |field|
          Time.zone.local(*['year', 'month', 'day', 'hour', 'minutes', 'seconds'].collect {|part| value[field][part].to_i}) rescue nil
        end

        if from_value.nil? and to_value.nil?
          nil
        elsif !from_value
          ["#{column.search_sql} <= ?", to_value.send(conversion).to_s(:db)]
        elsif !to_value
          ["#{column.search_sql} >= ?", from_value.send(conversion).to_s(:db)]
        else
          ["#{column.search_sql} BETWEEN ? AND ?", from_value.send(conversion).to_s(:db), to_value.send(conversion).to_s(:db)]
        end
      end
      alias_method :condition_for_date_type, :condition_for_datetime_type
      alias_method :condition_for_time_type, :condition_for_datetime_type
      alias_method :condition_for_timestamp_type, :condition_for_datetime_type

      def condition_for_dhtml_calendar_type(column, value, like_pattern = nil)
        return nil if value['from'].blank? or not ActiveScaffold::Finder::NumericComparators.include?(value['opt'])
        if value['opt'] == 'BETWEEN'
          ["#{column.search_sql} BETWEEN ? AND ?", value[:from], value[:to]]
        else
          ["#{column.search_sql} #{value['opt']} ?", value[:from]]
        end
      end
      alias_method :condition_for_calendar_date_select_type, :condition_for_dhtml_calendar_type

      def condition_for_exact_type(column, value, like_pattern = nil)
        ["#{column.search_sql} = ?", value]
      end

      def condition_for_record_select_type(column, value, like_pattern = nil)
        if value.is_a?(Array)
          ["#{column.search_sql} IN (?)", value]
        else
          ["#{column.search_sql} = ?", value]
        end
      end

      def condition_for_multi_select_type(column, value, like_pattern = nil)
        case value
        when Hash
          values = value.values
        else
          values = value
        end
        ["#{column.search_sql} in (?)", values]
      end
    end
    
    NumericComparators = [
      '=',
      '>=',<commit_msg>Bug fix Calendar date select<commit_after>module ActiveScaffold
  module Finder
    module ClassMethods
      # Takes a collection of search terms (the tokens) and creates SQL that
      # searches all specified ActiveScaffold columns. A row will match if each
      # token is found in at least one of the columns.
      def create_conditions_for_columns(tokens, columns, like_pattern = '%?%')
        # if there aren't any columns, then just return a nil condition
        return unless columns.length > 0

        tokens = [tokens] if tokens.is_a? String

        where_clauses = []
        columns.each do |column|
          where_clauses << ((column.column.nil? || column.column.text?) ? "LOWER(#{column.search_sql}) LIKE ?" : "#{column.search_sql} = ?")
        end
        phrase = "(#{where_clauses.join(' OR ')})"

        sql = ([phrase] * tokens.length).join(' AND ')
        tokens = tokens.collect do |value|
          columns.collect {|column| (column.column.nil? || column.column.text?) ? like_pattern.sub('?', value.downcase) : column.column.type_cast(value)}
        end.flatten

        [sql, *tokens]
      end

      # Generates an SQL condition for the given ActiveScaffold column based on
      # that column's database type (or form_ui ... for virtual columns?).
      # TODO: this should reside on the column, not the controller
      def condition_for_column(column, value, like_pattern = '%?%')
        # we must check false or not blank because we want to search for false but false is blank
        return unless column and column.search_sql and (not value.blank?)
        return if (value.is_a?(Array) and value.join.blank?)
        search_ui = column.search_ui || column.column.type
        if self.respond_to?("condition_for_#{column.name}_column")
          self.send("condition_for_#{column.name}_column", column, value, like_pattern)
        elsif self.respond_to?("condition_for_#{search_ui}_type")
          self.send("condition_for_#{search_ui}_type", column, value, like_pattern)
        else
          case search_ui
            when :boolean, :checkbox
            ["#{column.search_sql} = ?", column.column.type_cast(value)]
            when :select
            ["#{column.search_sql} = ?", value[:id]] unless value[:id].blank?
            when :multi_select
            ["#{column.search_sql} in (?)", value.values.collect{|hash| hash[:id]}]
            else
              if column.column.nil? || column.column.text?
                ["LOWER(#{column.search_sql}) LIKE ?", like_pattern.sub('?', value.downcase)]
              else
                ["#{column.search_sql} = ?", column.column.type_cast(value)]
              end
          end
        end
      end

      def condition_for_integer_type(column, value, like_pattern = nil)
        if value['from'].blank? or not ActiveScaffold::Finder::NumericComparators.include?(value['opt'])
          nil
        elsif value['opt'] == 'BETWEEN'
          ["#{column.search_sql} BETWEEN ? AND ?", value['from'].to_f, value['to'].to_f]
        else
          ["#{column.search_sql} #{value['opt']} ?", value['from'].to_f]
        end
      end
      alias_method :condition_for_decimal_type, :condition_for_integer_type
      alias_method :condition_for_float_type, :condition_for_integer_type
      alias_method :condition_for_usa_money_type, :condition_for_integer_type

      def condition_for_string_type(column, value, like_pattern = '%?%')
        if !value.is_a?(Hash)
          ["LOWER(#{column.search_sql}) LIKE ?", like_pattern.sub('?', value.downcase)]
        elsif value['from'].blank? or not ActiveScaffold::Finder::StringComparators.flatten.include?(value['opt'])
          nil
        elsif value['opt'] == 'BETWEEN'
          ["#{column.search_sql} BETWEEN ? AND ?", value['from'], value['to']]
        elsif value['opt'].include?('?')
          ["#{column.search_sql} LIKE ?", value['opt'].sub('?', value['from'].downcase)]
        else
          ["#{column.search_sql} #{value['opt']} ?", value['from']]
        end
      end
      alias_method :condition_for_email_type, :condition_for_string_type
      alias_method :condition_for_text_type, :condition_for_string_type

      def condition_for_datetime_type(column, value, like_pattern = nil)
        conversion = value['from']['hour'].blank? && value['to']['hour'].blank? ? 'to_date' : 'to_time'
        from_value, to_value = ['from', 'to'].collect do |field|
          Time.zone.local(*['year', 'month', 'day', 'hour', 'minutes', 'seconds'].collect {|part| value[field][part].to_i}) rescue nil
        end

        if from_value.nil? and to_value.nil?
          nil
        elsif !from_value
          ["#{column.search_sql} <= ?", to_value.send(conversion).to_s(:db)]
        elsif !to_value
          ["#{column.search_sql} >= ?", from_value.send(conversion).to_s(:db)]
        else
          ["#{column.search_sql} BETWEEN ? AND ?", from_value.send(conversion).to_s(:db), to_value.send(conversion).to_s(:db)]
        end
      end
      alias_method :condition_for_date_type, :condition_for_datetime_type
      alias_method :condition_for_time_type, :condition_for_datetime_type
      alias_method :condition_for_timestamp_type, :condition_for_datetime_type

      def condition_for_calendar_date_select_type(column, value, like_pattern = nil)
        return nil if value['from'].blank? or not ActiveScaffold::Finder::NumericComparators.include?(value['opt'])
        if value['opt'] == 'BETWEEN'
          ["#{column.search_sql} BETWEEN ? AND ?", value[:from].to_date, value[:to].to_date]
        else
          ["#{column.search_sql} #{value['opt']} ?", value[:from].to_date]
        end
      end

      def condition_for_exact_type(column, value, like_pattern = nil)
        ["#{column.search_sql} = ?", value]
      end

      def condition_for_record_select_type(column, value, like_pattern = nil)
        if value.is_a?(Array)
          ["#{column.search_sql} IN (?)", value]
        else
          ["#{column.search_sql} = ?", value]
        end
      end

      def condition_for_multi_select_type(column, value, like_pattern = nil)
        case value
        when Hash
          values = value.values
        else
          values = value
        end
        ["#{column.search_sql} in (?)", values]
      end
    end
    
    NumericComparators = [
      '=',
      '>=',
{'fraction_non_alphanumeric': 0.13511180855237348, 'fraction_numerical': 0.0001569242840329541, 'mean_word_length': 2.8264785349744823, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '6412144', 'n_tokens_mistral': 3855, 'n_tokens_neox': 3834, 'n_words': 835}