class SQL::Maker::Condition
Attributes
auto_bind[RW]
bind[RW]
name_sep[RW]
quote_char[RW]
sql[RW]
strict[RW]
Public Class Methods
new(args = {})
click to toggle source
# File lib/sql/maker/condition.rb, line 9 def initialize(args = {}) @quote_char = args[:quote_char] || '' @name_sep = args[:name_sep] || '.' @strict = args[:strict] || false @auto_bind = args[:auto_bind] || false @sql = args[:sql] || [] @bind = args[:bind] || [] end
Public Instance Methods
&(other)
click to toggle source
# File lib/sql/maker/condition.rb, line 27 def &(other) self.compose_and(other) end
_make_in_term(col, op, v)
click to toggle source
# File lib/sql/maker/condition.rb, line 96 def _make_in_term(col, op, v) if v.respond_to?(:as_sql) # make_term(foo => { 'IN' => sql_raw('SELECT foo FROM bar') }) => foo IN (SELECT foo FROM bar) term = "#{self._quote(col)} #{op} (#{v.as_sql})" [term, v.bind] elsif v.is_a?(Array) if v.size == 0 if op == 'IN' # make_term(foo => {'IN' => []}) => 0=1 return ['0=1', []] else # make_term(foo => {'NOT IN' => []}) => 1=1 return ['1=1', []] end else # make_term(foo => { 'IN' => [1,2,3] }) => [foo IN (?,?,?), [1,2,3]] term = "#{self._quote(col)} #{op} (#{(['?'] * v.size).join(', ')})" return [term, v] end else croad("_make_in_term: arguments must be either of query instance or array") end end
_make_or_term(col, op, values)
click to toggle source
# File lib/sql/maker/condition.rb, line 83 def _make_or_term(col, op, values) binds = [] terms = [] values.each do |v| term, bind = self._make_term(col => v) terms.push "(#{term})" binds.push bind end term = terms.join(" #{op} ") bind = binds.flatten return [term, bind] end
_make_term(*args)
click to toggle source
_make_term
(:x => 1)
# File lib/sql/maker/condition.rb, line 40 def _make_term(*args) col, val = parse_args(*args) col = col.to_s if val.is_a?(SQL::QueryMaker) return [val.as_sql(col, self.method(:_quote)), val.bind] elsif self.strict croak("Condition#add: can pass only SQL::QueryMaker object as an argument in strict mode") end if val.is_a?(Array) if val.first.is_a?(Hash) # {'foo'=>[{'>' => 'bar'},{'<' => 'baz'}]} => (`foo` > ?) OR (`foo` < ?) return self._make_or_term(col, 'OR', val) else # {'foo'=>['bar','baz']} => `foo` IN (?, ?) return self._make_in_term(col, 'IN', val) end elsif val.is_a?(Hash) op, v = val.each.first op = op.to_s.upcase if ( op == 'AND' || op == 'OR' ) && v.is_a?(Array) # {'foo'=>{'or' => [{'>' => 'bar'},{'<' => 'baz'}]}} => (`foo` > ?) OR (`foo` < ?) return self._make_or_term(col, op, v) elsif ( op == 'IN' || op == 'NOT IN' ) # {'foo'=>{'in' => ['bar','baz']}} => `foo` IN (?, ?) return self._make_in_term(col, op, v) elsif ( op == 'BETWEEN' ) && v.is_a?(Array) croak("USAGE: add(foo => {BETWEEN => [a, b]})") if v.size != 2 return [self._quote(col) + " BETWEEN ? AND ?", v] else # make_term(foo => { '<' => 3 }) => foo < 3 return [self._quote(col) + " #{op} ?", [v]] end elsif val # make_term(foo => "3") => foo = 3 return [self._quote(col) + " = ?", [val]] else # make_term(foo => nil) => foo IS NULL return [self._quote(col) + " IS NULL", []] end end
_quote(label)
click to toggle source
# File lib/sql/maker/condition.rb, line 35 def _quote(label) quote_identifier(label, self.quote_char, self.name_sep) end
add(*args)
click to toggle source
# File lib/sql/maker/condition.rb, line 120 def add(*args) term, bind = self._make_term(*args) self.sql.push "(#{term})" if term self.bind += array_wrap(bind) if bind return self # for influent interface end
add_raw(*args)
click to toggle source
# File lib/sql/maker/condition.rb, line 128 def add_raw(*args) term, bind = parse_args(*args) self.sql.push "(#{term})" self.bind += array_wrap(bind) if bind return self end
as_sql()
click to toggle source
# File lib/sql/maker/condition.rb, line 183 def as_sql sql = self.sql.join(' AND ') @auto_bind ? bind_param(sql, self.bind) : sql end
compose_and(other)
click to toggle source
# File lib/sql/maker/condition.rb, line 135 def compose_and(other) if self.sql.empty? if other.sql.empty? return new_condition end return new_condition( :sql => ['(' + other.as_sql() + ')'], :bind => other.bind, ) end if other.sql.empty? return new_condition( :sql => ['(' + self.as_sql() + ')'], :bind => self.bind, ) end return new_condition( :sql => ['(' + self.as_sql() + ') AND (' + other.as_sql() + ')'], :bind => self.bind + other.bind, ) end
compose_or(other)
click to toggle source
# File lib/sql/maker/condition.rb, line 158 def compose_or(other) if self.sql.empty? if other.sql.empty? return new_condition end return new_condition( :sql => ['(' + other.as_sql() + ')'], :bind => other.bind, ) end if other.sql.empty? return new_condition( :sql => ['(' + self.as_sql() + ')'], :bind => self.bind, ) end # return value is enclosed with '()'. # because 'OR' operator priority less than 'AND'. return new_condition( :sql => ['((' + self.as_sql() + ') OR (' + other.as_sql() + '))'], :bind => self.bind + other.bind, ) end
new_condition(args = {})
click to toggle source
# File lib/sql/maker/condition.rb, line 19 def new_condition(args = {}) SQL::Maker::Condition.new({ :quote_char => self.quote_char, :name_sep => self.name_sep, :strict => self.strict, }.merge(args)) end
|(other)
click to toggle source
# File lib/sql/maker/condition.rb, line 31 def |(other) self.compose_or(other) end