arel_extensions 2.0.11 → 2.0.16
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 +102 -0
- 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/gemfiles/rails6_1.gemfile +30 -0
- data/gemspecs/arel_extensions-v1.gemspec +28 -0
- data/{gemspec_v2 → gemspecs}/arel_extensions-v2.gemspec +0 -0
- data/generate_gems.sh +4 -3
- data/lib/arel_extensions.rb +6 -4
- 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 +18 -20
- 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 +2 -4
- 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 +11 -17
- 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 +4 -5
- 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 +68 -60
- 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 +49 -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 +56 -47
- data/test/arelx_test_helper.rb +0 -2
- data/test/database.yml +2 -0
- 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 +8 -4
@@ -0,0 +1,37 @@
|
|
1
|
+
module ArelExtensions
|
2
|
+
module Visitors
|
3
|
+
# Convert date format in strftime syntax to whatever the RDBMs
|
4
|
+
# wants, based on the table of conversion +mapping+.
|
5
|
+
def self.strftime_to_format format, mapping
|
6
|
+
@mapping_regexps ||= {}
|
7
|
+
@mapping_regexps[mapping] ||=
|
8
|
+
Regexp.new(
|
9
|
+
mapping
|
10
|
+
.keys
|
11
|
+
.map{|k| Regexp.escape(k)}
|
12
|
+
.join('|')
|
13
|
+
)
|
14
|
+
|
15
|
+
regexp = @mapping_regexps[mapping]
|
16
|
+
s = StringScanner.new format
|
17
|
+
res = StringIO.new
|
18
|
+
while !s.eos?
|
19
|
+
res <<
|
20
|
+
case
|
21
|
+
when s.scan(regexp)
|
22
|
+
if v = mapping[s.matched]
|
23
|
+
v
|
24
|
+
else
|
25
|
+
# Should never happen.
|
26
|
+
s.matched
|
27
|
+
end
|
28
|
+
when s.scan(/[^%]+/)
|
29
|
+
s.matched
|
30
|
+
when s.scan(/./)
|
31
|
+
s.matched
|
32
|
+
end
|
33
|
+
end
|
34
|
+
res.string
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
class Arel::Visitors::IBM_DB
|
4
|
-
|
5
4
|
def visit_ArelExtensions_Nodes_Ceil o, collector
|
6
5
|
collector << "CEILING("
|
7
6
|
collector = visit o.expr, collector
|
@@ -12,14 +11,13 @@ module ArelExtensions
|
|
12
11
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
13
12
|
collector << "LTRIM(RTRIM("
|
14
13
|
o.expressions.each_with_index { |arg, i|
|
15
|
-
collector <<
|
14
|
+
collector << COMMA if i != 0
|
16
15
|
collector = visit arg, collector
|
17
16
|
}
|
18
17
|
collector << "))"
|
19
18
|
collector
|
20
19
|
end
|
21
20
|
|
22
|
-
|
23
21
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
24
22
|
collector << "DAY("
|
25
23
|
collector = visit o.left, collector
|
@@ -33,9 +31,8 @@ module ArelExtensions
|
|
33
31
|
collector
|
34
32
|
end
|
35
33
|
|
36
|
-
|
37
34
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
38
|
-
#visit left for period
|
35
|
+
# visit left for period
|
39
36
|
if o.left == "d"
|
40
37
|
collector << "DAY("
|
41
38
|
elsif o.left == "m"
|
@@ -45,7 +42,7 @@ module ArelExtensions
|
|
45
42
|
elsif o.left == "y"
|
46
43
|
collector << "YEAR("
|
47
44
|
end
|
48
|
-
#visit right
|
45
|
+
# visit right
|
49
46
|
if o.right.is_a?(Arel::Attributes::Attribute)
|
50
47
|
collector = visit o.right, collector
|
51
48
|
else
|
@@ -55,12 +52,11 @@ module ArelExtensions
|
|
55
52
|
collector
|
56
53
|
end
|
57
54
|
|
58
|
-
|
59
55
|
def visit_ArelExtensions_Nodes_IsNull o, collector
|
60
56
|
collector << "COALESCE("
|
61
57
|
collector = visit o.left, collector
|
62
58
|
collector << ","
|
63
|
-
if(o.right.is_a?(Arel::Attributes::Attribute))
|
59
|
+
if (o.right.is_a?(Arel::Attributes::Attribute))
|
64
60
|
collector = visit o.right, collector
|
65
61
|
else
|
66
62
|
collector << "'#{o.right}'"
|
@@ -68,9 +64,6 @@ module ArelExtensions
|
|
68
64
|
collector << ")"
|
69
65
|
collector
|
70
66
|
end
|
71
|
-
|
72
|
-
|
73
|
-
|
74
67
|
end
|
75
68
|
end
|
76
69
|
end
|
@@ -1,13 +1,26 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
module MSSQL
|
4
|
-
|
4
|
+
|
5
|
+
Arel::Visitors::MSSQL::DATE_MAPPING = {
|
6
|
+
'd' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'
|
7
|
+
}.freeze
|
8
|
+
|
5
9
|
Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
|
6
10
|
'%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '', # year, month
|
7
11
|
'%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
|
8
12
|
'%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
|
9
13
|
'%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
|
10
|
-
}
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
Arel::Visitors::MSSQL::DATE_FORMAT_REGEX =
|
17
|
+
Regexp.new(
|
18
|
+
Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES
|
19
|
+
.keys
|
20
|
+
.map{|k| Regexp.escape(k)}
|
21
|
+
.join('|')
|
22
|
+
).freeze
|
23
|
+
|
11
24
|
# TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
|
12
25
|
Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS = {
|
13
26
|
'YYYY-MM-DD' => 120,
|
@@ -19,7 +32,7 @@ module ArelExtensions
|
|
19
32
|
'DD-MM-YY' => 5,
|
20
33
|
'DD.MM.YYYY' => 104,
|
21
34
|
'YYYY-MM-DDTHH:MM:SS:MMM' => 126
|
22
|
-
}
|
35
|
+
}.freeze
|
23
36
|
|
24
37
|
# Math Functions
|
25
38
|
def visit_ArelExtensions_Nodes_Ceil o, collector
|
@@ -32,7 +45,7 @@ module ArelExtensions
|
|
32
45
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
33
46
|
collector << "LOG10("
|
34
47
|
o.expressions.each_with_index { |arg, i|
|
35
|
-
collector << Arel::Visitors::ToSql::COMMA
|
48
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
36
49
|
collector = visit arg, collector
|
37
50
|
}
|
38
51
|
collector << ")"
|
@@ -42,7 +55,7 @@ module ArelExtensions
|
|
42
55
|
def visit_ArelExtensions_Nodes_Power o, collector
|
43
56
|
collector << "POWER("
|
44
57
|
o.expressions.each_with_index { |arg, i|
|
45
|
-
collector << Arel::Visitors::ToSql::COMMA
|
58
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
46
59
|
collector = visit arg, collector
|
47
60
|
}
|
48
61
|
collector << ")"
|
@@ -66,7 +79,7 @@ module ArelExtensions
|
|
66
79
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
67
80
|
collector << "CONCAT("
|
68
81
|
o.expressions.each_with_index { |arg, i|
|
69
|
-
collector << Arel::Visitors::MSSQL::COMMA
|
82
|
+
collector << Arel::Visitors::MSSQL::COMMA if i != 0
|
70
83
|
collector = visit arg, collector
|
71
84
|
}
|
72
85
|
collector << ")"
|
@@ -76,7 +89,7 @@ module ArelExtensions
|
|
76
89
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
77
90
|
collector << "REPLICATE("
|
78
91
|
o.expressions.each_with_index { |arg, i|
|
79
|
-
collector << Arel::Visitors::ToSql::COMMA
|
92
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
80
93
|
collector = visit arg, collector
|
81
94
|
}
|
82
95
|
collector << ")"
|
@@ -86,12 +99,12 @@ module ArelExtensions
|
|
86
99
|
|
87
100
|
|
88
101
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
102
|
+
case o.right_node_type
|
103
|
+
when :ruby_date, :ruby_time, :date, :datetime, :time
|
104
|
+
collector << case o.left_node_type
|
105
|
+
when :ruby_time, :datetime, :time then 'DATEDIFF(second'
|
106
|
+
else 'DATEDIFF(day'
|
107
|
+
end
|
95
108
|
collector << Arel::Visitors::MSSQL::COMMA
|
96
109
|
collector = visit o.right, collector
|
97
110
|
collector << Arel::Visitors::MSSQL::COMMA
|
@@ -151,7 +164,7 @@ module ArelExtensions
|
|
151
164
|
def visit_ArelExtensions_Nodes_Round o, collector
|
152
165
|
collector << "ROUND("
|
153
166
|
o.expressions.each_with_index { |arg, i|
|
154
|
-
collector << Arel::Visitors::MSSQL::COMMA
|
167
|
+
collector << Arel::Visitors::MSSQL::COMMA if i != 0
|
155
168
|
collector = visit arg, collector
|
156
169
|
}
|
157
170
|
if o.expressions.length == 1
|
@@ -242,42 +255,34 @@ module ArelExtensions
|
|
242
255
|
end
|
243
256
|
|
244
257
|
def visit_ArelExtensions_Nodes_Format o, collector
|
245
|
-
f = o.iso_format
|
246
|
-
Arel::Visitors::MSSQL::
|
247
|
-
if Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f]
|
258
|
+
f = ArelExtensions::Visitors::strftime_to_format(o.iso_format, Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES)
|
259
|
+
if fmt = Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS[f]
|
248
260
|
collector << "CONVERT(VARCHAR(#{f.length})"
|
249
261
|
collector << Arel::Visitors::MSSQL::COMMA
|
250
262
|
collector = visit o.left, collector
|
251
263
|
collector << Arel::Visitors::MSSQL::COMMA
|
252
|
-
collector <<
|
264
|
+
collector << fmt.to_s
|
253
265
|
collector << ')'
|
254
266
|
collector
|
255
267
|
else
|
268
|
+
s = StringScanner.new o.iso_format
|
256
269
|
collector << "("
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
collector << ')))'
|
272
|
-
if str.length > 1
|
273
|
-
collector << ' + '
|
274
|
-
collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
|
275
|
-
end
|
276
|
-
end
|
270
|
+
sep = ''
|
271
|
+
while !s.eos?
|
272
|
+
collector << sep
|
273
|
+
sep = ' + '
|
274
|
+
case
|
275
|
+
when s.scan(Arel::Visitors::MSSQL::DATE_FORMAT_REGEX)
|
276
|
+
dir = Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES[s.matched]
|
277
|
+
collector << 'LTRIM(STR(DATEPART('
|
278
|
+
collector << dir
|
279
|
+
collector << Arel::Visitors::MSSQL::COMMA
|
280
|
+
collector = visit o.left, collector
|
281
|
+
collector << ')))'
|
282
|
+
when s.scan(/[^%]+|./)
|
283
|
+
collector = visit Arel::Nodes.build_quoted(s.matched), collector
|
277
284
|
end
|
278
|
-
|
279
|
-
}
|
280
|
-
|
285
|
+
end
|
281
286
|
collector << ')'
|
282
287
|
collector
|
283
288
|
end
|
@@ -286,7 +291,7 @@ module ArelExtensions
|
|
286
291
|
def visit_ArelExtensions_Nodes_Replace o, collector
|
287
292
|
collector << "REPLACE("
|
288
293
|
o.expressions.each_with_index { |arg, i|
|
289
|
-
collector << Arel::Visitors::MSSQL::COMMA
|
294
|
+
collector << Arel::Visitors::MSSQL::COMMA if i != 0
|
290
295
|
collector = visit arg, collector
|
291
296
|
}
|
292
297
|
collector << ")"
|
@@ -296,7 +301,7 @@ module ArelExtensions
|
|
296
301
|
def visit_ArelExtensions_Nodes_FindInSet o, collector
|
297
302
|
collector << "dbo.FIND_IN_SET("
|
298
303
|
o.expressions.each_with_index { |arg, i|
|
299
|
-
collector << Arel::Visitors::MSSQL::COMMA
|
304
|
+
collector << Arel::Visitors::MSSQL::COMMA if i != 0
|
300
305
|
collector = visit arg, collector
|
301
306
|
}
|
302
307
|
collector << ")"
|
@@ -409,7 +414,7 @@ module ArelExtensions
|
|
409
414
|
collector << ") WITHIN GROUP (ORDER BY "
|
410
415
|
if o.order.present?
|
411
416
|
o.order.each_with_index do |order,i|
|
412
|
-
collector << Arel::Visitors::Oracle::COMMA
|
417
|
+
collector << Arel::Visitors::Oracle::COMMA if i != 0
|
413
418
|
collector = visit order, collector
|
414
419
|
end
|
415
420
|
else
|
@@ -1,20 +1,24 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
class Arel::Visitors::MySQL
|
4
|
-
|
5
|
-
|
4
|
+
DATE_MAPPING = {
|
5
|
+
'd' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY',
|
6
|
+
'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
6
10
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
7
11
|
'%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W', # day, weekday
|
8
12
|
'%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
|
9
13
|
'%M' => '%i', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => ''
|
10
|
-
}
|
14
|
+
}.freeze
|
11
15
|
|
12
16
|
|
13
|
-
#Math functions
|
17
|
+
# Math functions
|
14
18
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
15
19
|
collector << "LOG10("
|
16
20
|
o.expressions.each_with_index { |arg, i|
|
17
|
-
collector << Arel::Visitors::ToSql::COMMA
|
21
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
18
22
|
collector = visit arg, collector
|
19
23
|
}
|
20
24
|
collector << ")"
|
@@ -24,14 +28,14 @@ module ArelExtensions
|
|
24
28
|
def visit_ArelExtensions_Nodes_Power o, collector
|
25
29
|
collector << "POW("
|
26
30
|
o.expressions.each_with_index { |arg, i|
|
27
|
-
collector << Arel::Visitors::ToSql::COMMA
|
31
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
28
32
|
collector = visit arg, collector
|
29
33
|
}
|
30
34
|
collector << ")"
|
31
35
|
collector
|
32
36
|
end
|
33
37
|
|
34
|
-
#String functions
|
38
|
+
# String functions
|
35
39
|
def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
|
36
40
|
collector << 'LOWER('
|
37
41
|
collector = visit o.left, collector
|
@@ -112,10 +116,10 @@ module ArelExtensions
|
|
112
116
|
collector = visit o.expressions.first, collector
|
113
117
|
collector <<
|
114
118
|
if o.ai
|
115
|
-
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci'
|
116
|
-
#doesn't work in latin1
|
119
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci'}"
|
120
|
+
# doesn't work in latin1
|
117
121
|
elsif o.ci
|
118
|
-
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci'
|
122
|
+
" COLLATE #{charset == 'latin1' ? 'latin1_general_ci' : 'utf8_unicode_ci'}"
|
119
123
|
else
|
120
124
|
" COLLATE #{charset}_bin"
|
121
125
|
end
|
@@ -125,7 +129,7 @@ module ArelExtensions
|
|
125
129
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
126
130
|
collector << "CONCAT("
|
127
131
|
o.expressions.each_with_index { |arg, i|
|
128
|
-
collector <<
|
132
|
+
collector << COMMA if i != 0
|
129
133
|
if (arg.is_a?(Numeric)) || (arg.is_a?(Arel::Attributes::Attribute))
|
130
134
|
collector << "CAST("
|
131
135
|
collector = visit arg, collector
|
@@ -144,7 +148,7 @@ module ArelExtensions
|
|
144
148
|
if !o.order.blank?
|
145
149
|
collector << ' ORDER BY '
|
146
150
|
o.order.each_with_index do |order,i|
|
147
|
-
collector << Arel::Visitors::ToSql::COMMA
|
151
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
148
152
|
collector = visit order, collector
|
149
153
|
end
|
150
154
|
end
|
@@ -165,7 +169,7 @@ module ArelExtensions
|
|
165
169
|
collector
|
166
170
|
end
|
167
171
|
|
168
|
-
def visit_ArelExtensions_Nodes_Ltrim o
|
172
|
+
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
169
173
|
collector << 'TRIM(LEADING '
|
170
174
|
collector = visit o.right, collector
|
171
175
|
collector << " FROM "
|
@@ -174,7 +178,7 @@ module ArelExtensions
|
|
174
178
|
collector
|
175
179
|
end
|
176
180
|
|
177
|
-
def visit_ArelExtensions_Nodes_Rtrim o
|
181
|
+
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
178
182
|
collector << 'TRIM(TRAILING '
|
179
183
|
collector = visit o.right, collector
|
180
184
|
collector << " FROM "
|
@@ -186,7 +190,7 @@ module ArelExtensions
|
|
186
190
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
187
191
|
collector << "REPEAT("
|
188
192
|
o.expressions.each_with_index { |arg, i|
|
189
|
-
collector << Arel::Visitors::ToSql::COMMA
|
193
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
190
194
|
collector = visit arg, collector
|
191
195
|
}
|
192
196
|
collector << ")"
|
@@ -202,13 +206,12 @@ module ArelExtensions
|
|
202
206
|
|
203
207
|
def visit_ArelExtensions_Nodes_Format o, collector
|
204
208
|
case o.col_type
|
205
|
-
when :date, :datetime
|
209
|
+
when :date, :datetime, :time
|
210
|
+
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
206
211
|
collector << "DATE_FORMAT("
|
207
212
|
collector = visit o.left, collector
|
208
|
-
collector <<
|
209
|
-
|
210
|
-
Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
211
|
-
collector = visit Arel::Nodes.build_quoted(f), collector
|
213
|
+
collector << COMMA
|
214
|
+
collector = visit Arel::Nodes.build_quoted(fmt), collector
|
212
215
|
collector << ")"
|
213
216
|
when :integer, :float, :decimal
|
214
217
|
collector << "FORMAT("
|
@@ -225,14 +228,15 @@ module ArelExtensions
|
|
225
228
|
end
|
226
229
|
|
227
230
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
231
|
+
case o.right_node_type
|
232
|
+
when :ruby_date, :ruby_time, :date, :datetime, :time
|
233
|
+
collector <<
|
234
|
+
case o.left_node_type
|
235
|
+
when :ruby_time, :datetime, :time then 'TIMESTAMPDIFF(SECOND, '
|
236
|
+
else 'DATEDIFF('
|
237
|
+
end
|
234
238
|
collector = visit o.right, collector
|
235
|
-
collector <<
|
239
|
+
collector << COMMA
|
236
240
|
collector = visit o.left, collector
|
237
241
|
collector << ")"
|
238
242
|
else
|
@@ -256,13 +260,12 @@ module ArelExtensions
|
|
256
260
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
257
261
|
collector << "DATE_ADD("
|
258
262
|
collector = visit o.left, collector
|
259
|
-
collector <<
|
263
|
+
collector << COMMA
|
260
264
|
collector = visit o.mysql_value(o.right), collector
|
261
265
|
collector << ")"
|
262
266
|
collector
|
263
267
|
end
|
264
268
|
|
265
|
-
|
266
269
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
267
270
|
if o.left == 'wd'
|
268
271
|
collector << "(WEEKDAY("
|
@@ -276,13 +279,13 @@ module ArelExtensions
|
|
276
279
|
when 'h','mn','s'
|
277
280
|
interval = 'SECOND'
|
278
281
|
when /i\z/
|
279
|
-
interval =
|
282
|
+
interval = DATE_MAPPING[o.left[0..-2]]
|
280
283
|
else
|
281
284
|
interval = nil
|
282
285
|
end
|
283
286
|
end
|
284
287
|
collector << " INTERVAL " if o.with_interval && interval
|
285
|
-
collector << "#{
|
288
|
+
collector << "#{DATE_MAPPING[o.left]}("
|
286
289
|
collector = visit o.right, collector
|
287
290
|
collector << ")"
|
288
291
|
collector << " #{interval} " if o.with_interval && interval
|
@@ -290,7 +293,6 @@ module ArelExtensions
|
|
290
293
|
collector
|
291
294
|
end
|
292
295
|
|
293
|
-
|
294
296
|
def visit_ArelExtensions_Nodes_IsNull o, collector
|
295
297
|
collector << "ISNULL("
|
296
298
|
collector = visit o.expr, collector
|
@@ -316,30 +318,25 @@ module ArelExtensions
|
|
316
318
|
collector << "CAST("
|
317
319
|
collector = visit o.left, collector
|
318
320
|
collector << " AS "
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
when :binary
|
333
|
-
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
334
|
-
else
|
335
|
-
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
336
|
-
end
|
321
|
+
as_attr =
|
322
|
+
Arel::Nodes::SqlLiteral.new(
|
323
|
+
case o.as_attr
|
324
|
+
when :string then 'char'
|
325
|
+
when :time then 'time'
|
326
|
+
when :int then 'signed'
|
327
|
+
when :number, :decimal then 'decimal(20,6)'
|
328
|
+
when :datetime then 'datetime'
|
329
|
+
when :date then 'date'
|
330
|
+
when :binary then 'binary'
|
331
|
+
else o.as_attr.to_s
|
332
|
+
end
|
333
|
+
)
|
337
334
|
collector = visit as_attr, collector
|
338
335
|
collector << ")"
|
339
336
|
collector
|
340
337
|
end
|
341
338
|
|
342
|
-
alias_method
|
339
|
+
alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
|
343
340
|
def visit_Arel_Nodes_SelectStatement o, collector
|
344
341
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
345
342
|
o = o.dup
|
@@ -348,7 +345,7 @@ module ArelExtensions
|
|
348
345
|
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
349
346
|
end
|
350
347
|
|
351
|
-
alias_method
|
348
|
+
alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
|
352
349
|
def visit_Arel_Nodes_As o, collector
|
353
350
|
if o.left.is_a?(Arel::Nodes::Binary)
|
354
351
|
collector << '('
|
@@ -447,9 +444,9 @@ module ArelExtensions
|
|
447
444
|
collector
|
448
445
|
end
|
449
446
|
|
450
|
-
# JSON if implemented only after 10.2.3 in MariaDb and 5.7 in MySql
|
447
|
+
# JSON if implemented only after 10.2.3 (aggregations after 10.5.0) in MariaDb and 5.7 (aggregations after 5.7.22) in MySql
|
451
448
|
def json_supported?
|
452
|
-
version_supported?('10.
|
449
|
+
version_supported?('10.5.0', '5.7.22')
|
453
450
|
end
|
454
451
|
|
455
452
|
def window_supported?
|
@@ -467,21 +464,22 @@ module ArelExtensions
|
|
467
464
|
conn.respond_to?(:version) && conn.send(:version) >= mariadb_v || \
|
468
465
|
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mariadb_v) || \
|
469
466
|
!conn.send(:mariadb?) && \
|
470
|
-
|
471
|
-
|
472
|
-
|
467
|
+
(conn.respond_to?(:get_database_version) && conn.send(:get_database_version) >= mysql_v || \
|
468
|
+
conn.respond_to?(:version) && conn.send(:version) >= mysql_v || \
|
469
|
+
conn.instance_variable_get(:"@version") && conn.instance_variable_get(:"@version") >= mysql_v)
|
473
470
|
# ideally we should parse the instance_variable @full_version because @version contains only the supposedly
|
474
471
|
# corresponding mysql version of the current mariadb version (which is not very helpful most of the time)
|
475
472
|
end
|
476
473
|
|
477
474
|
def visit_ArelExtensions_Nodes_Json o,collector
|
478
475
|
return super if !json_supported?
|
476
|
+
|
479
477
|
case o.dict
|
480
478
|
when Array
|
481
479
|
collector << 'JSON_ARRAY('
|
482
480
|
o.dict.each.with_index do |v,i|
|
483
481
|
if i != 0
|
484
|
-
collector <<
|
482
|
+
collector << COMMA
|
485
483
|
end
|
486
484
|
collector = visit v, collector
|
487
485
|
end
|
@@ -490,10 +488,10 @@ module ArelExtensions
|
|
490
488
|
collector << 'JSON_OBJECT('
|
491
489
|
o.dict.each.with_index do |(k,v),i|
|
492
490
|
if i != 0
|
493
|
-
collector <<
|
491
|
+
collector << COMMA
|
494
492
|
end
|
495
493
|
collector = visit k, collector
|
496
|
-
collector <<
|
494
|
+
collector << COMMA
|
497
495
|
collector = visit v, collector
|
498
496
|
end
|
499
497
|
collector << ')'
|
@@ -507,7 +505,7 @@ module ArelExtensions
|
|
507
505
|
collector << 'JSON_MERGE_PATCH('
|
508
506
|
o.expressions.each.with_index do |v,i|
|
509
507
|
if i != 0
|
510
|
-
collector <<
|
508
|
+
collector << COMMA
|
511
509
|
end
|
512
510
|
collector = visit v, collector
|
513
511
|
end
|
@@ -518,7 +516,7 @@ module ArelExtensions
|
|
518
516
|
def visit_ArelExtensions_Nodes_JsonGet o,collector
|
519
517
|
collector << 'JSON_EXTRACT('
|
520
518
|
collector = visit o.dict, collector
|
521
|
-
collector <<
|
519
|
+
collector << COMMA
|
522
520
|
if o.key.is_a?(Integer)
|
523
521
|
collector << "\"$[#{o.key}]\""
|
524
522
|
else
|
@@ -531,13 +529,13 @@ module ArelExtensions
|
|
531
529
|
def visit_ArelExtensions_Nodes_JsonSet o,collector
|
532
530
|
collector << 'JSON_SET('
|
533
531
|
collector = visit o.dict, collector
|
534
|
-
collector <<
|
532
|
+
collector << COMMA
|
535
533
|
if o.key.is_a?(Integer)
|
536
534
|
collector << "\"$[#{o.key}]\""
|
537
535
|
else
|
538
536
|
collector = visit Arel::Nodes.build_quoted('$.')+o.key, collector
|
539
537
|
end
|
540
|
-
collector <<
|
538
|
+
collector << COMMA
|
541
539
|
collector = visit o.value, collector
|
542
540
|
collector << ')'
|
543
541
|
collector
|
@@ -545,6 +543,7 @@ module ArelExtensions
|
|
545
543
|
|
546
544
|
def visit_ArelExtensions_Nodes_JsonGroup o, collector
|
547
545
|
return super if !json_supported?
|
546
|
+
|
548
547
|
if o.as_array
|
549
548
|
collector << 'JSON_ARRAYAGG('
|
550
549
|
collector = visit o.dict, collector
|
@@ -555,11 +554,11 @@ module ArelExtensions
|
|
555
554
|
collector << 'JSON_MERGE_PATCH(' if o.dict.length > 1
|
556
555
|
o.dict.each.with_index do |(k,v),i|
|
557
556
|
if i != 0
|
558
|
-
collector <<
|
557
|
+
collector << COMMA
|
559
558
|
end
|
560
559
|
collector << 'JSON_OBJECTAGG('
|
561
560
|
collector = visit k, collector
|
562
|
-
collector <<
|
561
|
+
collector << COMMA
|
563
562
|
collector = visit v, collector
|
564
563
|
collector << ')'
|
565
564
|
end
|
@@ -572,7 +571,6 @@ module ArelExtensions
|
|
572
571
|
end
|
573
572
|
collector
|
574
573
|
end
|
575
|
-
|
576
574
|
end
|
577
575
|
end
|
578
576
|
end
|