influxdb-arel 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +350 -0
  8. data/Rakefile +6 -0
  9. data/influxdb-arel.gemspec +24 -0
  10. data/lib/influxdb-arel.rb +1 -0
  11. data/lib/influxdb.rb +4 -0
  12. data/lib/influxdb/arel.rb +38 -0
  13. data/lib/influxdb/arel/alias_predication.rb +9 -0
  14. data/lib/influxdb/arel/attributes.rb +1 -0
  15. data/lib/influxdb/arel/attributes/attribute.rb +74 -0
  16. data/lib/influxdb/arel/core_extensions.rb +49 -0
  17. data/lib/influxdb/arel/expressions.rb +73 -0
  18. data/lib/influxdb/arel/math.rb +21 -0
  19. data/lib/influxdb/arel/nodes.rb +27 -0
  20. data/lib/influxdb/arel/nodes/and.rb +32 -0
  21. data/lib/influxdb/arel/nodes/binary.rb +47 -0
  22. data/lib/influxdb/arel/nodes/duration.rb +30 -0
  23. data/lib/influxdb/arel/nodes/equality.rb +11 -0
  24. data/lib/influxdb/arel/nodes/function.rb +47 -0
  25. data/lib/influxdb/arel/nodes/grouping.rb +11 -0
  26. data/lib/influxdb/arel/nodes/in.rb +8 -0
  27. data/lib/influxdb/arel/nodes/infix_operation.rb +51 -0
  28. data/lib/influxdb/arel/nodes/node.rb +19 -0
  29. data/lib/influxdb/arel/nodes/now.rb +15 -0
  30. data/lib/influxdb/arel/nodes/select_statement.rb +59 -0
  31. data/lib/influxdb/arel/nodes/sql_literal.rb +23 -0
  32. data/lib/influxdb/arel/nodes/table_alias.rb +23 -0
  33. data/lib/influxdb/arel/nodes/time.rb +13 -0
  34. data/lib/influxdb/arel/nodes/unary.rb +35 -0
  35. data/lib/influxdb/arel/predications.rb +137 -0
  36. data/lib/influxdb/arel/select_manager.rb +129 -0
  37. data/lib/influxdb/arel/table.rb +219 -0
  38. data/lib/influxdb/arel/tree_manager.rb +30 -0
  39. data/lib/influxdb/arel/version.rb +5 -0
  40. data/lib/influxdb/arel/visitor.rb +287 -0
  41. data/spec/lib/influxdb/arel/core_extensions_spec.rb +49 -0
  42. data/spec/lib/influxdb/arel/nodes/and_spec.rb +17 -0
  43. data/spec/lib/influxdb/arel/nodes/binary_spec.rb +49 -0
  44. data/spec/lib/influxdb/arel/nodes/duration_spec.rb +72 -0
  45. data/spec/lib/influxdb/arel/nodes/equality_spec.rb +5 -0
  46. data/spec/lib/influxdb/arel/nodes/function_spec.rb +69 -0
  47. data/spec/lib/influxdb/arel/nodes/grouping_spec.rb +10 -0
  48. data/spec/lib/influxdb/arel/nodes/in_spec.rb +13 -0
  49. data/spec/lib/influxdb/arel/nodes/now_spec.rb +8 -0
  50. data/spec/lib/influxdb/arel/nodes/sql_literal_spec.rb +28 -0
  51. data/spec/lib/influxdb/arel/nodes/table_alias_spec.rb +36 -0
  52. data/spec/lib/influxdb/arel/nodes/time_spec.rb +5 -0
  53. data/spec/lib/influxdb/arel/nodes/unary_spec.rb +25 -0
  54. data/spec/lib/influxdb/arel/select_manager_spec.rb +459 -0
  55. data/spec/lib/influxdb/arel/table_spec.rb +193 -0
  56. data/spec/lib/influxdb/arel_spec.rb +11 -0
  57. data/spec/spec_helper.rb +20 -0
  58. data/spec/support/examples/binary_node.rb +10 -0
  59. data/spec/support/examples/function_node.rb +14 -0
  60. data/spec/support/examples/node_as.rb +8 -0
  61. data/spec/support/examples/node_expressions.rb +145 -0
  62. data/spec/support/examples/node_math.rb +29 -0
  63. data/spec/support/examples/node_predications.rb +248 -0
  64. data/spec/support/examples/node_to_sql.rb +5 -0
  65. data/spec/support/examples/unary_node.rb +10 -0
  66. data/spec/support/fabrics.rb +21 -0
  67. 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,5 @@
1
+ module Influxdb
2
+ module Arel
3
+ VERSION = "0.0.1"
4
+ end
5
+ 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