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,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