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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -7
  3. data/.travis.yml +91 -61
  4. data/Gemfile +20 -15
  5. data/README.md +12 -17
  6. data/Rakefile +29 -40
  7. data/appveyor.yml +1 -1
  8. data/arel_extensions.gemspec +3 -3
  9. data/functions.html +3 -3
  10. data/gemfiles/rails3.gemfile +9 -9
  11. data/gemfiles/rails4.gemfile +13 -13
  12. data/gemfiles/rails5_0.gemfile +13 -13
  13. data/gemfiles/rails5_1_4.gemfile +13 -13
  14. data/gemfiles/rails5_2.gemfile +13 -13
  15. data/init/mssql.sql +4 -4
  16. data/init/mysql.sql +38 -38
  17. data/init/postgresql.sql +21 -21
  18. data/lib/arel_extensions.rb +19 -69
  19. data/lib/arel_extensions/attributes.rb +1 -0
  20. data/lib/arel_extensions/boolean_functions.rb +14 -55
  21. data/lib/arel_extensions/common_sql_functions.rb +8 -7
  22. data/lib/arel_extensions/comparators.rb +15 -14
  23. data/lib/arel_extensions/date_duration.rb +5 -4
  24. data/lib/arel_extensions/insert_manager.rb +16 -17
  25. data/lib/arel_extensions/math.rb +12 -11
  26. data/lib/arel_extensions/math_functions.rb +22 -29
  27. data/lib/arel_extensions/nodes.rb +1 -1
  28. data/lib/arel_extensions/nodes/abs.rb +1 -0
  29. data/lib/arel_extensions/nodes/blank.rb +1 -0
  30. data/lib/arel_extensions/nodes/case.rb +8 -11
  31. data/lib/arel_extensions/nodes/cast.rb +2 -4
  32. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  33. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  34. data/lib/arel_extensions/nodes/coalesce.rb +3 -2
  35. data/lib/arel_extensions/nodes/collate.rb +2 -1
  36. data/lib/arel_extensions/nodes/concat.rb +16 -7
  37. data/lib/arel_extensions/nodes/date_diff.rb +13 -10
  38. data/lib/arel_extensions/nodes/duration.rb +3 -0
  39. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  40. data/lib/arel_extensions/nodes/floor.rb +1 -1
  41. data/lib/arel_extensions/nodes/format.rb +8 -34
  42. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  43. data/lib/arel_extensions/nodes/function.rb +16 -25
  44. data/lib/arel_extensions/nodes/json.rb +36 -43
  45. data/lib/arel_extensions/nodes/length.rb +1 -0
  46. data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
  47. data/lib/arel_extensions/nodes/locate.rb +1 -0
  48. data/lib/arel_extensions/nodes/log10.rb +2 -1
  49. data/lib/arel_extensions/nodes/matches.rb +6 -4
  50. data/lib/arel_extensions/nodes/md5.rb +1 -0
  51. data/lib/arel_extensions/nodes/power.rb +5 -5
  52. data/lib/arel_extensions/nodes/rand.rb +1 -0
  53. data/lib/arel_extensions/nodes/repeat.rb +4 -2
  54. data/lib/arel_extensions/nodes/replace.rb +6 -22
  55. data/lib/arel_extensions/nodes/round.rb +6 -5
  56. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  57. data/lib/arel_extensions/nodes/std.rb +21 -18
  58. data/lib/arel_extensions/nodes/substring.rb +16 -8
  59. data/lib/arel_extensions/nodes/then.rb +0 -0
  60. data/lib/arel_extensions/nodes/trim.rb +5 -3
  61. data/lib/arel_extensions/nodes/union.rb +5 -2
  62. data/lib/arel_extensions/nodes/union_all.rb +3 -0
  63. data/lib/arel_extensions/nodes/wday.rb +4 -0
  64. data/lib/arel_extensions/null_functions.rb +7 -5
  65. data/lib/arel_extensions/predications.rb +34 -35
  66. data/lib/arel_extensions/railtie.rb +5 -5
  67. data/lib/arel_extensions/set_functions.rb +4 -2
  68. data/lib/arel_extensions/string_functions.rb +22 -43
  69. data/lib/arel_extensions/tasks.rb +5 -5
  70. data/lib/arel_extensions/version.rb +1 -1
  71. data/lib/arel_extensions/visitors.rb +60 -68
  72. data/lib/arel_extensions/visitors/ibm_db.rb +12 -5
  73. data/lib/arel_extensions/visitors/mssql.rb +57 -63
  74. data/lib/arel_extensions/visitors/mysql.rb +98 -149
  75. data/lib/arel_extensions/visitors/oracle.rb +68 -71
  76. data/lib/arel_extensions/visitors/oracle12.rb +15 -2
  77. data/lib/arel_extensions/visitors/postgresql.rb +63 -116
  78. data/lib/arel_extensions/visitors/sqlite.rb +70 -83
  79. data/lib/arel_extensions/visitors/to_sql.rb +109 -141
  80. data/test/database.yml +0 -2
  81. data/test/helper.rb +18 -0
  82. data/test/real_db_test.rb +43 -28
  83. data/test/support/fake_record.rb +2 -2
  84. data/test/test_comparators.rb +12 -9
  85. data/test/visitors/test_bulk_insert_oracle.rb +8 -8
  86. data/test/visitors/test_bulk_insert_sqlite.rb +10 -9
  87. data/test/visitors/test_bulk_insert_to_sql.rb +10 -8
  88. data/test/visitors/test_oracle.rb +42 -42
  89. data/test/visitors/test_to_sql.rb +196 -361
  90. data/test/with_ar/all_agnostic_test.rb +160 -195
  91. data/test/with_ar/insert_agnostic_test.rb +4 -3
  92. data/test/with_ar/test_bulk_sqlite.rb +9 -6
  93. data/test/with_ar/test_math_sqlite.rb +12 -8
  94. data/test/with_ar/test_string_mysql.rb +11 -5
  95. data/test/with_ar/test_string_sqlite.rb +12 -4
  96. metadata +11 -22
  97. data/.github/workflows/ruby.yml +0 -102
  98. data/gemfiles/rails6.gemfile +0 -30
  99. data/gemfiles/rails6_1.gemfile +0 -30
  100. data/gemspecs/arel_extensions-v1.gemspec +0 -28
  101. data/gemspecs/arel_extensions-v2.gemspec +0 -28
  102. data/generate_gems.sh +0 -15
  103. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  104. data/lib/arel_extensions/nodes/sum.rb +0 -7
  105. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  106. data/test/arelx_test_helper.rb +0 -26
  107. data/version_v1.rb +0 -3
  108. data/version_v2.rb +0 -3
