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