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,38 +1,47 @@
1
1
  require "influxdb/arel/version"
2
-
3
- require 'influxdb/arel/expressions'
4
- require 'influxdb/arel/predications'
5
- require 'influxdb/arel/math'
6
- require 'influxdb/arel/alias_predication'
7
- require 'influxdb/arel/table'
8
- require 'influxdb/arel/attributes'
2
+ require 'influxdb/arel/core_extensions'
3
+ require 'influxdb/arel/extensions'
4
+ require 'influxdb/arel/clauses'
5
+ require 'influxdb/arel/builder'
9
6
 
10
7
  require 'influxdb/arel/visitor'
8
+ require 'influxdb/arel/visitor/where_statement'
9
+ require 'influxdb/arel/visitor/select_statement'
10
+ require 'influxdb/arel/visitor/delete_statement'
11
11
 
12
12
  require 'influxdb/arel/tree_manager'
13
13
  require 'influxdb/arel/select_manager'
14
- # require 'influxdb/arel/delete_manager'
14
+ require 'influxdb/arel/delete_manager'
15
15
  require 'influxdb/arel/nodes'
16
+ require 'influxdb/arel/quoter'
16
17
 
17
18
  module Influxdb
18
19
  module Arel
19
20
  extend self
20
21
 
22
+ STRING_OR_SYMBOL_CLASS = [Symbol, String]
23
+
21
24
  def sql(raw_sql)
22
- Nodes::SqlLiteral.new(raw_sql)
25
+ Nodes::SqlLiteral.new(raw_sql.to_s)
23
26
  end
24
27
 
25
28
  def star
26
29
  sql('*')
27
30
  end
28
31
 
29
- def now
30
- Influxdb::Arel::Nodes::Now.new
31
- end
32
-
33
- def time(duration)
34
- duration = sql(duration) if String === duration
35
- Influxdb::Arel::Nodes::Time.new(duration)
32
+ def arelize(expr, &block)
33
+ block ||= ->(e){ Arel.sql(e.to_s) }
34
+
35
+ case expr
36
+ when Array
37
+ expr.map{|value| arelize(value, &block) }.compact
38
+ when Hash
39
+ # TODO: Needs to convert Hash into sql node
40
+ when *STRING_OR_SYMBOL_CLASS
41
+ block.call(expr)
42
+ else
43
+ expr
44
+ end
36
45
  end
37
46
  end
38
47
  end
