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
@@ -0,0 +1,37 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Clauses
4
+ class SelectClause < Base
5
+ include Expressions
6
+
7
+ def initialize(*attributes, &block)
8
+ @attributes = attributes
9
+ super(&block)
10
+ end
11
+
12
+ def a(name)
13
+ Nodes::Attribute.new(name)
14
+ end
15
+
16
+ def method_missing(method, *args, &block)
17
+ a(method)
18
+ end
19
+
20
+ def to_arel
21
+ super{|result| result ? (@attributes | Array(result)) : @attributes }
22
+ end
23
+
24
+ protected
25
+
26
+ def function_node(name, *args)
27
+ args[0] = arelize(args[0])
28
+ Nodes.const_get(name).new(args)
29
+ end
30
+
31
+ def arelize_default_block
32
+ ->(expr){ a(expr) }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,102 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Clauses
4
+ class WhereClause < Base
5
+ include Expressions
6
+
7
+ def initialize(conditions, &block)
8
+ @conditions = build_where_expression(conditions)
9
+ super(&block)
10
+ end
11
+
12
+ def a(name)
13
+ Nodes::Attribute.new(name) #.extend(:math, :predications)
14
+ end
15
+
16
+ def now
17
+ Nodes::Now.new
18
+ end
19
+
20
+ def method_missing(method, *args, &block)
21
+ a(method)
22
+ end
23
+
24
+ def to_arel
25
+ super{|result| [@conditions, result].flatten.compact.inject(&:and) }
26
+ end
27
+
28
+ protected
29
+
30
+ def function_node(name, *args)
31
+ args[0] = arelize(args[0]){|expr| a(expr) }
32
+ Nodes.const_get(name).new(args)
33
+ end
34
+
35
+ def build_where_expression(conditions)
36
+ case conditions
37
+ when Hash
38
+ build_from_hash(conditions)
39
+ when Array
40
+ conditions.map{|expr| build_where_expression(expr) }.flatten.compact.inject(&:and)
41
+ when TreeManager
42
+ conditions.ast.wheres
43
+ when String
44
+ Arel.sql(conditions)
45
+ else
46
+ conditions
47
+ end
48
+ end
49
+
50
+ def build_from_hash(conditions)
51
+ conditions.each_with_object([]) do |(attribute, value), result|
52
+ check_attribute!(attribute)
53
+ attribute = a(attribute) unless Nodes::Attribute === attribute
54
+ result << build_attribute_expression(attribute, value)
55
+ end
56
+ end
57
+
58
+ def build_attribute_expression(attribute, value)
59
+ case value
60
+ when Array
61
+ build_array_expression(attribute, value)
62
+ when Regexp
63
+ attribute.matches(value)
64
+ when Range
65
+ attribute.in(value)
66
+ else
67
+ attribute.eq(value)
68
+ end
69
+ end
70
+
71
+ def build_array_expression(attribute, value)
72
+ ranges, values = value.to_a.partition{|v| v.is_a?(Range) }
73
+
74
+ values_predicate = if values.include?(nil)
75
+ values = values.compact
76
+
77
+ case values.length
78
+ when 0
79
+ attribute.eq(nil)
80
+ when 1
81
+ attribute.eq(values.first).or(attribute.eq(nil))
82
+ else
83
+ attribute.in(values).or(attribute.eq(nil))
84
+ end
85
+ else
86
+ attribute.in(values)
87
+ end
88
+
89
+ array_predicates = ranges.map{|range| attribute.in(range) }
90
+ array_predicates << values_predicate
91
+ array_predicates.inject{|composite, predicate| composite.or(predicate) }
92
+ end
93
+
94
+ def check_attribute!(attribute)
95
+ unless [Nodes::Attribute, String, Symbol].include?(attribute.class)
96
+ raise 'IllegalSQLConstruct: Illegal attribute name'
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -24,26 +24,10 @@ class Integer
24
24
  end
25
25
  end
26
26
 
27
- class String
28
- def to_influxdb_arel
29
- Influxdb::Arel::Nodes::SqlLiteral.new(self)
30
- end
31
-
32
- alias :to_arel :to_influxdb_arel unless method_defined?(:to_arel)
33
-
34
- def as(other)
35
- Influxdb::Arel::Nodes::As.new(to_influxdb_arel, other.to_influxdb_arel)
36
- end
37
- end
38
-
39
- class Symbol
40
- def to_influxdb_arel
41
- Influxdb::Arel::Table.new(self.to_s)
42
- end
43
-
44
- alias :to_arel :to_influxdb_arel unless method_defined?(:to_arel)
45
-
46
- def as(other)
47
- to_influxdb_arel.as(other)
27
+ class Object
28
+ def safe_clone
29
+ self.clone
30
+ rescue SecurityError, TypeError => e
31
+ self
48
32
  end
