arel_extensions 2.0.9 → 2.0.14
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/Gemfile +10 -10
- data/Rakefile +4 -4
- data/gemfiles/rails3.gemfile +9 -9
- data/gemfiles/rails4.gemfile +13 -13
- data/gemfiles/rails5_0.gemfile +13 -13
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +13 -13
- data/gemfiles/rails6.gemfile +13 -13
- data/lib/arel_extensions.rb +3 -3
- data/lib/arel_extensions/attributes.rb +0 -0
- data/lib/arel_extensions/boolean_functions.rb +21 -5
- data/lib/arel_extensions/common_sql_functions.rb +2 -4
- data/lib/arel_extensions/comparators.rb +11 -14
- data/lib/arel_extensions/date_duration.rb +4 -5
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +8 -9
- data/lib/arel_extensions/math_functions.rb +15 -17
- data/lib/arel_extensions/nodes/abs.rb +0 -1
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
- data/lib/arel_extensions/nodes/blank.rb +0 -1
- data/lib/arel_extensions/nodes/case.rb +3 -4
- data/lib/arel_extensions/nodes/cast.rb +4 -2
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +0 -1
- data/lib/arel_extensions/nodes/collate.rb +0 -1
- data/lib/arel_extensions/nodes/concat.rb +1 -3
- data/lib/arel_extensions/nodes/date_diff.rb +7 -8
- data/lib/arel_extensions/nodes/duration.rb +0 -1
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +27 -1
- data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
- data/lib/arel_extensions/nodes/function.rb +18 -15
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +39 -30
- data/lib/arel_extensions/nodes/length.rb +0 -1
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -1
- data/lib/arel_extensions/nodes/log10.rb +1 -2
- data/lib/arel_extensions/nodes/matches.rb +0 -2
- data/lib/arel_extensions/nodes/md5.rb +0 -1
- data/lib/arel_extensions/nodes/power.rb +0 -1
- data/lib/arel_extensions/nodes/rand.rb +0 -1
- data/lib/arel_extensions/nodes/repeat.rb +0 -2
- data/lib/arel_extensions/nodes/replace.rb +0 -2
- data/lib/arel_extensions/nodes/round.rb +0 -1
- data/lib/arel_extensions/nodes/soundex.rb +0 -1
- data/lib/arel_extensions/nodes/std.rb +0 -1
- data/lib/arel_extensions/nodes/substring.rb +0 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +0 -2
- data/lib/arel_extensions/nodes/union.rb +0 -2
- data/lib/arel_extensions/nodes/union_all.rb +0 -2
- data/lib/arel_extensions/nodes/wday.rb +0 -4
- data/lib/arel_extensions/null_functions.rb +3 -5
- data/lib/arel_extensions/predications.rb +5 -6
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +0 -2
- data/lib/arel_extensions/string_functions.rb +21 -22
- data/lib/arel_extensions/tasks.rb +1 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +9 -7
- data/lib/arel_extensions/visitors/convert_format.rb +37 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
- data/lib/arel_extensions/visitors/mssql.rb +48 -44
- data/lib/arel_extensions/visitors/mysql.rb +65 -67
- data/lib/arel_extensions/visitors/oracle.rb +58 -55
- data/lib/arel_extensions/visitors/oracle12.rb +2 -3
- data/lib/arel_extensions/visitors/postgresql.rb +41 -34
- data/lib/arel_extensions/visitors/sqlite.rb +23 -18
- data/lib/arel_extensions/visitors/to_sql.rb +69 -61
- data/test/arelx_test_helper.rb +0 -2
- data/test/real_db_test.rb +27 -42
- data/test/support/fake_record.rb +1 -1
- data/test/test_comparators.rb +0 -4
- data/test/visitors/test_bulk_insert_oracle.rb +0 -1
- data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
- data/test/visitors/test_oracle.rb +1 -2
- data/test/visitors/test_to_sql.rb +16 -25
- data/test/with_ar/all_agnostic_test.rb +135 -139
- data/test/with_ar/insert_agnostic_test.rb +0 -2
- data/test/with_ar/test_bulk_sqlite.rb +0 -4
- data/test/with_ar/test_math_sqlite.rb +4 -8
- data/test/with_ar/test_string_mysql.rb +1 -5
- data/test/with_ar/test_string_sqlite.rb +1 -5
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +3 -2
@@ -10,6 +10,10 @@ module ArelExtensions
|
|
10
10
|
|
11
11
|
RETURN_TYPE = :string # by default...
|
12
12
|
|
13
|
+
# Support multibyte string if they are available.
|
14
|
+
MBSTRING =
|
15
|
+
defined?(ActiveSupport::Multibyte::Chars) ? ActiveSupport::Multibyte::Chars : String
|
16
|
+
|
13
17
|
# overrides as to make new Node like AliasPredication
|
14
18
|
|
15
19
|
def return_type
|
@@ -50,8 +54,8 @@ module ArelExtensions
|
|
50
54
|
end
|
51
55
|
when ArelExtensions::Nodes::Function
|
52
56
|
att.return_type
|
53
|
-
# else
|
54
|
-
# nil
|
57
|
+
# else
|
58
|
+
# nil
|
55
59
|
end
|
56
60
|
end
|
57
61
|
|
@@ -63,7 +67,7 @@ module ArelExtensions
|
|
63
67
|
Arel::Nodes.build_quoted(object, self)
|
64
68
|
when Time
|
65
69
|
Arel::Nodes.build_quoted(object.strftime('%H:%M:%S'), self)
|
66
|
-
when String, Symbol
|
70
|
+
when MBSTRING, String, Symbol
|
67
71
|
Arel::Nodes.build_quoted(object.to_s)
|
68
72
|
when Date
|
69
73
|
Arel::Nodes.build_quoted(object.to_s, self)
|
@@ -74,7 +78,7 @@ module ArelExtensions
|
|
74
78
|
when Array
|
75
79
|
Arel::Nodes::Grouping.new(object.map{|r| convert_to_node(e)})
|
76
80
|
else
|
77
|
-
raise(ArgumentError, "#{object.class}
|
81
|
+
raise(ArgumentError, "#{object.class} cannot be converted to CONCAT arg")
|
78
82
|
end
|
79
83
|
end
|
80
84
|
|
@@ -97,8 +101,8 @@ module ArelExtensions
|
|
97
101
|
Arel::Nodes.build_quoted(object, self)
|
98
102
|
when Time
|
99
103
|
Arel::Nodes.build_quoted(object.strftime('%H:%M:%S'), self)
|
100
|
-
when String
|
101
|
-
Arel::Nodes.build_quoted(object)
|
104
|
+
when MBSTRING, String
|
105
|
+
Arel::Nodes.build_quoted(object.to_s)
|
102
106
|
when Date
|
103
107
|
Arel::Nodes.build_quoted(object, self)
|
104
108
|
when NilClass
|
@@ -106,7 +110,7 @@ module ArelExtensions
|
|
106
110
|
when ActiveSupport::Duration
|
107
111
|
Arel::Nodes.build_quoted(object.to_i.to_s)
|
108
112
|
else
|
109
|
-
raise(ArgumentError, "#{object.class}
|
113
|
+
raise(ArgumentError, "#{object.class} cannot be converted to CONCAT arg")
|
110
114
|
end
|
111
115
|
end
|
112
116
|
|
@@ -116,12 +120,12 @@ module ArelExtensions
|
|
116
120
|
object
|
117
121
|
when DateTime, Time
|
118
122
|
Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
|
119
|
-
when String
|
120
|
-
Arel::Nodes.build_quoted(Date.parse(object), self)
|
123
|
+
when MBSTRING, String
|
124
|
+
Arel::Nodes.build_quoted(Date.parse(object.to_s), self)
|
121
125
|
when Date
|
122
126
|
Arel::Nodes.build_quoted(object, self)
|
123
127
|
else
|
124
|
-
raise(ArgumentError, "#{object.class}
|
128
|
+
raise(ArgumentError, "#{object.class} cannot be converted to Date")
|
125
129
|
end
|
126
130
|
end
|
127
131
|
|
@@ -131,12 +135,12 @@ module ArelExtensions
|
|
131
135
|
object
|
132
136
|
when DateTime, Time
|
133
137
|
Arel::Nodes.build_quoted(object, self)
|
134
|
-
when String
|
135
|
-
Arel::Nodes.build_quoted(Time.parse(object), self)
|
138
|
+
when MBSTRING, String
|
139
|
+
Arel::Nodes.build_quoted(Time.parse(object.to_s), self)
|
136
140
|
when Date
|
137
141
|
Arel::Nodes.build_quoted(Time.utc(object.year, object.month, object.day, 0, 0, 0), self)
|
138
142
|
else
|
139
|
-
raise(ArgumentError, "#{object.class}
|
143
|
+
raise(ArgumentError, "#{object.class} cannot be converted to Datetime")
|
140
144
|
end
|
141
145
|
end
|
142
146
|
|
@@ -154,10 +158,9 @@ module ArelExtensions
|
|
154
158
|
when NilClass
|
155
159
|
0
|
156
160
|
else
|
157
|
-
raise(ArgumentError, "#{object.class}
|
161
|
+
raise(ArgumentError, "#{object.class} cannot be converted to NUMBER arg")
|
158
162
|
end
|
159
163
|
end
|
160
|
-
|
161
164
|
end
|
162
165
|
end
|
163
166
|
end
|
File without changes
|
@@ -26,43 +26,55 @@ module ArelExtensions
|
|
26
26
|
[@dict].hash
|
27
27
|
end
|
28
28
|
|
29
|
+
def convert_to_json_node(n)
|
30
|
+
case n
|
31
|
+
when JsonNode
|
32
|
+
n.dict
|
33
|
+
when Array
|
34
|
+
n.map{|e|
|
35
|
+
(e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_json_node(e)
|
36
|
+
}
|
37
|
+
when Hash
|
38
|
+
n.reduce({}){|acc,v|
|
39
|
+
acc[convert_to_json_node(v[0])] = (v[1].is_a?(Array) || v[1].is_a?(Hash)) ? Json.new(v[1]) : convert_to_json_node(v[1])
|
40
|
+
acc
|
41
|
+
}
|
42
|
+
when String, Numeric, TrueClass, FalseClass
|
43
|
+
convert_to_node(n)
|
44
|
+
when Date
|
45
|
+
convert_to_node(n.strftime("%Y-%m-%d"))
|
46
|
+
when DateTime, Time
|
47
|
+
convert_to_node(n.strftime("%Y-%m-%dT%H:%M:%S.%L%:z"))
|
48
|
+
when NilClass
|
49
|
+
Arel.sql('null')
|
50
|
+
else
|
51
|
+
convert_to_node(n)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def type_of_node(v)
|
56
|
+
if v.is_a?(Arel::Attributes::Attribute)
|
57
|
+
self.type_of_attribute(v)
|
58
|
+
elsif v.respond_to?(:return_type)
|
59
|
+
v.return_type
|
60
|
+
elsif v.nil?
|
61
|
+
:nil
|
62
|
+
else
|
63
|
+
:string
|
64
|
+
end
|
65
|
+
end
|
29
66
|
end
|
30
67
|
|
31
68
|
class Json < JsonNode
|
32
|
-
|
33
69
|
def initialize *expr
|
34
70
|
@dict =
|
35
71
|
if expr.length == 1
|
36
|
-
|
37
|
-
when JsonNode
|
38
|
-
exp.dict
|
39
|
-
when Array
|
40
|
-
exp.map{|e|
|
41
|
-
(e.is_a?(Array) || e.is_a?(Hash)) ? Json.new(e) : convert_to_node(e)
|
42
|
-
}
|
43
|
-
when Hash
|
44
|
-
exp.reduce({}){|acc,v|
|
45
|
-
acc[convert_to_node(v[0])] = (v[1].is_a?(Array) || v[1].is_a?(Hash)) ? Json.new(v[1]) : convert_to_node(v[1])
|
46
|
-
acc
|
47
|
-
}
|
48
|
-
when String, Numeric, TrueClass, FalseClass
|
49
|
-
convert_to_node(exp)
|
50
|
-
when NilClass
|
51
|
-
Arel.sql('null')
|
52
|
-
else
|
53
|
-
if (exp.is_a?(Arel::Attributes::Attribute) && type_of_attribute(exp) == :string) \
|
54
|
-
|| (exp.return_type == :string)
|
55
|
-
convert_to_node(exp)
|
56
|
-
else
|
57
|
-
[convert_to_node(exp)]
|
58
|
-
end
|
59
|
-
end
|
72
|
+
convert_to_json_node(expr.first)
|
60
73
|
else
|
61
|
-
expr.map{|e| (e
|
74
|
+
expr.map{|e| convert_to_json_node(e) }
|
62
75
|
end
|
63
76
|
super
|
64
77
|
end
|
65
|
-
|
66
78
|
end
|
67
79
|
|
68
80
|
class JsonMerge < JsonNode
|
@@ -87,7 +99,6 @@ module ArelExtensions
|
|
87
99
|
@dict = json
|
88
100
|
@key = convert_to_node(key)
|
89
101
|
end
|
90
|
-
|
91
102
|
end
|
92
103
|
|
93
104
|
class JsonSet < JsonNode
|
@@ -98,8 +109,6 @@ module ArelExtensions
|
|
98
109
|
@key = convert_to_node(key)
|
99
110
|
@value = Json.new(value)
|
100
111
|
end
|
101
|
-
|
102
112
|
end
|
103
|
-
|
104
113
|
end
|
105
114
|
end
|
File without changes
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
3
|
class IMatches < Arel::Nodes::Matches
|
4
|
-
|
5
4
|
attr_accessor :case_sensitive if Arel::VERSION.to_i < 7
|
6
5
|
|
7
6
|
def initialize(left, right, escape = nil)
|
@@ -26,6 +25,5 @@ module ArelExtensions
|
|
26
25
|
|
27
26
|
class SMatches < IMatches
|
28
27
|
end
|
29
|
-
|
30
28
|
end
|
31
29
|
end
|
@@ -14,7 +14,6 @@ module ArelExtensions
|
|
14
14
|
def +(other)
|
15
15
|
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
16
16
|
end
|
17
|
-
|
18
17
|
end
|
19
18
|
|
20
19
|
class RegexpReplace < Function
|
@@ -32,6 +31,5 @@ module ArelExtensions
|
|
32
31
|
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
33
32
|
end
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
File without changes
|
File without changes
|
@@ -13,7 +13,6 @@ module ArelExtensions
|
|
13
13
|
def +(other)
|
14
14
|
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
15
|
end
|
16
|
-
|
17
16
|
end
|
18
17
|
|
19
18
|
class Ltrim < Trim
|
@@ -23,6 +22,5 @@ module ArelExtensions
|
|
23
22
|
class Rtrim < Trim
|
24
23
|
RETURN_TYPE = :string
|
25
24
|
end
|
26
|
-
|
27
25
|
end
|
28
26
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
3
|
class Union < Arel::Nodes::Union
|
4
|
-
|
5
4
|
def initialize left,right
|
6
5
|
return super(left,right)
|
7
6
|
end
|
@@ -18,6 +17,5 @@ module ArelExtensions
|
|
18
17
|
Arel::Nodes::TableAlias.new Arel::Nodes::Grouping.new(self), Arel::Nodes::SqlLiteral.new(other.to_s)
|
19
18
|
end
|
20
19
|
end
|
21
|
-
|
22
20
|
end
|
23
21
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
3
|
class UnionAll < Arel::Nodes::UnionAll
|
4
|
-
|
5
4
|
def initialize left,right
|
6
5
|
return super(left,right)
|
7
6
|
end
|
@@ -14,6 +13,5 @@ module ArelExtensions
|
|
14
13
|
Arel::Nodes::TableAlias.new Arel::Nodes::Grouping.new(self), Arel::Nodes::SqlLiteral.new(other.to_s)
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
@@ -3,23 +3,21 @@ require 'arel_extensions/nodes/is_null'
|
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
5
|
module NullFunctions
|
6
|
-
|
7
|
-
#ISNULL function lets you return an alternative value when an expression is NULL.
|
6
|
+
# ISNULL function lets you return an alternative value when an expression is NULL.
|
8
7
|
def is_null
|
9
8
|
ArelExtensions::Nodes::IsNull.new [self]
|
10
9
|
end
|
11
10
|
|
12
|
-
#ISNOTNULL function lets you return an alternative value when an expression is NOT NULL.
|
11
|
+
# ISNOTNULL function lets you return an alternative value when an expression is NOT NULL.
|
13
12
|
def is_not_null
|
14
13
|
ArelExtensions::Nodes::IsNotNull.new [self]
|
15
14
|
end
|
16
15
|
|
17
16
|
# returns the first non-null expr in the expression list. You must specify at least two expressions.
|
18
|
-
#If all occurrences of expr evaluate to null, then the function returns null.
|
17
|
+
# If all occurrences of expr evaluate to null, then the function returns null.
|
19
18
|
def coalesce *args
|
20
19
|
args.unshift(self)
|
21
20
|
ArelExtensions::Nodes::Coalesce.new args
|
22
21
|
end
|
23
|
-
|
24
22
|
end
|
25
23
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Predications
|
3
|
-
|
4
3
|
def when right, expression = nil
|
5
4
|
ArelExtensions::Nodes::Case.new(self).when(right,expression)
|
6
5
|
end
|
@@ -21,12 +20,12 @@ module ArelExtensions
|
|
21
20
|
ArelExtensions::Nodes::Cast.new([self,right])
|
22
21
|
end
|
23
22
|
|
24
|
-
def in(*other) #In should handle nil element in the Array
|
23
|
+
def in(*other) # In should handle nil element in the Array
|
25
24
|
other = other.first if other.length <= 1
|
26
25
|
case other
|
27
26
|
when Range
|
28
27
|
self.between(other)
|
29
|
-
when Arel::Nodes::Grouping
|
28
|
+
when Arel::Nodes::Grouping, ArelExtensions::Nodes::Union, ArelExtensions::Nodes::UnionAll
|
30
29
|
Arel::Nodes::In.new(self, quoted_node(other))
|
31
30
|
when Enumerable
|
32
31
|
nils, values = other.partition{ |v| v.nil? }
|
@@ -49,12 +48,12 @@ module ArelExtensions
|
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
|
-
def not_in(*other) #In should handle nil element in the Array
|
51
|
+
def not_in(*other) # In should handle nil element in the Array
|
53
52
|
other = other.first if other.length <= 1
|
54
53
|
case other
|
55
54
|
when Range
|
56
55
|
Arel::Nodes::Not.new(self.between(other))
|
57
|
-
when Arel::Nodes::Grouping
|
56
|
+
when Arel::Nodes::Grouping, ArelExtensions::Nodes::Union, ArelExtensions::Nodes::UnionAll
|
58
57
|
Arel::Nodes::NotIn.new(self, quoted_node(other))
|
59
58
|
when Enumerable
|
60
59
|
nils, values = other.partition{ |v| v.nil? }
|
@@ -94,7 +93,7 @@ module ArelExtensions
|
|
94
93
|
when ActiveSupport::Duration
|
95
94
|
object.to_i
|
96
95
|
else
|
97
|
-
raise(ArgumentError, "#{object.class}
|
96
|
+
raise(ArgumentError, "#{object.class} cannot be converted to CONCAT arg")
|
98
97
|
end
|
99
98
|
end
|
100
99
|
end
|