influxdb-arel 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/Gemfile +1 -0
  4. data/README.md +218 -124
  5. data/lib/influxdb/arel.rb +25 -16
  6. data/lib/influxdb/arel/builder.rb +209 -0
  7. data/lib/influxdb/arel/clauses.rb +6 -0
  8. data/lib/influxdb/arel/clauses/base.rb +34 -0
  9. data/lib/influxdb/arel/clauses/expressions.rb +75 -0
  10. data/lib/influxdb/arel/clauses/from_clause.rb +45 -0
  11. data/lib/influxdb/arel/clauses/group_clause.rb +34 -0
  12. data/lib/influxdb/arel/clauses/select_clause.rb +37 -0
  13. data/lib/influxdb/arel/clauses/where_clause.rb +102 -0
  14. data/lib/influxdb/arel/core_extensions.rb +5 -21
  15. data/lib/influxdb/arel/delete_manager.rb +50 -0
  16. data/lib/influxdb/arel/extensions.rb +6 -0
  17. data/lib/influxdb/arel/extensions/alias_predication.rb +11 -0
  18. data/lib/influxdb/arel/extensions/boolean_predications.rb +15 -0
  19. data/lib/influxdb/arel/extensions/expressions.rb +75 -0
  20. data/lib/influxdb/arel/extensions/joining_merging.rb +21 -0
  21. data/lib/influxdb/arel/extensions/math.rb +23 -0
  22. data/lib/influxdb/arel/extensions/predications.rb +144 -0
  23. data/lib/influxdb/arel/nodes.rb +7 -14
  24. data/lib/influxdb/arel/nodes/attribute.rb +20 -0
  25. data/lib/influxdb/arel/nodes/binary.rb +4 -3
  26. data/lib/influxdb/arel/nodes/delete_statement.rb +37 -0
  27. data/lib/influxdb/arel/nodes/duration.rb +3 -3
  28. data/lib/influxdb/arel/nodes/function.rb +2 -2
  29. data/lib/influxdb/arel/nodes/grouping.rb +3 -3
  30. data/lib/influxdb/arel/nodes/infix_operation.rb +11 -4
  31. data/lib/influxdb/arel/nodes/merge.rb +13 -0
  32. data/lib/influxdb/arel/nodes/node.rb +18 -6
  33. data/lib/influxdb/arel/nodes/now.rb +1 -1
  34. data/lib/influxdb/arel/nodes/ordering.rb +15 -0
  35. data/lib/influxdb/arel/nodes/select_statement.rb +10 -8
  36. data/lib/influxdb/arel/nodes/sql_literal.rb +5 -8
  37. data/lib/influxdb/arel/nodes/table.rb +19 -0
  38. data/lib/influxdb/arel/nodes/table_alias.rb +2 -4
  39. data/lib/influxdb/arel/nodes/unary.rb +6 -1
  40. data/lib/influxdb/arel/quoter.rb +85 -0
  41. data/lib/influxdb/arel/select_manager.rb +111 -64
  42. data/lib/influxdb/arel/tree_manager.rb +15 -5
  43. data/lib/influxdb/arel/version.rb +1 -1
  44. data/lib/influxdb/arel/visitor.rb +96 -126
  45. data/lib/influxdb/arel/visitor/delete_statement.rb +32 -0
  46. data/lib/influxdb/arel/visitor/select_statement.rb +59 -0
  47. data/lib/influxdb/arel/visitor/where_statement.rb +14 -0
  48. data/spec/lib/influxdb/arel/builder_spec.rb +173 -0
  49. data/spec/lib/influxdb/arel/core_extensions_spec.rb +0 -21
  50. data/spec/lib/influxdb/arel/nodes/and_spec.rb +6 -9
  51. data/spec/lib/influxdb/arel/nodes/attribute_spec.rb +21 -0
  52. data/spec/lib/influxdb/arel/nodes/binary_spec.rb +0 -4
  53. data/spec/lib/influxdb/arel/nodes/duration_spec.rb +1 -0
  54. data/spec/lib/influxdb/arel/nodes/in_spec.rb +1 -0
  55. data/spec/lib/influxdb/arel/nodes/infix_operation_spec.rb +17 -0
  56. data/spec/lib/influxdb/arel/nodes/merge_spec.rb +25 -0
  57. data/spec/lib/influxdb/arel/nodes/now_spec.rb +1 -0
  58. data/spec/lib/influxdb/arel/nodes/ordering_spec.rb +19 -0
  59. data/spec/lib/influxdb/arel/nodes/sql_literal_spec.rb +1 -5
  60. data/spec/lib/influxdb/arel/nodes/table_alias_spec.rb +3 -10
  61. data/spec/lib/influxdb/arel/nodes/table_spec.rb +8 -0
  62. data/spec/lib/influxdb/arel/nodes/unary_spec.rb +0 -4
  63. data/spec/lib/influxdb/arel/quoter/repository_spec.rb +10 -0
  64. data/spec/lib/influxdb/arel/quoter_spec.rb +33 -0
  65. data/spec/lib/influxdb/arel/select_manager_spec.rb +356 -156
  66. data/spec/lib/influxdb/arel_spec.rb +22 -0
  67. data/spec/spec_helper.rb +15 -0
  68. data/spec/support/examples/binary_node.rb +1 -0
  69. data/spec/support/examples/function_node.rb +1 -0
  70. data/spec/support/examples/infix_operation_node.rb +15 -0
  71. data/spec/support/examples/node_boolean_predications.rb +21 -0
  72. data/spec/support/examples/node_joining_merging.rb +53 -0
  73. data/spec/support/examples/unary_node.rb +1 -0
  74. data/spec/support/fabrics.rb +3 -3
  75. metadata +49 -11
  76. data/lib/influxdb/arel/alias_predication.rb +0 -9
  77. data/lib/influxdb/arel/attributes.rb +0 -1
  78. data/lib/influxdb/arel/attributes/attribute.rb +0 -74
  79. data/lib/influxdb/arel/expressions.rb +0 -73
  80. data/lib/influxdb/arel/math.rb +0 -21
  81. data/lib/influxdb/arel/predications.rb +0 -137
  82. data/lib/influxdb/arel/table.rb +0 -219
  83. data/spec/lib/influxdb/arel/table_spec.rb +0 -193
