arel_extensions 2.0.9 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/Gemfile +10 -10
- data/Rakefile +4 -4
- data/gemfiles/rails3.gemfile +9 -9
- data/gemfiles/rails4.gemfile +13 -13
- data/gemfiles/rails5_0.gemfile +13 -13
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +13 -13
- data/gemfiles/rails6.gemfile +13 -13
- data/lib/arel_extensions.rb +3 -3
- data/lib/arel_extensions/attributes.rb +0 -0
- data/lib/arel_extensions/boolean_functions.rb +21 -5
- data/lib/arel_extensions/common_sql_functions.rb +2 -4
- data/lib/arel_extensions/comparators.rb +11 -14
- data/lib/arel_extensions/date_duration.rb +4 -5
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +8 -9
- data/lib/arel_extensions/math_functions.rb +15 -17
- data/lib/arel_extensions/nodes/abs.rb +0 -1
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
- data/lib/arel_extensions/nodes/blank.rb +0 -1
- data/lib/arel_extensions/nodes/case.rb +3 -4
- data/lib/arel_extensions/nodes/cast.rb +4 -2
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +0 -1
- data/lib/arel_extensions/nodes/collate.rb +0 -1
- data/lib/arel_extensions/nodes/concat.rb +1 -3
- data/lib/arel_extensions/nodes/date_diff.rb +7 -8
- data/lib/arel_extensions/nodes/duration.rb +0 -1
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +27 -1
- data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
- data/lib/arel_extensions/nodes/function.rb +18 -15
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +39 -30
- data/lib/arel_extensions/nodes/length.rb +0 -1
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -1
- data/lib/arel_extensions/nodes/log10.rb +1 -2
- data/lib/arel_extensions/nodes/matches.rb +0 -2
- data/lib/arel_extensions/nodes/md5.rb +0 -1
- data/lib/arel_extensions/nodes/power.rb +0 -1
- data/lib/arel_extensions/nodes/rand.rb +0 -1
- data/lib/arel_extensions/nodes/repeat.rb +0 -2
- data/lib/arel_extensions/nodes/replace.rb +0 -2
- data/lib/arel_extensions/nodes/round.rb +0 -1
- data/lib/arel_extensions/nodes/soundex.rb +0 -1
- data/lib/arel_extensions/nodes/std.rb +0 -1
- data/lib/arel_extensions/nodes/substring.rb +0 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +0 -2
- data/lib/arel_extensions/nodes/union.rb +0 -2
- data/lib/arel_extensions/nodes/union_all.rb +0 -2
- data/lib/arel_extensions/nodes/wday.rb +0 -4
- data/lib/arel_extensions/null_functions.rb +3 -5
- data/lib/arel_extensions/predications.rb +5 -6
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +0 -2
- data/lib/arel_extensions/string_functions.rb +21 -22
- data/lib/arel_extensions/tasks.rb +1 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +9 -7
- data/lib/arel_extensions/visitors/convert_format.rb +37 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
- data/lib/arel_extensions/visitors/mssql.rb +48 -44
- data/lib/arel_extensions/visitors/mysql.rb +65 -67
- data/lib/arel_extensions/visitors/oracle.rb +58 -55
- data/lib/arel_extensions/visitors/oracle12.rb +2 -3
- data/lib/arel_extensions/visitors/postgresql.rb +41 -34
- data/lib/arel_extensions/visitors/sqlite.rb +23 -18
- data/lib/arel_extensions/visitors/to_sql.rb +69 -61
- data/test/arelx_test_helper.rb +0 -2
- data/test/real_db_test.rb +27 -42
- data/test/support/fake_record.rb +1 -1
- data/test/test_comparators.rb +0 -4
- data/test/visitors/test_bulk_insert_oracle.rb +0 -1
- data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
- data/test/visitors/test_oracle.rb +1 -2
- data/test/visitors/test_to_sql.rb +16 -25
- data/test/with_ar/all_agnostic_test.rb +135 -139
- data/test/with_ar/insert_agnostic_test.rb +0 -2
- data/test/with_ar/test_bulk_sqlite.rb +0 -4
- data/test/with_ar/test_math_sqlite.rb +4 -8
- data/test/with_ar/test_string_mysql.rb +1 -5
- data/test/with_ar/test_string_sqlite.rb +1 -5
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +3 -2
@@ -1,6 +1,5 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
4
3
|
Arel::Visitors.send(:remove_const,'Oracle12') if Arel::Visitors.const_defined?('Oracle12')
|
5
4
|
Arel::Visitors.const_set('Oracle12',Class.new(Arel::Visitors::Oracle)).class_eval do
|
6
5
|
def visit_Arel_Nodes_SelectStatement(o, collector)
|
@@ -12,6 +11,7 @@ module ArelExtensions
|
|
12
11
|
`SELECT FOR UPDATE and FETCH FIRST n ROWS` generates ORA-02014.`
|
13
12
|
MSG
|
14
13
|
end
|
14
|
+
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
@@ -84,7 +84,7 @@ module ArelExtensions
|
|
84
84
|
collector << 'FORMAT JSON'
|
85
85
|
end
|
86
86
|
collector << ')'
|
87
|
-
when String,Numeric,TrueClass,FalseClass
|
87
|
+
when String, Numeric, TrueClass, FalseClass
|
88
88
|
collector = visit Arel::Nodes.build_quoted("#{o.dict}"), collector
|
89
89
|
collector << ' FORMAT JSON'
|
90
90
|
when NilClass
|
@@ -97,7 +97,6 @@ module ArelExtensions
|
|
97
97
|
end
|
98
98
|
collector
|
99
99
|
end
|
100
|
-
|
101
100
|
end
|
102
101
|
end
|
103
102
|
end
|
@@ -1,20 +1,29 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
class Arel::Visitors::PostgreSQL
|
4
|
-
|
5
|
-
|
6
|
-
'
|
4
|
+
DATE_MAPPING = {
|
5
|
+
'd' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW',
|
6
|
+
'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
DATE_FORMAT_DIRECTIVES = {
|
10
|
+
'%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY',
|
11
|
+
'%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
7
12
|
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
|
8
13
|
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
9
|
-
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
10
|
-
|
11
|
-
|
14
|
+
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz', # seconds, subseconds
|
15
|
+
'%%' => '%',
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
NUMBER_COMMA_MAPPING = {
|
19
|
+
'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '
|
20
|
+
}.freeze
|
12
21
|
|
13
22
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
14
23
|
collector << "RANDOM("
|
15
|
-
if(o.left != nil && o.right != nil)
|
24
|
+
if (o.left != nil && o.right != nil)
|
16
25
|
collector = visit o.left, collector
|
17
|
-
collector <<
|
26
|
+
collector << COMMA
|
18
27
|
collector = isit o.right, collector
|
19
28
|
end
|
20
29
|
collector << ")"
|
@@ -24,7 +33,7 @@ module ArelExtensions
|
|
24
33
|
def visit_ArelExtensions_Nodes_Power o, collector
|
25
34
|
collector << "POWER("
|
26
35
|
o.expressions.each_with_index { |arg, i|
|
27
|
-
collector << Arel::Visitors::ToSql::COMMA
|
36
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
28
37
|
collector = visit arg, collector
|
29
38
|
}
|
30
39
|
collector << ")"
|
@@ -34,7 +43,7 @@ module ArelExtensions
|
|
34
43
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
35
44
|
collector << "LOG("
|
36
45
|
o.expressions.each_with_index { |arg, i|
|
37
|
-
collector << Arel::Visitors::ToSql::COMMA
|
46
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
38
47
|
collector = visit arg, collector
|
39
48
|
}
|
40
49
|
collector << ")"
|
@@ -68,7 +77,7 @@ module ArelExtensions
|
|
68
77
|
collector
|
69
78
|
end
|
70
79
|
|
71
|
-
alias_method
|
80
|
+
alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
|
72
81
|
def visit_Arel_Nodes_As o, collector
|
73
82
|
if o.left.is_a?(Arel::Nodes::Binary)
|
74
83
|
collector << '('
|
@@ -89,14 +98,14 @@ module ArelExtensions
|
|
89
98
|
if !o.group.blank?
|
90
99
|
collector << " PARTITION BY "
|
91
100
|
o.group.each_with_index do |group, i|
|
92
|
-
collector <<
|
101
|
+
collector << COMMA if i != 0
|
93
102
|
visit group, collector
|
94
103
|
end
|
95
104
|
end
|
96
105
|
if !o.order.blank?
|
97
106
|
collector << " ORDER BY "
|
98
107
|
o.order.each_with_index do |order, i|
|
99
|
-
collector <<
|
108
|
+
collector << COMMA if i != 0
|
100
109
|
visit order, collector
|
101
110
|
end
|
102
111
|
end
|
@@ -111,7 +120,7 @@ module ArelExtensions
|
|
111
120
|
if o.order && !o.order.blank?
|
112
121
|
collector << " ORDER BY"
|
113
122
|
o.order.each_with_index do |order, i|
|
114
|
-
collector <<
|
123
|
+
collector << COMMA if i != 0
|
115
124
|
collector << " "
|
116
125
|
visit order, collector
|
117
126
|
end
|
@@ -119,7 +128,7 @@ module ArelExtensions
|
|
119
128
|
collector << ")"
|
120
129
|
o.order = nil
|
121
130
|
visit_Aggregate_For_AggregateFunction o, collector
|
122
|
-
collector <<
|
131
|
+
collector << COMMA
|
123
132
|
collector =
|
124
133
|
if o.separator && o.separator != 'NULL'
|
125
134
|
visit o.separator, collector
|
@@ -158,14 +167,11 @@ module ArelExtensions
|
|
158
167
|
end
|
159
168
|
|
160
169
|
def visit_ArelExtensions_Nodes_Format o, collector
|
170
|
+
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
161
171
|
collector << "TO_CHAR("
|
162
172
|
collector = visit o.left, collector
|
163
|
-
collector <<
|
164
|
-
|
165
|
-
f = o.iso_format.dup
|
166
|
-
Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
|
167
|
-
collector = visit Arel::Nodes.build_quoted(f), collector
|
168
|
-
|
173
|
+
collector << COMMA
|
174
|
+
collector = visit Arel::Nodes.build_quoted(fmt), collector
|
169
175
|
collector << ")"
|
170
176
|
collector
|
171
177
|
end
|
@@ -173,7 +179,7 @@ module ArelExtensions
|
|
173
179
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
174
180
|
collector << "REPEAT("
|
175
181
|
o.expressions.each_with_index { |arg, i|
|
176
|
-
collector << Arel::Visitors::ToSql::COMMA
|
182
|
+
collector << Arel::Visitors::ToSql::COMMA if i != 0
|
177
183
|
collector = visit arg, collector
|
178
184
|
}
|
179
185
|
collector << ")"
|
@@ -231,7 +237,7 @@ module ArelExtensions
|
|
231
237
|
|
232
238
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
233
239
|
collector = visit o.left, collector
|
234
|
-
collector << ' + ' #(o.right.value >= 0 ? ' + ' : ' - ')
|
240
|
+
collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
|
235
241
|
collector = visit o.postgresql_value(o.right), collector
|
236
242
|
collector
|
237
243
|
end
|
@@ -245,7 +251,7 @@ module ArelExtensions
|
|
245
251
|
end
|
246
252
|
collector = visit o.right, collector
|
247
253
|
collector << (o.right_node_type == :date ? '::date' : '::timestamp')
|
248
|
-
collector <<
|
254
|
+
collector << COMMA
|
249
255
|
collector = visit o.left, collector
|
250
256
|
collector << (o.left_node_type == :date ? '::date' : '::timestamp')
|
251
257
|
collector << ")"
|
@@ -273,11 +279,11 @@ module ArelExtensions
|
|
273
279
|
collector << "("
|
274
280
|
collector = visit o.right, collector
|
275
281
|
collector << ")"
|
276
|
-
collector << " * (INTERVAL '1' #{
|
282
|
+
collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
|
277
283
|
return collector
|
278
284
|
end
|
279
285
|
end
|
280
|
-
collector << "EXTRACT(#{
|
286
|
+
collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
|
281
287
|
collector = visit o.right, collector
|
282
288
|
collector << ")"
|
283
289
|
collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
|
@@ -296,7 +302,7 @@ module ArelExtensions
|
|
296
302
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
297
303
|
collector << "SUBSTR("
|
298
304
|
o.expressions.each_with_index { |arg, i|
|
299
|
-
collector <<
|
305
|
+
collector << COMMA if i != 0
|
300
306
|
collector = visit arg, collector
|
301
307
|
}
|
302
308
|
collector << ")"
|
@@ -308,7 +314,7 @@ module ArelExtensions
|
|
308
314
|
visit o.left, collector
|
309
315
|
collector << Arel::Visitors::ToSql::COMMA
|
310
316
|
tab = o.pattern.inspect+ 'g' # Make it always global
|
311
|
-
pattern = tab.split('/')[1..-2].join('/')
|
317
|
+
pattern = tab.split('/')[1..-2].join('/')
|
312
318
|
flags = tab.split('/')[-1]
|
313
319
|
visit Arel::Nodes.build_quoted(pattern), collector
|
314
320
|
collector << Arel::Visitors::ToSql::COMMA
|
@@ -350,6 +356,8 @@ module ArelExtensions
|
|
350
356
|
as_attr = case o.as_attr
|
351
357
|
when :string
|
352
358
|
Arel::Nodes::SqlLiteral.new('varchar')
|
359
|
+
when :text, :ntext
|
360
|
+
Arel::Nodes::SqlLiteral.new('text')
|
353
361
|
when :time
|
354
362
|
Arel::Nodes::SqlLiteral.new('time')
|
355
363
|
when :int
|
@@ -378,8 +386,8 @@ module ArelExtensions
|
|
378
386
|
|
379
387
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
380
388
|
col = o.left.coalesce(0)
|
381
|
-
comma = o.precision == 0 ? '' : (
|
382
|
-
thousand_separator =
|
389
|
+
comma = o.precision == 0 ? '' : (NUMBER_COMMA_MAPPING[o.locale][0] || '.')
|
390
|
+
thousand_separator = NUMBER_COMMA_MAPPING[o.locale][1] || (NUMBER_COMMA_MAPPING[o.locale] ? '' : 'G')
|
383
391
|
nines_after = (1..o.precision).map{'9'}.join('')
|
384
392
|
nines_before = ("999#{thousand_separator}"*4+"990")
|
385
393
|
|
@@ -433,7 +441,7 @@ module ArelExtensions
|
|
433
441
|
end
|
434
442
|
|
435
443
|
|
436
|
-
alias_method
|
444
|
+
alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
|
437
445
|
def visit_Arel_Nodes_SelectStatement o, collector
|
438
446
|
|
439
447
|
if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
|
@@ -443,7 +451,7 @@ module ArelExtensions
|
|
443
451
|
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
444
452
|
end
|
445
453
|
|
446
|
-
alias_method
|
454
|
+
alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
|
447
455
|
def visit_Arel_Nodes_TableAlias o, collector
|
448
456
|
if o.name.length > 63
|
449
457
|
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
@@ -451,7 +459,7 @@ module ArelExtensions
|
|
451
459
|
old_visit_Arel_Nodes_TableAlias(o,collector)
|
452
460
|
end
|
453
461
|
|
454
|
-
alias_method
|
462
|
+
alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
|
455
463
|
def visit_Arel_Attributes_Attribute o, collector
|
456
464
|
join_name = o.relation.table_alias || o.relation.name
|
457
465
|
if join_name.length > 63
|
@@ -569,7 +577,6 @@ module ArelExtensions
|
|
569
577
|
end
|
570
578
|
collector
|
571
579
|
end
|
572
|
-
|
573
580
|
end
|
574
581
|
end
|
575
582
|
end
|
@@ -1,16 +1,23 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
class Arel::Visitors::SQLite
|
4
|
-
|
5
|
-
|
4
|
+
DATE_MAPPING = {
|
5
|
+
'd' => '%d', 'm' => '%m', 'w' => '%W', 'y' => '%Y', 'wd' => '%w', 'M' => '%M',
|
6
|
+
'h' => '%H', 'mn' => '%M', 's' => '%S'
|
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' => '%M', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => '' # seconds, subseconds
|
10
|
-
}
|
11
|
-
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
NUMBER_COMMA_MAPPING = {
|
17
|
+
'fr_FR' => {',' => ' ', '.' =>','}
|
18
|
+
}.freeze
|
12
19
|
|
13
|
-
#String functions
|
20
|
+
# String functions
|
14
21
|
def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
|
15
22
|
collector = visit o.left.ci_collate, collector
|
16
23
|
collector << ' LIKE '
|
@@ -73,7 +80,6 @@ module ArelExtensions
|
|
73
80
|
collector
|
74
81
|
end
|
75
82
|
|
76
|
-
|
77
83
|
def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
|
78
84
|
collector = visit o.left.lower, collector
|
79
85
|
collector << ' NOT LIKE '
|
@@ -90,14 +96,15 @@ module ArelExtensions
|
|
90
96
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
91
97
|
collector << "date("
|
92
98
|
collector = visit o.expressions.first, collector
|
93
|
-
collector <<
|
99
|
+
collector << COMMA
|
94
100
|
collector = visit o.sqlite_value, collector
|
95
101
|
collector << ")"
|
96
102
|
collector
|
97
103
|
end
|
98
104
|
|
99
105
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
100
|
-
|
106
|
+
case o.left_node_type
|
107
|
+
when :ruby_time, :datetime, :time
|
101
108
|
collector << "strftime('%s', "
|
102
109
|
collector = visit o.left, collector
|
103
110
|
collector << ") - strftime('%s', "
|
@@ -113,17 +120,16 @@ module ArelExtensions
|
|
113
120
|
end
|
114
121
|
|
115
122
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
116
|
-
collector << "strftime('#{
|
123
|
+
collector << "strftime('#{DATE_MAPPING[o.left]}'#{COMMA}"
|
117
124
|
collector = visit o.right, collector
|
118
125
|
collector << ")"
|
119
126
|
collector
|
120
127
|
end
|
121
128
|
|
122
|
-
|
123
129
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
124
130
|
collector << "instr("
|
125
131
|
collector = visit o.expr, collector
|
126
|
-
collector <<
|
132
|
+
collector << COMMA
|
127
133
|
collector = visit o.right, collector
|
128
134
|
collector << ")"
|
129
135
|
collector
|
@@ -142,7 +148,7 @@ module ArelExtensions
|
|
142
148
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
143
149
|
collector << "SUBSTR("
|
144
150
|
o.expressions.each_with_index { |arg, i|
|
145
|
-
collector <<
|
151
|
+
collector << COMMA if i != 0
|
146
152
|
collector = visit arg, collector
|
147
153
|
}
|
148
154
|
collector << ")"
|
@@ -165,7 +171,7 @@ module ArelExtensions
|
|
165
171
|
collector << "RANDOM("
|
166
172
|
if o.left != nil && o.right != nil
|
167
173
|
collector = visit o.left, collector
|
168
|
-
collector <<
|
174
|
+
collector << COMMA
|
169
175
|
collector = visit o.right, collector
|
170
176
|
end
|
171
177
|
collector << ")"
|
@@ -247,7 +253,7 @@ module ArelExtensions
|
|
247
253
|
collector << quote(attr.name)
|
248
254
|
end
|
249
255
|
end
|
250
|
-
collector <<
|
256
|
+
collector << COMMA unless i == len
|
251
257
|
}
|
252
258
|
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
253
259
|
end
|
@@ -275,7 +281,7 @@ module ArelExtensions
|
|
275
281
|
collector << quote(attr.name)
|
276
282
|
end
|
277
283
|
end
|
278
|
-
collector <<
|
284
|
+
collector << COMMA unless i == len
|
279
285
|
}
|
280
286
|
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
281
287
|
end
|
@@ -364,7 +370,7 @@ module ArelExtensions
|
|
364
370
|
collector
|
365
371
|
end
|
366
372
|
|
367
|
-
alias_method
|
373
|
+
alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
|
368
374
|
def visit_Arel_Nodes_As o, collector
|
369
375
|
if o.left.is_a?(Arel::Nodes::Binary)
|
370
376
|
collector << '('
|
@@ -381,14 +387,13 @@ module ArelExtensions
|
|
381
387
|
|
382
388
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
383
389
|
format = Arel::Nodes::NamedFunction.new('printf',[Arel::Nodes.build_quoted(o.original_string),o.left])
|
384
|
-
locale_map =
|
390
|
+
locale_map = NUMBER_COMMA_MAPPING[o.locale]
|
385
391
|
if locale_map
|
386
392
|
format = format.replace(',',locale_map[',']).replace('.',locale_map['.'])
|
387
393
|
end
|
388
394
|
visit format, collector
|
389
395
|
collector
|
390
396
|
end
|
391
|
-
|
392
397
|
end
|
393
398
|
end
|
394
399
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
3
|
class Arel::Visitors::ToSql
|
4
|
-
|
4
|
+
COMMA = ', ' unless defined?(COMMA)
|
5
5
|
|
6
6
|
# Math Functions
|
7
7
|
def visit_ArelExtensions_Nodes_Abs o, collector
|
8
8
|
collector << "ABS("
|
9
9
|
o.expressions.each_with_index { |arg, i|
|
10
|
-
collector <<
|
10
|
+
collector << COMMA if i != 0
|
11
11
|
collector = visit arg, collector
|
12
12
|
}
|
13
13
|
collector << ")"
|
@@ -17,7 +17,7 @@ module ArelExtensions
|
|
17
17
|
def visit_ArelExtensions_Nodes_Ceil o, collector
|
18
18
|
collector << "CEIL("
|
19
19
|
o.expressions.each_with_index { |arg, i|
|
20
|
-
collector <<
|
20
|
+
collector << COMMA if i != 0
|
21
21
|
collector = visit arg, collector
|
22
22
|
}
|
23
23
|
collector << ")"
|
@@ -27,7 +27,7 @@ module ArelExtensions
|
|
27
27
|
def visit_ArelExtensions_Nodes_Floor o, collector
|
28
28
|
collector << "FLOOR("
|
29
29
|
o.expressions.each_with_index { |arg, i|
|
30
|
-
collector <<
|
30
|
+
collector << COMMA if i != 0
|
31
31
|
collector = visit arg, collector
|
32
32
|
}
|
33
33
|
collector << ")"
|
@@ -37,7 +37,7 @@ module ArelExtensions
|
|
37
37
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
38
38
|
collector << "RAND("
|
39
39
|
o.expressions.each_with_index { |arg, i|
|
40
|
-
collector <<
|
40
|
+
collector << COMMA if i != 0
|
41
41
|
collector = visit arg, collector
|
42
42
|
}
|
43
43
|
collector << ")"
|
@@ -47,7 +47,7 @@ module ArelExtensions
|
|
47
47
|
def visit_ArelExtensions_Nodes_Round o, collector
|
48
48
|
collector << "ROUND("
|
49
49
|
o.expressions.each_with_index { |arg, i|
|
50
|
-
collector <<
|
50
|
+
collector << COMMA if i != 0
|
51
51
|
collector = visit arg, collector
|
52
52
|
}
|
53
53
|
collector << ")"
|
@@ -64,7 +64,7 @@ module ArelExtensions
|
|
64
64
|
def visit_ArelExtensions_Nodes_Power o, collector
|
65
65
|
collector << "POW("
|
66
66
|
o.expressions.each_with_index { |arg, i|
|
67
|
-
collector <<
|
67
|
+
collector << COMMA if i != 0
|
68
68
|
collector = visit arg, collector
|
69
69
|
}
|
70
70
|
collector << ")"
|
@@ -81,9 +81,9 @@ module ArelExtensions
|
|
81
81
|
# String functions
|
82
82
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
83
83
|
collector << "CONCAT("
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
o.expressions.each_with_index { |arg, i|
|
85
|
+
collector << COMMA if i != 0
|
86
|
+
collector = visit arg, collector
|
87
87
|
}
|
88
88
|
collector << ")"
|
89
89
|
collector
|
@@ -93,7 +93,7 @@ module ArelExtensions
|
|
93
93
|
collector << "GROUP_CONCAT("
|
94
94
|
collector = visit o.left, collector
|
95
95
|
if o.separator && o.separator != 'NULL'
|
96
|
-
collector <<
|
96
|
+
collector << COMMA
|
97
97
|
collector = visit o.separator, collector
|
98
98
|
end
|
99
99
|
collector << ")"
|
@@ -117,7 +117,7 @@ module ArelExtensions
|
|
117
117
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
118
118
|
collector << "LOCATE("
|
119
119
|
collector = visit o.right, collector
|
120
|
-
collector <<
|
120
|
+
collector << COMMA
|
121
121
|
collector = visit o.left, collector
|
122
122
|
collector << ")"
|
123
123
|
collector
|
@@ -126,7 +126,7 @@ module ArelExtensions
|
|
126
126
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
127
127
|
collector << "SUBSTRING("
|
128
128
|
o.expressions.each_with_index { |arg, i|
|
129
|
-
collector <<
|
129
|
+
collector << COMMA if i != 0
|
130
130
|
collector = visit arg, collector
|
131
131
|
}
|
132
132
|
collector << ")"
|
@@ -136,9 +136,9 @@ module ArelExtensions
|
|
136
136
|
def visit_ArelExtensions_Nodes_Replace o, collector
|
137
137
|
collector << "REPLACE("
|
138
138
|
visit o.left, collector
|
139
|
-
collector <<
|
139
|
+
collector << COMMA
|
140
140
|
visit o.pattern, collector
|
141
|
-
collector <<
|
141
|
+
collector << COMMA
|
142
142
|
visit o.substitute, collector
|
143
143
|
collector << ")"
|
144
144
|
collector
|
@@ -147,9 +147,9 @@ module ArelExtensions
|
|
147
147
|
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
148
148
|
collector << "REGEXP_REPLACE("
|
149
149
|
visit o.left, collector
|
150
|
-
collector <<
|
150
|
+
collector << COMMA
|
151
151
|
visit Arel::Nodes.build_quoted(o.pattern.to_s), collector
|
152
|
-
collector <<
|
152
|
+
collector << COMMA
|
153
153
|
visit o.substitute, collector
|
154
154
|
collector << ")"
|
155
155
|
collector
|
@@ -158,7 +158,7 @@ module ArelExtensions
|
|
158
158
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
159
159
|
collector << "REPEAT("
|
160
160
|
o.expressions.each_with_index { |arg, i|
|
161
|
-
collector <<
|
161
|
+
collector << COMMA if i != 0
|
162
162
|
collector = visit arg, collector
|
163
163
|
}
|
164
164
|
collector << ")"
|
@@ -168,7 +168,7 @@ module ArelExtensions
|
|
168
168
|
def visit_ArelExtensions_Nodes_FindInSet o, collector
|
169
169
|
collector << "FIND_IN_SET("
|
170
170
|
o.expressions.each_with_index { |arg, i|
|
171
|
-
collector <<
|
171
|
+
collector << COMMA if i != 0
|
172
172
|
collector = visit arg, collector
|
173
173
|
}
|
174
174
|
collector << ")"
|
@@ -178,7 +178,7 @@ module ArelExtensions
|
|
178
178
|
def visit_ArelExtensions_Nodes_Soundex o, collector
|
179
179
|
collector << "SOUNDEX("
|
180
180
|
o.expressions.each_with_index { |arg, i|
|
181
|
-
collector <<
|
181
|
+
collector << COMMA if i != 0
|
182
182
|
collector = visit arg, collector
|
183
183
|
}
|
184
184
|
collector << ")"
|
@@ -188,7 +188,7 @@ module ArelExtensions
|
|
188
188
|
def visit_ArelExtensions_Nodes_Downcase o, collector
|
189
189
|
collector << "LOWER("
|
190
190
|
o.expressions.each_with_index { |arg, i|
|
191
|
-
collector <<
|
191
|
+
collector << COMMA if i != 0
|
192
192
|
collector = visit arg, collector
|
193
193
|
}
|
194
194
|
collector << ")"
|
@@ -198,7 +198,7 @@ module ArelExtensions
|
|
198
198
|
def visit_ArelExtensions_Nodes_Upcase o, collector
|
199
199
|
collector << "UPPER("
|
200
200
|
o.expressions.each_with_index { |arg, i|
|
201
|
-
collector <<
|
201
|
+
collector << COMMA if i != 0
|
202
202
|
collector = visit arg, collector
|
203
203
|
}
|
204
204
|
collector << ")"
|
@@ -208,7 +208,7 @@ module ArelExtensions
|
|
208
208
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
209
209
|
collector << "TRIM("
|
210
210
|
o.expressions.each_with_index { |arg, i|
|
211
|
-
collector <<
|
211
|
+
collector << COMMA if i != 0
|
212
212
|
collector = visit arg, collector
|
213
213
|
}
|
214
214
|
collector << ")"
|
@@ -218,7 +218,7 @@ module ArelExtensions
|
|
218
218
|
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
219
219
|
collector << "LTRIM("
|
220
220
|
o.expressions.each_with_index { |arg, i|
|
221
|
-
collector <<
|
221
|
+
collector << COMMA if i != 0
|
222
222
|
collector = visit arg, collector
|
223
223
|
}
|
224
224
|
collector << ")"
|
@@ -228,7 +228,7 @@ module ArelExtensions
|
|
228
228
|
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
229
229
|
collector << "RTRIM("
|
230
230
|
o.expressions.each_with_index { |arg, i|
|
231
|
-
collector <<
|
231
|
+
collector << COMMA if i != 0
|
232
232
|
collector = visit arg, collector
|
233
233
|
}
|
234
234
|
collector << ")"
|
@@ -236,21 +236,20 @@ module ArelExtensions
|
|
236
236
|
end
|
237
237
|
|
238
238
|
def visit_ArelExtensions_Nodes_Blank o, collector
|
239
|
-
|
239
|
+
# visit o.left.coalesce('').trim.length.eq(0), collector
|
240
240
|
collector << 'LENGTH(TRIM(COALESCE('
|
241
241
|
collector = visit o.expr, collector
|
242
|
-
collector <<
|
242
|
+
collector << COMMA
|
243
243
|
collector = visit Arel::Nodes.build_quoted(''), collector
|
244
244
|
collector << "))) = 0"
|
245
245
|
collector
|
246
246
|
end
|
247
247
|
|
248
|
-
|
249
248
|
def visit_ArelExtensions_Nodes_NotBlank o, collector
|
250
|
-
|
249
|
+
# visit o.left.coalesce('').trim.length.gt(0), collector
|
251
250
|
collector << 'LENGTH(TRIM(COALESCE('
|
252
251
|
collector = visit o.expr, collector
|
253
|
-
collector <<
|
252
|
+
collector << COMMA
|
254
253
|
collector = visit Arel::Nodes.build_quoted(''), collector
|
255
254
|
collector << "))) > 0"
|
256
255
|
collector
|
@@ -261,13 +260,13 @@ module ArelExtensions
|
|
261
260
|
when :date, :datetime, :time
|
262
261
|
collector << "STRFTIME("
|
263
262
|
collector = visit o.right, collector
|
264
|
-
collector <<
|
263
|
+
collector << COMMA
|
265
264
|
collector = visit o.left, collector
|
266
265
|
collector << ")"
|
267
266
|
when :integer, :float, :decimal
|
268
267
|
collector << "FORMAT("
|
269
268
|
collector = visit o.left, collector
|
270
|
-
collector <<
|
269
|
+
collector << COMMA
|
271
270
|
collector = visit o.right, collector
|
272
271
|
collector << ")"
|
273
272
|
else
|
@@ -276,7 +275,7 @@ module ArelExtensions
|
|
276
275
|
collector
|
277
276
|
end
|
278
277
|
|
279
|
-
#comparators
|
278
|
+
# comparators
|
280
279
|
|
281
280
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
282
281
|
collector << "CAST("
|
@@ -295,6 +294,8 @@ module ArelExtensions
|
|
295
294
|
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
296
295
|
when :binary
|
297
296
|
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
297
|
+
when :text, :ntext
|
298
|
+
as_attr = Arel::Nodes::SqlLiteral.new('text')
|
298
299
|
else
|
299
300
|
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
300
301
|
end
|
@@ -306,7 +307,7 @@ module ArelExtensions
|
|
306
307
|
def visit_ArelExtensions_Nodes_Coalesce o, collector
|
307
308
|
collector << "COALESCE("
|
308
309
|
o.expressions.each_with_index { |arg, i|
|
309
|
-
collector <<
|
310
|
+
collector << COMMA if i != 0
|
310
311
|
collector = visit arg, collector
|
311
312
|
}
|
312
313
|
collector << ")"
|
@@ -320,7 +321,7 @@ module ArelExtensions
|
|
320
321
|
'DATEDIFF('
|
321
322
|
end
|
322
323
|
collector = visit o.left, collector
|
323
|
-
collector <<
|
324
|
+
collector << COMMA
|
324
325
|
collector = visit o.right, collector
|
325
326
|
collector << ")"
|
326
327
|
collector
|
@@ -329,13 +330,13 @@ module ArelExtensions
|
|
329
330
|
def visit_ArelExtensions_Nodes_DateSub o, collector
|
330
331
|
collector << "DATE_SUB("
|
331
332
|
collector = visit o.left, collector
|
332
|
-
collector <<
|
333
|
+
collector << COMMA
|
333
334
|
collector = visit o.right, collector
|
334
335
|
collector << ")"
|
335
336
|
collector
|
336
337
|
end
|
337
338
|
|
338
|
-
|
339
|
+
# override
|
339
340
|
remove_method(:visit_Arel_Nodes_As) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_As)
|
340
341
|
def visit_Arel_Nodes_As o, collector
|
341
342
|
if o.left.is_a?(Arel::Nodes::Binary)
|
@@ -416,7 +417,7 @@ module ArelExtensions
|
|
416
417
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
417
418
|
collector << "DATE_ADD("
|
418
419
|
collector = visit o.left, collector
|
419
|
-
collector <<
|
420
|
+
collector << COMMA
|
420
421
|
collector = visit o.sqlite_value(o.right), collector
|
421
422
|
collector << ')'
|
422
423
|
collector
|
@@ -436,7 +437,7 @@ module ArelExtensions
|
|
436
437
|
else
|
437
438
|
collector << quote(value, attr && column_for(attr)).to_s
|
438
439
|
end
|
439
|
-
collector <<
|
440
|
+
collector << COMMA unless i == len
|
440
441
|
}
|
441
442
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
442
443
|
end
|
@@ -458,7 +459,7 @@ module ArelExtensions
|
|
458
459
|
else
|
459
460
|
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
460
461
|
end
|
461
|
-
collector <<
|
462
|
+
collector << COMMA unless i == len
|
462
463
|
}
|
463
464
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
464
465
|
end
|
@@ -537,7 +538,7 @@ module ArelExtensions
|
|
537
538
|
def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
|
538
539
|
collector << "LEVENSHTEIN_DISTANCE("
|
539
540
|
collector = visit o.left, collector
|
540
|
-
collector <<
|
541
|
+
collector << COMMA
|
541
542
|
collector = visit o.right, collector
|
542
543
|
collector << ')'
|
543
544
|
collector
|
@@ -545,7 +546,7 @@ module ArelExtensions
|
|
545
546
|
|
546
547
|
# Boolean logic.
|
547
548
|
|
548
|
-
alias_method
|
549
|
+
alias_method(:old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And) rescue nil
|
549
550
|
def visit_Arel_Nodes_And o, collector
|
550
551
|
case o.children.length
|
551
552
|
when 0
|
@@ -565,7 +566,7 @@ module ArelExtensions
|
|
565
566
|
collector
|
566
567
|
end
|
567
568
|
|
568
|
-
alias_method
|
569
|
+
alias_method(:old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or) rescue nil
|
569
570
|
def visit_Arel_Nodes_Or o, collector
|
570
571
|
case o.children.length
|
571
572
|
when 0
|
@@ -585,6 +586,26 @@ module ArelExtensions
|
|
585
586
|
collector
|
586
587
|
end
|
587
588
|
|
589
|
+
def json_value(o,v)
|
590
|
+
case o.type_of_node(v)
|
591
|
+
when :string
|
592
|
+
Arel.when(v.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + v.replace('\\','\\\\').replace('"','\"') + '"')
|
593
|
+
when :date
|
594
|
+
s = v.format('%Y-%m-%d')
|
595
|
+
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
596
|
+
when :datetime
|
597
|
+
s = v.format('%Y-%m-%dT%H:%M:%S')
|
598
|
+
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
599
|
+
when :time
|
600
|
+
s = v.format('%H:%M:%S')
|
601
|
+
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
602
|
+
when :nil
|
603
|
+
Arel::Nodes.build_quoted("null")
|
604
|
+
else
|
605
|
+
ArelExtensions::Nodes::Cast.new([v, :string]).coalesce("null")
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
588
609
|
def visit_ArelExtensions_Nodes_Json o,collector
|
589
610
|
case o.dict
|
590
611
|
when Array
|
@@ -593,11 +614,7 @@ module ArelExtensions
|
|
593
614
|
if i != 0
|
594
615
|
res += ', '
|
595
616
|
end
|
596
|
-
|
597
|
-
res = res + '"' + v + '"'
|
598
|
-
else
|
599
|
-
res += v
|
600
|
-
end
|
617
|
+
res += json_value(o,v)
|
601
618
|
end
|
602
619
|
res += ']'
|
603
620
|
collector = visit res, collector
|
@@ -607,12 +624,8 @@ module ArelExtensions
|
|
607
624
|
if i != 0
|
608
625
|
res += ', '
|
609
626
|
end
|
610
|
-
res += Arel::Nodes.build_quoted('"')+k + '": '
|
611
|
-
|
612
|
-
res = res + '"' + v + '"'
|
613
|
-
else
|
614
|
-
res += v
|
615
|
-
end
|
627
|
+
res += Arel::Nodes.build_quoted('"') + ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("").replace('\\','\\\\').replace('"','\"') + '": '
|
628
|
+
res += json_value(o,v)
|
616
629
|
end
|
617
630
|
res += '}'
|
618
631
|
collector = visit res, collector
|
@@ -633,12 +646,8 @@ module ArelExtensions
|
|
633
646
|
if i != 0
|
634
647
|
res = res + ', '
|
635
648
|
end
|
636
|
-
kv = Arel::Nodes.build_quoted('"')+k + '": '
|
637
|
-
|
638
|
-
kv = kv + '"' + v + '"'
|
639
|
-
else
|
640
|
-
kv += v
|
641
|
-
end
|
649
|
+
kv = Arel::Nodes.build_quoted('"') + ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("").replace('\\','\\\\').replace('"','\"') + '": '
|
650
|
+
kv += json_value(o,v)
|
642
651
|
res = res + kv.group_concat(', ', order: Array(orders)).coalesce('')
|
643
652
|
end
|
644
653
|
res = res + '}'
|
@@ -646,7 +655,6 @@ module ArelExtensions
|
|
646
655
|
end
|
647
656
|
collector
|
648
657
|
end
|
649
|
-
|
650
658
|
end
|
651
659
|
end
|
652
660
|
end
|