influxdb-arel 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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