@@ -1,96 +1,98 @@
1
1
  module Influxdb
2
2
  module Arel
3
3
  class SelectManager < Arel::TreeManager
4
- def initialize(*tables)
4
+ DIRECTIONS = [:asc, :desc].freeze
5
+
6
+ def initialize(*tables, &block)
5
7
  super()
6
8
  @ast = Nodes::SelectStatement.new
7
- from(*tables)
9
+ from(*tables, &block)
8
10
  end
9
11
 
10
- def initialize_copy(other)
11
- super
12
+ def group(*attributes, &block)
13
+ ast.groups |= Clauses::GroupClause.new(*attributes, &block).to_arel
14
+ self
12
15
  end
13
16
 
14
- def limit
15
- ast.limit
17
+ def group!(*attributes, &block)
18
+ ast.groups = process_value_with_bang(Clauses::GroupClause, attributes, &block)
19
+ self
16
20
  end
17
21
 
18
- alias :taken :limit
19
-
20
- def wheres
21
- ast.wheres
22
+ def group_values
23
+ ast.groups
22
24
  end
23
25
 
24
- def group(*columns)
25
- columns.each do |column|
26
- column = STRING_OR_SYMBOL_CLASS.include?(column.class) ? Arel.sql(column.to_s) : column
27
- ast.groups.push(Nodes::Group.new(column))
28
- end
29
-
26
+ def select(*attributes, &block)
27
+ ast.attributes |= Clauses::SelectClause.new(*attributes, &block).to_arel
30
28
  self
