arel_extensions 1.2.14 → 1.2.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +102 -0
  3. data/.travis.yml +2 -0
  4. data/Gemfile +10 -10
  5. data/Rakefile +4 -4
  6. data/arel_extensions.gemspec +1 -1
  7. data/gemfiles/rails3.gemfile +9 -9
  8. data/gemfiles/rails4.gemfile +13 -13
  9. data/gemfiles/rails5_0.gemfile +13 -13
  10. data/gemfiles/rails5_1_4.gemfile +13 -13
  11. data/gemfiles/rails5_2.gemfile +13 -13
  12. data/gemfiles/rails6.gemfile +13 -13
  13. data/gemfiles/rails6_1.gemfile +30 -0
  14. data/gemspecs/arel_extensions-v1.gemspec +28 -0
  15. data/{gemspec_v2 → gemspecs}/arel_extensions-v2.gemspec +0 -0
  16. data/generate_gems.sh +4 -3
  17. data/lib/arel_extensions.rb +6 -4
  18. data/lib/arel_extensions/attributes.rb +0 -0
  19. data/lib/arel_extensions/boolean_functions.rb +21 -5
  20. data/lib/arel_extensions/common_sql_functions.rb +2 -4
  21. data/lib/arel_extensions/comparators.rb +11 -14
  22. data/lib/arel_extensions/date_duration.rb +4 -5
  23. data/lib/arel_extensions/insert_manager.rb +16 -17
  24. data/lib/arel_extensions/math.rb +8 -9
  25. data/lib/arel_extensions/math_functions.rb +18 -20
  26. data/lib/arel_extensions/nodes/abs.rb +0 -1
  27. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
  28. data/lib/arel_extensions/nodes/blank.rb +0 -1
  29. data/lib/arel_extensions/nodes/case.rb +3 -4
  30. data/lib/arel_extensions/nodes/cast.rb +4 -2
  31. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  32. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  33. data/lib/arel_extensions/nodes/coalesce.rb +0 -1
  34. data/lib/arel_extensions/nodes/collate.rb +0 -1
  35. data/lib/arel_extensions/nodes/concat.rb +2 -4
  36. data/lib/arel_extensions/nodes/date_diff.rb +7 -8
  37. data/lib/arel_extensions/nodes/duration.rb +0 -1
  38. data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
  39. data/lib/arel_extensions/nodes/floor.rb +1 -1
  40. data/lib/arel_extensions/nodes/format.rb +27 -1
  41. data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
  42. data/lib/arel_extensions/nodes/function.rb +18 -15
  43. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  44. data/lib/arel_extensions/nodes/json.rb +39 -30
  45. data/lib/arel_extensions/nodes/length.rb +0 -1
  46. data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
  47. data/lib/arel_extensions/nodes/locate.rb +0 -1
  48. data/lib/arel_extensions/nodes/log10.rb +1 -2
  49. data/lib/arel_extensions/nodes/matches.rb +0 -2
  50. data/lib/arel_extensions/nodes/md5.rb +0 -1
  51. data/lib/arel_extensions/nodes/power.rb +0 -1
  52. data/lib/arel_extensions/nodes/rand.rb +0 -1
  53. data/lib/arel_extensions/nodes/repeat.rb +0 -2
  54. data/lib/arel_extensions/nodes/replace.rb +0 -2
  55. data/lib/arel_extensions/nodes/round.rb +0 -1
  56. data/lib/arel_extensions/nodes/soundex.rb +0 -1
  57. data/lib/arel_extensions/nodes/std.rb +4 -5
  58. data/lib/arel_extensions/nodes/substring.rb +0 -1
  59. data/lib/arel_extensions/nodes/sum.rb +0 -0
  60. data/lib/arel_extensions/nodes/then.rb +0 -0
  61. data/lib/arel_extensions/nodes/trim.rb +0 -2
  62. data/lib/arel_extensions/nodes/union.rb +0 -2
  63. data/lib/arel_extensions/nodes/union_all.rb +0 -2
  64. data/lib/arel_extensions/nodes/wday.rb +0 -4
  65. data/lib/arel_extensions/null_functions.rb +3 -5
  66. data/lib/arel_extensions/predications.rb +5 -6
  67. data/lib/arel_extensions/railtie.rb +5 -5
  68. data/lib/arel_extensions/set_functions.rb +0 -2
  69. data/lib/arel_extensions/string_functions.rb +21 -22
  70. data/lib/arel_extensions/tasks.rb +1 -1
  71. data/lib/arel_extensions/version.rb +1 -1
  72. data/lib/arel_extensions/visitors.rb +68 -60
  73. data/lib/arel_extensions/visitors/convert_format.rb +37 -0
  74. data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
  75. data/lib/arel_extensions/visitors/mssql.rb +49 -44
  76. data/lib/arel_extensions/visitors/mysql.rb +65 -67
  77. data/lib/arel_extensions/visitors/oracle.rb +58 -55
  78. data/lib/arel_extensions/visitors/oracle12.rb +2 -3
  79. data/lib/arel_extensions/visitors/postgresql.rb +41 -34
  80. data/lib/arel_extensions/visitors/sqlite.rb +23 -18
  81. data/lib/arel_extensions/visitors/to_sql.rb +78 -61
  82. data/test/arelx_test_helper.rb +0 -2
  83. data/test/database.yml +2 -0
  84. data/test/real_db_test.rb +27 -42
  85. data/test/support/fake_record.rb +1 -1
  86. data/test/test_comparators.rb +0 -4
  87. data/test/visitors/test_bulk_insert_oracle.rb +0 -1
  88. data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
  89. data/test/visitors/test_oracle.rb +1 -2
  90. data/test/visitors/test_to_sql.rb +16 -25
  91. data/test/with_ar/all_agnostic_test.rb +135 -139
  92. data/test/with_ar/insert_agnostic_test.rb +0 -2
  93. data/test/with_ar/test_bulk_sqlite.rb +0 -4
  94. data/test/with_ar/test_math_sqlite.rb +4 -8
  95. data/test/with_ar/test_string_mysql.rb +1 -5
  96. data/test/with_ar/test_string_sqlite.rb +1 -5
  97. data/version_v1.rb +1 -1
  98. data/version_v2.rb +1 -1
  99. metadata +8 -4
