arel_extensions 1.2.23 → 2.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -7
- data/.travis.yml +91 -61
- data/Gemfile +20 -15
- data/README.md +12 -17
- data/Rakefile +29 -40
- data/appveyor.yml +1 -1
- data/arel_extensions.gemspec +3 -3
- data/functions.html +3 -3
- 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/init/mssql.sql +4 -4
- data/init/mysql.sql +38 -38
- data/init/postgresql.sql +21 -21
- data/lib/arel_extensions.rb +19 -69
- data/lib/arel_extensions/attributes.rb +1 -0
- data/lib/arel_extensions/boolean_functions.rb +14 -55
- data/lib/arel_extensions/common_sql_functions.rb +8 -7
- data/lib/arel_extensions/comparators.rb +15 -14
- data/lib/arel_extensions/date_duration.rb +5 -4
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +12 -11
- data/lib/arel_extensions/math_functions.rb +22 -29
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/nodes/abs.rb +1 -0
- data/lib/arel_extensions/nodes/blank.rb +1 -0
- data/lib/arel_extensions/nodes/case.rb +8 -11
- data/lib/arel_extensions/nodes/cast.rb +2 -4
- 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 +3 -2
- data/lib/arel_extensions/nodes/collate.rb +2 -1
- data/lib/arel_extensions/nodes/concat.rb +16 -7
- data/lib/arel_extensions/nodes/date_diff.rb +13 -10
- data/lib/arel_extensions/nodes/duration.rb +3 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +8 -34
- data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
- data/lib/arel_extensions/nodes/function.rb +16 -25
- data/lib/arel_extensions/nodes/json.rb +36 -43
- data/lib/arel_extensions/nodes/length.rb +1 -0
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +1 -0
- data/lib/arel_extensions/nodes/log10.rb +2 -1
- data/lib/arel_extensions/nodes/matches.rb +6 -4
- data/lib/arel_extensions/nodes/md5.rb +1 -0
- data/lib/arel_extensions/nodes/power.rb +5 -5
- data/lib/arel_extensions/nodes/rand.rb +1 -0
- data/lib/arel_extensions/nodes/repeat.rb +4 -2
- data/lib/arel_extensions/nodes/replace.rb +6 -22
- data/lib/arel_extensions/nodes/round.rb +6 -5
- data/lib/arel_extensions/nodes/soundex.rb +15 -15
- data/lib/arel_extensions/nodes/std.rb +21 -18
- data/lib/arel_extensions/nodes/substring.rb +16 -8
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +5 -3
- data/lib/arel_extensions/nodes/union.rb +5 -2
- data/lib/arel_extensions/nodes/union_all.rb +3 -0
- data/lib/arel_extensions/nodes/wday.rb +4 -0
- data/lib/arel_extensions/null_functions.rb +7 -5
- data/lib/arel_extensions/predications.rb +34 -35
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +4 -2
- data/lib/arel_extensions/string_functions.rb +22 -43
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +60 -68
- data/lib/arel_extensions/visitors/ibm_db.rb +12 -5
- data/lib/arel_extensions/visitors/mssql.rb +57 -63
- data/lib/arel_extensions/visitors/mysql.rb +98 -149
- data/lib/arel_extensions/visitors/oracle.rb +68 -71
- data/lib/arel_extensions/visitors/oracle12.rb +15 -2
- data/lib/arel_extensions/visitors/postgresql.rb +63 -116
- data/lib/arel_extensions/visitors/sqlite.rb +70 -83
- data/lib/arel_extensions/visitors/to_sql.rb +109 -141
- data/test/database.yml +0 -2
- data/test/helper.rb +18 -0
- data/test/real_db_test.rb +43 -28
- data/test/support/fake_record.rb +2 -2
- data/test/test_comparators.rb +12 -9
- data/test/visitors/test_bulk_insert_oracle.rb +8 -8
- data/test/visitors/test_bulk_insert_sqlite.rb +10 -9
- data/test/visitors/test_bulk_insert_to_sql.rb +10 -8
- data/test/visitors/test_oracle.rb +42 -42
- data/test/visitors/test_to_sql.rb +196 -361
- data/test/with_ar/all_agnostic_test.rb +160 -195
- data/test/with_ar/insert_agnostic_test.rb +4 -3
- data/test/with_ar/test_bulk_sqlite.rb +9 -6
- data/test/with_ar/test_math_sqlite.rb +12 -8
- data/test/with_ar/test_string_mysql.rb +11 -5
- data/test/with_ar/test_string_sqlite.rb +12 -4
- metadata +11 -22
- data/.github/workflows/ruby.yml +0 -102
- data/gemfiles/rails6.gemfile +0 -30
- data/gemfiles/rails6_1.gemfile +0 -30
- data/gemspecs/arel_extensions-v1.gemspec +0 -28
- data/gemspecs/arel_extensions-v2.gemspec +0 -28
- data/generate_gems.sh +0 -15
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
- data/lib/arel_extensions/nodes/sum.rb +0 -7
- data/lib/arel_extensions/visitors/convert_format.rb +0 -37
- data/test/arelx_test_helper.rb +0 -26
- data/version_v1.rb +0 -3
- data/version_v2.rb +0 -3
@@ -1,23 +1,16 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
4
|
-
DATE_MAPPING = {
|
5
|
-
|
6
|
-
'h' => '%H', 'mn' => '%M', 's' => '%S'
|
7
|
-
}.freeze
|
8
|
-
|
9
|
-
DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
3
|
+
Arel::Visitors::SQLite.class_eval do
|
4
|
+
Arel::Visitors::SQLite::DATE_MAPPING = {'d' => '%d', 'm' => '%m', 'w' => '%W', 'y' => '%Y', 'wd' => '%w', 'M' => '%M', 'h' => '%H', 'mn' => '%M', 's' => '%S'}
|
5
|
+
Arel::Visitors::SQLite::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
10
6
|
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
11
7
|
'%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W', # day, weekday
|
12
8
|
'%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
|
13
9
|
'%M' => '%M', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => '' # seconds, subseconds
|
14
|
-
}
|
15
|
-
|
16
|
-
NUMBER_COMMA_MAPPING = {
|
17
|
-
'fr_FR' => {',' => ' ', '.' =>','}
|
18
|
-
}.freeze
|
10
|
+
}
|
11
|
+
Arel::Visitors::SQLite::NUMBER_COMMA_MAPPING = { 'fr_FR' => {',' => ' ','.' =>','} }
|
19
12
|
|
20
|
-
#
|
13
|
+
#String functions
|
21
14
|
def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
|
22
15
|
collector = visit o.left.ci_collate, collector
|
23
16
|
collector << ' LIKE '
|
@@ -80,6 +73,7 @@ module ArelExtensions
|
|
80
73
|
collector
|
81
74
|
end
|
82
75
|
|
76
|
+
|
83
77
|
def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
|
84
78
|
collector = visit o.left.lower, collector
|
85
79
|
collector << ' NOT LIKE '
|
@@ -96,15 +90,14 @@ module ArelExtensions
|
|
96
90
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
97
91
|
collector << "date("
|
98
92
|
collector = visit o.expressions.first, collector
|
99
|
-
collector << COMMA
|
93
|
+
collector << Arel::Visitors::SQLite::COMMA
|
100
94
|
collector = visit o.sqlite_value, collector
|
101
95
|
collector << ")"
|
102
96
|
collector
|
103
97
|
end
|
104
98
|
|
105
99
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
106
|
-
|
107
|
-
when :ruby_time, :datetime, :time
|
100
|
+
if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
108
101
|
collector << "strftime('%s', "
|
109
102
|
collector = visit o.left, collector
|
110
103
|
collector << ") - strftime('%s', "
|
@@ -120,16 +113,17 @@ module ArelExtensions
|
|
120
113
|
end
|
121
114
|
|
122
115
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
123
|
-
collector << "strftime('#{DATE_MAPPING[o.left]}'#{COMMA}"
|
116
|
+
collector << "strftime('#{Arel::Visitors::SQLite::DATE_MAPPING[o.left]}'#{Arel::Visitors::SQLite::COMMA}"
|
124
117
|
collector = visit o.right, collector
|
125
118
|
collector << ")"
|
126
119
|
collector
|
127
120
|
end
|
128
121
|
|
122
|
+
|
129
123
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
130
124
|
collector << "instr("
|
131
125
|
collector = visit o.expr, collector
|
132
|
-
collector << COMMA
|
126
|
+
collector << Arel::Visitors::SQLite::COMMA
|
133
127
|
collector = visit o.right, collector
|
134
128
|
collector << ")"
|
135
129
|
collector
|
@@ -148,7 +142,7 @@ module ArelExtensions
|
|
148
142
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
149
143
|
collector << "SUBSTR("
|
150
144
|
o.expressions.each_with_index { |arg, i|
|
151
|
-
collector << COMMA
|
145
|
+
collector << Arel::Visitors::SQLite::COMMA unless i == 0
|
152
146
|
collector = visit arg, collector
|
153
147
|
}
|
154
148
|
collector << ")"
|
@@ -171,7 +165,7 @@ module ArelExtensions
|
|
171
165
|
collector << "RANDOM("
|
172
166
|
if o.left != nil && o.right != nil
|
173
167
|
collector = visit o.left, collector
|
174
|
-
collector << COMMA
|
168
|
+
collector << Arel::Visitors::SQLite::COMMA
|
175
169
|
collector = visit o.right, collector
|
176
170
|
end
|
177
171
|
collector << ")"
|
@@ -199,28 +193,18 @@ module ArelExtensions
|
|
199
193
|
collector
|
200
194
|
end
|
201
195
|
|
202
|
-
#
|
203
|
-
#
|
204
|
-
# WHEN 3.42 >= 0 THEN CAST(3.42 AS INT)
|
205
|
-
# WHEN CAST(3.42 AS INT) = 3.42 THEN CAST(3.42 AS INT)
|
206
|
-
# ELSE CAST((3.42 - 1.0) AS INT)
|
207
|
-
# END
|
208
|
-
# AS FLOAT
|
209
|
-
# )
|
196
|
+
# CASE WHEN ROUND(3.42,1) > round(3.42) THEN round(3.42) ELSE round(3.42)-1 END
|
197
|
+
# OR CAST(3.14 AS INTEGER)
|
210
198
|
def visit_ArelExtensions_Nodes_Floor o, collector
|
211
|
-
collector << "
|
212
|
-
collector = visit o.left, collector
|
213
|
-
collector << " >= 0 THEN CAST("
|
214
|
-
collector = visit o.left, collector
|
215
|
-
collector << " AS INT) WHEN CAST("
|
199
|
+
collector << "CASE WHEN ROUND("
|
216
200
|
collector = visit o.left, collector
|
217
|
-
collector << "
|
201
|
+
collector << ", 1) > ROUND("
|
218
202
|
collector = visit o.left, collector
|
219
|
-
collector << " THEN
|
203
|
+
collector << ") THEN ROUND("
|
220
204
|
collector = visit o.left, collector
|
221
|
-
collector << "
|
205
|
+
collector << ") ELSE ROUND("
|
222
206
|
collector = visit o.left, collector
|
223
|
-
collector << " - 1
|
207
|
+
collector << ") - 1 END"
|
224
208
|
collector
|
225
209
|
end
|
226
210
|
|
@@ -241,8 +225,9 @@ module ArelExtensions
|
|
241
225
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
242
226
|
o.left.each_with_index do |row, idx|
|
243
227
|
collector << 'SELECT '
|
244
|
-
|
245
|
-
|
228
|
+
v = Arel::Nodes::Values.new(row, o.cols)
|
229
|
+
len = v.expressions.length - 1
|
230
|
+
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
246
231
|
case value
|
247
232
|
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
248
233
|
collector = visit value.as(attr.name), collector
|
@@ -253,7 +238,7 @@ module ArelExtensions
|
|
253
238
|
collector << quote(attr.name)
|
254
239
|
end
|
255
240
|
end
|
256
|
-
collector << COMMA unless i == len
|
241
|
+
collector << Arel::Visitors::SQLite::COMMA unless i == len
|
257
242
|
}
|
258
243
|
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
259
244
|
end
|
@@ -264,24 +249,19 @@ module ArelExtensions
|
|
264
249
|
o.left.each_with_index do |row, idx|
|
265
250
|
collector << 'SELECT '
|
266
251
|
len = row.length - 1
|
267
|
-
row.
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
else
|
278
|
-
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
279
|
-
if idx == 0
|
280
|
-
collector << " AS "
|
281
|
-
collector << quote(attr.name)
|
282
|
-
end
|
252
|
+
row.each_with_index { |value, i|
|
253
|
+
attr = o.cols[i]
|
254
|
+
case value
|
255
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
256
|
+
collector = visit value.as(attr.name), collector
|
257
|
+
else
|
258
|
+
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
259
|
+
if idx == 0
|
260
|
+
collector << " AS "
|
261
|
+
collector << quote(attr.name)
|
283
262
|
end
|
284
|
-
|
263
|
+
end
|
264
|
+
collector << Arel::Visitors::SQLite::COMMA unless i == len
|
285
265
|
}
|
286
266
|
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
287
267
|
end
|
@@ -290,36 +270,32 @@ module ArelExtensions
|
|
290
270
|
end
|
291
271
|
|
292
272
|
def visit_ArelExtensions_Nodes_Union o, collector
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
end
|
273
|
+
if o.left.is_a?(Arel::SelectManager)
|
274
|
+
collector = visit o.left.ast, collector
|
275
|
+
else
|
276
|
+
collector = visit o.left, collector
|
277
|
+
end
|
299
278
|
collector << " UNION "
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
end
|
279
|
+
if o.right.is_a?(Arel::SelectManager)
|
280
|
+
collector = visit o.right.ast, collector
|
281
|
+
else
|
282
|
+
collector = visit o.right, collector
|
283
|
+
end
|
306
284
|
collector
|
307
285
|
end
|
308
286
|
|
309
287
|
def visit_ArelExtensions_Nodes_UnionAll o, collector
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
end
|
288
|
+
if o.left.is_a?(Arel::SelectManager)
|
289
|
+
collector = visit o.left.ast, collector
|
290
|
+
else
|
291
|
+
collector = visit o.left, collector
|
292
|
+
end
|
316
293
|
collector << " UNION ALL "
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
end
|
294
|
+
if o.right.is_a?(Arel::SelectManager)
|
295
|
+
collector = visit o.right.ast, collector
|
296
|
+
else
|
297
|
+
collector = visit o.right, collector
|
298
|
+
end
|
323
299
|
collector
|
324
300
|
end
|
325
301
|
|
@@ -370,7 +346,17 @@ module ArelExtensions
|
|
370
346
|
collector
|
371
347
|
end
|
372
348
|
|
373
|
-
|
349
|
+
|
350
|
+
alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
|
351
|
+
def visit_Arel_Nodes_SelectStatement o, collector
|
352
|
+
if !collector.value.blank? && o.limit.blank?
|
353
|
+
o = o.dup
|
354
|
+
o.orders = []
|
355
|
+
end
|
356
|
+
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
357
|
+
end
|
358
|
+
|
359
|
+
alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
|
374
360
|
def visit_Arel_Nodes_As o, collector
|
375
361
|
if o.left.is_a?(Arel::Nodes::Binary)
|
376
362
|
collector << '('
|
@@ -387,13 +373,14 @@ module ArelExtensions
|
|
387
373
|
|
388
374
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
389
375
|
format = Arel::Nodes::NamedFunction.new('printf',[Arel::Nodes.build_quoted(o.original_string),o.left])
|
390
|
-
locale_map = NUMBER_COMMA_MAPPING[o.locale]
|
376
|
+
locale_map = Arel::Visitors::SQLite::NUMBER_COMMA_MAPPING[o.locale]
|
391
377
|
if locale_map
|
392
378
|
format = format.replace(',',locale_map[',']).replace('.',locale_map['.'])
|
393
379
|
end
|
394
380
|
visit format, collector
|
395
381
|
collector
|
396
382
|
end
|
383
|
+
|
397
384
|
end
|
398
385
|
end
|
399
386
|
end
|
@@ -1,22 +1,13 @@
|
|
1
1
|
module ArelExtensions
|
2
2
|
module Visitors
|
3
|
-
|
4
|
-
COMMA =
|
5
|
-
|
6
|
-
# Escape properly the string expression expr.
|
7
|
-
# Take care of escaping.
|
8
|
-
def make_json_string expr
|
9
|
-
Arel::Nodes.build_quoted('"') \
|
10
|
-
+ expr
|
11
|
-
.replace('\\','\\\\').replace('"','\"').replace("\n", '\n') \
|
12
|
-
+ '"'
|
13
|
-
end
|
3
|
+
Arel::Visitors::ToSql.class_eval do
|
4
|
+
Arel::Visitors::ToSql::COMMA = ", "
|
14
5
|
|
15
6
|
# Math Functions
|
16
7
|
def visit_ArelExtensions_Nodes_Abs o, collector
|
17
8
|
collector << "ABS("
|
18
9
|
o.expressions.each_with_index { |arg, i|
|
19
|
-
collector << COMMA
|
10
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
20
11
|
collector = visit arg, collector
|
21
12
|
}
|
22
13
|
collector << ")"
|
@@ -26,7 +17,7 @@ module ArelExtensions
|
|
26
17
|
def visit_ArelExtensions_Nodes_Ceil o, collector
|
27
18
|
collector << "CEIL("
|
28
19
|
o.expressions.each_with_index { |arg, i|
|
29
|
-
collector << COMMA
|
20
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
30
21
|
collector = visit arg, collector
|
31
22
|
}
|
32
23
|
collector << ")"
|
@@ -36,7 +27,7 @@ module ArelExtensions
|
|
36
27
|
def visit_ArelExtensions_Nodes_Floor o, collector
|
37
28
|
collector << "FLOOR("
|
38
29
|
o.expressions.each_with_index { |arg, i|
|
39
|
-
collector << COMMA
|
30
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
40
31
|
collector = visit arg, collector
|
41
32
|
}
|
42
33
|
collector << ")"
|
@@ -46,7 +37,7 @@ module ArelExtensions
|
|
46
37
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
47
38
|
collector << "RAND("
|
48
39
|
o.expressions.each_with_index { |arg, i|
|
49
|
-
collector << COMMA
|
40
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
50
41
|
collector = visit arg, collector
|
51
42
|
}
|
52
43
|
collector << ")"
|
@@ -56,43 +47,36 @@ module ArelExtensions
|
|
56
47
|
def visit_ArelExtensions_Nodes_Round o, collector
|
57
48
|
collector << "ROUND("
|
58
49
|
o.expressions.each_with_index { |arg, i|
|
59
|
-
collector << COMMA
|
50
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
60
51
|
collector = visit arg, collector
|
61
52
|
}
|
62
53
|
collector << ")"
|
63
54
|
collector
|
64
55
|
end
|
65
|
-
|
56
|
+
|
66
57
|
def visit_ArelExtensions_Nodes_Log10 o, collector
|
67
58
|
collector << "LOG10("
|
68
59
|
collector = visit o.left, collector
|
69
60
|
collector << ")"
|
70
61
|
collector
|
71
62
|
end
|
72
|
-
|
63
|
+
|
73
64
|
def visit_ArelExtensions_Nodes_Power o, collector
|
74
65
|
collector << "POW("
|
75
66
|
o.expressions.each_with_index { |arg, i|
|
76
|
-
collector << COMMA
|
67
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
77
68
|
collector = visit arg, collector
|
78
69
|
}
|
79
70
|
collector << ")"
|
80
71
|
collector
|
81
72
|
end
|
82
73
|
|
83
|
-
def visit_ArelExtensions_Nodes_Sum o, collector
|
84
|
-
collector << "SUM("
|
85
|
-
collector = visit o.expr, collector
|
86
|
-
collector << ")"
|
87
|
-
collector
|
88
|
-
end
|
89
|
-
|
90
74
|
# String functions
|
91
75
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
92
76
|
collector << "CONCAT("
|
93
|
-
|
94
|
-
|
95
|
-
|
77
|
+
o.expressions.each_with_index { |arg, i|
|
78
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
79
|
+
collector = visit arg, collector
|
96
80
|
}
|
97
81
|
collector << ")"
|
98
82
|
collector
|
@@ -101,9 +85,9 @@ module ArelExtensions
|
|
101
85
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
102
86
|
collector << "GROUP_CONCAT("
|
103
87
|
collector = visit o.left, collector
|
104
|
-
if o.
|
105
|
-
collector << COMMA
|
106
|
-
collector = visit o.
|
88
|
+
if o.right && o.right != 'NULL'
|
89
|
+
collector << Arel::Visitors::ToSql::COMMA
|
90
|
+
collector = visit o.right, collector
|
107
91
|
end
|
108
92
|
collector << ")"
|
109
93
|
collector
|
@@ -126,7 +110,7 @@ module ArelExtensions
|
|
126
110
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
127
111
|
collector << "LOCATE("
|
128
112
|
collector = visit o.right, collector
|
129
|
-
collector << COMMA
|
113
|
+
collector << Arel::Visitors::ToSql::COMMA
|
130
114
|
collector = visit o.left, collector
|
131
115
|
collector << ")"
|
132
116
|
collector
|
@@ -135,7 +119,7 @@ module ArelExtensions
|
|
135
119
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
136
120
|
collector << "SUBSTRING("
|
137
121
|
o.expressions.each_with_index { |arg, i|
|
138
|
-
collector << COMMA
|
122
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
139
123
|
collector = visit arg, collector
|
140
124
|
}
|
141
125
|
collector << ")"
|
@@ -144,30 +128,18 @@ module ArelExtensions
|
|
144
128
|
|
145
129
|
def visit_ArelExtensions_Nodes_Replace o, collector
|
146
130
|
collector << "REPLACE("
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
visit o.substitute, collector
|
152
|
-
collector << ")"
|
153
|
-
collector
|
154
|
-
end
|
155
|
-
|
156
|
-
def visit_ArelExtensions_Nodes_RegexpReplace o, collector
|
157
|
-
collector << "REGEXP_REPLACE("
|
158
|
-
visit o.left, collector
|
159
|
-
collector << COMMA
|
160
|
-
visit Arel::Nodes.build_quoted(o.pattern.to_s), collector
|
161
|
-
collector << COMMA
|
162
|
-
visit o.substitute, collector
|
131
|
+
o.expressions.each_with_index { |arg, i|
|
132
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
133
|
+
collector = visit arg, collector
|
134
|
+
}
|
163
135
|
collector << ")"
|
164
136
|
collector
|
165
137
|
end
|
166
|
-
|
138
|
+
|
167
139
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
168
140
|
collector << "REPEAT("
|
169
141
|
o.expressions.each_with_index { |arg, i|
|
170
|
-
collector << COMMA
|
142
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
171
143
|
collector = visit arg, collector
|
172
144
|
}
|
173
145
|
collector << ")"
|
@@ -177,7 +149,7 @@ module ArelExtensions
|
|
177
149
|
def visit_ArelExtensions_Nodes_FindInSet o, collector
|
178
150
|
collector << "FIND_IN_SET("
|
179
151
|
o.expressions.each_with_index { |arg, i|
|
180
|
-
collector << COMMA
|
152
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
181
153
|
collector = visit arg, collector
|
182
154
|
}
|
183
155
|
collector << ")"
|
@@ -187,7 +159,7 @@ module ArelExtensions
|
|
187
159
|
def visit_ArelExtensions_Nodes_Soundex o, collector
|
188
160
|
collector << "SOUNDEX("
|
189
161
|
o.expressions.each_with_index { |arg, i|
|
190
|
-
collector << COMMA
|
162
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
191
163
|
collector = visit arg, collector
|
192
164
|
}
|
193
165
|
collector << ")"
|
@@ -197,7 +169,7 @@ module ArelExtensions
|
|
197
169
|
def visit_ArelExtensions_Nodes_Downcase o, collector
|
198
170
|
collector << "LOWER("
|
199
171
|
o.expressions.each_with_index { |arg, i|
|
200
|
-
collector << COMMA
|
172
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
201
173
|
collector = visit arg, collector
|
202
174
|
}
|
203
175
|
collector << ")"
|
@@ -207,7 +179,7 @@ module ArelExtensions
|
|
207
179
|
def visit_ArelExtensions_Nodes_Upcase o, collector
|
208
180
|
collector << "UPPER("
|
209
181
|
o.expressions.each_with_index { |arg, i|
|
210
|
-
collector << COMMA
|
182
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
211
183
|
collector = visit arg, collector
|
212
184
|
}
|
213
185
|
collector << ")"
|
@@ -217,7 +189,7 @@ module ArelExtensions
|
|
217
189
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
218
190
|
collector << "TRIM("
|
219
191
|
o.expressions.each_with_index { |arg, i|
|
220
|
-
collector << COMMA
|
192
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
221
193
|
collector = visit arg, collector
|
222
194
|
}
|
223
195
|
collector << ")"
|
@@ -227,7 +199,7 @@ module ArelExtensions
|
|
227
199
|
def visit_ArelExtensions_Nodes_Ltrim o, collector
|
228
200
|
collector << "LTRIM("
|
229
201
|
o.expressions.each_with_index { |arg, i|
|
230
|
-
collector << COMMA
|
202
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
231
203
|
collector = visit arg, collector
|
232
204
|
}
|
233
205
|
collector << ")"
|
@@ -237,7 +209,7 @@ module ArelExtensions
|
|
237
209
|
def visit_ArelExtensions_Nodes_Rtrim o, collector
|
238
210
|
collector << "RTRIM("
|
239
211
|
o.expressions.each_with_index { |arg, i|
|
240
|
-
collector << COMMA
|
212
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
241
213
|
collector = visit arg, collector
|
242
214
|
}
|
243
215
|
collector << ")"
|
@@ -245,20 +217,21 @@ module ArelExtensions
|
|
245
217
|
end
|
246
218
|
|
247
219
|
def visit_ArelExtensions_Nodes_Blank o, collector
|
248
|
-
|
220
|
+
#visit o.left.coalesce('').trim.length.eq(0), collector
|
249
221
|
collector << 'LENGTH(TRIM(COALESCE('
|
250
222
|
collector = visit o.expr, collector
|
251
|
-
collector << COMMA
|
223
|
+
collector << Arel::Visitors::ToSql::COMMA
|
252
224
|
collector = visit Arel::Nodes.build_quoted(''), collector
|
253
225
|
collector << "))) = 0"
|
254
226
|
collector
|
255
227
|
end
|
256
228
|
|
229
|
+
|
257
230
|
def visit_ArelExtensions_Nodes_NotBlank o, collector
|
258
|
-
|
231
|
+
#visit o.left.coalesce('').trim.length.gt(0), collector
|
259
232
|
collector << 'LENGTH(TRIM(COALESCE('
|
260
233
|
collector = visit o.expr, collector
|
261
|
-
collector << COMMA
|
234
|
+
collector << Arel::Visitors::ToSql::COMMA
|
262
235
|
collector = visit Arel::Nodes.build_quoted(''), collector
|
263
236
|
collector << "))) > 0"
|
264
237
|
collector
|
@@ -269,13 +242,13 @@ module ArelExtensions
|
|
269
242
|
when :date, :datetime, :time
|
270
243
|
collector << "STRFTIME("
|
271
244
|
collector = visit o.right, collector
|
272
|
-
collector << COMMA
|
245
|
+
collector << Arel::Visitors::ToSql::COMMA
|
273
246
|
collector = visit o.left, collector
|
274
247
|
collector << ")"
|
275
248
|
when :integer, :float, :decimal
|
276
249
|
collector << "FORMAT("
|
277
250
|
collector = visit o.left, collector
|
278
|
-
collector << COMMA
|
251
|
+
collector << Arel::Visitors::ToSql::COMMA
|
279
252
|
collector = visit o.right, collector
|
280
253
|
collector << ")"
|
281
254
|
else
|
@@ -284,7 +257,7 @@ module ArelExtensions
|
|
284
257
|
collector
|
285
258
|
end
|
286
259
|
|
287
|
-
#
|
260
|
+
#comparators
|
288
261
|
|
289
262
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
290
263
|
collector << "CAST("
|
@@ -297,14 +270,12 @@ module ArelExtensions
|
|
297
270
|
as_attr = Arel::Nodes::SqlLiteral.new('int')
|
298
271
|
when :decimal, :float, :number
|
299
272
|
as_attr = Arel::Nodes::SqlLiteral.new('float')
|
300
|
-
when :datetime
|
273
|
+
when :datetime
|
301
274
|
as_attr = Arel::Nodes::SqlLiteral.new('datetime')
|
302
275
|
when :time
|
303
276
|
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
304
|
-
when :binary
|
305
|
-
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
306
|
-
when :text, :ntext
|
307
|
-
as_attr = Arel::Nodes::SqlLiteral.new('text')
|
277
|
+
when :binary
|
278
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
308
279
|
else
|
309
280
|
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
310
281
|
end
|
@@ -316,7 +287,7 @@ module ArelExtensions
|
|
316
287
|
def visit_ArelExtensions_Nodes_Coalesce o, collector
|
317
288
|
collector << "COALESCE("
|
318
289
|
o.expressions.each_with_index { |arg, i|
|
319
|
-
collector << COMMA
|
290
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
320
291
|
collector = visit arg, collector
|
321
292
|
}
|
322
293
|
collector << ")"
|
@@ -330,27 +301,24 @@ module ArelExtensions
|
|
330
301
|
'DATEDIFF('
|
331
302
|
end
|
332
303
|
collector = visit o.left, collector
|
333
|
-
collector << COMMA
|
304
|
+
collector << Arel::Visitors::ToSql::COMMA
|
334
305
|
collector = visit o.right, collector
|
335
306
|
collector << ")"
|
336
307
|
collector
|
337
308
|
end
|
338
|
-
|
309
|
+
|
339
310
|
def visit_ArelExtensions_Nodes_DateSub o, collector
|
340
311
|
collector << "DATE_SUB("
|
341
312
|
collector = visit o.left, collector
|
342
|
-
collector << COMMA
|
313
|
+
collector << Arel::Visitors::ToSql::COMMA
|
343
314
|
collector = visit o.right, collector
|
344
315
|
collector << ")"
|
345
316
|
collector
|
346
317
|
end
|
347
318
|
|
348
|
-
|
319
|
+
# override
|
349
320
|
remove_method(:visit_Arel_Nodes_As) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_As)
|
350
321
|
def visit_Arel_Nodes_As o, collector
|
351
|
-
if o.left.respond_to?(:alias)
|
352
|
-
o.left.alias = nil
|
353
|
-
end
|
354
322
|
if o.left.is_a?(Arel::Nodes::Binary)
|
355
323
|
collector << '('
|
356
324
|
collector = visit o.left, collector
|
@@ -417,7 +385,7 @@ module ArelExtensions
|
|
417
385
|
collector = visit o.left, collector
|
418
386
|
collector << ") THEN "
|
419
387
|
collector = visit o.right, collector
|
420
|
-
if o.expressions[2]
|
388
|
+
if o.expressions[2]
|
421
389
|
collector << " ELSE "
|
422
390
|
collector = visit o.expressions[2], collector
|
423
391
|
end
|
@@ -429,7 +397,7 @@ module ArelExtensions
|
|
429
397
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
430
398
|
collector << "DATE_ADD("
|
431
399
|
collector = visit o.left, collector
|
432
|
-
collector << COMMA
|
400
|
+
collector << Arel::Visitors::ToSql::COMMA
|
433
401
|
collector = visit o.sqlite_value(o.right), collector
|
434
402
|
collector << ')'
|
435
403
|
collector
|
@@ -441,15 +409,16 @@ module ArelExtensions
|
|
441
409
|
row_nb = o.left.length
|
442
410
|
o.left.each_with_index do |row, idx|
|
443
411
|
collector << '('
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
412
|
+
v = Arel::Nodes::Values.new(row, o.cols)
|
413
|
+
len = v.expressions.length - 1
|
414
|
+
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
415
|
+
case value
|
416
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
417
|
+
collector = visit value, collector
|
418
|
+
else
|
419
|
+
collector << quote(value, attr && column_for(attr)).to_s
|
420
|
+
end
|
421
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == len
|
453
422
|
}
|
454
423
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
455
424
|
end
|
@@ -462,16 +431,15 @@ module ArelExtensions
|
|
462
431
|
o.left.each_with_index do |row, idx|
|
463
432
|
collector << '('
|
464
433
|
len = row.length - 1
|
465
|
-
row.
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
collector << COMMA unless i == len
|
434
|
+
row.each_with_index { |value, i|
|
435
|
+
attr = o.cols[i]
|
436
|
+
case value
|
437
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
438
|
+
collector = visit value, collector
|
439
|
+
else
|
440
|
+
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
441
|
+
end
|
442
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == len
|
475
443
|
}
|
476
444
|
collector << (idx == row_nb-1 ? ')' : '), ')
|
477
445
|
end
|
@@ -485,7 +453,7 @@ module ArelExtensions
|
|
485
453
|
collector = visit o.right, collector
|
486
454
|
collector
|
487
455
|
end
|
488
|
-
|
456
|
+
|
489
457
|
def visit_ArelExtensions_Nodes_UnionAll o, collector
|
490
458
|
collector = visit o.left, collector
|
491
459
|
collector << " UNION ALL "
|
@@ -522,25 +490,25 @@ module ArelExtensions
|
|
522
490
|
visit Arel::Nodes.build_quoted(o.expr), collector
|
523
491
|
end
|
524
492
|
|
525
|
-
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
493
|
+
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
526
494
|
visit o.left, collector
|
527
495
|
end
|
528
|
-
|
529
|
-
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
496
|
+
|
497
|
+
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
530
498
|
def visit_Arel_Nodes_LessThan o, collector
|
531
499
|
collector = visit o.left, collector
|
532
500
|
collector << " < "
|
533
501
|
visit o.right, collector
|
534
502
|
end
|
535
|
-
|
536
|
-
def visit_ArelExtensions_Nodes_Std o, collector
|
503
|
+
|
504
|
+
def visit_ArelExtensions_Nodes_Std o, collector
|
537
505
|
collector << "STD("
|
538
506
|
visit o.left, collector
|
539
507
|
collector << ")"
|
540
508
|
collector
|
541
509
|
end
|
542
|
-
|
543
|
-
def visit_ArelExtensions_Nodes_Variance o, collector
|
510
|
+
|
511
|
+
def visit_ArelExtensions_Nodes_Variance o, collector
|
544
512
|
collector << "VARIANCE("
|
545
513
|
visit o.left, collector
|
546
514
|
collector << ")"
|
@@ -550,19 +518,17 @@ module ArelExtensions
|
|
550
518
|
def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
|
551
519
|
collector << "LEVENSHTEIN_DISTANCE("
|
552
520
|
collector = visit o.left, collector
|
553
|
-
collector << COMMA
|
521
|
+
collector << Arel::Visitors::ToSql::COMMA
|
554
522
|
collector = visit o.right, collector
|
555
523
|
collector << ')'
|
556
524
|
collector
|
557
525
|
end
|
558
526
|
|
559
|
-
|
560
|
-
|
561
|
-
alias_method(:old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And) rescue nil
|
527
|
+
alias_method :old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And
|
562
528
|
def visit_Arel_Nodes_And o, collector
|
563
529
|
case o.children.length
|
564
530
|
when 0
|
565
|
-
collector << '1
|
531
|
+
collector << '1=1' # but this should not happen
|
566
532
|
when 1
|
567
533
|
collector = visit o.children[0], collector
|
568
534
|
else
|
@@ -578,11 +544,10 @@ module ArelExtensions
|
|
578
544
|
collector
|
579
545
|
end
|
580
546
|
|
581
|
-
|
582
|
-
def visit_Arel_Nodes_Or o, collector
|
547
|
+
def visit_ArelExtensions_Nodes_Or o, collector
|
583
548
|
case o.children.length
|
584
549
|
when 0
|
585
|
-
collector << '1
|
550
|
+
collector << '0=1' # but this should not happen
|
586
551
|
when 1
|
587
552
|
collector = visit o.children[0], collector
|
588
553
|
else
|
@@ -598,24 +563,14 @@ module ArelExtensions
|
|
598
563
|
collector
|
599
564
|
end
|
600
565
|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
s = v.format('%Y-%m-%dT%H:%M:%S')
|
610
|
-
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
611
|
-
when :time
|
612
|
-
s = v.format('%H:%M:%S')
|
613
|
-
Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
|
614
|
-
when :nil
|
615
|
-
Arel::Nodes.build_quoted("null")
|
616
|
-
else
|
617
|
-
ArelExtensions::Nodes::Cast.new([v, :string]).coalesce("null")
|
618
|
-
end
|
566
|
+
alias_method :old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or
|
567
|
+
def visit_Arel_Nodes_Or o, collector
|
568
|
+
collector << '('
|
569
|
+
collector = visit o.left, collector
|
570
|
+
collector << ') OR ('
|
571
|
+
collector = visit o.right, collector
|
572
|
+
collector << ')'
|
573
|
+
collector
|
619
574
|
end
|
620
575
|
|
621
576
|
def visit_ArelExtensions_Nodes_Json o,collector
|
@@ -626,7 +581,11 @@ module ArelExtensions
|
|
626
581
|
if i != 0
|
627
582
|
res += ', '
|
628
583
|
end
|
629
|
-
|
584
|
+
if (v.is_a?(Arel::Attributes::Attribute) && o.type_of_attribute(v) == :string) || (v.return_type == :string)
|
585
|
+
res = res + '"' + v + '"'
|
586
|
+
else
|
587
|
+
res += v
|
588
|
+
end
|
630
589
|
end
|
631
590
|
res += ']'
|
632
591
|
collector = visit res, collector
|
@@ -636,8 +595,12 @@ module ArelExtensions
|
|
636
595
|
if i != 0
|
637
596
|
res += ', '
|
638
597
|
end
|
639
|
-
res +=
|
640
|
-
|
598
|
+
res += Arel::Nodes.build_quoted('"')+k + '": '
|
599
|
+
if (v.is_a?(Arel::Attributes::Attribute) && o.type_of_attribute(v) == :string) || (v.respond_to?(:return_type) && v.return_type == :string)
|
600
|
+
res = res + '"' + v + '"'
|
601
|
+
else
|
602
|
+
res += v
|
603
|
+
end
|
641
604
|
end
|
642
605
|
res += '}'
|
643
606
|
collector = visit res, collector
|
@@ -649,7 +612,7 @@ module ArelExtensions
|
|
649
612
|
|
650
613
|
def visit_ArelExtensions_Nodes_JsonGroup o, collector
|
651
614
|
if o.as_array
|
652
|
-
res = Arel::Nodes.build_quoted('[') + (o.orders ? o.dict.group_concat(', ',
|
615
|
+
res = Arel::Nodes.build_quoted('[') + (o.orders ? o.dict.group_concat(', ',o.orders) : o.dict.group_concat(', ')) + ']'
|
653
616
|
collector = visit res, collector
|
654
617
|
else
|
655
618
|
res = Arel::Nodes.build_quoted('{')
|
@@ -658,15 +621,20 @@ module ArelExtensions
|
|
658
621
|
if i != 0
|
659
622
|
res = res + ', '
|
660
623
|
end
|
661
|
-
kv =
|
662
|
-
|
663
|
-
|
624
|
+
kv = Arel::Nodes.build_quoted('"')+k + '": '
|
625
|
+
if (v.is_a?(Arel::Attributes::Attribute) && o.type_of_attribute(v) == :string) || (v.respond_to?(:return_type) && v.return_type == :string)
|
626
|
+
kv = kv + '"' + v + '"'
|
627
|
+
else
|
628
|
+
kv += v
|
629
|
+
end
|
630
|
+
res = res + kv.group_concat(', ',orders)
|
664
631
|
end
|
665
632
|
res = res + '}'
|
666
633
|
collector = visit res, collector
|
667
634
|
end
|
668
635
|
collector
|
669
636
|
end
|
637
|
+
|
670
638
|
end
|
671
639
|
end
|
672
640
|
end
|