31
29
  end
32
30
 
33
- def fill(value)
34
- ast.fill = Nodes::Fill.new(value)
31
+ def select!(*attributes, &block)
32
+ ast.attributes = process_value_with_bang(Clauses::SelectClause, attributes, &block)
35
33
  self
36
34
  end
37
35
 
38
- def from(*series)
39
- series = series.map do |table|
40
- case table
41
- when String, Symbol
42
- Arel.sql(table.to_s)
43
- when Regexp
44
- Arel.sql(table.inspect)
45
- else
46
- table
47
- end
48
- end.compact
49
-
50
- ast.series = series unless series.empty?
51
- self
36
+ def select_values
37
+ ast.attributes
52
38
  end
53
39
 
54
- def join(table = nil)
55
- if table && !series.empty?
56
- table = STRING_OR_SYMBOL_CLASS.include?(table.class) ? Arel.sql(table.to_s) : table
57
- ast.join = Nodes::Join.new(series[0], table)
58
- elsif series.size > 1
59
- ast.join = Nodes::Join.new(series[0], series[1])
60
- end
40
+ def fill(value)
41
+ ast.fill = Nodes::Fill.new(value)
61
42
  self
62
43
  end
63
44
 
64
- def merge(table = nil)
65
- if table && !series.empty?
66
- table = STRING_OR_SYMBOL_CLASS.include?(table.class) ? Arel.sql(table.to_s) : table
67
- ast.merge = Nodes::Merge.new(series[0].unalias, table.unalias)
68
- elsif series.size > 1
69
- ast.merge = Nodes::Merge.new(series[0].unalias, series[1].unalias)
70
- end
71
- self
45
+ def fill_value
46
+ ast.fill
72
47
  end
73
48
 
74
- def column(*columns)
75
- columns.each do |column|
76
- column = STRING_OR_SYMBOL_CLASS.include?(column.class) ? Arel.sql(column.to_s) : column
77
- ast.columns.push(column)
49
+ def from(*new_tables, &block)
50
+ new_tables = new_tables.compact
51
+ return self if new_tables.empty? && !block_given?
52
+
53
+ expr = Clauses::FromClause.new(*new_tables, &block).to_arel
54
+
55
+ case expr
56
+ when Array
57
+ regexps, merges, joins, others = separate_tables(expr.to_a)
58
+ ast.regexp = Nodes::Table.new(regexps.first) if regexps
59
+ ast.join = joins.first if joins
60
+ ast.merge = merges.first if merges
61
+ ast.tables = others if others
62
+ when Nodes::Join
63
+ ast.join = expr
64
+ when Nodes::Merge
65
+ ast.merge = expr
66
+ when Regexp
67
+ ast.regexp = expr
68
+ else
69
+ ast.tables = Array(expr)
78
70
  end
79
71
 
80
72
  self
81
73
  end
82
74
 
83
- def columns
84
- ast.columns
75
+ def tables
76
+ [ast.regexp] || ast.tables
85
77
  end
86
78
 
87
- def columns=(columns)
88
- self.column(*columns)
79
+ def join(*joining_tables)
80
+ ast.join = process_value_for_tables_union(Nodes::Join, joining_tables, :joining)
81
+ self
82
+ end
83
+
84
+ def merge(*merging_tables)
85
+ ast.merge = process_value_for_tables_union(Nodes::Merge, merging_tables, :merging)
86
+ self
89
87
  end
90
88
 
91
89
  def order(expr)
92
- expr = STRING_OR_SYMBOL_CLASS.include?(expr.class) ? Nodes::Ordering.new(expr.to_s) : expr
93
- ast.order = expr
90
+ case
91
+ when Nodes::Ordering === expr
92
+ ast.order = expr
93
+ when DIRECTIONS.include?(expr.to_sym)
94
+ send(expr)
95
+ end
94
96
  self
95
97
  end
96
98
 
