class Babik::Selection::Operation::Base

Base class

Attributes

field[R]
sql_operation[R]
sql_operation_template[R]
value[R]

Public Class Methods

date_special_cases(field, operator, value) click to toggle source

Special conversion of operations for date lookup

# File lib/babik/queryset/lib/selection/operation/base.rb, line 103
def self.date_special_cases(field, operator, value)
  return field, 'between', [value.beginning_of_day, value.end_of_day] if operator == 'date' && value.is_a?(::Date)
  return field, 'between', [Time(value.year, 1, 1).beginning_of_day, Time(value.year, 12, 31).end_of_day] if operator == 'year' && value.is_a?(::Date)
  [field, operator, value]
end
escape(str) click to toggle source

Escape a string

# File lib/babik/queryset/lib/selection/operation/base.rb, line 110
def self.escape(str)
  Babik::Database.escape(str)
end
factory(field, operator, value) click to toggle source

Operation factory

# File lib/babik/queryset/lib/selection/operation/base.rb, line 45
def self.factory(field, operator, value)
  # Some operators can have a secondary operator, like the year lookup that can be followed by
  # a gt, lt, equal, etc. Check this case, and get it to prepare its passing to the operation.
  raw_main_operator, secondary_operator = self.initialize_operators(operator)
  # The field, operator or value can change in some special cases, e.g. if operator is equals and the value
  # is an array, the operator should be 'in' actually.
  field, main_operator, value = self.special_cases(field, raw_main_operator, value)
  # At last, initialize operation
  self.initialize_operation(field, main_operator, secondary_operator, value)
end
initialize_operation(field, operator, secondary_operator, value) click to toggle source

Initialize the operation @param field [String] Field name that takes part in the selection operation. @param operator [Symbol] Operator name that defines which operation will be used. @param secondary_operator [Symbol] Some operations have a particular operation that's it. @param value [String, Integer] Value used in the selection. @return [Babik::Selection::Operation::Base] A SQL selection operation.

# File lib/babik/queryset/lib/selection/operation/base.rb, line 84
def self.initialize_operation(field, operator, secondary_operator, value)
  operation_class_name = Babik::Selection::Operation::CORRESPONDENCE[operator.to_sym]
  raise "Unknown lookup #{operator}" unless operation_class_name
  operation_class = Object.const_get("Babik::Selection::Operation::#{operation_class_name}")
  # If there is a secondary operator, pass it to the operation
  if secondary_operator || operation_class.operator?
    return operation_class.new(field, secondary_operator, value)
  end
  # Otherwise, return the operation
  operation_class.new(field, value)
end
initialize_operators(operator) click to toggle source

Initialize the operators (both main and secondary) When the operator is an Array, it means it actually is two different operators. The first one will be applied to the main operation, and the second one, to the lookup. e.g. selector 'created_at__time__gt' contains two operators, 'time' and 'gt'. @return [Array<String>] Array with both operations.

First element will be the main operation, the second one will be
the secondary operation. If there is no secondary operation, the second item will be nil.
# File lib/babik/queryset/lib/selection/operation/base.rb, line 69
def self.initialize_operators(operator)
  secondary_operator = nil
  if operator.class == Array
    secondary_operator = operator[1]
    operator = operator[0]
  end
  [operator, secondary_operator]
end
new(field, sql_operation, value) click to toggle source

Construct a SQL operation @param field [String] Name of the field. Prefixed with the table or table alias. @param sql_operation [String] Template string with the SQL code or the operation.

Something like ?field = ?value.
# File lib/babik/queryset/lib/selection/operation/base.rb, line 16
def initialize(field, sql_operation, value)
  @field = field
  @value = value
  @sql_operation_template = sql_operation.dup
  @sql_operation = sql_operation.dup
  _init_sql_operation
end
operator?() click to toggle source

Inform if the operation has a operator @return [Boolean] True if the operation needs an operator, false otherwise.

# File lib/babik/queryset/lib/selection/operation/base.rb, line 58
def self.operator?
  self.const_defined?('HAS_OPERATOR') && self.const_get('HAS_OPERATOR')
end
special_cases(field, operator, value) click to toggle source

Special conversion of operations

# File lib/babik/queryset/lib/selection/operation/base.rb, line 97
def self.special_cases(field, operator, value)
  return field, 'in', value if operator == 'equal' && [Babik::QuerySet::Base, Array].include?(value.class)
  self.date_special_cases(field, operator, value)
end

Public Instance Methods

_init_sql_operation() click to toggle source

Replace the SQL operation template and store the result in sql_operation attribute

# File lib/babik/queryset/lib/selection/operation/base.rb, line 25
def _init_sql_operation
  @sql_operation = @sql_operation_template.sub('?field', @field).sub('?value', '?')
  # Use Rails SQL escaping and avoid possible SQL-injection issues
  # and also several DB-related issues (like MySQL escaping quotes by \' instead of '')
  # Only if it has not been already replaced
  @sql_operation = ActiveRecord::Base.sanitize_sql([@sql_operation, @value]) if @sql_operation.include?('?')
end
db_engine() click to toggle source

Return the database engine: sqlite3, mysql, postgres, mssql, etc.

# File lib/babik/queryset/lib/selection/operation/base.rb, line 40
def db_engine
  Babik::Database.config[:adapter]
end
to_s() click to toggle source

Convert the operation to string @return [String] Return the replaced SQL operation.

# File lib/babik/queryset/lib/selection/operation/base.rb, line 35
def to_s
  @sql_operation
end