arel_extensions 1.2.5 → 1.2.15
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/.rubocop.yml +7 -4
- data/.travis.yml +54 -86
- data/README.md +7 -2
- data/Rakefile +38 -27
- data/arel_extensions.gemspec +1 -1
- data/functions.html +2 -2
- data/gemfiles/rails4.gemfile +1 -1
- data/gemfiles/rails6.gemfile +30 -0
- data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
- data/generate_gems.sh +14 -0
- data/lib/arel_extensions.rb +49 -21
- data/lib/arel_extensions/attributes.rb +0 -1
- data/lib/arel_extensions/boolean_functions.rb +38 -13
- data/lib/arel_extensions/common_sql_functions.rb +5 -4
- data/lib/arel_extensions/insert_manager.rb +26 -24
- data/lib/arel_extensions/math.rb +3 -3
- data/lib/arel_extensions/math_functions.rb +4 -4
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/case.rb +8 -4
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +0 -0
- data/lib/arel_extensions/nodes/collate.rb +1 -1
- data/lib/arel_extensions/nodes/concat.rb +0 -0
- data/lib/arel_extensions/nodes/date_diff.rb +1 -3
- data/lib/arel_extensions/nodes/duration.rb +0 -2
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/formatted_number.rb +20 -20
- data/lib/arel_extensions/nodes/function.rb +0 -0
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +43 -30
- data/lib/arel_extensions/nodes/length.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -0
- data/lib/arel_extensions/nodes/power.rb +5 -4
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/replace.rb +23 -5
- data/lib/arel_extensions/nodes/round.rb +5 -5
- data/lib/arel_extensions/nodes/soundex.rb +14 -13
- data/lib/arel_extensions/nodes/substring.rb +8 -15
- data/lib/arel_extensions/nodes/trim.rb +1 -1
- data/lib/arel_extensions/nodes/union.rb +0 -1
- data/lib/arel_extensions/nodes/union_all.rb +0 -1
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/predications.rb +35 -33
- data/lib/arel_extensions/set_functions.rb +2 -2
- data/lib/arel_extensions/string_functions.rb +25 -6
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +13 -12
- data/lib/arel_extensions/visitors/mysql.rb +67 -37
- data/lib/arel_extensions/visitors/oracle.rb +14 -14
- data/lib/arel_extensions/visitors/oracle12.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +46 -28
- data/lib/arel_extensions/visitors/sqlite.rb +52 -44
- data/lib/arel_extensions/visitors/to_sql.rb +73 -59
- data/test/arelx_test_helper.rb +28 -0
- data/test/support/fake_record.rb +4 -0
- data/test/test_comparators.rb +8 -7
- data/test/visitors/test_bulk_insert_oracle.rb +8 -7
- data/test/visitors/test_bulk_insert_sqlite.rb +8 -7
- data/test/visitors/test_bulk_insert_to_sql.rb +3 -3
- data/test/visitors/test_oracle.rb +41 -41
- data/test/visitors/test_to_sql.rb +367 -199
- data/test/with_ar/all_agnostic_test.rb +63 -41
- data/test/with_ar/insert_agnostic_test.rb +1 -1
- data/test/with_ar/test_bulk_sqlite.rb +5 -4
- data/test/with_ar/test_math_sqlite.rb +2 -2
- data/test/with_ar/test_string_mysql.rb +2 -4
- data/test/with_ar/test_string_sqlite.rb +2 -6
- data/version_v1.rb +3 -0
- data/version_v2.rb +3 -0
- metadata +10 -5
- data/test/helper.rb +0 -18
data/generate_gems.sh
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
gem uninstall arel_extensions
|
3
|
+
|
4
|
+
# VERSION ~> 1
|
5
|
+
cp ./version_v1.rb lib/arel_extensions/version.rb
|
6
|
+
gem build ./arel_extensions.gemspec
|
7
|
+
|
8
|
+
# VERSION ~> 2
|
9
|
+
cp ./version_v2.rb lib/arel_extensions/version.rb
|
10
|
+
mv ./arel_extensions.gemspec ./arel_extensions.gemspec.bck
|
11
|
+
cp ./gemspec_v2/arel_extensions-v2.gemspec ./arel_extensions.gemspec
|
12
|
+
gem build ./arel_extensions.gemspec
|
13
|
+
cp ./version_v1.rb lib/arel_extensions/version.rb
|
14
|
+
cp ./arel_extensions.gemspec.bck ./arel_extensions.gemspec
|
data/lib/arel_extensions.rb
CHANGED
@@ -7,35 +7,37 @@ require 'arel_extensions/railtie' if defined?(Rails::Railtie)
|
|
7
7
|
# Count|NamedFunction < Function < Arel::Nodes::Node
|
8
8
|
|
9
9
|
# pure Arel internals improvements
|
10
|
-
Arel::Nodes::Binary
|
10
|
+
class Arel::Nodes::Binary
|
11
11
|
include Arel::AliasPredication
|
12
12
|
include Arel::Expressions
|
13
13
|
end
|
14
14
|
|
15
|
-
Arel::Nodes::Casted
|
15
|
+
class Arel::Nodes::Casted
|
16
16
|
include Arel::AliasPredication
|
17
|
+
|
18
|
+
# They forget to define hash.
|
19
|
+
def hash
|
20
|
+
[self.class, self.val, self.attribute].hash
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
|
-
Arel::Nodes::Unary
|
24
|
+
class Arel::Nodes::Unary
|
20
25
|
include Arel::Math
|
21
26
|
include Arel::AliasPredication
|
22
27
|
include Arel::Expressions
|
23
28
|
end
|
24
29
|
|
25
|
-
Arel::Nodes::Grouping
|
26
|
-
include Arel::Math
|
27
|
-
include Arel::AliasPredication
|
30
|
+
class Arel::Nodes::Grouping
|
28
31
|
include Arel::OrderPredications
|
29
|
-
include Arel::Expressions
|
30
32
|
end
|
31
33
|
|
32
|
-
Arel::Nodes::Function
|
34
|
+
class Arel::Nodes::Function
|
33
35
|
include Arel::Math
|
34
36
|
include Arel::Expressions
|
35
37
|
end
|
36
38
|
|
37
|
-
if Arel::VERSION >= "7.1.0"
|
38
|
-
Arel::Nodes::Case
|
39
|
+
if Gem::Version.new(Arel::VERSION) >= Gem::Version.new("7.1.0")
|
40
|
+
class Arel::Nodes::Case
|
39
41
|
include Arel::Math
|
40
42
|
include Arel::Expressions
|
41
43
|
end
|
@@ -101,14 +103,18 @@ module Arel
|
|
101
103
|
Arel::Nodes::Equality.new(1,0)
|
102
104
|
end
|
103
105
|
|
106
|
+
def self.tuple *v
|
107
|
+
tmp = Arel::Nodes::Grouping.new(nil)
|
108
|
+
Arel::Nodes::Grouping.new(v.map{|e| tmp.convert_to_node(e)})
|
109
|
+
end
|
104
110
|
end
|
105
111
|
|
106
|
-
Arel::Attributes::Attribute
|
112
|
+
class Arel::Attributes::Attribute
|
107
113
|
include Arel::Math
|
108
114
|
include ArelExtensions::Attributes
|
109
115
|
end
|
110
116
|
|
111
|
-
Arel::Nodes::Function
|
117
|
+
class Arel::Nodes::Function
|
112
118
|
include ArelExtensions::Math
|
113
119
|
include ArelExtensions::Comparators
|
114
120
|
include ArelExtensions::DateDuration
|
@@ -118,12 +124,23 @@ Arel::Nodes::Function.class_eval do
|
|
118
124
|
include ArelExtensions::NullFunctions
|
119
125
|
include ArelExtensions::Predications
|
120
126
|
|
127
|
+
alias_method :old_as, :as
|
121
128
|
def as other
|
122
129
|
Arel::Nodes::As.new(self, Arel.sql(other))
|
123
130
|
end
|
124
131
|
end
|
125
132
|
|
126
|
-
Arel::Nodes::
|
133
|
+
class Arel::Nodes::Grouping
|
134
|
+
include ArelExtensions::Math
|
135
|
+
include ArelExtensions::Comparators
|
136
|
+
include ArelExtensions::DateDuration
|
137
|
+
include ArelExtensions::MathFunctions
|
138
|
+
include ArelExtensions::NullFunctions
|
139
|
+
include ArelExtensions::StringFunctions
|
140
|
+
include ArelExtensions::Predications
|
141
|
+
end
|
142
|
+
|
143
|
+
class Arel::Nodes::Unary
|
127
144
|
include ArelExtensions::Math
|
128
145
|
include ArelExtensions::Attributes
|
129
146
|
include ArelExtensions::MathFunctions
|
@@ -131,7 +148,7 @@ Arel::Nodes::Unary.class_eval do
|
|
131
148
|
include ArelExtensions::Predications
|
132
149
|
end
|
133
150
|
|
134
|
-
Arel::Nodes::Binary
|
151
|
+
class Arel::Nodes::Binary
|
135
152
|
include ArelExtensions::Math
|
136
153
|
include ArelExtensions::Attributes
|
137
154
|
include ArelExtensions::MathFunctions
|
@@ -140,29 +157,40 @@ Arel::Nodes::Binary.class_eval do
|
|
140
157
|
include ArelExtensions::Predications
|
141
158
|
end
|
142
159
|
|
143
|
-
Arel::Nodes::Equality
|
160
|
+
class Arel::Nodes::Equality
|
144
161
|
include ArelExtensions::Comparators
|
145
162
|
include ArelExtensions::DateDuration
|
146
163
|
include ArelExtensions::MathFunctions
|
147
164
|
include ArelExtensions::StringFunctions
|
148
165
|
end
|
149
166
|
|
150
|
-
|
151
|
-
Arel::InsertManager.class_eval do
|
167
|
+
class Arel::InsertManager
|
152
168
|
include ArelExtensions::InsertManager
|
153
169
|
end
|
154
170
|
|
155
|
-
Arel::SelectManager
|
171
|
+
class Arel::SelectManager
|
156
172
|
include ArelExtensions::SetFunctions
|
157
173
|
include ArelExtensions::Nodes
|
158
174
|
end
|
159
175
|
|
160
|
-
Arel::Nodes::As
|
176
|
+
class Arel::Nodes::As
|
161
177
|
include ArelExtensions::Nodes
|
162
178
|
end
|
163
179
|
|
164
|
-
Arel::Table
|
180
|
+
class Arel::Table
|
181
|
+
alias_method :old_alias, :alias
|
165
182
|
def alias(name = "#{self.name}_2")
|
166
|
-
name.blank? ? self :
|
183
|
+
name.blank? ? self : Arel::Nodes::TableAlias.new(self,name)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class Arel::Nodes::TableAlias
|
188
|
+
def method_missing(*args)
|
189
|
+
met = args.shift.to_sym
|
190
|
+
if self.relation.respond_to?(met)
|
191
|
+
self.relation.send(met,args)
|
192
|
+
else
|
193
|
+
super(met,*args)
|
194
|
+
end
|
167
195
|
end
|
168
196
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
require 'arel_extensions/nodes/then'
|
2
3
|
|
3
4
|
module ArelExtensions
|
@@ -8,7 +9,7 @@ module ArelExtensions
|
|
8
9
|
end
|
9
10
|
|
10
11
|
def and *others
|
11
|
-
Arel::Nodes::And.new
|
12
|
+
Arel::Nodes::And.new self, others
|
12
13
|
end
|
13
14
|
|
14
15
|
def ⋁(other)
|
@@ -16,30 +17,54 @@ module ArelExtensions
|
|
16
17
|
end
|
17
18
|
|
18
19
|
def or *others
|
19
|
-
|
20
|
-
if args.length == 1
|
21
|
-
Arel::Nodes::Or.new(self, args.first)
|
22
|
-
else
|
23
|
-
ArelExtensions::Nodes::Or.new([self]+ args)
|
24
|
-
end
|
20
|
+
Arel::Nodes::Or.new self, others
|
25
21
|
end
|
26
22
|
|
27
23
|
def then(t, f = nil)
|
28
24
|
ArelExtensions::Nodes::Then.new [self, t, f]
|
29
25
|
end
|
26
|
+
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
33
|
-
Arel::Nodes::And
|
30
|
+
class Arel::Nodes::And
|
34
31
|
include ArelExtensions::BooleanFunctions
|
35
|
-
end
|
36
32
|
|
37
|
-
|
38
|
-
|
33
|
+
def self.new *children
|
34
|
+
children =
|
35
|
+
children.flatten.map { |c|
|
36
|
+
c.is_a?(self) ? c.children : c
|
37
|
+
}.flatten
|
38
|
+
super(children)
|
39
|
+
end
|
40
|
+
|
39
41
|
end
|
40
42
|
|
41
|
-
|
43
|
+
# For some reason, Arel's And is properly defined as variadic (it
|
44
|
+
# stores @children, and hashes it all). However Arel's Or is defined
|
45
|
+
# as binary, with only @left and @right, and hashing only @left and @right.
|
46
|
+
#
|
47
|
+
# So reimplement its ctor and accessors.
|
48
|
+
|
49
|
+
class Arel::Nodes::Or
|
42
50
|
include ArelExtensions::BooleanFunctions
|
43
|
-
end
|
44
51
|
|
52
|
+
attr_reader :children
|
45
53
|
|
54
|
+
def self.new *children
|
55
|
+
children =
|
56
|
+
children.flatten.map { |c|
|
57
|
+
c.is_a?(self) ? c.children : c
|
58
|
+
}.flatten
|
59
|
+
super(*children)
|
60
|
+
end
|
61
|
+
|
62
|
+
def initialize *children
|
63
|
+
@children = children
|
64
|
+
end
|
65
|
+
|
66
|
+
def hash
|
67
|
+
children.hash
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -39,6 +39,7 @@ module ArelExtensions
|
|
39
39
|
|
40
40
|
def add_sql_functions(env_db = nil)
|
41
41
|
env_db ||= @cnx.adapter_name
|
42
|
+
env_db = 'mysql' if env_db =~ /mysql/i
|
42
43
|
if env_db =~ /sqlite/i
|
43
44
|
begin
|
44
45
|
add_sqlite_functions
|
@@ -52,10 +53,10 @@ module ArelExtensions
|
|
52
53
|
sql.split(/^GO\s*$/).each {|str|
|
53
54
|
@cnx.execute(str.strip) unless str.blank?
|
54
55
|
}
|
55
|
-
elsif env_db ==
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
elsif env_db =='mysql'
|
57
|
+
sql.split("$$")[1..-2].each { |str|
|
58
|
+
@cnx.execute(str.strip) unless str.strip.blank?
|
59
|
+
}
|
59
60
|
else
|
60
61
|
@cnx.execute(sql) unless sql.blank?
|
61
62
|
end
|
@@ -3,31 +3,33 @@ require 'arel'
|
|
3
3
|
module ArelExtensions
|
4
4
|
module InsertManager
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
6
|
+
def bulk_insert(cols, data)
|
7
|
+
res_columns = []
|
8
|
+
case cols.first
|
9
|
+
when String, Symbol
|
10
|
+
cols.each { |c|
|
11
|
+
res_columns << @ast.relation[c]
|
12
|
+
}
|
13
|
+
when Array
|
14
|
+
if String === cols.first.first
|
15
|
+
res_columns = cols.map {|c| [@ast.relation[c.first]] }
|
16
|
+
elsif Arel::Attributes::Attribute == cols.first.first
|
17
|
+
res_columns = cols
|
18
|
+
end
|
19
|
+
when NilClass
|
20
|
+
res_columns = @ast.relation.columns
|
21
|
+
end
|
22
|
+
self.values = BulkValues.new(res_columns, data)
|
23
|
+
@ast.columns = res_columns
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
class BulkValues < Arel::Nodes::Node
|
27
|
+
attr_accessor :left, :cols
|
28
|
+
def initialize(cols, values)
|
29
|
+
@left = values
|
30
|
+
@cols = cols
|
31
|
+
end
|
32
|
+
end
|
31
33
|
|
32
34
|
end
|
33
35
|
end
|
data/lib/arel_extensions/math.rb
CHANGED
@@ -24,7 +24,7 @@ module ArelExtensions
|
|
24
24
|
else
|
25
25
|
return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
26
26
|
end
|
27
|
-
when
|
27
|
+
when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
|
28
28
|
return case self.return_type
|
29
29
|
when :string, :text
|
30
30
|
self.concat(other)
|
@@ -35,7 +35,7 @@ module ArelExtensions
|
|
35
35
|
else
|
36
36
|
self.concat(other)
|
37
37
|
end
|
38
|
-
when
|
38
|
+
when Arel::Nodes::Function
|
39
39
|
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
40
40
|
else
|
41
41
|
begin
|
@@ -115,7 +115,7 @@ module ArelExtensions
|
|
115
115
|
end
|
116
116
|
when Arel::Nodes::Node, DateTime, Time, String, Date
|
117
117
|
ArelExtensions::Nodes::DateDiff.new [self, other]
|
118
|
-
when
|
118
|
+
when ArelExtensions::Nodes::Duration, Integer
|
119
119
|
ArelExtensions::Nodes::DateSub.new [self, other]
|
120
120
|
else # ActiveSupport::Duration
|
121
121
|
ArelExtensions::Nodes::DateAdd.new [self, -other]
|
@@ -63,15 +63,15 @@ module ArelExtensions
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# Aggregate Functions
|
66
|
-
def std opts={unbiased: true}
|
66
|
+
def std opts = {unbiased: true}
|
67
67
|
ArelExtensions::Nodes::Std.new self, opts
|
68
68
|
end
|
69
69
|
|
70
|
-
def variance opts={unbiased: true}
|
70
|
+
def variance opts = {unbiased: true}
|
71
71
|
ArelExtensions::Nodes::Variance.new self, opts
|
72
72
|
end
|
73
73
|
|
74
|
-
def sum opts={unbiased: true}
|
74
|
+
def sum opts = {unbiased: true}
|
75
75
|
ArelExtensions::Nodes::Sum.new self, opts
|
76
76
|
end
|
77
77
|
|
@@ -91,7 +91,7 @@ module ArelExtensions
|
|
91
91
|
end
|
92
92
|
|
93
93
|
# function returning a number at a specific format
|
94
|
-
def format_number format_string, locale=nil
|
94
|
+
def format_number format_string, locale = nil
|
95
95
|
begin
|
96
96
|
sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
|
97
97
|
m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
|
File without changes
|
@@ -1,7 +1,11 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Nodes
|
3
|
-
if Arel::VERSION < "7.1.0"
|
3
|
+
if Gem::Version.new(Arel::VERSION) < Gem::Version.new("7.1.0")
|
4
4
|
class Case < Arel::Nodes::Node
|
5
|
+
include Arel::Expressions
|
6
|
+
include Arel::Math
|
7
|
+
include Arel::Predications
|
8
|
+
include Arel::OrderPredications
|
5
9
|
attr_accessor :case, :conditions, :default
|
6
10
|
|
7
11
|
def initialize expression = nil, default = nil
|
@@ -26,8 +30,10 @@ module ArelExtensions
|
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
29
|
-
ArelExtensions::Nodes::Case
|
33
|
+
class ArelExtensions::Nodes::Case
|
30
34
|
include Arel::Expressions
|
35
|
+
include Arel::Math
|
36
|
+
include Arel::Predications
|
31
37
|
include Arel::OrderPredications
|
32
38
|
include ArelExtensions::Math
|
33
39
|
include ArelExtensions::Comparators
|
@@ -41,8 +47,6 @@ module ArelExtensions
|
|
41
47
|
@conditions.last.right
|
42
48
|
elsif @default
|
43
49
|
@default.expr
|
44
|
-
else
|
45
|
-
nil
|
46
50
|
end
|
47
51
|
if obj.respond_to?(:return_type)
|
48
52
|
obj.return_type
|
File without changes
|
File without changes
|
File without changes
|
@@ -136,7 +136,7 @@ module ArelExtensions
|
|
136
136
|
if ArelExtensions::Nodes::Duration === v
|
137
137
|
v.with_interval = true
|
138
138
|
case v.left
|
139
|
-
when
|
139
|
+
when 'd','m','y'
|
140
140
|
Arel.sql('day')
|
141
141
|
when 'h','mn','s'
|
142
142
|
Arel.sql('second')
|
@@ -145,8 +145,6 @@ module ArelExtensions
|
|
145
145
|
else
|
146
146
|
Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
|
147
147
|
end
|
148
|
-
else
|
149
|
-
nil
|
150
148
|
end
|
151
149
|
end
|
152
150
|
end
|