@@ -104,25 +106,70 @@ module Influxdb
104
106
  self
105
107
  end
106
108
 
107
- def ordering
109
+ def invert_order
110
+ ast.order = (ast.order && ast.order.invert) || Nodes::Ordering.new('asc')
111
+ self
112
+ end
113
+
114
+ def order_value
108
115
  ast.order
109
116
  end
110
117
 
111
- def take(limit)
118
+ def limit(limit)
112
119
  ast.limit = limit ? Nodes::Limit.new(limit) : nil
113
120
  self
114
121
  end
115
122
 
116
- alias :limit= :take
123
+ def limit_value
124
+ ast.limit
125
+ end
117
126
 
118
127
  def into(table)
119
- table = STRING_OR_SYMBOL_CLASS.include?(table.class) ? Arel.sql(table.to_s) : table
120
- ast.into = Nodes::Into.new(table)
128
+ ast.into = Nodes::Into.new(Arel.arelize(table))
121
129
  self
122
130
  end
123
131
 
124
- def series
125
- ast.series
132
+ def into_value
133
+ ast.into
134
+ end
135
+
136
+ def delete
137
+ raise 'IllegalSQLConstruct: Ambiguous deletion operation' if ast.tables.size != 1
138
+ DeleteManager.new.tap do |manager|
139
+ manager.tables = ast.tables
140
+ manager.regexp = ast.regexp
141
+ manager.where_values = where_values
142
+ end
143
+ end
144
+
145
+ private
146
+
147
+ def process_value_with_bang(klass, attributes, &block)
148
+ return nil if attributes.empty? && !block_given?
149
+ klass.new(*attributes, &block).to_arel
150
+ end
151
+
152
+ def process_value_for_tables_union(klass, tables, type)
153
+ _tables = (ast.tables + tables).compact
154
+ raise "IllegalSQLConstruct: Ambiguous #{type} clause" if _tables.size != 2
155
+ _tables = Arel.arelize(_tables){|expr| Nodes::Table.new(expr) }
156
+ klass.new(*_tables)
157
+ end
158
+
159
+ def separate_tables(expr)
160
+ grouped_tables = expr.group_by do |value|
161
+ case value
162
+ when Nodes::Join
163
+ :joins
164
+ when Nodes::Merge
165
+ :merges
166
+ when Regexp
167
+ :regexp
168
+ else
169
+ :others
170
+ end
171
+ end
172
+ grouped_tables.values_at(:regexp, :merges, :joins, :others)
126
173
  end
127
174
  end
128
175
  end
@@ -15,16 +15,26 @@ module Influxdb
15
15
 
16
16
  def initialize_copy(other)
17
17
  super
18
- @ast = @ast.clone
18
+ @ast = ast.clone
19
19
  end
20
20
 
21
- def where(expr)
22
- expr = expr.ast if TreeManager === expr
23
- expr = Arel.sql(expr) if String === expr
21
+ def where(expr = nil, &block)
22
+ ast.wheres << Clauses::WhereClause.new(expr, &block).to_arel
23
+ self
24
+ end
24
25
 
25
- ast.wheres << expr
26
+ def where!(expr = nil, &block)
27
+ ast.wheres = [Clauses::WhereClause.new(expr, &block).to_arel].compact
26
28
  self
27
29
  end
30
+
31
+ def where_values
32
+ ast.wheres
33
+ end
34
+
35
+ def where_values=(value)
36
+ ast.wheres = value
37
+ end
28
38
  end
29
39
  end
30
40
  end
@@ -1,5 +1,5 @@
1
1
  module Influxdb
2
2
  module Arel
3
- VERSION = "0.0.1"
3
+ VERSION = '0.1.0'
4
4
  end
5
5
  end
@@ -18,90 +18,60 @@ module Influxdb
18
18
  method_hash[node_class] = "visit_#{(node_class.name || '').gsub('::', '_')}"
19
19
  end
20
20
 