@@ -1,22 +1,21 @@
1
- #require 'oracle_visitor'
1
+ # require 'oracle_visitor'
2
2
  module ArelExtensions
3
3
  module Visitors
4
4
  class Arel::Visitors::Oracle
5
-
6
5
  SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
7
- Arel::Visitors::Oracle::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
8
- Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES = {
6
+ DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
7
+ DATE_FORMAT_DIRECTIVES = {
9
8
  '%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
10
9
  '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
11
10
  '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
12
11
  '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
13
12
  }
14
- Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
13
+ NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
15
14
 
16
15
  def visit_ArelExtensions_Nodes_Log10 o, collector
17
16
  collector << "LOG("
18
17
  o.expressions.each_with_index { |arg, i|
19
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
18
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
20
19
  collector = visit arg, collector
21
20
  }
22
21
  collector << ",10)"
@@ -26,7 +25,7 @@ module ArelExtensions
26
25
  def visit_ArelExtensions_Nodes_Power o, collector
27
26
  collector << "POWER("
28
27
  o.expressions.each_with_index { |arg, i|
29
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
28
+ collector << Arel::Visitors::ToSql::COMMA if i != 0
30
29
  collector = visit arg, collector
31
30
  }
32
31
  collector << ")"
@@ -93,7 +92,6 @@ module ArelExtensions
93
92
  end
94
93
  end
95
94
 
96
-
97
95
  def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
98
96
  collector << 'LOWER('
99
97
  collector = visit o.left, collector
@@ -112,25 +110,25 @@ module ArelExtensions
112
110
  if o.ai
113
111
  collector << "NLSSORT("
114
112
  collector = visit o.expressions.first, collector
115
- collector << Arel::Visitors::Oracle::COMMA
113
+ collector << COMMA
116
114
  collector << "'NLS_SORT = BINARY_AI NLS_COMP = LINGUISTIC'"
117
115
  collector << ")"
118
116
  elsif o.ci
119
117
  collector << "NLSSORT("
120
118
  collector = visit o.expressions.first, collector
121
- collector << Arel::Visitors::Oracle::COMMA
119
+ collector << COMMA
122
120
  collector << "'NLS_SORT = BINARY_CI NLS_COMP = LINGUISTIC'"
123
121
  collector << ")"
124
122
  else
125
123
  collector = visit o.expressions.first, collector
126
124
  end
127
- collector
125
+ collector
128
126
  end
129
127
 
130
128
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
131
129
  collector << "(LISTAGG("
132
130
  collector = visit o.left, collector
133
- collector << Arel::Visitors::Oracle::COMMA
131
+ collector << COMMA
134
132
  collector =
135
133
  if o.separator && o.separator != 'NULL'
136
134
  visit o.separator, collector
@@ -140,7 +138,7 @@ module ArelExtensions
140
138
  collector << ") WITHIN GROUP (ORDER BY "
141
139
  if !o.order.blank?
142
140
  o.order.each_with_index do |order,i|
143
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
141
+ collector << COMMA if i != 0
144
142
  collector = visit order, collector
145
143
  end
146
144
  else
@@ -153,7 +151,7 @@ module ArelExtensions
153
151
  def visit_ArelExtensions_Nodes_Coalesce o, collector
154
152
  collector << "COALESCE("
155
153
  o.expressions.each_with_index { |arg, i|
156
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
154
+ collector << COMMA if i != 0
157
155
  if i > 0 && o.left_node_type == :text
158
156
  if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
159
157
  collector << "NULL"
@@ -196,7 +194,7 @@ module ArelExtensions
196
194
  collector << 'TO_DATE(' if lc
197
195
  collector = visit o.left, collector
198
196
  collector << ')' if lc
199
- collector << Arel::Visitors::Oracle::COMMA
197
+ collector << COMMA
200
198
  collector << "'DDD') = "
201
199
  collector << 'TO_DATE(' if lc
202
200
  collector = visit o.left, collector
@@ -222,8 +220,8 @@ module ArelExtensions
222
220
  when 'wd', 'w'
223
221
  collector << "TO_CHAR("
224
222
  collector = visit o.right, collector
225
- collector << Arel::Visitors::Oracle::COMMA
226
- collector = visit Arel::Nodes.build_quoted(Arel::Visitors::Oracle::DATE_MAPPING[o.left]), collector
223
+ collector << COMMA
224
+ collector = visit Arel::Nodes.build_quoted(DATE_MAPPING[o.left]), collector
227
225
  else
228
226
  right = case o.left
229
227
  when 'd','m','y'
@@ -233,7 +231,7 @@ module ArelExtensions
233
231
  interval = 'SECOND'
234
232
  o.right.cast(:datetime)
235
233
  when /i\z/
236
- interval = Arel::Visitors::Oracle::DATE_MAPPING[o.left[0..-2]]
234
+ interval = DATE_MAPPING[o.left[0..-2]]
237
235
  collector << '('
238
236
  collector = visit o.right, collector
239
237
  collector << ") * (INTERVAL '1' #{interval})"
@@ -242,7 +240,7 @@ module ArelExtensions
242
240
  interval = nil
243
241
  o.right
244
242
  end
245
- collector << "EXTRACT(#{Arel::Visitors::Oracle::DATE_MAPPING[o.left]} FROM "
243
+ collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
246
244
  collector = visit right, collector
247
245
  end
248
246
  collector << ")"
@@ -257,6 +255,16 @@ module ArelExtensions
257
255
  collector = visit o.left, collector
258
256
  collector << ")"
259
257
  return collector
258
+ when :text
259
+ collector << "TO_CLOB("
260
+ collector = visit o.left, collector
261
+ collector << ")"
262
+ return collector
263
+ when :ntext
264
+ collector << "TO_NCLOB("
265
+ collector = visit o.left, collector
266
+ collector << ")"
267
+ return collector
260
268
  when :time
261
269
  if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
262
270
  collector << "TO_DATE("
@@ -322,7 +330,7 @@ module ArelExtensions
322
330
  collector << "DBMS_RANDOM.VALUE("
323
331
  if o.left && o.right
324
332
  collector = visit o.left, collector
325
- collector << Arel::Visitors::Oracle::COMMA
333
+ collector << COMMA
326
334
  collector = visit o.right, collector
327
335
  end
328
336
  collector << ")"
@@ -332,7 +340,7 @@ module ArelExtensions
332
340
  def visit_Arel_Nodes_Regexp o, collector
333
341
  collector << " REGEXP_LIKE("
334
342
  collector = visit o.left, collector
335
- collector << Arel::Visitors::Oracle::COMMA
343
+ collector << COMMA
336
344
  collector = visit o.right, collector
337
345
  collector << ')'
338
346
  collector
@@ -341,7 +349,7 @@ module ArelExtensions
341
349
  def visit_Arel_Nodes_NotRegexp o, collector
342
350
  collector << " NOT REGEXP_LIKE("
343
351
  collector = visit o.left, collector
344
- collector << Arel::Visitors::Oracle::COMMA
352
+ collector << COMMA
345
353
  collector = visit o.right, collector
346
354
  collector << ')'
347
355
  collector
@@ -350,7 +358,7 @@ module ArelExtensions
350
358
  def visit_ArelExtensions_Nodes_Locate o, collector
351
359
  collector << "INSTR("
352
360
  o.expressions.each_with_index { |arg, i|
353
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
361
+ collector << COMMA if i != 0
354
362
  collector = visit arg, collector
355
363
  }
356
364
  collector << ")"
@@ -360,7 +368,7 @@ module ArelExtensions
360
368
  def visit_ArelExtensions_Nodes_Substring o, collector
361
369
  collector << "SUBSTR("
362
370
  o.expressions.each_with_index { |arg, i|
363
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
371
+ collector << COMMA if i != 0
364
372
  collector = visit arg, collector
365
373
  }
366
374
  collector << ")"
@@ -379,11 +387,11 @@ module ArelExtensions
379
387
  if o.type_of_attribute(o.left) == :text
380
388
  collector << 'dbms_lob.SUBSTR('
381
389
  collector = visit o.left, collector
382
- collector << Arel::Visitors::Oracle::COMMA
390
+ collector << COMMA
383
391
  collector << 'COALESCE(dbms_lob.GETLENGTH('
384
392
  collector = visit o.left, collector
385
393
  collector << "), 0)"
386
- collector << Arel::Visitors::Oracle::COMMA
394
+ collector << COMMA
387
395
  collector << '1)'
388
396
  else
389
397
  collector = visit o.left, collector
@@ -430,28 +438,25 @@ module ArelExtensions
430
438
  def visit_ArelExtensions_Nodes_DateAdd o, collector
431
439
  collector << '('
432
440
  collector = visit o.left, collector
433
- collector << ' + '# (o.right.value >= 0 ? ' + ' : ' - ')
441
+ collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
434
442
  collector = visit o.oracle_value(o.right), collector
435
443
  collector << ')'
436
444
  collector
437
445
  end
438
446
 
439
447
  def visit_ArelExtensions_Nodes_Format o, collector
448
+ fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
440
449
  collector << "TO_CHAR("
441
450
  collector = visit o.left, collector
442
- collector << Arel::Visitors::Oracle::COMMA
443
-
444
- f = o.iso_format.gsub(/\ (\w+)/, ' "\1"')
445
- Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
446
- collector = visit Arel::Nodes.build_quoted(f), collector
447
-
451
+ collector << COMMA
452
+ collector = visit Arel::Nodes.build_quoted(fmt), collector
448
453
  collector << ")"
449
454
  collector
450
455
  end
451
456
 
452
457
  def visit_ArelExtensions_Nodes_Repeat o, collector
453
458
  collector << "LPAD("
454
- collector = visit o.expressions[0], collector #can't put empty string, otherwise it wouldn't work
459
+ collector = visit o.expressions[0], collector # can't put empty string, otherwise it wouldn't work
455
460
  collector << Arel::Visitors::ToSql::COMMA
456
461
  collector = visit o.expressions[1], collector
457
462
  collector << Arel::Visitors::ToSql::COMMA
@@ -460,24 +465,24 @@ module ArelExtensions
460
465
  collector
461
466
  end
462
467
 
463
- # add primary_key if not present, avoid zip
468
+ # add primary_key if not present, avoid zip
464
469
  if Arel::VERSION.to_i < 7
465
470
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
466
471
  collector << "("
467
472
  o.left.each_with_index do |row, idx| # values
468
473
  collector << " UNION ALL " if idx != 0
469
- collector << "(SELECT "
470
- len = row.length - 1
471
- row.zip(o.cols).each_with_index { |(value, attr), i|
472
- case value
473
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
474
- collector = visit value, collector
475
- else
476
- collector << quote(value, attr && column_for(attr)).to_s
477
- end
478
- collector << Arel::Visitors::Oracle::COMMA unless i == len
479
- }
480
- collector << ' FROM DUAL)'
474
+ collector << "(SELECT "
475
+ len = row.length - 1
476
+ row.zip(o.cols).each_with_index { |(value, attr), i|
477
+ case value
478
+ when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
479
+ collector = visit value, collector
480
+ else
481
+ collector << quote(value, attr && column_for(attr)).to_s
482
+ end
483
+ collector << COMMA unless i == len
484
+ }
485
+ collector << ' FROM DUAL)'
481
486
  end
482
487
  collector << ")"
483
488
  collector
@@ -498,7 +503,7 @@ module ArelExtensions
498
503
  else
499
504
  collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
500
505
  end
501
- collector << Arel::Visitors::Oracle::COMMA unless i == len
506
+ collector << COMMA unless i == len
502
507
  }
503
508
  collector << ' FROM DUAL)'
504
509
  end
@@ -557,7 +562,7 @@ module ArelExtensions
557
562
  end
558
563
 
559
564
 
560
- alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
565
+ alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
561
566
  def visit_Arel_Nodes_SelectStatement o, collector
562
567
  if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
563
568
  o = o.dup
@@ -566,7 +571,7 @@ module ArelExtensions
566
571
  old_visit_Arel_Nodes_SelectStatement(o,collector)
567
572
  end
568
573
 
569
- alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
574
+ alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
570
575
  def visit_Arel_Nodes_TableAlias o, collector
571
576
  if o.name.length > 30
572
577
  o = Arel::Table.new(o.table_name).alias(Base64.urlsafe_encode64(Digest::MD5.new.digest(o.name)).tr('=', '').tr('-', '_'))
@@ -574,7 +579,7 @@ module ArelExtensions
574
579
  old_visit_Arel_Nodes_TableAlias(o,collector)
575
580
  end
576
581
 
577
- alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
582
+ alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
578
583
  def visit_Arel_Nodes_As o, collector
579
584
  if o.left.is_a?(Arel::Nodes::Binary)
580
585
  collector << '('
@@ -594,7 +599,7 @@ module ArelExtensions
594
599
  visit_Arel_Nodes_As o, collector
595
600
  end
596
601
 
597
- alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
602
+ alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
598
603
  def visit_Arel_Attributes_Attribute o, collector
599
604
  join_name = o.relation.table_alias || o.relation.name
600
605
  if join_name.length > 30
@@ -603,10 +608,9 @@ module ArelExtensions
603
608
  collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
604
609
  end
605
610
 
606
-
607
611
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
608
612
  col = o.left.coalesce(0)
609
- comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
613
+ comma = NUMBER_COMMA_MAPPING[o.locale] || '.,'
610
614
  comma_in_format = o.precision == 0 ? '' : 'D'
611
615
  nines_after = (1..o.precision-1).map{'9'}.join('')+'0'
612
616
  if comma.length == 1
@@ -683,7 +687,6 @@ module ArelExtensions
683
687
  collector << ')'
684
688
  collector
685
689
  end
686
-
687
690
  end
688
691
  end
689
692
  end
@@ -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