49
33
  end
@@ -0,0 +1,50 @@
1
+ module Influxdb
2
+ module Arel
3
+ class DeleteManager < TreeManager
4
+ def initialize
5
+ @ast = Nodes::DeleteStatement.new
6
+ end
7
+
8
+ def from(*new_tables, &block)
9
+ expr = Clauses::FromClause.new(*new_tables, &block).to_arel
10
+
11
+ case expr
12
+ when Array
13
+ regexps, others = separate_tables(expr.to_a)
14
+ ast.regexp = regexps.first if regexps
15
+ ast.tables = others
16
+ when Regexp
17
+ ast.regexp = expr
18
+ else
19
+ ast.tables = Array(expr)
20
+ end
21
+
22
+ self
23
+ end
24
+
25
+ def tables=(value)
26
+ ast.tables = value
27
+ end
28
+
29
+ def regexp=(value)
30
+ ast.regexp = value
31
+ end
32
+
33
+ private
34
+
35
+ def separate_tables(expr)
36
+ grouped_tables = expr.group_by do |value|
37
+ case value
38
+ when Nodes::Join, Nodes::Merge
39
+ :filtered
40
+ when Regexp
41
+ :regexp
42
+ else
43
+ :others
44
+ end
45
+ end
46
+ grouped_tables.values_at(:regexp, :others)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,6 @@
1
+ require 'influxdb/arel/extensions/expressions'
2
+ require 'influxdb/arel/extensions/boolean_predications'
3
+ require 'influxdb/arel/extensions/alias_predication'
4
+ require 'influxdb/arel/extensions/joining_merging'
5
+ require 'influxdb/arel/extensions/predications'
6
+ require 'influxdb/arel/extensions/math'
@@ -0,0 +1,11 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Extensions
4
+ module AliasPredication
5
+ def as(other)
6
+ Nodes::As.new(self, Arel.sql(other.to_s))
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Extensions
4
+ module BooleanPredications
5
+ def or(right)
6
+ Nodes::Grouping.new(Nodes::Or.new(self, right))
7
+ end
8
+
9
+ def and(right)
10
+ Nodes::And.new([self, right])
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,75 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Extensions
4
+ module Expressions
5
+ def count
6
+ Nodes::Count.new([self])
7
+ end
8
+
9
+ def sum
10
+ Nodes::Sum.new([self])
11
+ end
12
+
13
+ def max
14
+ Nodes::Max.new([self])
15
+ end
16
+
17
+ def min
18
+ Nodes::Min.new([self])
19
+ end
20
+
21
+ def mean
22
+ Nodes::Mean.new([self])
23
+ end
24
+
25
+ def mode
26
+ Nodes::Mode.new([self])
27
+ end
28
+
29
+ def median
30
+ Nodes::Median.new([self])
31
+ end
32
+
33
+ def distinct
34
+ Nodes::Distinct.new([self])
35
+ end
36
+
37
+ def percentile(nth)
38
+ Nodes::Percentile.new([self, nth])
39
+ end
40
+
41
+ def histogram(bucket_size = nil)
42
+ Nodes::Histogram.new([self, bucket_size || 1.0])
43
+ end
44
+
45
+ def derivative
46
+ Nodes::Derivative.new([self])
47
+ end
48
+
49
+ def stddev
50
+ Nodes::Stddev.new([self])
51
+ end
52
+
53
+ def first
54
+ Nodes::First.new([self])
55
+ end
56
+
57
+ def last
58
+ Nodes::Last.new([self])
59
+ end
60
+
61
+ def difference
62
+ Nodes::Difference.new([self])
63
+ end
64
+
65
+ def top(size)
66
+ Nodes::Top.new([self, size])
67
+ end
68
+
69
+ def bottom(size)
70
+ Nodes::Bottom.new([self, size])
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,21 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Extensions
4
+ module JoiningMerging
5
+ def join(table)
6
+ Nodes::Join.new(self, table_arelize(table))
7
+ end
8
+
9
+ def merge(table)
10
+ Nodes::Merge.new(self, table_arelize(table))
11
+ end
12
+
13
+ private
14
+
15
+ def table_arelize(table)
16
+ Arel.arelize(table){|expr| Nodes::Table.new(expr) }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Extensions
4
+ module Math
5
+ def *(other)
6
+ Nodes::Multiplication.new(self, other)
7
+ end
8
+
9
+ def +(other)
10
+ Nodes::Grouping.new(Nodes::Addition.new(self, other))
11
+ end
12
+
13
+ def -(other)
14
+ Nodes::Grouping.new(Nodes::Subtraction.new(self, other))
15
+ end
16
+
17
+ def /(other)
18
+ Nodes::Division.new(self, other)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,144 @@
1
+ module Influxdb
2
+ module Arel
3
+ module Extensions
4
+ module Predications
5
+ def not_eq(other)
6
+ Nodes::NotEqual.new(self, other)
7
+ end
8
+
9
+ def not_eq_any(others)
10
+ grouping_any(:not_eq, others)
11
+ end
12
+
13
+ def not_eq_all(others)
14
+ grouping_all(:not_eq, others)
15
+ end
16
+
17
+ def eq(other)
18
+ Nodes::Equality.new(self, other)
19
+ end
20
+
21
+ def eq_any(others)
22
+ grouping_any(:eq, others)
23
+ end
24
+
25
+ def eq_all(others)
26
+ grouping_all(:eq, others)
27
+ end
28
+
29
+ def in(other)
30
+ case other
31
+ when Range
32
+ in_range(other)
33
+ else
34
+ Nodes::In.new(self, other)
35
+ end
36
+ end
37
+
38
+ def matches(other)
39
+ Nodes::Matches.new(self, other)
40
+ end
41
+
42
+ def matches_any(others)
43
+ grouping_any(:matches, others)
44
+ end
45
+
46
+ def matches_all(others)
47
+ grouping_all(:matches, others)
48
+ end
49
+
50
+ def does_not_match(other)
51
+ Nodes::DoesNotMatch.new(self, other)
52
+ end
53
+
54
+ def does_not_match_any(others)
55
+ grouping_any(:does_not_match, others)
56
+ end
57
+
58
+ def does_not_match_all(others)
59
+ grouping_all(:does_not_match, others)
60
+ end
61
+
62
+ def gteq(right)
63
+ Nodes::GreaterThanOrEqual.new(self, right)
64
+ end
65
+
66
+ def gteq_any(others)
67
+ grouping_any(:gteq, others)
68
+ end
69
+
70
+ def gteq_all(others)
71
+ grouping_all(:gteq, others)
72
+ end
73
+
74
+ def gt(right)
75
+ Nodes::GreaterThan.new(self, right)
76
+ end
77
+
78
+ def gt_any(others)
79
+ grouping_any(:gt, others)
80
+ end
81
+
82
+ def gt_all(others)
83
+ grouping_all(:gt, others)
84
+ end
85
+
86
+ def lt(right)
87
+ Nodes::LessThan.new(self, right)
88
+ end
89
+
90
+ def lt_any(others)
91
+ grouping_any(:lt, others)
92
+ end
93
+
94
+ def lt_all(others)
95
+ grouping_all(:lt, others)
96
+ end
97
+
98
+ def lteq(right)
99
+ Nodes::LessThanOrEqual.new(self, right)
100
+ end
101
+
102
+ def lteq_any(others)
103
+ grouping_any(:lteq, others)
104
+ end
105
+
106
+ def lteq_all(others)
107
+ grouping_all(:lteq, others)
108
+ end
109
+
110
+ private
111
+
112
+ def in_range(other)
113
+ case
114
+ when other.begin == -Float::INFINITY && other.end == Float::INFINITY
115
+ Nodes::Equality.new(1, 1)
116
+ when other.end == Float::INFINITY
117
+ Nodes::GreaterThanOrEqual.new(self, other.begin)
118
+ when other.begin == -Float::INFINITY && other.exclude_end?
119
+ Nodes::LessThan.new(self, other.end)
120
+ when other.begin == -Float::INFINITY
121
+ Nodes::LessThanOrEqual.new(self, other.end)
122
+ else
123
+ in_regular_range(other)
124
+ end
125
+ end
126
+
127
+ def in_regular_range(other)
128
+ left = Nodes::GreaterThanOrEqual.new(self, other.begin)
129
+ right = (other.exclude_end? ? Nodes::LessThan : Nodes::LessThanOrEqual).new(self, other.end)
130
+ Nodes::And.new([left, right])
131
+ end
132
+
133
+ def grouping_any(method_id, others)
134
+ nodes = others.map{|expr| send(method_id, expr) }
135
+ Nodes::Grouping.new(nodes.inject{|result, node| Nodes::Or.new(result, node) })
136
+ end
137
+
138
+ def grouping_all(method_id, others)
139
+ Nodes::Grouping.new(Nodes::And.new(others.map{|expr| send(method_id, expr) }))
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end