21
- def visit(object, attribute = nil)
22
- send DISPATCH[object.class], object, attribute
21
+ def visit(object)
22
+ send(DISPATCH[object.class], object)
23
23
  rescue NoMethodError => e
24
24
  raise e if respond_to?(DISPATCH[object.class], true)
25
-
26
- superklass = object.class.ancestors.find{|klass|
27
- respond_to?(DISPATCH[klass], true)
28
- }
29
- raise(TypeError, "Cannot visit #{object.class}") unless superklass
30
-
31
- DISPATCH[object.class] = DISPATCH[superklass]
25
+ DISPATCH[object.class] = DISPATCH[find_visitable_superclass(object)]
32
26
  retry
33
27
  end
34
28
 
35
- def visit_Influxdb_Arel_Nodes_SelectStatement(object, attribute)
36
- result = 'SELECT'
37
-
38
- unless object.columns.empty?
39
- result << SPACE
40
- result << object.columns.map{|column| visit(column, attribute) }.join(COMMA)
41
- else
42
- result << SPACE
43
- result << Arel.star
44
- end
45
-
46
- result << " FROM #{visit(object.table, attribute)}"
47
-
48
- unless object.wheres.empty?
49
- result << WHERE
50
- result << object.wheres.map{|where| visit(where, attribute) }.join(AND)
51
- end
52
-
53
- unless object.groups.empty?
54
- result << GROUP_BY
55
- result << object.groups.map{|group| visit(group, attribute) }.join(COMMA)
56
- result << " #{visit(object.fill, attribute)}" if object.fill
57
- end
58
-
59
- result << " #{visit(object.order, attribute)}" if object.order
60
- result << " #{visit(object.limit, attribute)}" if object.limit
61
- result << " #{visit(object.into, attribute)}" if object.into
29
+ def visit_Influxdb_Arel_Nodes_SelectStatement(object)
30
+ SelectStatement.new(self).visit(object)
31
+ end
62
32
 
63
- result.strip!
64
- result
33
+ def visit_Influxdb_Arel_Nodes_DeleteStatement(object)
34
+ DeleteStatement.new(self).visit(object)
65
35
  end
66
36
 
67
- def visit_Influxdb_Arel_Table(object, attribute)
37
+ def visit_Influxdb_Arel_Nodes_Table(object)
68
38
  quote_table_name(object.name)
69
39
  end
70
40
 
71
- def visit_Influxdb_Arel_Nodes_Join(object, attribute)
72
- "#{visit(object.left, attribute)} INNER JOIN #{visit(object.right, attribute)}"
41
+ def visit_Influxdb_Arel_Nodes_Join(object)
42
+ visit_predication(object, 'INNER JOIN')
73
43
  end
74
44
 
75
- def visit_Influxdb_Arel_Nodes_Merge(object, attribute)
76
- "#{visit(object.left, attribute)} MERGE #{visit(object.right, attribute)}"
45
+ def visit_Influxdb_Arel_Nodes_Merge(object)
46
+ visit_predication(object, 'MERGE')
77
47
  end
78
48
 
79
- def visit_Influxdb_Arel_Nodes_Limit(object, attribute)
80
- "LIMIT #{visit(object.expr, attribute)}"
49
+ def visit_Influxdb_Arel_Nodes_Limit(object)
50
+ "LIMIT #{visit(object.expr)}"
81
51
  end
82
52
 
83
- def visit_Influxdb_Arel_Nodes_Ordering(object, attribute)
53
+ def visit_Influxdb_Arel_Nodes_Ordering(object)
84
54
  "ORDER #{object.value.upcase}"
85
55
  end
86
56
 
87
- def visit_Influxdb_Arel_Nodes_Into(object, attribute)
88
- "INTO #{visit(object.expr, attribute)}"
57
+ def visit_Influxdb_Arel_Nodes_Into(object)
58
+ "INTO #{visit(object.expr)}"
89
59
  end
90
60
 