@@ -0,0 +1,209 @@
1
+ module Influxdb
2
+ module Arel
3
+ class Builder
4
+ attr_accessor :default_table
5
+
6
+ def initialize(default_table = nil)
7
+ @default_table = default_table
8
+ end
9
+
10
+ # Specify tables for query
11
+ #
12
+ # builder = Influxdb::Arel::Builder.new
13
+ # builder.from(:table1).to_sql
14
+ # => SELECT * FROM table1
15
+ #
16
+ # builder = Influxdb::Arel::Builder.new
17
+ # builder.from{ table1.as(:alias1).join(table2.as(:alias2)) }.to_sql
18
+ # => SELECT * FROM table1 AS alias1 INNER JOIN table2 AS alias2
19
+ #
20
+ # builder = Influxdb::Arel::Builder.new
21
+ # builder.from(/.*/).to_sql
22
+ # => SELECT * FROM /.*/
23
+ #
24
+ # See: <tt>Influxdb::Arel::SelectManager#from</tt>
25
+ #
26
+ def from(*tables, &block)
27
+ SelectManager.new(*tables, &block)
28
+ end
29
+
30
+ # Merging of two tables into one.
31
+ #
32
+ # Tt will merge default table from builder with given table if <tt>tables</tt> contains one table.
33
+ #
34
+ # builder = Influxdb::Arel::Builder.new(:table1)
35
+ # builder.merge(:table2).to_sql
36
+ # => SELECT * FROM table1 MERGE table2
37
+ #
38
+ # It will merge tables if <tt>tables</tt> contains two tables.
39
+ #
40
+ # builder = Influxdb::Arel::Builder.new
41
+ # builder.merge(:table1, :table2).to_sql
42
+ # => SELECT * FROM table1 MERGE table2
43
+ #
44
+ # It will raise exception if <tt>table</tt> is nil and tables list contains only one table.
45
+ #
46
+ # builder.merge.to_sql
47
+ # => IllegalSQLConstruct: Ambiguous merging clause
48
+ #
49
+ # See: <tt>Influxdb::Arel::SelectManager#merge</tt>
50
+ #
51
+ def merge(*tables)
52
+ from(default_table).merge(*tables)
53
+ end
54
+
55
+ # Joining of two tables into one.
56
+ #
57
+ # It will join default table from builder with given table if <tt>tables</tt> contains one table.
58
+ #
59
+ # builder = Influxdb::Arel::Builder.new(:table1)
60
+ # builder.join(:table2).to_sql
61
+ # => SELECT * FROM table1 INNER JOIN table2
62
+ #
63
+ # It will join tables if <tt>tables</tt> contains two tables.
64
+ #
65
+ # builder = Influxdb::Arel::Builder.new
66
+ # builder.join(:table1, :table2).to_sql
67
+ # => SELECT * FROM table1 INNER JOIN table2
68
+ #
69
+ # It will raise exception if <tt>table</tt> is nil and tables list contains only one table.
70
+ #
71
+ # builder.join.to_sql
72
+ # => IllegalSQLConstruct: Ambiguous merging clause
73
+ #
74
+ # See: <tt>Influxdb::Arel::SelectManager#join</tt>
75
+ #
76
+ def join(*tables)
77
+ from(default_table).join(*tables)
78
+ end
79
+
80
+ # Grouping results by specified attributes or expressions, such as <tt>time(10m)</tt>
81
+ #
82
+ # builder = Influxdb::Arel::Builder.new(:table)
83
+ # builder.group{ time(10.s), host }.to_sql
84
+ # => SELECT * FROM table GROUP BY time(10m), host
85
+ #
86
+ # If you want to fill intervals with no data you shoult call <tt>fill</tt> method after grouping:
87
+ #
88
+ # builder.group{ time(10.s), host }.fill(0).to_sql
89
+ # => SELECT * FROM table GROUP BY time(10m), host fill(0)
90
+ #
91
+ # See: <tt>Influxdb::Arel::SelectManager#group</tt>
92
+ #
93
+ def group(*attributes, &block)
94
+ from(default_table).group(*attributes, &block)
95
+ end
96
+
97
+ # Set the ordering of results
98
+ # Possible values:
99
+ #
100
+ # * <tt>:asc</tt>
101
+ # Default value. Results will be sorted by ascending order.
102
+ #
103
+ # * <tt>:desc</tt>
104
+ # Default value. Results will be sorted by descending order.
105
+ #
106
+ # Example:
107
+ #
108
+ # builder = Influxdb::Arel::Builder.new(:table)
109
+ # builder.order(:desc).to_sql
110
+ # builder.order('desc').to_sql
111
+ # => SELECT * FROM table ORDER DESC
112
+ #
113
+ # builder.order(:asc).to_sql
114
+ # builder.order('asc').to_sql
115
+ # => SELECT * FROM table ORDER ASC
116
+ #
117
+ # See: <tt>Influxdb::Arel::SelectManager#order</tt>
118
+ #
119
+ def order(expr)
120
+ from(default_table).order(expr)
121
+ end
122
+
123
+ # Results will be sorted by ascending order.
124
+ #
125
+ # builder = Influxdb::Arel::Builder.new(:table)
126
+ # builder.asc.to_sql
127
+ # => SELECT * FROM table ORDER ASC
128
+ #
129
+ def asc
130
+ from(default_table).asc
131
+ end
132
+
133
+ # Results will be sorted by descending order.
134
+ #
135
+ # builder = Influxdb::Arel::Builder.new(:table)
136
+ # builder.desc.to_sql
137
+ # => SELECT * FROM table ORDER DESC
138
+ #
139
+ def desc
140
+ from(default_table).desc
141
+ end
142
+
143
+ # Specify conditions for selection or deletion query
144
+ # Example:
145
+ #
146
+ # builder = Influxdb::Arel::Builder.new(:table)
147
+ # builder.where(name: 'Undr').to_sql
148
+ # => SELECT * FROM table WHERE name = 'Undr'
149
+ #
150
+ # builder.where(name: 'Undr'){ time.lt(10.h.ago) }.to_sql
151
+ # => SELECT * FROM table WHERE name = 'Undr' AND time < (now() - 10h)
152
+ #
153
+ # builder.where{ name.eq('Undr').or(name.eq('Andrei')) }.to_sql
154
+ # => SELECT * FROM table WHERE name = 'Undr' OR name = 'Andrei'
155
+ #
156
+ # See: <tt>Influxdb::Arel::SelectManager#where</tt>
157
+ #
158
+ def where(conditions = nil, &block)
159
+ from(default_table).where(conditions, &block)
160
+ end
161
+
162
+ # Specify attributes or expressions for select.
163
+ # Example:
164
+ #
165
+ # builder = Influxdb::Arel::Builder.new(:cpu_load)
166
+ # builder.to_sql
167
+ # => SELECT * FROM cpu_load
168
+ #
169
+ # builder.select(:idle){ (system + user).as(:sum) }.to_sql
170
+ # => SELECT idle, (system + user) AS sum FROM cpu_load
171
+ #
172
+ # builder.select{ [mean(idle).as(:idle_mean), mean(user).as(:user_mean)] }.to_sql
173
+ # => SELECT MEAN(idle) AS idle_mean, MEAN(user) AS user_mean FROM cpu_load
174
+ #
175
+ # See: <tt>Influxdb::Arel::SelectManager#select</tt>
176
+ #
177
+ def select(*attributes, &block)
178
+ from(default_table).select(*attributes, &block)
179
+ end
180
+
181
+ # Set limit for result's points
182
+ # Example:
183
+ #
184
+ # builder = Influxdb::Arel::Builder.new(:table)
185
+ # builder.limit(100).to_sql
186
+ # => SELECT * FROM table LIMIT 100
187
+ #
188
+ def limit(amount)
189
+ from(default_table).limit(amount)
190
+ end
191
+
192
+ # Create <tt>Influxdb::Arel::SelectManager</tt>
193
+ #
194
+ def select_manager
195
+ SelectManager.new(default_table)
196
+ end
197
+
198
+ def hash
199
+ @default_table.hash
200
+ end
201
+
202
+ def eql?(other)
203
+ self.class == other.class && self.name == other.name
204
+ end
205
+
206
+ alias :== :eql?
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,6 @@
1
+ require 'influxdb/arel/clauses/base'
2
+ require 'influxdb/arel/clauses/expressions'
3
+ require 'influxdb/arel/clauses/select_clause'
4
+ require 'influxdb/arel/clauses/from_clause'
5
+ require 'influxdb/arel/clauses/where_clause'
6
+ require 'influxdb/arel/clauses/group_clause'
@@ -0,0 +1,34 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Clauses
4
+ class Base
5
+ def initialize(&block)
6
+ @block = block
7
+ @outer = eval('self', block.binding) if block
8
+ end
9
+
10
+ def o(&block)
11
+ @outer.instance_exec(&block)
12
+ end
13
+
14
+ def to_arel
15
+ result = nil
16
+ result = instance_eval(&@block) if @block
17
+ result = yield result if block_given?
18
+ arelize(result)
19
+ end
20
+
21
+ protected
22
+
23
+ def arelize_default_block
24
+ ->(expr){ Arel.sql(expr) }
25
+ end
26
+
27
+ def arelize(expr, &block)
28
+ block ||= arelize_default_block
29
+ Arel.arelize(expr, &block)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,75 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Clauses
4
+ module Expressions
5
+ def count(expr)
6
+ function_node(:Count, expr)
7
+ end
8
+
9
+ def sum(expr)
10
+ function_node(:Sum, expr)
11
+ end
12
+
13
+ def max(expr)
14
+ function_node(:Max, expr)
15
+ end
16
+
17
+ def min(expr)
18
+ function_node(:Min, expr)
19
+ end
20
+
21
+ def mean(expr)
22
+ function_node(:Mean, expr)
23
+ end
24
+
25
+ def mode(expr)
26
+ function_node(:Mode, expr)
27
+ end
28
+
29
+ def median(expr)
30
+ function_node(:Median, expr)
31
+ end
32
+
33
+ def distinct(expr)
34
+ function_node(:Distinct, expr)
35
+ end
36
+
37
+ def percentile(expr, nth)
38
+ function_node(:Percentile, expr, nth)
39
+ end
40
+
41
+ def histogram(expr, bucket_size = nil)
42
+ function_node(:Histogram, expr, bucket_size || 1)
43
+ end
44
+
45
+ def derivative(expr)
46
+ function_node(:Derivative, expr)
47
+ end
48
+
49
+ def stddev(expr)
50
+ function_node(:Stddev, expr)
51
+ end
52
+
53
+ def first(expr)
54
+ function_node(:First, expr)
55
+ end
56
+
57
+ def last(expr)
58
+ function_node(:Last, expr)
59
+ end
60
+
61
+ def difference(expr)
62
+ function_node(:Difference, expr)
63
+ end
64
+
65
+ def top(expr, size)
66
+ function_node(:Top, expr, size)
67
+ end
68
+
69
+ def bottom(expr, size)
70
+ function_node(:Bottom, expr, size)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,45 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Clauses
4
+ class FromClause < Base
5
+ def initialize(*tables, &block)
6
+ @tables = tables
7
+ super(&block)
8
+ end
9
+
10
+ def t(name)
11
+ Nodes::Table.new(name)
12
+ end
13
+
14
+ def join(*tables)
15
+ tables_union(Nodes::Join, tables, :merging)
16
+ end
17
+
18
+ def merge(*tables)
19
+ tables_union(Nodes::Merge, tables, :merging)
20
+ end
21
+
22
+ def method_missing(method, *args, &block)
23
+ t(method)
24
+ end
25
+
26
+ def to_arel
27
+ super{|result| result ? (@tables | Array(result)) : @tables }.uniq
28
+ end
29
+
30
+ protected
31
+
32
+ def tables_union(klass, tables, type)
33
+ _tables = @tables + tables
34
+ raise "IllegalSQLConstruct: The #{type} without first table" if _tables.size != 2
35
+ first, last = arelize(_tables)
36
+ klass.new(first, last)
37
+ end
38
+
39
+ def arelize_default_block
40
+ ->(expr){ t(expr) }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Clauses
4
+ class GroupClause < Base
5
+ def initialize(*attributes, &block)
6
+ @attributes = attributes
7
+ super(&block)
8
+ end
9
+
10
+ def a(name)
11
+ Nodes::Attribute.new(name)
12
+ end
13
+
14
+ def time(duration)
15
+ Nodes::Time.new(Arel.arelize(duration))
16
+ end
17
+
18
+ def method_missing(method, *args, &block)
19
+ a(method)
20
+ end
21
+
22
+ def to_arel
23
+ super{|result| result ? (@attributes | Array(result)) : @attributes }
24
+ end
25
+
26
+ protected
27
+
28
+ def arelize_default_block
29
+ ->(expr){ a(expr) }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end