@@ -1,23 +1,16 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- class Arel::Visitors::SQLite
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
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
- }.freeze
15
-
16
- NUMBER_COMMA_MAPPING = {
17
- 'fr_FR' => {',' => ' ', '.' =>','}
18
- }.freeze
10
+ }
11
+ Arel::Visitors::SQLite::NUMBER_COMMA_MAPPING = { 'fr_FR' => {',' => ' ','.' =>','} }
19
12
 
20
- # String functions
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
- case o.left_node_type
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 if i != 0
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
- # CAST(
203
- # CASE
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 << "CAST(CASE WHEN "
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 << " AS INT) = "
201
+ collector << ", 1) > ROUND("
218
202
  collector = visit o.left, collector
219
- collector << " THEN CAST("
203
+ collector << ") THEN ROUND("
220
204
  collector = visit o.left, collector
221
- collector << " AS INT) ELSE CAST(("
205
+ collector << ") ELSE ROUND("
222
206
  collector = visit o.left, collector
223
- collector << " - 1.0) AS INT) END AS FLOAT)"
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
- len = row.length - 1
245
- row.zip(o.cols).each_with_index { |(value, attr), i|
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.zip(o.cols).each_with_index { |(value, attr), i|
268
- case value
269
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
270
- collector = visit value.as(attr.name), collector
271
- when Integer
272
- collector << value.to_s
273
- if idx == 0
274
- collector << " AS "
275
- collector << quote(attr.name)
276
- end
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
- collector << COMMA unless i == len
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
- collector =
294
- if o.left.is_a?(Arel::SelectManager)
295
- visit o.left.ast, collector
296
- else
297
- visit o.left, collector
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
- collector =
301
- if o.right.is_a?(Arel::SelectManager)
302
- visit o.right.ast, collector
303
- else
304
- visit o.right, collector
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
- collector =
311
- if o.left.is_a?(Arel::SelectManager)
312
- visit o.left.ast, collector
313
- else
314
- visit o.left, collector
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
- collector =
318
- if o.right.is_a?(Arel::SelectManager)
319
- visit o.right.ast, collector
320
- else
321
- visit o.right, collector
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
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
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
- class Arel::Visitors::ToSql
4
- COMMA = ', ' unless defined?(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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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
- o.expressions.each_with_index { |arg, i|
94
- collector << COMMA if i != 0
95
- collector = visit arg, collector
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.separator && o.separator != 'NULL'
105
- collector << COMMA
106
- collector = visit o.separator, collector
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 if i != 0
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
- visit o.left, collector
148
- collector << COMMA
149
- visit o.pattern, collector
150
- collector << COMMA
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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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 if i != 0
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
- # visit o.left.coalesce('').trim.length.eq(0), collector
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
- # visit o.left.coalesce('').trim.length.gt(0), collector
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
- # comparators
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 if i != 0
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
- # override
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
- len = row.length - 1
445
- row.zip(o.cols).each_with_index { |(value, attr), i|
446
- case value
447
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
448
- collector = visit value, collector
449
- else
450
- collector << quote(value, attr && column_for(attr)).to_s
451
- end
452
- collector << COMMA unless i == len
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.zip(o.cols).each_with_index { |(value, attr), i|
466
- case value
467
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
468
- collector = visit value, collector
469
- when Integer
470
- collector << value.to_s
471
- else
472
- collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
473
- end
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
- # Boolean logic.
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 = 1' # but this should not happen
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
- alias_method(:old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or) rescue nil
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 = 0' # but this should not happen
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
- def json_value(o,v)
602
- case o.type_of_node(v)
603
- when :string
604
- Arel.when(v.is_null).then(Arel::Nodes.build_quoted("null")).else(make_json_string(v))
605
- when :date
606
- s = v.format('%Y-%m-%d')
607
- Arel.when(s.is_null).then(Arel::Nodes.build_quoted("null")).else(Arel::Nodes.build_quoted('"') + s + '"')
608
- when :datetime
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
- res += json_value(o,v)
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 += make_json_string(ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("")) + ': '
640
- res += json_value(o,v)
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(', ', order: Array(o.orders)) : o.dict.group_concat(', ')).coalesce('') + ']'
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 = make_json_string(ArelExtensions::Nodes::Cast.new([k, :string]).coalesce("")) + ': '
662
- kv += json_value(o,v)
663
- res = res + kv.group_concat(', ', order: Array(orders)).coalesce('')
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