91
- def visit_Influxdb_Arel_Nodes_Grouping(object, attribute)
92
- "(#{visit(object.expr, attribute)})"
61
+ def visit_Influxdb_Arel_Nodes_Grouping(object)
62
+ "(#{visit(object.expr)})"
93
63
  end
94
64
 
95
- def visit_Influxdb_Arel_Nodes_Group(object, attribute)
96
- visit(object.expr, attribute)
65
+ def visit_Influxdb_Arel_Nodes_Group(object)
66
+ visit(object.expr)
97
67
  end
98
68
 
99
- def visit_Influxdb_Arel_Nodes_TableAlias(object, attribute)
100
- "#{visit(object.relation, attribute)} AS #{quote_table_name(object.name)}"
69
+ def visit_Influxdb_Arel_Nodes_TableAlias(object)
70
+ "#{visit(object.relation)} AS #{quote_table_name(object.name)}"
101
71
  end
102
72
 
103
- def function(object, attribute)
104
- expressions = object.expressions.map{|exp| visit(exp, attribute) }.join(COMMA)
73
+ def function(object)
74
+ expressions = object.expressions.map{|exp| visit(exp) }.join(COMMA)
105
75
  function_clause = object.class.name.split('::').last.upcase
106
76
  "#{function_clause}(#{expressions})"
107
77
  end
@@ -124,104 +94,99 @@ module Influxdb
124
94
  alias :visit_Influxdb_Arel_Nodes_Top :function
125
95
  alias :visit_Influxdb_Arel_Nodes_Bottom :function
126
96
 
127
- def visit_Influxdb_Arel_Nodes_Fill(object, attribute)
128
- "fill(#{visit(object.expr, attribute)})"
97
+ def visit_Influxdb_Arel_Nodes_Fill(object)
98
+ "fill(#{visit(object.expr)})"
129
99
  end
130
100
 
131
- def visit_Influxdb_Arel_Nodes_Time(object, attribute)
132
- "time(#{visit(object.expr, attribute)})"
101
+ def visit_Influxdb_Arel_Nodes_Time(object)
102
+ "time(#{visit(object.expr)})"
133
103
  end
134
104
 
135
- def visit_Influxdb_Arel_Nodes_Duration(object, attribute)
105
+ def visit_Influxdb_Arel_Nodes_Duration(object)
136
106
  "#{object.value}#{object.suffix}"
137
107
  end
138
108
 
139
- def visit_Influxdb_Arel_Nodes_Now(object, attribute)
109
+ def visit_Influxdb_Arel_Nodes_Now(object)
140
110
  "now()"
141
111
  end
142
112
 
143
- def visit_Influxdb_Arel_Nodes_In(object, attribute)
113
+ def visit_Influxdb_Arel_Nodes_In(object)
144
114
  if Array === object.right && object.right.empty?
145
115
  '1 = 0'
146
116
  else
147
- attribute = object.left if Arel::Attributes::Attribute === object.left
148
- "#{visit(object.left, attribute)} IN (#{visit(object.right, attribute)})"
117
+ "#{visit(object.left)} IN (#{visit(object.right)})"
149
118
  end
150
119
  end
151
120
 
152
- def visit_Influxdb_Arel_Nodes_GreaterThanOrEqual(object, attribute)
153
- attribute = object.left if Attributes::Attribute === object.left
154
- "#{visit(object.left, attribute)} >= #{visit(object.right, attribute)}"
121
+ def visit_Influxdb_Arel_Nodes_GreaterThanOrEqual(object)
122
+ if object.left.is_a?(Nodes::Attribute) && object.left.time?
123
+ right = object.right - 1
124
+ operator = '>'
125
+ else
126
+ right = object.right
127
+ operator = '>='
128
+ end
129
+ visit_predication(object, operator, right)
155
130
  end
156
131
 
