influxdb-arel 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +350 -0
- data/Rakefile +6 -0
- data/influxdb-arel.gemspec +24 -0
- data/lib/influxdb-arel.rb +1 -0
- data/lib/influxdb.rb +4 -0
- data/lib/influxdb/arel.rb +38 -0
- data/lib/influxdb/arel/alias_predication.rb +9 -0
- data/lib/influxdb/arel/attributes.rb +1 -0
- data/lib/influxdb/arel/attributes/attribute.rb +74 -0
- data/lib/influxdb/arel/core_extensions.rb +49 -0
- data/lib/influxdb/arel/expressions.rb +73 -0
- data/lib/influxdb/arel/math.rb +21 -0
- data/lib/influxdb/arel/nodes.rb +27 -0
- data/lib/influxdb/arel/nodes/and.rb +32 -0
- data/lib/influxdb/arel/nodes/binary.rb +47 -0
- data/lib/influxdb/arel/nodes/duration.rb +30 -0
- data/lib/influxdb/arel/nodes/equality.rb +11 -0
- data/lib/influxdb/arel/nodes/function.rb +47 -0
- data/lib/influxdb/arel/nodes/grouping.rb +11 -0
- data/lib/influxdb/arel/nodes/in.rb +8 -0
- data/lib/influxdb/arel/nodes/infix_operation.rb +51 -0
- data/lib/influxdb/arel/nodes/node.rb +19 -0
- data/lib/influxdb/arel/nodes/now.rb +15 -0
- data/lib/influxdb/arel/nodes/select_statement.rb +59 -0
- data/lib/influxdb/arel/nodes/sql_literal.rb +23 -0
- data/lib/influxdb/arel/nodes/table_alias.rb +23 -0
- data/lib/influxdb/arel/nodes/time.rb +13 -0
- data/lib/influxdb/arel/nodes/unary.rb +35 -0
- data/lib/influxdb/arel/predications.rb +137 -0
- data/lib/influxdb/arel/select_manager.rb +129 -0
- data/lib/influxdb/arel/table.rb +219 -0
- data/lib/influxdb/arel/tree_manager.rb +30 -0
- data/lib/influxdb/arel/version.rb +5 -0
- data/lib/influxdb/arel/visitor.rb +287 -0
- data/spec/lib/influxdb/arel/core_extensions_spec.rb +49 -0
- data/spec/lib/influxdb/arel/nodes/and_spec.rb +17 -0
- data/spec/lib/influxdb/arel/nodes/binary_spec.rb +49 -0
- data/spec/lib/influxdb/arel/nodes/duration_spec.rb +72 -0
- data/spec/lib/influxdb/arel/nodes/equality_spec.rb +5 -0
- data/spec/lib/influxdb/arel/nodes/function_spec.rb +69 -0
- data/spec/lib/influxdb/arel/nodes/grouping_spec.rb +10 -0
- data/spec/lib/influxdb/arel/nodes/in_spec.rb +13 -0
- data/spec/lib/influxdb/arel/nodes/now_spec.rb +8 -0
- data/spec/lib/influxdb/arel/nodes/sql_literal_spec.rb +28 -0
- data/spec/lib/influxdb/arel/nodes/table_alias_spec.rb +36 -0
- data/spec/lib/influxdb/arel/nodes/time_spec.rb +5 -0
- data/spec/lib/influxdb/arel/nodes/unary_spec.rb +25 -0
- data/spec/lib/influxdb/arel/select_manager_spec.rb +459 -0
- data/spec/lib/influxdb/arel/table_spec.rb +193 -0
- data/spec/lib/influxdb/arel_spec.rb +11 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/examples/binary_node.rb +10 -0
- data/spec/support/examples/function_node.rb +14 -0
- data/spec/support/examples/node_as.rb +8 -0
- data/spec/support/examples/node_expressions.rb +145 -0
- data/spec/support/examples/node_math.rb +29 -0
- data/spec/support/examples/node_predications.rb +248 -0
- data/spec/support/examples/node_to_sql.rb +5 -0
- data/spec/support/examples/unary_node.rb +10 -0
- data/spec/support/fabrics.rb +21 -0
- metadata +177 -0
@@ -0,0 +1,219 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Arel
|
3
|
+
class Table
|
4
|
+
class << self
|
5
|
+
def comparable_classes
|
6
|
+
[Influxdb::Arel::Table, Influxdb::Arel::Nodes::SqlLiteral]
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :name
|
11
|
+
|
12
|
+
alias :table_name :name
|
13
|
+
|
14
|
+
def initialize(name)
|
15
|
+
@name = name.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
# Specify alias for table
|
19
|
+
# Example:
|
20
|
+
#
|
21
|
+
# Influxdb::Arel::Table.new('table').as('alias_table').to_sql
|
22
|
+
# => table AS alias_table
|
23
|
+
#
|
24
|
+
def alias(name)
|
25
|
+
Nodes::TableAlias.new(self, name)
|
26
|
+
end
|
27
|
+
|
28
|
+
alias :as :alias
|
29
|
+
|
30
|
+
def from(*tables)
|
31
|
+
SelectManager.new(*tables)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Merging of two series into one.
|
35
|
+
#
|
36
|
+
# If <tt>table</tt> is nil it will merge two first tables from tables list.
|
37
|
+
#
|
38
|
+
# table = Influxdb::Arel::Table.new('table')
|
39
|
+
# table.from('table1', 'table2').merge.to_sql
|
40
|
+
# => SELECT * FROM table1 MERGE table2
|
41
|
+
#
|
42
|
+
# If <tt>table</tt> is nil and tables list contains only one table it will change nothing.
|
43
|
+
#
|
44
|
+
# table.merge.to_sql
|
45
|
+
# => SELECT * FROM table
|
46
|
+
#
|
47
|
+
# If <tt>table</tt> exists it will merge first table from tables list with given table.
|
48
|
+
#
|
49
|
+
# table.merge('table2').to_sql
|
50
|
+
# => SELECT * FROM table MERGE table2
|
51
|
+
#
|
52
|
+
# table.from('table1', 'table2').merge('table3').to_sql
|
53
|
+
# => SELECT * FROM table1 MERGE table3
|
54
|
+
#
|
55
|
+
def merge(table = nil)
|
56
|
+
from(self).merge(table)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Joining of two series.
|
60
|
+
#
|
61
|
+
# If <tt>table</tt> is nil it will join two first tables from tables list.
|
62
|
+
#
|
63
|
+
# table = Influxdb::Arel::Table.new('table')
|
64
|
+
# table.from('table1', 'table2').join.to_sql
|
65
|
+
# => SELECT * FROM table1 INNER JOIN table2
|
66
|
+
#
|
67
|
+
# If <tt>table</tt> is nil and tables list contains only one table it will change nothing.
|
68
|
+
#
|
69
|
+
# table.join.to_sql
|
70
|
+
# => SELECT * FROM table
|
71
|
+
#
|
72
|
+
# If <tt>table</tt> exists it will join first table from tables list with given table.
|
73
|
+
#
|
74
|
+
# table.join('table2').to_sql
|
75
|
+
# => SELECT * FROM table INNER JOIN table2
|
76
|
+
#
|
77
|
+
# table.from('table1', 'table2').join('table3').to_sql
|
78
|
+
# => SELECT * FROM table1 INNER JOIN table3
|
79
|
+
#
|
80
|
+
# Aliases.
|
81
|
+
# You can define alias for each joined table. It would be usefull for self joining table.
|
82
|
+
#
|
83
|
+
# table.from(table.as(:table_one)).join(table.as(:table_two)).to_sql
|
84
|
+
# => SELECT * FROM table AS table_one INNER JOIN table AS table_two
|
85
|
+
#
|
86
|
+
def join(table = nil)
|
87
|
+
from(self).join(table)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Grouping results by specified columns or expressions, such as <tt>time(10m)</tt>
|
91
|
+
#
|
92
|
+
# table = Influxdb::Arel::Table.new('table')
|
93
|
+
# table.group(table.time(10.m), table[:host]).to_sql
|
94
|
+
# => SELECT * FROM table GROUP BY time(10m), host
|
95
|
+
#
|
96
|
+
# If you want to fill intervals with no data you shoult call <tt>fill</tt> method after:
|
97
|
+
#
|
98
|
+
# table.group(10.m.time, table[:host]).fill(0).to_sql
|
99
|
+
# => SELECT * FROM table GROUP BY time(10m), host fill(0)
|
100
|
+
#
|
101
|
+
def group(*columns)
|
102
|
+
from(self).group(*columns)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Set the ordering of results
|
106
|
+
# Possible values:
|
107
|
+
#
|
108
|
+
# * <tt>:asc</tt>
|
109
|
+
# Default value. Results will be sorted by ascending order.
|
110
|
+
#
|
111
|
+
# * <tt>:desc</tt>
|
112
|
+
# Default value. Results will be sorted by descending order.
|
113
|
+
#
|
114
|
+
# Example:
|
115
|
+
#
|
116
|
+
# table = Influxdb::Arel::Table.new('table')
|
117
|
+
# table.order(:desc).to_sql
|
118
|
+
# table.order('desc').to_sql
|
119
|
+
# => SELECT * FROM table ORDER DESC
|
120
|
+
#
|
121
|
+
# table.order(:asc).to_sql
|
122
|
+
# table.order('asc').to_sql
|
123
|
+
# => SELECT * FROM table ORDER ASC
|
124
|
+
#
|
125
|
+
def order(expr)
|
126
|
+
from(self).order(expr)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Specify conditions for selection or deletion query
|
130
|
+
# Example:
|
131
|
+
#
|
132
|
+
# table = Influxdb::Arel::Table.new('table')
|
133
|
+
# table.where(table[:name].eq('Undr')).to_sql
|
134
|
+
# => SELECT * FROM table WHERE name = 'Undr'
|
135
|
+
#
|
136
|
+
# table.where(table[:name].eq('Undr')).where(table[:time].lt(10.h.ago).to_sql
|
137
|
+
# => SELECT * FROM table WHERE name = 'Undr' AND time < (now() - 10h)
|
138
|
+
#
|
139
|
+
# table.where(table[:name].eq('Undr').or(table[:name].eq('Andrei'))).to_sql
|
140
|
+
# => SELECT * FROM table WHERE name = 'Undr' OR name = 'Andrei'
|
141
|
+
#
|
142
|
+
def where(condition)
|
143
|
+
from(self).where(condition)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Specify columns or expressions for select.
|
147
|
+
# Example:
|
148
|
+
#
|
149
|
+
# table = Influxdb::Arel::Table.new('cpu_load')
|
150
|
+
# table.to_sql
|
151
|
+
# => SELECT * FROM cpu_load
|
152
|
+
#
|
153
|
+
# table.column((table[:system] + table[:user]).as(:sum)).to_sql
|
154
|
+
# => SELECT (system + user) AS sum FROM cpu_load
|
155
|
+
#
|
156
|
+
# table.column(table[:idle].mean.as(:idle_mean), table[:user].mean.as(:user_mean)).to_sql
|
157
|
+
# => SELECT MEAN(idle) AS idle_mean, MEAN(user) AS user_mean FROM cpu_load
|
158
|
+
#
|
159
|
+
def column(*things)
|
160
|
+
from(self).column(*things)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Set limit for result's points
|
164
|
+
# Example:
|
165
|
+
#
|
166
|
+
# table = Influxdb::Arel::Table.new('cpu_load')
|
167
|
+
# table.take(100).to_sql
|
168
|
+
# => SELECT * FROM table LIMIT 100
|
169
|
+
#
|
170
|
+
def take(amount)
|
171
|
+
from(self).take(amount)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Get attribute
|
175
|
+
#
|
176
|
+
def [](name)
|
177
|
+
Attribute.new(self, name)
|
178
|
+
end
|
179
|
+
|
180
|
+
def select_manager
|
181
|
+
SelectManager.new
|
182
|
+
end
|
183
|
+
|
184
|
+
def hash
|
185
|
+
@name.hash
|
186
|
+
end
|
187
|
+
|
188
|
+
def eql?(other)
|
189
|
+
self.class.comparable_classes.include?(self.class) && self.name == other.name
|
190
|
+
end
|
191
|
+
|
192
|
+
alias :== :eql?
|
193
|
+
|
194
|
+
def table_alias
|
195
|
+
nil
|
196
|
+
end
|
197
|
+
|
198
|
+
def unalias
|
199
|
+
self
|
200
|
+
end
|
201
|
+
|
202
|
+
def sql(raw_sql)
|
203
|
+
Arel.sql(raw_sql)
|
204
|
+
end
|
205
|
+
|
206
|
+
def star
|
207
|
+
Arel.star
|
208
|
+
end
|
209
|
+
|
210
|
+
def now
|
211
|
+
Arel.now
|
212
|
+
end
|
213
|
+
|
214
|
+
def time(duration)
|
215
|
+
Arel.time(duration)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Arel
|
3
|
+
class TreeManager
|
4
|
+
STRING_OR_SYMBOL_CLASS = [Symbol, String]
|
5
|
+
|
6
|
+
attr_reader :ast
|
7
|
+
|
8
|
+
def visitor
|
9
|
+
Visitor.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_sql
|
13
|
+
visitor.accept(ast)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize_copy(other)
|
17
|
+
super
|
18
|
+
@ast = @ast.clone
|
19
|
+
end
|
20
|
+
|
21
|
+
def where(expr)
|
22
|
+
expr = expr.ast if TreeManager === expr
|
23
|
+
expr = Arel.sql(expr) if String === expr
|
24
|
+
|
25
|
+
ast.wheres << expr
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,287 @@
|
|
1
|
+
module Influxdb
|
2
|
+
module Arel
|
3
|
+
class Visitor
|
4
|
+
WHERE = ' WHERE '
|
5
|
+
SPACE = ' '
|
6
|
+
COMMA = ', '
|
7
|
+
GROUP_BY = ' GROUP BY '
|
8
|
+
AND = ' AND '
|
9
|
+
OR = ' OR '
|
10
|
+
|
11
|
+
def accept(object)
|
12
|
+
visit(object)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
DISPATCH = Hash.new do |method_hash, node_class|
|
18
|
+
method_hash[node_class] = "visit_#{(node_class.name || '').gsub('::', '_')}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def visit(object, attribute = nil)
|
22
|
+
send DISPATCH[object.class], object, attribute
|
23
|
+
rescue NoMethodError => e
|
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]
|
32
|
+
retry
|
33
|
+
end
|
34
|
+
|
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
|
62
|
+
|
63
|
+
result.strip!
|
64
|
+
result
|
65
|
+
end
|
66
|
+
|
67
|
+
def visit_Influxdb_Arel_Table(object, attribute)
|
68
|
+
quote_table_name(object.name)
|
69
|
+
end
|
70
|
+
|
71
|
+
def visit_Influxdb_Arel_Nodes_Join(object, attribute)
|
72
|
+
"#{visit(object.left, attribute)} INNER JOIN #{visit(object.right, attribute)}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def visit_Influxdb_Arel_Nodes_Merge(object, attribute)
|
76
|
+
"#{visit(object.left, attribute)} MERGE #{visit(object.right, attribute)}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def visit_Influxdb_Arel_Nodes_Limit(object, attribute)
|
80
|
+
"LIMIT #{visit(object.expr, attribute)}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def visit_Influxdb_Arel_Nodes_Ordering(object, attribute)
|
84
|
+
"ORDER #{object.value.upcase}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def visit_Influxdb_Arel_Nodes_Into(object, attribute)
|
88
|
+
"INTO #{visit(object.expr, attribute)}"
|
89
|
+
end
|
90
|
+
|
91
|
+
def visit_Influxdb_Arel_Nodes_Grouping(object, attribute)
|
92
|
+
"(#{visit(object.expr, attribute)})"
|
93
|
+
end
|
94
|
+
|
95
|
+
def visit_Influxdb_Arel_Nodes_Group(object, attribute)
|
96
|
+
visit(object.expr, attribute)
|
97
|
+
end
|
98
|
+
|
99
|
+
def visit_Influxdb_Arel_Nodes_TableAlias(object, attribute)
|
100
|
+
"#{visit(object.relation, attribute)} AS #{quote_table_name(object.name)}"
|
101
|
+
end
|
102
|
+
|
103
|
+
def function(object, attribute)
|
104
|
+
expressions = object.expressions.map{|exp| visit(exp, attribute) }.join(COMMA)
|
105
|
+
function_clause = object.class.name.split('::').last.upcase
|
106
|
+
"#{function_clause}(#{expressions})"
|
107
|
+
end
|
108
|
+
|
109
|
+
alias :visit_Influxdb_Arel_Nodes_Count :function
|
110
|
+
alias :visit_Influxdb_Arel_Nodes_Sum :function
|
111
|
+
alias :visit_Influxdb_Arel_Nodes_Max :function
|
112
|
+
alias :visit_Influxdb_Arel_Nodes_Min :function
|
113
|
+
alias :visit_Influxdb_Arel_Nodes_Mean :function
|
114
|
+
alias :visit_Influxdb_Arel_Nodes_Mode :function
|
115
|
+
alias :visit_Influxdb_Arel_Nodes_Median :function
|
116
|
+
alias :visit_Influxdb_Arel_Nodes_Distinct :function
|
117
|
+
alias :visit_Influxdb_Arel_Nodes_Percentile :function
|
118
|
+
alias :visit_Influxdb_Arel_Nodes_Histogram :function
|
119
|
+
alias :visit_Influxdb_Arel_Nodes_Derivative :function
|
120
|
+
alias :visit_Influxdb_Arel_Nodes_Stddev :function
|
121
|
+
alias :visit_Influxdb_Arel_Nodes_First :function
|
122
|
+
alias :visit_Influxdb_Arel_Nodes_Last :function
|
123
|
+
alias :visit_Influxdb_Arel_Nodes_Difference :function
|
124
|
+
alias :visit_Influxdb_Arel_Nodes_Top :function
|
125
|
+
alias :visit_Influxdb_Arel_Nodes_Bottom :function
|
126
|
+
|
127
|
+
def visit_Influxdb_Arel_Nodes_Fill(object, attribute)
|
128
|
+
"fill(#{visit(object.expr, attribute)})"
|
129
|
+
end
|
130
|
+
|
131
|
+
def visit_Influxdb_Arel_Nodes_Time(object, attribute)
|
132
|
+
"time(#{visit(object.expr, attribute)})"
|
133
|
+
end
|
134
|
+
|
135
|
+
def visit_Influxdb_Arel_Nodes_Duration(object, attribute)
|
136
|
+
"#{object.value}#{object.suffix}"
|
137
|
+
end
|
138
|
+
|
139
|
+
def visit_Influxdb_Arel_Nodes_Now(object, attribute)
|
140
|
+
"now()"
|
141
|
+
end
|
142
|
+
|
143
|
+
def visit_Influxdb_Arel_Nodes_In(object, attribute)
|
144
|
+
if Array === object.right && object.right.empty?
|
145
|
+
'1 = 0'
|
146
|
+
else
|
147
|
+
attribute = object.left if Arel::Attributes::Attribute === object.left
|
148
|
+
"#{visit(object.left, attribute)} IN (#{visit(object.right, attribute)})"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
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)}"
|
155
|
+
end
|
156
|
+
|
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)}"
|
160
|
+
end
|
161
|
+
|
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)}"
|
165
|
+
end
|
166
|
+
|
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)}"
|
170
|
+
end
|
171
|
+
|
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
|
181
|
+
end
|
182
|
+
|
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
|
192
|
+
end
|
193
|
+
|
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}"
|
197
|
+
end
|
198
|
+
|
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)}"
|
202
|
+
end
|
203
|
+
|
204
|
+
def visit_Influxdb_Arel_Nodes_And(object, attribute)
|
205
|
+
object.children.map{|node| visit(node, attribute) }.join(AND)
|
206
|
+
end
|
207
|
+
|
208
|
+
def visit_Influxdb_Arel_Nodes_Or(object, attribute)
|
209
|
+
[visit(object.left, attribute), visit(object.right, attribute)].join(OR)
|
210
|
+
end
|
211
|
+
|
212
|
+
def visit_Influxdb_Arel_Nodes_As(object, attribute)
|
213
|
+
"#{visit(object.left, attribute)} AS #{visit(object.right, attribute)}"
|
214
|
+
end
|
215
|
+
|
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
|
222
|
+
end
|
223
|
+
|
224
|
+
def literal(object, attribute)
|
225
|
+
object
|
226
|
+
end
|
227
|
+
|
228
|
+
alias :visit_Influxdb_Arel_Nodes_SqlLiteral :literal
|
229
|
+
alias :visit_Bignum :literal
|
230
|
+
alias :visit_Fixnum :literal
|
231
|
+
|
232
|
+
def quoted(object, attribute)
|
233
|
+
quote(object)
|
234
|
+
end
|
235
|
+
|
236
|
+
alias :visit_ActiveSupport_Multibyte_Chars :quoted
|
237
|
+
alias :visit_ActiveSupport_StringInquirer :quoted
|
238
|
+
alias :visit_BigDecimal :quoted
|
239
|
+
alias :visit_Class :quoted
|
240
|
+
alias :visit_Date :quoted
|
241
|
+
alias :visit_DateTime :quoted
|
242
|
+
alias :visit_FalseClass :quoted
|
243
|
+
alias :visit_Float :quoted
|
244
|
+
alias :visit_Hash :quoted
|
245
|
+
alias :visit_NilClass :quoted
|
246
|
+
alias :visit_String :quoted
|
247
|
+
alias :visit_Symbol :quoted
|
248
|
+
alias :visit_Time :quoted
|
249
|
+
alias :visit_TrueClass :quoted
|
250
|
+
alias :visit_Regexp :quoted
|
251
|
+
|
252
|
+
def visit_Influxdb_Arel_Nodes_InfixOperation(object, attribute)
|
253
|
+
"#{visit(object.left, attribute)} #{object.operator} #{visit(object.right, attribute)}"
|
254
|
+
end
|
255
|
+
|
256
|
+
alias :visit_Influxdb_Arel_Nodes_Addition :visit_Influxdb_Arel_Nodes_InfixOperation
|
257
|
+
alias :visit_Influxdb_Arel_Nodes_Subtraction :visit_Influxdb_Arel_Nodes_InfixOperation
|
258
|
+
alias :visit_Influxdb_Arel_Nodes_Multiplication :visit_Influxdb_Arel_Nodes_InfixOperation
|
259
|
+
alias :visit_Influxdb_Arel_Nodes_Division :visit_Influxdb_Arel_Nodes_InfixOperation
|
260
|
+
|
261
|
+
def visit_Array(object, attribute)
|
262
|
+
object.map{|node| visit(node, attribute) }.join(COMMA)
|
263
|
+
end
|
264
|
+
|
265
|
+
def quote(value)
|
266
|
+
return value if Arel::Nodes::SqlLiteral === value
|
267
|
+
attribute_for(value).encode(value)
|
268
|
+
end
|
269
|
+
|
270
|
+
def quote_table_name(name)
|
271
|
+
return name if Arel::Nodes::SqlLiteral === name
|
272
|
+
return name.inspect if Regexp === name
|
273
|
+
/(?!\.)[\W\s]+/.match(name.to_s) ? "\"#{name}\"" : name
|
274
|
+
end
|
275
|
+
|
276
|
+
def quote_column_name(name)
|
277
|
+
name
|
278
|
+
end
|
279
|
+
|
280
|
+
def attribute_for(value)
|
281
|
+
Influxdb::Arel::Attributes.const_get(value.class.name, false)
|
282
|
+
rescue
|
283
|
+
Influxdb::Arel::Attributes::Attribute
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|