Class: SQL::Maker::Condition
- Inherits:
-
Object
- Object
- SQL::Maker::Condition
- Includes:
- Util
- Defined in:
- lib/sql/maker/condition.rb
Instance Attribute Summary collapse
-
#auto_bind ⇒ Object
Returns the value of attribute auto_bind.
-
#bind ⇒ Object
Returns the value of attribute bind.
-
#name_sep ⇒ Object
Returns the value of attribute name_sep.
-
#quote_char ⇒ Object
Returns the value of attribute quote_char.
-
#sql ⇒ Object
Returns the value of attribute sql.
-
#strict ⇒ Object
Returns the value of attribute strict.
Instance Method Summary collapse
- #&(other) ⇒ Object
- #_make_in_term(col, op, v) ⇒ Object
- #_make_or_term(col, op, values) ⇒ Object
-
#_make_term(*args) ⇒ Object
_make_term(:x => 1).
- #_quote(label) ⇒ Object
- #add(*args) ⇒ Object
- #add_raw(*args) ⇒ Object
- #as_sql ⇒ Object
- #compose_and(other) ⇒ Object
- #compose_or(other) ⇒ Object
-
#initialize(args = {}) ⇒ Condition
constructor
A new instance of Condition.
- #new_condition(args = {}) ⇒ Object
- #|(other) ⇒ Object
Methods included from Util
#array_wrap, #bind_param, bind_param, #croak, included, #parse_args, #quote_identifier, quote_identifier
Constructor Details
#initialize(args = {}) ⇒ Condition
Returns a new instance of Condition.
9 10 11 12 13 14 15 16 17 |
# 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 |
Instance Attribute Details
#auto_bind ⇒ Object
Returns the value of attribute auto_bind.
6 7 8 |
# File 'lib/sql/maker/condition.rb', line 6 def auto_bind @auto_bind end |
#bind ⇒ Object
Returns the value of attribute bind.
7 8 9 |
# File 'lib/sql/maker/condition.rb', line 7 def bind @bind end |
#name_sep ⇒ Object
Returns the value of attribute name_sep.
6 7 8 |
# File 'lib/sql/maker/condition.rb', line 6 def name_sep @name_sep end |
#quote_char ⇒ Object
Returns the value of attribute quote_char.
6 7 8 |
# File 'lib/sql/maker/condition.rb', line 6 def quote_char @quote_char end |
#sql ⇒ Object
Returns the value of attribute sql.
7 8 9 |
# File 'lib/sql/maker/condition.rb', line 7 def sql @sql end |
#strict ⇒ Object
Returns the value of attribute strict.
6 7 8 |
# File 'lib/sql/maker/condition.rb', line 6 def strict @strict end |
Instance Method Details
#&(other) ⇒ Object
27 28 29 |
# File 'lib/sql/maker/condition.rb', line 27 def &(other) self.compose_and(other) end |
#_make_in_term(col, op, v) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# 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) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 |
# 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) ⇒ Object
_make_term(:x => 1)
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# 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) ⇒ Object
35 36 37 |
# File 'lib/sql/maker/condition.rb', line 35 def _quote(label) quote_identifier(label, self.quote_char, self.name_sep) end |
#add(*args) ⇒ Object
120 121 122 123 124 125 126 |
# 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) ⇒ Object
128 129 130 131 132 133 |
# 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 ⇒ Object
183 184 185 186 |
# 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) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# 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) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# 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 = {}) ⇒ Object
19 20 21 22 23 24 25 |
# 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) ⇒ Object
31 32 33 |
# File 'lib/sql/maker/condition.rb', line 31 def |(other) self.compose_or(other) end |