157
- def visit_Influxdb_Arel_Nodes_GreaterThan(object, attribute)
158
- attribute = object.left if Attributes::Attribute === object.left
159
- "#{visit(object.left, attribute)} > #{visit(object.right, attribute)}"
132
+ def visit_Influxdb_Arel_Nodes_GreaterThan(object)
133
+ visit_predication(object, '>')
160
134
  end
161
135
 
162
- def visit_Influxdb_Arel_Nodes_LessThanOrEqual(object, attribute)
163
- attribute = object.left if Attributes::Attribute === object.left
164
- "#{visit(object.left, attribute)} <= #{visit(object.right, attribute)}"
136
+ def visit_Influxdb_Arel_Nodes_LessThanOrEqual(object)
137
+ if object.left.is_a?(Nodes::Attribute) && object.left.time?
138
+ right = object.right + 1
139
+ operator = '<'
140
+ else
141
+ right = object.right
142
+ operator = '<='
143
+ end
144
+ visit_predication(object, operator, right)
165
145
  end
166
146
 
167
- def visit_Influxdb_Arel_Nodes_LessThan(object, attribute)
168
- attribute = object.left if Attributes::Attribute === object.left
169
- "#{visit(object.left, attribute)} < #{visit(object.right, attribute)}"
147
+ def visit_Influxdb_Arel_Nodes_LessThan(object)
148
+ visit_predication(object, '<')
170
149
  end
171
150
 
172
- def visit_Influxdb_Arel_Nodes_NotEqual(object, attribute)
173
- right = object.right
174
- attribute = object.left if Attributes::Attribute === object.left
175
-
176
- if right.nil?
177
- "#{visit(object.left, attribute)} <> null"
178
- else
179
- "#{visit(object.left, attribute)} <> #{visit(right, attribute)}"
180
- end
151
+ def visit_Influxdb_Arel_Nodes_NotEqual(object)
152
+ visit_predication(object, '<>')
181
153
  end
182
154
 
183
- def visit_Influxdb_Arel_Nodes_Equality(object, attribute)
184
- right = object.right
185
- attribute = object.left if Attributes::Attribute === object.left
186
-
187
- if right.nil?
188
- "#{visit(object.left, attribute)} = null"
189
- else
190
- "#{visit(object.left, attribute)} = #{visit(right, attribute)}"
191
- end
155
+ def visit_Influxdb_Arel_Nodes_Equality(object)
156
+ visit_predication(object, '=')
192
157
  end
193
158
 
194
- def visit_Influxdb_Arel_Nodes_Matches(object, attribute)
195
- attribute = object.left if Attributes::Attribute === object.left
196
- "#{visit object.left, attribute} =~ #{visit object.right, attribute}"
159
+ def visit_Influxdb_Arel_Nodes_Matches(object)
160
+ visit_predication(object, '=~')
197
161
  end
198
162
 
199
- def visit_Influxdb_Arel_Nodes_DoesNotMatch(object, attribute)
200
- attribute = object.left if Attributes::Attribute === object.left
201
- "#{visit(object.left, attribute)} !~ #{visit(object.right, attribute)}"
163
+ def visit_Influxdb_Arel_Nodes_DoesNotMatch(object)
164
+ visit_predication(object, '!~')
202
165
  end
203
166
 
204
- def visit_Influxdb_Arel_Nodes_And(object, attribute)
205
- object.children.map{|node| visit(node, attribute) }.join(AND)
167
+ def visit_Influxdb_Arel_Nodes_And(object)
168
+ object.children.map{|node| visit(node) }.join(AND)
206
169
  end
207
170
 
208
- def visit_Influxdb_Arel_Nodes_Or(object, attribute)
209
- [visit(object.left, attribute), visit(object.right, attribute)].join(OR)
171
+ def visit_Influxdb_Arel_Nodes_Or(object)
172
+ [visit(object.left), visit(object.right)].join(OR)
210
173
  end
211
174
 
