arel_extensions 2.1.4 → 2.1.5
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 +41 -89
- data/.gitignore +7 -6
- data/.rubocop.yml +37 -0
- data/Gemfile +3 -3
- data/README.md +1 -0
- data/appveyor.yml +73 -0
- data/gemfiles/rails3.gemfile +5 -5
- data/gemfiles/rails4.gemfile +7 -7
- data/gemfiles/rails5_0.gemfile +6 -6
- data/gemfiles/rails5_1_4.gemfile +6 -6
- data/gemfiles/rails5_2.gemfile +6 -5
- data/gemfiles/rails6.gemfile +5 -4
- data/gemfiles/rails6_1.gemfile +5 -4
- data/gemfiles/rails7.gemfile +5 -4
- data/lib/arel_extensions/common_sql_functions.rb +2 -2
- data/lib/arel_extensions/helpers.rb +12 -12
- data/lib/arel_extensions/math.rb +32 -17
- data/lib/arel_extensions/nodes/cast.rb +2 -2
- data/lib/arel_extensions/nodes/coalesce.rb +1 -1
- data/lib/arel_extensions/nodes/collate.rb +1 -1
- data/lib/arel_extensions/nodes/date_diff.rb +6 -6
- data/lib/arel_extensions/nodes/locate.rb +1 -1
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/substring.rb +1 -1
- data/lib/arel_extensions/nodes/then.rb +1 -1
- data/lib/arel_extensions/nodes/trim.rb +2 -2
- data/lib/arel_extensions/nodes/union.rb +3 -3
- data/lib/arel_extensions/nodes/union_all.rb +2 -2
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/ibm_db.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +30 -17
- data/lib/arel_extensions/visitors/mysql.rb +15 -10
- data/lib/arel_extensions/visitors/oracle.rb +22 -17
- data/lib/arel_extensions/visitors/postgresql.rb +17 -12
- data/lib/arel_extensions/visitors/sqlite.rb +4 -4
- data/lib/arel_extensions/visitors/to_sql.rb +4 -1
- data/lib/arel_extensions.rb +10 -0
- data/test/arelx_test_helper.rb +1 -1
- data/test/real_db_test.rb +5 -5
- data/test/support/fake_record.rb +1 -1
- data/test/visitors/test_bulk_insert_oracle.rb +3 -3
- data/test/visitors/test_bulk_insert_sqlite.rb +1 -1
- data/test/visitors/test_bulk_insert_to_sql.rb +1 -1
- data/test/visitors/test_to_sql.rb +6 -6
- data/test/with_ar/all_agnostic_test.rb +67 -60
- data/test/with_ar/insert_agnostic_test.rb +3 -3
- data/test/with_ar/test_bulk_sqlite.rb +1 -1
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +3 -2
data/lib/arel_extensions/math.rb
CHANGED
@@ -16,16 +16,16 @@ module ArelExtensions
|
|
16
16
|
# Date and integer adds or subtracts a specified time interval from a date.
|
17
17
|
def +(other)
|
18
18
|
case self
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
when Arel::Nodes::Quoted
|
20
|
+
self.concat(other)
|
21
|
+
when Arel::Nodes::Grouping
|
22
|
+
if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
|
23
|
+
self.concat(other)
|
24
|
+
else
|
25
|
+
Arel.grouping(Arel::Nodes::Addition.new self, other)
|
26
|
+
end
|
27
|
+
when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
|
28
|
+
case self.return_type
|
29
29
|
when :string, :text
|
30
30
|
self.concat(other)
|
31
31
|
when :integer, :decimal, :float, :number, :int
|
@@ -38,12 +38,17 @@ module ArelExtensions
|
|
38
38
|
when Arel::Nodes::Function
|
39
39
|
Arel.grouping(Arel::Nodes::Addition.new self, other)
|
40
40
|
else
|
41
|
-
col =
|
42
|
-
|
41
|
+
col =
|
42
|
+
if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
|
43
|
+
self.type_caster
|
44
|
+
else
|
45
|
+
Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
|
46
|
+
end
|
47
|
+
if !col # if the column doesn't exist in the database
|
43
48
|
Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
|
44
49
|
else
|
45
50
|
arg = col.type
|
46
|
-
if arg == :integer ||
|
51
|
+
if arg == :integer || !arg
|
47
52
|
other = other.to_i if other.is_a?(String)
|
48
53
|
Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
|
49
54
|
elsif arg == :decimal || arg == :float
|
@@ -82,16 +87,26 @@ module ArelExtensions
|
|
82
87
|
when Arel::Nodes::Function
|
83
88
|
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
84
89
|
else
|
85
|
-
col =
|
86
|
-
|
90
|
+
col =
|
91
|
+
if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
|
92
|
+
self.type_caster
|
93
|
+
else
|
94
|
+
Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
|
95
|
+
end
|
96
|
+
if !col # if the column doesn't exist in the database
|
87
97
|
Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
|
88
98
|
else
|
89
99
|
arg = col.type
|
90
100
|
if (arg == :date || arg == :datetime)
|
91
101
|
case other
|
92
102
|
when Arel::Attributes::Attribute
|
93
|
-
col2 =
|
94
|
-
|
103
|
+
col2 =
|
104
|
+
if other.is_a?(Arel::Attribute) && other.respond_to?(:type_caster) && other.able_to_type_cast?
|
105
|
+
other.type_caster
|
106
|
+
else
|
107
|
+
Arel.column_of(other.relation.table_name, other.name.to_s) if other.respond_to?(:relation)
|
108
|
+
end
|
109
|
+
if !col2 # if the column doesn't exist in the database
|
95
110
|
ArelExtensions::Nodes::DateSub.new [self, other]
|
96
111
|
else
|
97
112
|
arg2 = col2.type
|
@@ -32,13 +32,13 @@ module ArelExtensions
|
|
32
32
|
@as_attr = :string
|
33
33
|
end
|
34
34
|
tab = [convert_to_node(expr.first)]
|
35
|
-
|
35
|
+
super(tab)
|
36
36
|
end
|
37
37
|
|
38
38
|
def +(other)
|
39
39
|
case @return_type
|
40
40
|
when :string
|
41
|
-
|
41
|
+
ArelExtensions::Nodes::Concat.new [self, other]
|
42
42
|
when :ruby_time
|
43
43
|
ArelExtensions::Nodes::DateAdd.new [self, other]
|
44
44
|
else
|
@@ -19,7 +19,7 @@ module ArelExtensions
|
|
19
19
|
when DateTime, Time
|
20
20
|
@left_node_type = :ruby_time
|
21
21
|
end
|
22
|
-
res << ([
|
22
|
+
res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(col) : convert_to_datetime_node(col))
|
23
23
|
case expr[1]
|
24
24
|
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
25
25
|
@right_node_type = type_of_attribute(expr[1])
|
@@ -28,7 +28,7 @@ module ArelExtensions
|
|
28
28
|
when DateTime, Time
|
29
29
|
@right_node_type = :ruby_time
|
30
30
|
end
|
31
|
-
res << ([
|
31
|
+
res << (%i[date ruby_date].include?(@left_node_type) ? convert_to_date_node(expr[1]) : convert_to_datetime_node(expr[1]))
|
32
32
|
super res
|
33
33
|
end
|
34
34
|
end
|
@@ -43,19 +43,19 @@ module ArelExtensions
|
|
43
43
|
tab = expr.map do |arg|
|
44
44
|
convert(arg)
|
45
45
|
end
|
46
|
-
|
46
|
+
super(tab)
|
47
47
|
end
|
48
48
|
|
49
49
|
def sqlite_value
|
50
50
|
v = self.expressions.last
|
51
51
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
52
52
|
if @date_type == :date
|
53
|
-
|
53
|
+
Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
54
54
|
elsif @date_type == :datetime
|
55
|
-
|
55
|
+
Arel.quoted((v.value >= 0 ? '+' : '-') + v.inspect)
|
56
56
|
end
|
57
57
|
else
|
58
|
-
|
58
|
+
v
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -7,11 +7,11 @@ module ArelExtensions
|
|
7
7
|
tab = expr.map { |arg|
|
8
8
|
convert_to_node(arg)
|
9
9
|
}
|
10
|
-
|
10
|
+
super(tab)
|
11
11
|
end
|
12
12
|
|
13
13
|
def +(other)
|
14
|
-
|
14
|
+
ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -7,11 +7,11 @@ module ArelExtensions
|
|
7
7
|
tab = expr.map { |arg|
|
8
8
|
convert_to_node(arg)
|
9
9
|
}
|
10
|
-
|
10
|
+
super(tab)
|
11
11
|
end
|
12
12
|
|
13
13
|
def +(other)
|
14
|
-
|
14
|
+
ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -2,15 +2,15 @@ module ArelExtensions
|
|
2
2
|
module Nodes
|
3
3
|
class Union < Arel::Nodes::Union
|
4
4
|
def initialize left, right
|
5
|
-
|
5
|
+
super(left, right)
|
6
6
|
end
|
7
7
|
|
8
8
|
def +(other)
|
9
|
-
|
9
|
+
ArelExtensions::Nodes::Union.new(self, other)
|
10
10
|
end
|
11
11
|
|
12
12
|
def union(other)
|
13
|
-
|
13
|
+
ArelExtensions::Nodes::UnionAll.new(self, other)
|
14
14
|
end
|
15
15
|
|
16
16
|
def as other
|
@@ -2,11 +2,11 @@ module ArelExtensions
|
|
2
2
|
module Nodes
|
3
3
|
class UnionAll < Arel::Nodes::UnionAll
|
4
4
|
def initialize left, right
|
5
|
-
|
5
|
+
super(left, right)
|
6
6
|
end
|
7
7
|
|
8
8
|
def union_all(other)
|
9
|
-
|
9
|
+
ArelExtensions::Nodes::UnionAll.new(self, other)
|
10
10
|
end
|
11
11
|
|
12
12
|
def as other
|
@@ -56,7 +56,7 @@ module ArelExtensions
|
|
56
56
|
collector << 'COALESCE('
|
57
57
|
collector = visit o.left, collector
|
58
58
|
collector << ','
|
59
|
-
if
|
59
|
+
if o.right.is_a?(Arel::Attributes::Attribute)
|
60
60
|
collector = visit o.right, collector
|
61
61
|
else
|
62
62
|
collector << "'#{o.right}'"
|
@@ -157,7 +157,7 @@ module ArelExtensions
|
|
157
157
|
collector = visit o.right, collector
|
158
158
|
else
|
159
159
|
left = o.left.end_with?('i') ? o.left[0..-2] : o.left
|
160
|
-
conv = [
|
160
|
+
conv = %w[h mn s].include?(o.left)
|
161
161
|
collector << 'DATEPART('
|
162
162
|
collector << LOADED_VISITOR::DATE_MAPPING[left]
|
163
163
|
collector << LOADED_VISITOR::COMMA
|
@@ -220,11 +220,19 @@ module ArelExtensions
|
|
220
220
|
end
|
221
221
|
|
222
222
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
223
|
+
# NOTE: in MSSQL's `blank`, o.right is the space char so we need to
|
224
|
+
# account for it.
|
225
|
+
if o.right && !/\A\s\Z/.match(o.right.expr)
|
226
|
+
collector << 'dbo.TrimChar('
|
227
|
+
collector = visit o.left, collector
|
228
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
229
|
+
collector = visit o.right, collector
|
230
|
+
collector << ')'
|
231
|
+
else
|
232
|
+
collector << "LTRIM(RTRIM("
|
233
|
+
collector = visit o.left, collector
|
234
|
+
collector << "))"
|
235
|
+
end
|
228
236
|
collector
|
229
237
|
end
|
230
238
|
|
@@ -308,7 +316,7 @@ module ArelExtensions
|
|
308
316
|
dir = LOADED_VISITOR::DATE_FORMAT_DIRECTIVES[s.matched]
|
309
317
|
fmt = LOADED_VISITOR::DATE_FORMAT_FORMAT[dir]
|
310
318
|
date_name = LOADED_VISITOR::DATE_NAME.include?(s.matched)
|
311
|
-
collector << '
|
319
|
+
collector << 'LTRIM(RTRIM('
|
312
320
|
collector << 'FORMAT(' if fmt
|
313
321
|
collector << 'STR(' if !fmt && !date_name
|
314
322
|
collector << (date_name ? 'DATENAME(' : 'DATEPART(')
|
@@ -334,7 +342,7 @@ module ArelExtensions
|
|
334
342
|
collector << ')'
|
335
343
|
collector << ')' if !fmt && !date_name
|
336
344
|
collector << LOADED_VISITOR::COMMA << "'#{fmt}')" if fmt
|
337
|
-
collector << ')'
|
345
|
+
collector << '))'
|
338
346
|
when s.scan(/^%%/)
|
339
347
|
collector = visit Arel.quoted('%'), collector
|
340
348
|
when s.scan(/[^%]+|./)
|
@@ -575,15 +583,20 @@ module ArelExtensions
|
|
575
583
|
])
|
576
584
|
end
|
577
585
|
|
578
|
-
repeated_char =
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
586
|
+
repeated_char =
|
587
|
+
if o.width == 0
|
588
|
+
Arel.quoted('')
|
589
|
+
else
|
590
|
+
Arel
|
591
|
+
.when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
|
592
|
+
.then(Arel.quoted(
|
593
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
594
|
+
).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
|
595
|
+
)
|
596
|
+
.else('')
|
597
|
+
end
|
598
|
+
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
599
|
+
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
587
600
|
after = o.flags.include?('-') ? repeated_char : ''
|
588
601
|
full_number =
|
589
602
|
ArelExtensions::Nodes::Concat.new([
|
@@ -126,7 +126,7 @@ module ArelExtensions
|
|
126
126
|
collector << 'CONCAT('
|
127
127
|
o.expressions.each_with_index { |arg, i|
|
128
128
|
collector << COMMA if i != 0
|
129
|
-
if
|
129
|
+
if arg.is_a?(Numeric) || arg.is_a?(Arel::Attributes::Attribute)
|
130
130
|
collector << 'CAST('
|
131
131
|
collector = visit arg, collector
|
132
132
|
collector << ' AS char)'
|
@@ -398,15 +398,20 @@ module ArelExtensions
|
|
398
398
|
Arel::Nodes::NamedFunction.new('FORMAT', [col.abs] + params)
|
399
399
|
end
|
400
400
|
|
401
|
-
repeated_char =
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
401
|
+
repeated_char =
|
402
|
+
if o.width == 0
|
403
|
+
Arel.quoted('')
|
404
|
+
else
|
405
|
+
Arel
|
406
|
+
.when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
|
407
|
+
.then(Arel.quoted(
|
408
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
409
|
+
).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
|
410
|
+
)
|
411
|
+
.else('')
|
412
|
+
end
|
413
|
+
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
414
|
+
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
410
415
|
after = o.flags.include?('-') ? repeated_char : ''
|
411
416
|
full_number = ArelExtensions::Nodes::Concat.new([
|
412
417
|
before,
|
@@ -11,7 +11,7 @@ module ArelExtensions
|
|
11
11
|
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
12
12
|
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
13
13
|
}
|
14
|
-
NUMBER_COMMA_MAPPING = {
|
14
|
+
NUMBER_COMMA_MAPPING = {'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '}
|
15
15
|
|
16
16
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
17
17
|
collector << 'LOG('
|
@@ -455,7 +455,7 @@ module ArelExtensions
|
|
455
455
|
src_tz, dst_tz = o.time_zone.first
|
456
456
|
collector << ' as timestamp) at time zone '
|
457
457
|
collector = visit Arel.quoted(src_tz), collector
|
458
|
-
|
458
|
+
collector < ' at time zone '
|
459
459
|
collector = visit Arel.quoted(dst_tz), collector
|
460
460
|
when String
|
461
461
|
collector << ' as timestamp) at time zone '
|
@@ -587,7 +587,7 @@ module ArelExtensions
|
|
587
587
|
alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
|
588
588
|
def visit_Arel_Nodes_TableAlias o, collector
|
589
589
|
if o.name.length > 30
|
590
|
-
o = Arel::Table.new(o.table_name).alias(
|
590
|
+
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
591
591
|
end
|
592
592
|
old_visit_Arel_Nodes_TableAlias(o, collector)
|
593
593
|
end
|
@@ -601,7 +601,7 @@ module ArelExtensions
|
|
601
601
|
else
|
602
602
|
collector = visit o.left, collector
|
603
603
|
end
|
604
|
-
quote =
|
604
|
+
quote = /(\A".*"\z)|\A[a-zA-Z_]*\z/.match?(o.right.to_s) ? '' : '"'
|
605
605
|
collector << " AS #{quote}"
|
606
606
|
collector = visit o.right, collector
|
607
607
|
collector << "#{quote}"
|
@@ -627,10 +627,10 @@ module ArelExtensions
|
|
627
627
|
comma_in_format = o.precision == 0 ? '' : 'D'
|
628
628
|
nines_after = (1..o.precision - 1).map{'9'}.join('') + '0'
|
629
629
|
if comma.length == 1
|
630
|
-
options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '
|
630
|
+
options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma} '")
|
631
631
|
nines_before = ('999' * 4 + '990')
|
632
632
|
else
|
633
|
-
options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '
|
633
|
+
options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma}'")
|
634
634
|
nines_before = ('999G' * 4 + '990')
|
635
635
|
end
|
636
636
|
sign = Arel.when(col < 0).
|
@@ -643,7 +643,7 @@ module ArelExtensions
|
|
643
643
|
if o.scientific_notation
|
644
644
|
number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
645
645
|
Arel.quoted(col.abs),
|
646
|
-
Arel.quoted(
|
646
|
+
Arel.quoted("FM#{nines_before}#{comma_in_format}#{nines_after}EEEE"),
|
647
647
|
options
|
648
648
|
])
|
649
649
|
if o.type == 'e'
|
@@ -652,20 +652,25 @@ module ArelExtensions
|
|
652
652
|
else
|
653
653
|
number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
654
654
|
Arel.quoted(col.abs),
|
655
|
-
Arel.quoted(
|
655
|
+
Arel.quoted("FM#{nines_before}#{comma_in_format}#{nines_after}"),
|
656
656
|
options
|
657
657
|
])
|
658
658
|
end
|
659
659
|
|
660
|
-
repeated_char =
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
660
|
+
repeated_char =
|
661
|
+
if o.width == 0
|
662
|
+
Arel.quoted('')
|
663
|
+
else
|
664
|
+
Arel
|
665
|
+
.when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
|
666
|
+
.then(Arel.quoted(
|
667
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
668
|
+
).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
|
669
|
+
)
|
670
|
+
.else('')
|
671
|
+
end
|
672
|
+
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
673
|
+
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
669
674
|
after = o.flags.include?('-') ? repeated_char : ''
|
670
675
|
full_number = ArelExtensions::Nodes::Concat.new([
|
671
676
|
before,
|
@@ -425,32 +425,37 @@ module ArelExtensions
|
|
425
425
|
Arel::Nodes::NamedFunction.new('TRIM', [
|
426
426
|
Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
427
427
|
Arel.when(col.not_eq 0).then(col.abs / Arel.quoted(10).pow(col.abs.log10.floor)).else(1),
|
428
|
-
Arel.quoted(
|
428
|
+
Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
|
429
429
|
])]),
|
430
430
|
o.type,
|
431
431
|
Arel::Nodes::NamedFunction.new('TRIM', [
|
432
432
|
Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
433
433
|
Arel.when(col.not_eq 0).then(col.abs.log10.floor).else(0),
|
434
|
-
Arel.quoted(
|
434
|
+
Arel.quoted("FM#{nines_before}")
|
435
435
|
])])
|
436
436
|
])
|
437
437
|
else
|
438
438
|
Arel::Nodes::NamedFunction.new('TRIM', [
|
439
439
|
Arel::Nodes::NamedFunction.new('TO_CHAR', [
|
440
440
|
Arel.quoted(col.abs),
|
441
|
-
Arel.quoted(
|
441
|
+
Arel.quoted("FM#{nines_before}\"#{comma}\"V#{nines_after}")
|
442
442
|
])])
|
443
443
|
end
|
444
444
|
|
445
|
-
repeated_char =
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
445
|
+
repeated_char =
|
446
|
+
if o.width == 0
|
447
|
+
Arel.quoted('')
|
448
|
+
else
|
449
|
+
Arel
|
450
|
+
.when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
|
451
|
+
.then(Arel.quoted(
|
452
|
+
o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
|
453
|
+
).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
|
454
|
+
)
|
455
|
+
.else('')
|
456
|
+
end
|
457
|
+
before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
458
|
+
middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
|
454
459
|
after = o.flags.include?('-') ? repeated_char : ''
|
455
460
|
full_number = ArelExtensions::Nodes::Concat.new([
|
456
461
|
before,
|
@@ -325,16 +325,16 @@ module ArelExtensions
|
|
325
325
|
|
326
326
|
def get_time_converted element
|
327
327
|
if element.is_a?(Time)
|
328
|
-
|
328
|
+
Arel::Nodes::NamedFunction.new('STRFTIME', [element, '%H:%M:%S'])
|
329
329
|
elsif element.is_a?(Arel::Attributes::Attribute)
|
330
330
|
col = Arel.column_of(element.relation.table_name, element.name.to_s)
|
331
331
|
if col && (col.type == :time)
|
332
|
-
|
332
|
+
Arel::Nodes::NamedFunction.new('STRFTIME', [element, '%H:%M:%S'])
|
333
333
|
else
|
334
|
-
|
334
|
+
element
|
335
335
|
end
|
336
336
|
else
|
337
|
-
|
337
|
+
element
|
338
338
|
end
|
339
339
|
end
|
340
340
|
|
@@ -649,7 +649,10 @@ module ArelExtensions
|
|
649
649
|
|
650
650
|
def visit_ArelExtensions_Nodes_JsonGroup o, collector
|
651
651
|
if o.as_array
|
652
|
-
res =
|
652
|
+
res =
|
653
|
+
Arel.quoted('[') \
|
654
|
+
+ (o.orders ? o.dict.group_concat(', ', order: Array(o.orders)) : o.dict.group_concat(', ')).coalesce('') \
|
655
|
+
+ ']'
|
653
656
|
collector = visit res, collector
|
654
657
|
else
|
655
658
|
res = Arel.quoted('{')
|
data/lib/arel_extensions.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'arel'
|
2
|
+
require 'base64'
|
2
3
|
|
3
4
|
require 'arel_extensions/railtie' if defined?(Rails::Railtie)
|
4
5
|
|
@@ -268,3 +269,12 @@ class Arel::Nodes::TableAlias
|
|
268
269
|
end
|
269
270
|
end
|
270
271
|
end
|
272
|
+
|
273
|
+
|
274
|
+
class Arel::Attributes::Attribute
|
275
|
+
def to_sql(engine = Arel::Table.engine)
|
276
|
+
collector = Arel::Collectors::SQLString.new
|
277
|
+
collector = engine.connection.visitor.accept self, collector
|
278
|
+
collector.value
|
279
|
+
end
|
280
|
+
end
|
data/test/arelx_test_helper.rb
CHANGED
@@ -7,7 +7,7 @@ require 'active_record'
|
|
7
7
|
require 'support/fake_record'
|
8
8
|
|
9
9
|
def colored(color, msg)
|
10
|
-
ENV['TERM']
|
10
|
+
/^xterm|-256color$/.match?(ENV['TERM']) ? "\x1b[#{color}m#{msg}\x1b[89m\x1b[0m" : "#{msg}"
|
11
11
|
end
|
12
12
|
|
13
13
|
YELLOW = '33'
|
data/test/real_db_test.rb
CHANGED
@@ -14,7 +14,7 @@ def setup_db
|
|
14
14
|
ActiveRecord::Base.default_timezone = :utc
|
15
15
|
end
|
16
16
|
@cnx = ActiveRecord::Base.connection
|
17
|
-
if ActiveRecord::Base.connection.adapter_name
|
17
|
+
if /sqlite/i.match?(ActiveRecord::Base.connection.adapter_name)
|
18
18
|
$sqlite = true
|
19
19
|
db = @cnx.raw_connection
|
20
20
|
if !$load_extension_disabled
|
@@ -82,7 +82,7 @@ class ListTest < Minitest::Test
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def test_coalesce
|
85
|
-
if @cnx.adapter_name
|
85
|
+
if /pgsql/i.match?(@cnx.adapter_name)
|
86
86
|
assert_equal 100, User.where(User.arel_table[:name].eq('Test')).select((User.arel_table[:age].coalesce(100)).as('res')).first.res
|
87
87
|
assert_equal 'Camille', User.where(User.arel_table[:name].eq('Camille')).select((User.arel_table[:name].coalesce('Null', 'default')).as('res')).first.res
|
88
88
|
else
|
@@ -128,7 +128,7 @@ class ListTest < Minitest::Test
|
|
128
128
|
end
|
129
129
|
|
130
130
|
def test_isnull
|
131
|
-
if ActiveRecord::Base.connection.adapter_name
|
131
|
+
if /pgsql/i.match?(ActiveRecord::Base.connection.adapter_name)
|
132
132
|
assert_equal 100, User.where(User.arel_table[:name].eq('Test')).select((User.arel_table[:age].isnull(100)).as('res')).first.res
|
133
133
|
else
|
134
134
|
assert_equal 'default', User.where(User.arel_table[:name].eq('Test')).select((User.arel_table[:age].isnull('default')).as('res')).first.res
|
@@ -196,8 +196,8 @@ class ListTest < Minitest::Test
|
|
196
196
|
end
|
197
197
|
|
198
198
|
def test_replace
|
199
|
-
assert_equal 'LucaX', User.where(User.arel_table[:name].eq('Lucas')).select((
|
200
|
-
assert_equal 'replace', User.where(User.arel_table[:name].eq('Lucas')).select((
|
199
|
+
assert_equal 'LucaX', User.where(User.arel_table[:name].eq('Lucas')).select((User.arel_table[:name].replace('s', 'X')).as('res')).first.res
|
200
|
+
assert_equal 'replace', User.where(User.arel_table[:name].eq('Lucas')).select((User.arel_table[:name].replace(User.arel_table[:name], 'replace')).as('res')).first.res
|
201
201
|
end
|
202
202
|
|
203
203
|
def test_round
|