Class: Seaquel::ExpressionConverter
- Inherits:
-
Object
- Object
- Seaquel::ExpressionConverter
- Extended by:
- Forwardable
- Defined in:
- lib/seaquel/expression_converter.rb
Instance Attribute Summary collapse
-
#quoter ⇒ Object
readonly
Returns the value of attribute quoter.
Instance Method Summary collapse
-
#initialize(quoter) ⇒ ExpressionConverter
constructor
A new instance of ExpressionConverter.
- #sql(node) ⇒ Object
- #visit_alias(name, to) ⇒ Object
- #visit_assign(left, right) ⇒ Object
- #visit_binding(pos) ⇒ Object
- #visit_binop(op, left, right) ⇒ Object
- #visit_column(col) ⇒ Object
- #visit_column_list(elements) ⇒ Object
- #visit_funcall(name, args) ⇒ Object
- #visit_joinop(op, exps) ⇒ Object
- #visit_list(elements) ⇒ Object
- #visit_literal(literal) ⇒ Object
- #visit_new_statement(*args) ⇒ Object
-
#visit_node(node) ⇒ Object
Gets called whenever the expression contains a statement-type AST::Node.
- #visit_order(order, expr) ⇒ Object
- #visit_table(table) ⇒ Object
- #visit_table_alias(table, name) ⇒ Object
- #visit_unary(op, exp) ⇒ Object
Constructor Details
#initialize(quoter) ⇒ ExpressionConverter
Returns a new instance of ExpressionConverter.
9 10 11 |
# File 'lib/seaquel/expression_converter.rb', line 9 def initialize quoter @quoter = quoter end |
Instance Attribute Details
#quoter ⇒ Object (readonly)
Returns the value of attribute quoter.
7 8 9 |
# File 'lib/seaquel/expression_converter.rb', line 7 def quoter @quoter end |
Instance Method Details
#sql(node) ⇒ Object
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/seaquel/expression_converter.rb', line 152 def sql node # p [:sql, node] case node when nil bit('NULL') when Array sql_bits = node.map { |el| sql(el).at(0) } bit("(" + sql_bits.join(', ') + ")") when String bit(quote_string(node)) when Fixnum bit(quote_number(node)) when true,false node ? bit('TRUE') : bit('FALSE') else node.visit(self) end end |
#visit_alias(name, to) ⇒ Object
61 62 63 64 |
# File 'lib/seaquel/expression_converter.rb', line 61 def visit_alias name, to prec = precedence(:as) bit("#{sql(to).at(prec)} AS \"#{name}\"") end |
#visit_assign(left, right) ⇒ Object
22 23 24 25 26 27 28 29 30 |
# File 'lib/seaquel/expression_converter.rb', line 22 def visit_assign left, right if left.kind_of? AST::Column bit( [left.as_column_reference(quoter), '=', sql(right).at(0)].join) else bit( [sql(left).at(0), '=', sql(right).at(0)].join) end end |
#visit_binding(pos) ⇒ Object
139 140 141 |
# File 'lib/seaquel/expression_converter.rb', line 139 def visit_binding pos bit("$#{pos}") end |
#visit_binop(op, left, right) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/seaquel/expression_converter.rb', line 66 def visit_binop op, left, right prec = precedence(op) if right.nil? op = :is if op==:eq op = :isnot if op==:noteq end if op==:in && right.kind_of?(Range) raise "Ranges excluding the right side are not permitted in Seaquel." \ if right.exclude_end? return bit([ sql(left).at(0), 'BETWEEN', right.begin, 'AND', right.end].join(' ')) end if binops.has_key?(op) symbol = binops[op] return bit( [sql(left).at(prec), symbol, sql(right).at(prec)].join, prec) end raise "No such operation (#{op.inspect})." end |
#visit_column(col) ⇒ Object
135 136 137 |
# File 'lib/seaquel/expression_converter.rb', line 135 def visit_column col bit(col.as_full_reference(quoter)) end |
#visit_column_list(elements) ⇒ Object
44 45 46 47 |
# File 'lib/seaquel/expression_converter.rb', line 44 def visit_column_list elements # Column lists only contain columns. bit(elements.map { |e| e.as_column_reference(quoter) }.join(', ')) end |
#visit_funcall(name, args) ⇒ Object
143 144 145 146 |
# File 'lib/seaquel/expression_converter.rb', line 143 def visit_funcall name, args arglist = args.map { |arg| sql(arg).toplevel }.join(', ') bit("#{name}(#{arglist})") end |
#visit_joinop(op, exps) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/seaquel/expression_converter.rb', line 97 def visit_joinop op, exps # Shortcut if we join one element only. if exps.size == 1 el = exps.first return sql(el) end prec = precedence(op) parts = exps.map { |e| sql(e).at(prec) } sql = case op when :and parts.join(' AND ') when :or parts.join(' OR ') else raise "AF: JoinOp called for #{op.inspect}, but has no branch for it." end bit(sql, prec) end |
#visit_list(elements) ⇒ Object
40 41 42 |
# File 'lib/seaquel/expression_converter.rb', line 40 def visit_list elements bit(elements.map { |e| sql(e).at(0) }.join(', ')) end |
#visit_literal(literal) ⇒ Object
36 37 38 |
# File 'lib/seaquel/expression_converter.rb', line 36 def visit_literal literal bit(literal) end |
#visit_new_statement(*args) ⇒ Object
32 33 34 |
# File 'lib/seaquel/expression_converter.rb', line 32 def visit_new_statement *args ::Seaquel::Generator.new(self).compact_sql end |
#visit_node(node) ⇒ Object
Gets called whenever the expression contains a statement-type AST::Node.
15 16 17 |
# File 'lib/seaquel/expression_converter.rb', line 15 def visit_node node bit(node.to_sql, 0) end |
#visit_order(order, expr) ⇒ Object
148 149 150 |
# File 'lib/seaquel/expression_converter.rb', line 148 def visit_order order, expr bit("#{sql(expr).at(0)} #{order.upcase}") end |
#visit_table(table) ⇒ Object
49 50 51 |
# File 'lib/seaquel/expression_converter.rb', line 49 def visit_table table bit(table.quote(quoter)) end |
#visit_table_alias(table, name) ⇒ Object
53 54 55 56 57 58 59 |
# File 'lib/seaquel/expression_converter.rb', line 53 def visit_table_alias table, name bit([ sql(table).at(0), "AS", quoter.identifier(name) ].join(' ')) end |
#visit_unary(op, exp) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/seaquel/expression_converter.rb', line 119 def visit_unary op, exp raise "No such unary operation #{op.inspect}." \ unless unaryops.has_key?(op) symbol, prefix = unaryops[op] prec = precedences[op] parts = [] parts << symbol if prefix parts << sql(exp).at(0) parts << symbol unless prefix bit(parts.join, prec) end |