212
- def visit_Influxdb_Arel_Nodes_As(object, attribute)
213
- "#{visit(object.left, attribute)} AS #{visit(object.right, attribute)}"
175
+ def visit_Influxdb_Arel_Nodes_As(object)
176
+ visit_predication(object, 'AS')
214
177
  end
215
178
 
216
- def visit_Influxdb_Arel_Attributes_Attribute(object, attribute)
217
- if object.relation.table_alias
218
- "#{quote_table_name(object.relation.table_alias)}.#{quote_column_name(object.name)}"
219
- else
220
- quote_column_name(object.name)
221
- end
179
+ def visit_Influxdb_Arel_Nodes_Attribute(object)
180
+ # if object.relation.table_alias
181
+ # "#{quote_table_name(object.relation.table_alias)}.#{quote_column_name(object.name)}"
182
+ # else
183
+ # quote_column_name(object.name)
184
+ # end
185
+
186
+ quote_column_name(object.value)
222
187
  end
223
188
 
224
- def literal(object, attribute)
189
+ def literal(object)
225
190
  object
226
191
  end
227
192
 
@@ -229,7 +194,7 @@ module Influxdb
229
194
  alias :visit_Bignum :literal
230
195
  alias :visit_Fixnum :literal
231
196
 
232
- def quoted(object, attribute)
197
+ def quoted(object)
233
198
  quote(object)
234
199
  end
235
200
 
@@ -249,8 +214,8 @@ module Influxdb
249
214
  alias :visit_TrueClass :quoted
250
215
  alias :visit_Regexp :quoted
251
216
 
252
- def visit_Influxdb_Arel_Nodes_InfixOperation(object, attribute)
253
- "#{visit(object.left, attribute)} #{object.operator} #{visit(object.right, attribute)}"
217
+ def visit_Influxdb_Arel_Nodes_InfixOperation(object)
218
+ visit_predication(object, object.operator)
254
219
  end
255
220
 
256
221
  alias :visit_Influxdb_Arel_Nodes_Addition :visit_Influxdb_Arel_Nodes_InfixOperation
@@ -258,17 +223,20 @@ module Influxdb
258
223
  alias :visit_Influxdb_Arel_Nodes_Multiplication :visit_Influxdb_Arel_Nodes_InfixOperation
259
224
  alias :visit_Influxdb_Arel_Nodes_Division :visit_Influxdb_Arel_Nodes_InfixOperation
260
225
 
261
- def visit_Array(object, attribute)
262
- object.map{|node| visit(node, attribute) }.join(COMMA)
226
+ def visit_Array(object)
227
+ object.map{|node| visit(node) }.join(COMMA)
228
+ end
229
+
230
+ def visit_predication(object, expression, right = nil)
231
+ "#{visit(object.left)} #{expression} #{visit(right || object.right)}"
263
232
  end
264
233
 
265
234
  def quote(value)
266
- return value if Arel::Nodes::SqlLiteral === value
267
- attribute_for(value).encode(value)
235
+ Quoter.quote(value)
268
236
  end
269
237
 
270
238
  def quote_table_name(name)
271
- return name if Arel::Nodes::SqlLiteral === name
239
+ return name if Nodes::SqlLiteral === name
272
240
  return name.inspect if Regexp === name
273
241
  /(?!\.)[\W\s]+/.match(name.to_s) ? "\"#{name}\"" : name
274
242
  end
@@ -277,10 +245,12 @@ module Influxdb
277
245
  name
278
246
  end
279
247
 
280
- def attribute_for(value)
281
- Influxdb::Arel::Attributes.const_get(value.class.name, false)
282
- rescue
283
- Influxdb::Arel::Attributes::Attribute
248
+ def find_visitable_superclass(object)
249
+ object.class.ancestors.find{|klass|
250
+ respond_to?(DISPATCH[klass], true)
251
+ }.tap do |superklass|
252
+ raise(TypeError, "Cannot visit #{object.class}") unless superklass
253
+ end
284
254
  end
285
255
  end
286
256
  end