arel_extensions 1.2.23 → 2.0.0.rc3
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/.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
|