arel_extensions 2.0.9 → 2.0.14

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