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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/Gemfile +1 -0
- data/README.md +218 -124
- data/lib/influxdb/arel.rb +25 -16
- data/lib/influxdb/arel/builder.rb +209 -0
- data/lib/influxdb/arel/clauses.rb +6 -0
- data/lib/influxdb/arel/clauses/base.rb +34 -0
- data/lib/influxdb/arel/clauses/expressions.rb +75 -0
- data/lib/influxdb/arel/clauses/from_clause.rb +45 -0
- data/lib/influxdb/arel/clauses/group_clause.rb +34 -0
- data/lib/influxdb/arel/clauses/select_clause.rb +37 -0
- data/lib/influxdb/arel/clauses/where_clause.rb +102 -0
- data/lib/influxdb/arel/core_extensions.rb +5 -21
- data/lib/influxdb/arel/delete_manager.rb +50 -0
- data/lib/influxdb/arel/extensions.rb +6 -0
- data/lib/influxdb/arel/extensions/alias_predication.rb +11 -0
- data/lib/influxdb/arel/extensions/boolean_predications.rb +15 -0
- data/lib/influxdb/arel/extensions/expressions.rb +75 -0
- data/lib/influxdb/arel/extensions/joining_merging.rb +21 -0
- data/lib/influxdb/arel/extensions/math.rb +23 -0
- data/lib/influxdb/arel/extensions/predications.rb +144 -0
- data/lib/influxdb/arel/nodes.rb +7 -14
- data/lib/influxdb/arel/nodes/attribute.rb +20 -0
- data/lib/influxdb/arel/nodes/binary.rb +4 -3
- data/lib/influxdb/arel/nodes/delete_statement.rb +37 -0
- data/lib/influxdb/arel/nodes/duration.rb +3 -3
- data/lib/influxdb/arel/nodes/function.rb +2 -2
- data/lib/influxdb/arel/nodes/grouping.rb +3 -3
- data/lib/influxdb/arel/nodes/infix_operation.rb +11 -4
- data/lib/influxdb/arel/nodes/merge.rb +13 -0
- data/lib/influxdb/arel/nodes/node.rb +18 -6
- data/lib/influxdb/arel/nodes/now.rb +1 -1
- data/lib/influxdb/arel/nodes/ordering.rb +15 -0
- data/lib/influxdb/arel/nodes/select_statement.rb +10 -8
- data/lib/influxdb/arel/nodes/sql_literal.rb +5 -8
- data/lib/influxdb/arel/nodes/table.rb +19 -0
- data/lib/influxdb/arel/nodes/table_alias.rb +2 -4
- data/lib/influxdb/arel/nodes/unary.rb +6 -1
- data/lib/influxdb/arel/quoter.rb +85 -0
- data/lib/influxdb/arel/select_manager.rb +111 -64
- data/lib/influxdb/arel/tree_manager.rb +15 -5
- data/lib/influxdb/arel/version.rb +1 -1
- data/lib/influxdb/arel/visitor.rb +96 -126
- data/lib/influxdb/arel/visitor/delete_statement.rb +32 -0
- data/lib/influxdb/arel/visitor/select_statement.rb +59 -0
- data/lib/influxdb/arel/visitor/where_statement.rb +14 -0
- data/spec/lib/influxdb/arel/builder_spec.rb +173 -0
- data/spec/lib/influxdb/arel/core_extensions_spec.rb +0 -21
- data/spec/lib/influxdb/arel/nodes/and_spec.rb +6 -9
- data/spec/lib/influxdb/arel/nodes/attribute_spec.rb +21 -0
- data/spec/lib/influxdb/arel/nodes/binary_spec.rb +0 -4
- data/spec/lib/influxdb/arel/nodes/duration_spec.rb +1 -0
- data/spec/lib/influxdb/arel/nodes/in_spec.rb +1 -0
- data/spec/lib/influxdb/arel/nodes/infix_operation_spec.rb +17 -0
- data/spec/lib/influxdb/arel/nodes/merge_spec.rb +25 -0
- data/spec/lib/influxdb/arel/nodes/now_spec.rb +1 -0
- data/spec/lib/influxdb/arel/nodes/ordering_spec.rb +19 -0
- data/spec/lib/influxdb/arel/nodes/sql_literal_spec.rb +1 -5
- data/spec/lib/influxdb/arel/nodes/table_alias_spec.rb +3 -10
- data/spec/lib/influxdb/arel/nodes/table_spec.rb +8 -0
- data/spec/lib/influxdb/arel/nodes/unary_spec.rb +0 -4
- data/spec/lib/influxdb/arel/quoter/repository_spec.rb +10 -0
- data/spec/lib/influxdb/arel/quoter_spec.rb +33 -0
- data/spec/lib/influxdb/arel/select_manager_spec.rb +356 -156
- data/spec/lib/influxdb/arel_spec.rb +22 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/examples/binary_node.rb +1 -0
- data/spec/support/examples/function_node.rb +1 -0
- data/spec/support/examples/infix_operation_node.rb +15 -0
- data/spec/support/examples/node_boolean_predications.rb +21 -0
- data/spec/support/examples/node_joining_merging.rb +53 -0
- data/spec/support/examples/unary_node.rb +1 -0
- data/spec/support/fabrics.rb +3 -3
- metadata +49 -11
- data/lib/influxdb/arel/alias_predication.rb +0 -9
- data/lib/influxdb/arel/attributes.rb +0 -1
- data/lib/influxdb/arel/attributes/attribute.rb +0 -74
- data/lib/influxdb/arel/expressions.rb +0 -73
- data/lib/influxdb/arel/math.rb +0 -21
- data/lib/influxdb/arel/predications.rb +0 -137
- data/lib/influxdb/arel/table.rb +0 -219
- 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
|
28
|
-
def
|
29
|
-
|
30
|
-
|
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,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
|