arel_extensions 2.0.20 → 2.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +153 -72
- data/README.md +42 -0
- data/arel_extensions.gemspec +1 -1
- data/gemfiles/rails5_2.gemfile +6 -5
- data/gemfiles/rails6.gemfile +6 -6
- data/gemfiles/rails6_1.gemfile +5 -5
- data/gemfiles/rails7.gemfile +30 -0
- data/gemspecs/arel_extensions-v1.gemspec +1 -1
- data/gemspecs/arel_extensions-v2.gemspec +1 -1
- data/lib/arel_extensions/aliases.rb +14 -0
- data/lib/arel_extensions/attributes.rb +2 -0
- data/lib/arel_extensions/insert_manager.rb +19 -17
- data/lib/arel_extensions/math.rb +16 -16
- data/lib/arel_extensions/nodes/case.rb +2 -1
- data/lib/arel_extensions/nodes/cast.rb +1 -1
- data/lib/arel_extensions/nodes/function.rb +4 -2
- data/lib/arel_extensions/nodes/json.rb +3 -1
- data/lib/arel_extensions/nodes/length.rb +6 -0
- data/lib/arel_extensions/nodes/replace.rb +0 -8
- data/lib/arel_extensions/nodes/union.rb +1 -1
- data/lib/arel_extensions/nodes/union_all.rb +1 -1
- data/lib/arel_extensions/string_functions.rb +10 -2
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +1 -1
- data/lib/arel_extensions/visitors/mysql.rb +9 -2
- data/lib/arel_extensions/visitors/oracle.rb +2 -2
- data/lib/arel_extensions/visitors/postgresql.rb +14 -8
- data/lib/arel_extensions/visitors/to_sql.rb +14 -9
- data/lib/arel_extensions/visitors.rb +9 -1
- data/lib/arel_extensions.rb +55 -11
- data/test/real_db_test.rb +5 -1
- data/test/visitors/test_to_sql.rb +18 -11
- data/test/with_ar/all_agnostic_test.rb +14 -4
- data/test/with_ar/insert_agnostic_test.rb +6 -2
- data/test/with_ar/test_bulk_sqlite.rb +6 -2
- data/test/with_ar/test_math_sqlite.rb +6 -2
- data/test/with_ar/test_string_mysql.rb +6 -2
- data/test/with_ar/test_string_sqlite.rb +6 -2
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +9 -7
@@ -10,10 +10,6 @@ module ArelExtensions
|
|
10
10
|
@substitute = convert_to_node(substitute)
|
11
11
|
super([@left,@pattern,@substitute])
|
12
12
|
end
|
13
|
-
|
14
|
-
def +(other)
|
15
|
-
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
16
|
-
end
|
17
13
|
end
|
18
14
|
|
19
15
|
class RegexpReplace < Function
|
@@ -26,10 +22,6 @@ module ArelExtensions
|
|
26
22
|
@substitute = convert_to_node(substitute)
|
27
23
|
super([@left,@pattern,@substitute])
|
28
24
|
end
|
29
|
-
|
30
|
-
def +(other)
|
31
|
-
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
32
|
-
end
|
33
25
|
end
|
34
26
|
end
|
35
27
|
end
|
@@ -14,7 +14,7 @@ module ArelExtensions
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def as other
|
17
|
-
Arel::Nodes::TableAlias.new Arel
|
17
|
+
Arel::Nodes::TableAlias.new Arel.grouping(self), Arel::Nodes::SqlLiteral.new(other.to_s)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -10,7 +10,7 @@ module ArelExtensions
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def as other
|
13
|
-
Arel::Nodes::TableAlias.new Arel
|
13
|
+
Arel::Nodes::TableAlias.new Arel.grouping(self), Arel::Nodes::SqlLiteral.new(other.to_s)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -24,9 +24,17 @@ module ArelExtensions
|
|
24
24
|
ArelExtensions::Nodes::FindInSet.new [other, self]
|
25
25
|
end
|
26
26
|
|
27
|
-
# LENGTH function returns the length of the value in a text field.
|
27
|
+
# LENGTH function returns the length (bytewise) of the value in a text field.
|
28
28
|
def length
|
29
|
-
ArelExtensions::Nodes::Length.new
|
29
|
+
ArelExtensions::Nodes::Length.new self, true
|
30
|
+
end
|
31
|
+
|
32
|
+
def byte_length
|
33
|
+
ArelExtensions::Nodes::Length.new self, true
|
34
|
+
end
|
35
|
+
|
36
|
+
def char_length
|
37
|
+
ArelExtensions::Nodes::Length.new self, false
|
30
38
|
end
|
31
39
|
|
32
40
|
# LOCATE function returns the first starting position of a string in another string.
|
@@ -354,9 +354,16 @@ module ArelExtensions
|
|
354
354
|
else
|
355
355
|
collector = visit o.left, collector
|
356
356
|
end
|
357
|
-
collector << " AS
|
357
|
+
collector << " AS "
|
358
|
+
|
359
|
+
# sometimes these values are already quoted, if they are, don't double quote it
|
360
|
+
quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '`' && o.right[-1] != '`'
|
361
|
+
|
362
|
+
collector << '`' if quote
|
358
363
|
collector = visit o.right, collector
|
359
|
-
collector <<
|
364
|
+
collector << '`' if quote
|
365
|
+
|
366
|
+
collector
|
360
367
|
collector
|
361
368
|
end
|
362
369
|
|
@@ -5,7 +5,7 @@ module ArelExtensions
|
|
5
5
|
SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
|
6
6
|
DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
7
7
|
DATE_FORMAT_DIRECTIVES = {
|
8
|
-
'%Y' => '
|
8
|
+
'%Y' => 'YYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
9
9
|
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
|
10
10
|
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
11
11
|
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
@@ -308,7 +308,7 @@ module ArelExtensions
|
|
308
308
|
end
|
309
309
|
|
310
310
|
def visit_ArelExtensions_Nodes_Length o, collector
|
311
|
-
collector << "LENGTH("
|
311
|
+
collector << "LENGTH#{o.bytewise ? 'B' : ''}("
|
312
312
|
collector = visit o.expr, collector
|
313
313
|
collector << ")"
|
314
314
|
collector
|
@@ -7,7 +7,7 @@ module ArelExtensions
|
|
7
7
|
}.freeze
|
8
8
|
|
9
9
|
DATE_FORMAT_DIRECTIVES = {
|
10
|
-
'%Y' => '
|
10
|
+
'%Y' => 'YYYY', '%C' => 'CC', '%y' => 'YY',
|
11
11
|
'%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
12
12
|
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
|
13
13
|
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
@@ -86,9 +86,15 @@ module ArelExtensions
|
|
86
86
|
else
|
87
87
|
collector = visit o.left, collector
|
88
88
|
end
|
89
|
-
collector << " AS
|
89
|
+
collector << " AS "
|
90
|
+
|
91
|
+
# sometimes these values are already quoted, if they are, don't double quote it
|
92
|
+
quote = o.right.is_a?(Arel::Nodes::SqlLiteral) && o.right[0] != '"' && o.right[-1] != '"'
|
93
|
+
|
94
|
+
collector << '"' if quote
|
90
95
|
collector = visit o.right, collector
|
91
|
-
collector << "
|
96
|
+
collector << '"' if quote
|
97
|
+
|
92
98
|
collector
|
93
99
|
end
|
94
100
|
|
@@ -373,6 +379,8 @@ module ArelExtensions
|
|
373
379
|
Arel::Nodes::SqlLiteral.new('date')
|
374
380
|
when :binary
|
375
381
|
Arel::Nodes::SqlLiteral.new('binary')
|
382
|
+
when :jsonb
|
383
|
+
Arel::Nodes::SqlLiteral.new('jsonb')
|
376
384
|
else
|
377
385
|
Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
378
386
|
end
|
@@ -401,13 +409,13 @@ module ArelExtensions
|
|
401
409
|
ArelExtensions::Nodes::Concat.new([
|
402
410
|
Arel::Nodes::NamedFunction.new('TRIM',[
|
403
411
|
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
404
|
-
col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
|
412
|
+
Arel.when(col.not_eq 0).then(col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor)).else(1),
|
405
413
|
Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
|
406
414
|
])]),
|
407
415
|
o.type,
|
408
416
|
Arel::Nodes::NamedFunction.new('TRIM',[
|
409
417
|
Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
410
|
-
col.abs.log10.floor,
|
418
|
+
Arel.when(col.not_eq 0).then(col.abs.log10.floor).else(0),
|
411
419
|
Arel::Nodes.build_quoted('FM'+nines_before)
|
412
420
|
])])
|
413
421
|
])
|
@@ -511,8 +519,6 @@ module ArelExtensions
|
|
511
519
|
collector << '::jsonb'
|
512
520
|
when NilClass
|
513
521
|
collector << %Q['null'::jsonb]
|
514
|
-
when Arel::Attributes::Attribute
|
515
|
-
collector = visit o.dict.cast(:jsonb), collector
|
516
522
|
else
|
517
523
|
collector = visit o.dict, collector
|
518
524
|
collector << '::jsonb'
|
@@ -532,7 +538,7 @@ module ArelExtensions
|
|
532
538
|
|
533
539
|
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
534
540
|
collector = visit o.dict, collector
|
535
|
-
collector << '
|
541
|
+
collector << ' ->> '
|
536
542
|
collector = visit o.key, collector
|
537
543
|
collector
|
538
544
|
end
|
@@ -8,10 +8,15 @@ module ArelExtensions
|
|
8
8
|
def make_json_string expr
|
9
9
|
Arel::Nodes.build_quoted('"') \
|
10
10
|
+ expr
|
11
|
+
.coalesce('')
|
11
12
|
.replace('\\','\\\\').replace('"','\"').replace("\n", '\n') \
|
12
13
|
+ '"'
|
13
14
|
end
|
14
15
|
|
16
|
+
def make_json_null
|
17
|
+
Arel::Nodes.build_quoted("null")
|
18
|
+
end
|
19
|
+
|
15
20
|
# Math Functions
|
16
21
|
def visit_ArelExtensions_Nodes_Abs o, collector
|
17
22
|
collector << "ABS("
|
@@ -117,7 +122,7 @@ module ArelExtensions
|
|
117
122
|
end
|
118
123
|
|
119
124
|
def visit_ArelExtensions_Nodes_Length o, collector
|
120
|
-
collector << "LENGTH("
|
125
|
+
collector << "#{o.bytewise ? '' : 'CHAR_'}LENGTH("
|
121
126
|
collector = visit o.left, collector
|
122
127
|
collector << ")"
|
123
128
|
collector
|
@@ -601,20 +606,20 @@ module ArelExtensions
|
|
601
606
|
def json_value(o,v)
|
602
607
|
case o.type_of_node(v)
|
603
608
|
when :string
|
604
|
-
Arel.when(v.is_null).then(
|
609
|
+
Arel.when(v.is_null).then(make_json_null).else(make_json_string(v))
|
605
610
|
when :date
|
606
611
|
s = v.format('%Y-%m-%d')
|
607
|
-
Arel.when(s.is_null).then(
|
612
|
+
Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
|
608
613
|
when :datetime
|
609
614
|
s = v.format('%Y-%m-%dT%H:%M:%S')
|
610
|
-
Arel.when(s.is_null).then(
|
615
|
+
Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
|
611
616
|
when :time
|
612
617
|
s = v.format('%H:%M:%S')
|
613
|
-
Arel.when(s.is_null).then(
|
618
|
+
Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
|
614
619
|
when :nil
|
615
|
-
|
620
|
+
make_json_null
|
616
621
|
else
|
617
|
-
ArelExtensions::Nodes::Cast.new([v, :string]).coalesce(
|
622
|
+
ArelExtensions::Nodes::Cast.new([v, :string]).coalesce(make_json_null)
|
618
623
|
end
|
619
624
|
end
|
620
625
|
|
@@ -636,7 +641,7 @@ module ArelExtensions
|
|
636
641
|
if i != 0
|
637
642
|
res += ', '
|
638
643
|
end
|
639
|
-
res += make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])
|
644
|
+
res += make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])) + ': '
|
640
645
|
res += json_value(o,v)
|
641
646
|
end
|
642
647
|
res += '}'
|
@@ -658,7 +663,7 @@ module ArelExtensions
|
|
658
663
|
if i != 0
|
659
664
|
res = res + ', '
|
660
665
|
end
|
661
|
-
kv = make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])
|
666
|
+
kv = make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])) + ': '
|
662
667
|
kv += json_value(o,v)
|
663
668
|
res = res + kv.group_concat(', ', order: Array(orders)).coalesce('')
|
664
669
|
end
|
@@ -9,9 +9,17 @@ if defined?(Arel::Visitors::Oracle)
|
|
9
9
|
require 'arel_extensions/visitors/oracle12'
|
10
10
|
end
|
11
11
|
|
12
|
-
if defined?(Arel::Visitors::MSSQL)
|
12
|
+
if defined?(Arel::Visitors::SQLServer) || defined?(Arel::Visitors::MSSQL)
|
13
13
|
require 'arel_extensions/visitors/mssql'
|
14
|
+
end
|
14
15
|
|
16
|
+
if defined?(Arel::Visitors::SQLServer)
|
17
|
+
class Arel::Visitors::SQLServer
|
18
|
+
include ArelExtensions::Visitors::MSSQL
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
if defined?(Arel::Visitors::MSSQL)
|
15
23
|
class Arel::Visitors::MSSQL
|
16
24
|
include ArelExtensions::Visitors::MSSQL
|
17
25
|
|
data/lib/arel_extensions.rb
CHANGED
@@ -33,6 +33,12 @@ class Arel::Nodes::Grouping
|
|
33
33
|
include Arel::OrderPredications
|
34
34
|
end
|
35
35
|
|
36
|
+
class Arel::Nodes::Ordering
|
37
|
+
def eql? other
|
38
|
+
self.hash.eql? other.hash
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
36
42
|
class Arel::Nodes::Function
|
37
43
|
include Arel::Math
|
38
44
|
include Arel::Expressions
|
@@ -46,6 +52,7 @@ if Gem::Version.new(Arel::VERSION) >= Gem::Version.new("7.1.0")
|
|
46
52
|
end
|
47
53
|
|
48
54
|
require 'arel_extensions/version'
|
55
|
+
require 'arel_extensions/aliases'
|
49
56
|
require 'arel_extensions/attributes'
|
50
57
|
require 'arel_extensions/visitors'
|
51
58
|
require 'arel_extensions/nodes'
|
@@ -82,11 +89,13 @@ module Arel
|
|
82
89
|
end
|
83
90
|
|
84
91
|
def self.json *expr
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
92
|
+
ArelExtensions::Nodes::Json.new(
|
93
|
+
if expr.length == 1
|
94
|
+
expr.first
|
95
|
+
else
|
96
|
+
expr
|
97
|
+
end
|
98
|
+
)
|
90
99
|
end
|
91
100
|
|
92
101
|
def self.when condition
|
@@ -94,20 +103,31 @@ module Arel
|
|
94
103
|
end
|
95
104
|
|
96
105
|
def self.duration s, expr
|
97
|
-
ArelExtensions::Nodes::Duration.new(s
|
106
|
+
ArelExtensions::Nodes::Duration.new("#{s}i", expr)
|
98
107
|
end
|
99
108
|
|
109
|
+
def self.grouping *v
|
110
|
+
Arel::Nodes::Grouping.new(*v)
|
111
|
+
end
|
112
|
+
|
113
|
+
# The TRUE pseudo literal.
|
100
114
|
def self.true
|
101
|
-
Arel::Nodes::Equality.new(1,1)
|
115
|
+
Arel::Nodes::Equality.new(1, 1)
|
102
116
|
end
|
103
117
|
|
118
|
+
# The FALSE pseudo literal.
|
104
119
|
def self.false
|
105
|
-
Arel::Nodes::Equality.new(1,0)
|
120
|
+
Arel::Nodes::Equality.new(1, 0)
|
121
|
+
end
|
122
|
+
|
123
|
+
# The NULL literal.
|
124
|
+
def self.null
|
125
|
+
Arel::Nodes.build_quoted(nil)
|
106
126
|
end
|
107
127
|
|
108
128
|
def self.tuple *v
|
109
|
-
tmp = Arel
|
110
|
-
Arel
|
129
|
+
tmp = Arel.grouping(nil)
|
130
|
+
Arel.grouping v.map{|e| tmp.convert_to_node(e)}
|
111
131
|
end
|
112
132
|
end
|
113
133
|
|
@@ -117,6 +137,7 @@ class Arel::Attributes::Attribute
|
|
117
137
|
end
|
118
138
|
|
119
139
|
class Arel::Nodes::Function
|
140
|
+
include ArelExtensions::Aliases
|
120
141
|
include ArelExtensions::Math
|
121
142
|
include ArelExtensions::Comparators
|
122
143
|
include ArelExtensions::DateDuration
|
@@ -152,6 +173,9 @@ class Arel::Nodes::Unary
|
|
152
173
|
include ArelExtensions::MathFunctions
|
153
174
|
include ArelExtensions::Comparators
|
154
175
|
include ArelExtensions::Predications
|
176
|
+
def eql? other
|
177
|
+
hash == other.hash
|
178
|
+
end
|
155
179
|
end
|
156
180
|
|
157
181
|
class Arel::Nodes::Binary
|
@@ -161,6 +185,9 @@ class Arel::Nodes::Binary
|
|
161
185
|
include ArelExtensions::Comparators
|
162
186
|
include ArelExtensions::BooleanFunctions
|
163
187
|
include ArelExtensions::Predications
|
188
|
+
def eql? other
|
189
|
+
hash == other.hash
|
190
|
+
end
|
164
191
|
end
|
165
192
|
|
166
193
|
class Arel::Nodes::Equality
|
@@ -177,6 +204,19 @@ end
|
|
177
204
|
class Arel::SelectManager
|
178
205
|
include ArelExtensions::SetFunctions
|
179
206
|
include ArelExtensions::Nodes
|
207
|
+
|
208
|
+
def as table_name
|
209
|
+
Arel::Nodes::TableAlias.new(self, table_name)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Install an alias, if present.
|
213
|
+
def xas table_name
|
214
|
+
if table_name.present?
|
215
|
+
as table_name
|
216
|
+
else
|
217
|
+
self
|
218
|
+
end
|
219
|
+
end
|
180
220
|
end
|
181
221
|
|
182
222
|
class Arel::Nodes::As
|
@@ -186,7 +226,11 @@ end
|
|
186
226
|
class Arel::Table
|
187
227
|
alias_method(:old_alias, :alias) rescue nil
|
188
228
|
def alias(name = "#{self.name}_2")
|
189
|
-
name.
|
229
|
+
if name.present?
|
230
|
+
Arel::Nodes::TableAlias.new(self, name)
|
231
|
+
else
|
232
|
+
self
|
233
|
+
end
|
190
234
|
end
|
191
235
|
end
|
192
236
|
|
data/test/real_db_test.rb
CHANGED
@@ -8,7 +8,11 @@ require 'arel_extensions'
|
|
8
8
|
def setup_db
|
9
9
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
10
10
|
ActiveRecord::Base.establish_connection(ENV['DB'].try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
11
|
-
ActiveRecord::
|
11
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
12
|
+
ActiveRecord.default_timezone = :utc
|
13
|
+
else
|
14
|
+
ActiveRecord::Base.default_timezone = :utc
|
15
|
+
end
|
12
16
|
@cnx = ActiveRecord::Base.connection
|
13
17
|
if ActiveRecord::Base.connection.adapter_name =~ /sqlite/i
|
14
18
|
$sqlite = true
|
@@ -282,16 +282,23 @@ module ArelExtensions
|
|
282
282
|
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END ILIKE 'value'}
|
283
283
|
end
|
284
284
|
|
285
|
-
it "should be possible to use as on anything" do
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
.
|
285
|
+
it "should be possible to use as/xas on anything" do
|
286
|
+
{
|
287
|
+
@table[:name] => %{"users"."name" AS alias},
|
288
|
+
@table[:name].concat(' test') => %{CONCAT("users"."name", ' test') AS alias},
|
289
|
+
(@table[:name] + ' test') => %{CONCAT("users"."name", ' test') AS alias},
|
290
|
+
(@table[:age] + 42) => %{("users"."age" + 42) AS alias},
|
291
|
+
@table[:name].coalesce('') => %{COALESCE("users"."name", '') AS alias},
|
292
|
+
Arel::Nodes.build_quoted('test') => %{'test' AS alias},
|
293
|
+
@table.project(@table[:name]) => %{(SELECT "users"."name" FROM "users") "alias"},
|
294
|
+
@table[:name].when("smith").then("cool").else("uncool") => %{CASE "users"."name" WHEN 'smith' THEN 'cool' ELSE 'uncool' END AS alias},
|
295
|
+
}.each do |exp, res|
|
296
|
+
_(compile(exp.as('alias'))).must_be_like res
|
297
|
+
_(compile(exp.xas('alias'))).must_be_like res
|
298
|
+
|
299
|
+
res_no_alias = res.gsub(/\s*(?:AS alias|"alias")\s*\z/, '')
|
300
|
+
_(compile(exp.xas(nil))).must_be_like res_no_alias
|
301
|
+
end
|
295
302
|
end
|
296
303
|
|
297
304
|
it "should accept comparators on functions" do
|
@@ -373,7 +380,7 @@ module ArelExtensions
|
|
373
380
|
end
|
374
381
|
|
375
382
|
it "should respecting Grouping" do
|
376
|
-
g = ->(*v) { Arel
|
383
|
+
g = ->(*v) { Arel.grouping(v) }
|
377
384
|
_(compile(g[@table[:id], @table[:age]].in [g[1, 42]]))
|
378
385
|
.must_be_like %{("users"."id", "users"."age") IN ((1, 42))}
|
379
386
|
_(compile(g[@table[:id], @table[:age]].in [g[1, 42], g[2, 51]]))
|
@@ -2,7 +2,7 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
class ListTest < Minitest::Test
|
7
7
|
require 'minitest/pride'
|
8
8
|
def connect_db
|
@@ -14,7 +14,11 @@ module ArelExtensions
|
|
14
14
|
@env_db = ENV['DB']
|
15
15
|
end
|
16
16
|
ActiveRecord::Base.establish_connection(@env_db.try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
17
|
-
ActiveRecord::
|
17
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
18
|
+
ActiveRecord.default_timezone = :utc
|
19
|
+
else
|
20
|
+
ActiveRecord::Base.default_timezone = :utc
|
21
|
+
end
|
18
22
|
@cnx = ActiveRecord::Base.connection
|
19
23
|
$sqlite = @cnx.adapter_name =~ /sqlite/i
|
20
24
|
$load_extension_disabled ||= false
|
@@ -166,6 +170,12 @@ module ArelExtensions
|
|
166
170
|
# Since Arel10 (Rails6.1), some unwanted behaviors on aggregated calculation were present.
|
167
171
|
# This should works no matter which version of rails is used
|
168
172
|
assert User.group(:score).average(:id).values.all?{|e| !e.nil?}
|
173
|
+
|
174
|
+
# Since Rails 7, a patch to calculations.rb has tirggered a double
|
175
|
+
# quoting of the alias name. See https://github.com/rails/rails/commit/7e6e9091e55c3357b0162d44b6ab955ed0c718d5
|
176
|
+
# Before the patch that fixed this the following error would occur:
|
177
|
+
# ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: zero-length delimited identifier at or near """"
|
178
|
+
assert User.group(:score).count(:id).values.all?{|e| !e.nil?}
|
169
179
|
end
|
170
180
|
|
171
181
|
# String Functions
|
@@ -358,7 +368,6 @@ module ArelExtensions
|
|
358
368
|
|
359
369
|
def test_format
|
360
370
|
assert_equal '2016-05-23', t(@lucas, @created_at.format('%Y-%m-%d'))
|
361
|
-
skip "SQL Server does not accept any format" if @env_db == 'mssql'
|
362
371
|
assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S'))
|
363
372
|
assert_equal '12:42%', t(@lucas, @updated_at.format('%R%%'))
|
364
373
|
end
|
@@ -500,7 +509,8 @@ module ArelExtensions
|
|
500
509
|
assert_equal Time, t(@lucas,@updated_at.cast(:string).cast(:datetime)).class
|
501
510
|
assert_equal Time, t(@lucas,@updated_at.cast(:time)).class
|
502
511
|
|
503
|
-
|
512
|
+
# mysql adapter in rails7 adds some infos we just squeeze here
|
513
|
+
assert_equal "2014-03-03 12:42:00", t(@lucas,@updated_at.cast(:string)).split('.').first unless @env_db == 'mssql' # locale dependent
|
504
514
|
assert_equal Date.parse("2014-03-03"), t(@lucas,Arel::Nodes.build_quoted('2014-03-03').cast(:date))
|
505
515
|
assert_equal Date.parse("5014-03-03"), t(@lucas,(@age.cast(:string) + '014-03-03').cast(:date))
|
506
516
|
assert_equal Time.parse("2014-03-03 12:42:00 UTC"), t(@lucas,@updated_at.cast(:string).cast(:datetime))
|
@@ -2,7 +2,7 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
class InsertManagerTest < Minitest::Test
|
7
7
|
def setup_db
|
8
8
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
@@ -13,7 +13,11 @@ module ArelExtensions
|
|
13
13
|
@env_db = ENV['DB']
|
14
14
|
end
|
15
15
|
ActiveRecord::Base.establish_connection(@env_db.try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
16
|
-
ActiveRecord::
|
16
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
17
|
+
ActiveRecord.default_timezone = :utc
|
18
|
+
else
|
19
|
+
ActiveRecord::Base.default_timezone = :utc
|
20
|
+
end
|
17
21
|
@cnx = ActiveRecord::Base.connection
|
18
22
|
Arel::Table.engine = ActiveRecord::Base
|
19
23
|
if File.exist?("init/#{@env_db}.sql")
|
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'arelx_test_helper'
|
2
2
|
|
3
3
|
module ArelExtensions
|
4
|
-
module
|
4
|
+
module WithAr
|
5
5
|
describe 'the sqlite visitor' do
|
6
6
|
before do
|
7
7
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
8
8
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
9
|
-
ActiveRecord::
|
9
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
10
|
+
ActiveRecord.default_timezone = :utc
|
11
|
+
else
|
12
|
+
ActiveRecord::Base.default_timezone = :utc
|
13
|
+
end
|
10
14
|
@cnx = ActiveRecord::Base.connection
|
11
15
|
Arel::Table.engine = ActiveRecord::Base
|
12
16
|
@cnx.drop_table(:users) rescue nil
|
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'arelx_test_helper'
|
2
2
|
|
3
3
|
module ArelExtensions
|
4
|
-
module
|
4
|
+
module WithAr
|
5
5
|
describe 'the sqlite visitor can do maths' do
|
6
6
|
before do
|
7
7
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
8
8
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
9
|
-
ActiveRecord::
|
9
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
10
|
+
ActiveRecord.default_timezone = :utc
|
11
|
+
else
|
12
|
+
ActiveRecord::Base.default_timezone = :utc
|
13
|
+
end
|
10
14
|
Arel::Table.engine = ActiveRecord::Base
|
11
15
|
@cnx = ActiveRecord::Base.connection
|
12
16
|
@cnx.drop_table(:users) rescue nil
|
@@ -2,12 +2,16 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
describe 'the mysql visitor can do string operations' do
|
7
7
|
before do
|
8
8
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
9
9
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-mysql" : :mysql))
|
10
|
-
ActiveRecord::
|
10
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
11
|
+
ActiveRecord.default_timezone = :utc
|
12
|
+
else
|
13
|
+
ActiveRecord::Base.default_timezone = :utc
|
14
|
+
end
|
11
15
|
begin
|
12
16
|
@cnx = ActiveRecord::Base.connection
|
13
17
|
rescue => e
|
@@ -2,12 +2,16 @@ require 'arelx_test_helper'
|
|
2
2
|
require 'date'
|
3
3
|
|
4
4
|
module ArelExtensions
|
5
|
-
module
|
5
|
+
module WithAr
|
6
6
|
describe 'the sqlite visitor can do string operations' do
|
7
7
|
before do
|
8
8
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
9
9
|
ActiveRecord::Base.establish_connection(ENV['DB'] || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
10
|
-
ActiveRecord::
|
10
|
+
if ActiveRecord::VERSION::MAJOR >= 7
|
11
|
+
ActiveRecord.default_timezone = :utc
|
12
|
+
else
|
13
|
+
ActiveRecord::Base.default_timezone = :utc
|
14
|
+
end
|
11
15
|
@cnx = ActiveRecord::Base.connection
|
12
16
|
Arel::Table.engine = ActiveRecord::Base
|
13
17
|
@cnx.drop_table(:users) rescue nil
|
data/version_v1.rb
CHANGED