arel_extensions 2.0.1 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -4
  3. data/.travis.yml +10 -10
  4. data/Gemfile +14 -19
  5. data/README.md +17 -12
  6. data/Rakefile +23 -23
  7. data/appveyor.yml +1 -1
  8. data/arel_extensions.gemspec +2 -2
  9. data/functions.html +3 -3
  10. data/gemfiles/rails6.gemfile +30 -0
  11. data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
  12. data/generate_gems.sh +13 -0
  13. data/init/mssql.sql +4 -4
  14. data/init/mysql.sql +38 -38
  15. data/init/postgresql.sql +21 -21
  16. data/lib/arel_extensions/boolean_functions.rb +0 -2
  17. data/lib/arel_extensions/common_sql_functions.rb +5 -4
  18. data/lib/arel_extensions/comparators.rb +4 -2
  19. data/lib/arel_extensions/insert_manager.rb +12 -12
  20. data/lib/arel_extensions/math.rb +3 -3
  21. data/lib/arel_extensions/math_functions.rb +10 -5
  22. data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
  23. data/lib/arel_extensions/nodes/case.rb +0 -2
  24. data/lib/arel_extensions/nodes/coalesce.rb +2 -2
  25. data/lib/arel_extensions/nodes/collate.rb +1 -1
  26. data/lib/arel_extensions/nodes/concat.rb +6 -13
  27. data/lib/arel_extensions/nodes/date_diff.rb +3 -5
  28. data/lib/arel_extensions/nodes/duration.rb +0 -2
  29. data/lib/arel_extensions/nodes/format.rb +8 -8
  30. data/lib/arel_extensions/nodes/formatted_number.rb +23 -23
  31. data/lib/arel_extensions/nodes/function.rb +2 -0
  32. data/lib/arel_extensions/nodes/json.rb +28 -30
  33. data/lib/arel_extensions/nodes/matches.rb +4 -4
  34. data/lib/arel_extensions/nodes/power.rb +6 -5
  35. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  36. data/lib/arel_extensions/nodes/replace.rb +24 -6
  37. data/lib/arel_extensions/nodes/round.rb +5 -5
  38. data/lib/arel_extensions/nodes/soundex.rb +16 -15
  39. data/lib/arel_extensions/nodes/std.rb +19 -21
  40. data/lib/arel_extensions/nodes/substring.rb +8 -15
  41. data/lib/arel_extensions/nodes/sum.rb +7 -0
  42. data/lib/arel_extensions/nodes/trim.rb +3 -3
  43. data/lib/arel_extensions/nodes/union.rb +2 -3
  44. data/lib/arel_extensions/nodes/union_all.rb +0 -1
  45. data/lib/arel_extensions/nodes.rb +1 -1
  46. data/lib/arel_extensions/null_functions.rb +2 -2
  47. data/lib/arel_extensions/predications.rb +16 -17
  48. data/lib/arel_extensions/string_functions.rb +21 -12
  49. data/lib/arel_extensions/tasks.rb +5 -5
  50. data/lib/arel_extensions/version.rb +1 -1
  51. data/lib/arel_extensions/visitors/mssql.rb +14 -13
  52. data/lib/arel_extensions/visitors/mysql.rb +72 -37
  53. data/lib/arel_extensions/visitors/oracle.rb +12 -11
  54. data/lib/arel_extensions/visitors/oracle12.rb +1 -1
  55. data/lib/arel_extensions/visitors/postgresql.rb +77 -31
  56. data/lib/arel_extensions/visitors/sqlite.rb +54 -40
  57. data/lib/arel_extensions/visitors/to_sql.rb +50 -31
  58. data/lib/arel_extensions.rb +20 -1
  59. data/test/helper.rb +1 -1
  60. data/test/real_db_test.rb +1 -1
  61. data/test/support/fake_record.rb +0 -4
  62. data/test/test_comparators.rb +1 -1
  63. data/test/visitors/test_bulk_insert_oracle.rb +6 -6
  64. data/test/visitors/test_bulk_insert_sqlite.rb +6 -6
  65. data/test/visitors/test_bulk_insert_to_sql.rb +7 -9
  66. data/test/visitors/test_oracle.rb +1 -0
  67. data/test/visitors/test_to_sql.rb +15 -1
  68. data/test/with_ar/all_agnostic_test.rb +54 -32
  69. data/test/with_ar/insert_agnostic_test.rb +2 -1
  70. data/test/with_ar/test_bulk_sqlite.rb +2 -2
  71. data/test/with_ar/test_math_sqlite.rb +3 -3
  72. data/test/with_ar/test_string_mysql.rb +3 -5
  73. data/test/with_ar/test_string_sqlite.rb +2 -6
  74. data/version_v1.rb +3 -0
  75. data/version_v2.rb +3 -0
  76. metadata +13 -6
@@ -83,23 +83,49 @@ module ArelExtensions
83
83
  collector
84
84
  end
85
85
 
86
+ def visit_Aggregate_For_AggregateFunction o, collector
87
+ if !o.order.blank? || !o.group.blank?
88
+ collector << " OVER ("
89
+ if !o.group.blank?
90
+ collector << " PARTITION BY "
91
+ o.group.each_with_index do |group, i|
92
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
93
+ visit group, collector
94
+ end
95
+ end
96
+ if !o.order.blank?
97
+ collector << " ORDER BY "
98
+ o.order.each_with_index do |order, i|
99
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
100
+ visit order, collector
101
+ end
102
+ end
103
+ collector << ")"
104
+ end
105
+ collector
106
+ end
107
+
86
108
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
87
109
  collector << "array_to_string(array_agg("
88
110
  collector = visit o.left, collector
89
- if !o.orders.blank?
90
- collector << ' ORDER BY '
91
- o.orders.each_with_index do |order,i|
111
+ if o.order && !o.order.blank?
112
+ collector << " ORDER BY"
113
+ o.order.each_with_index do |order, i|
92
114
  collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
93
- collector = visit order, collector
115
+ collector << " "
116
+ visit order, collector
94
117
  end
95
118
  end
96
119
  collector << ")"
120
+ o.order = nil
121
+ visit_Aggregate_For_AggregateFunction o, collector
97
122
  collector << Arel::Visitors::PostgreSQL::COMMA
98
- if o.right && o.right != 'NULL'
99
- collector = visit o.right, collector
100
- else
101
- collector = visit Arel::Nodes.build_quoted(','), collector
102
- end
123
+ collector =
124
+ if o.separator && o.separator != 'NULL'
125
+ visit o.separator, collector
126
+ else
127
+ visit Arel::Nodes.build_quoted(','), collector
128
+ end
103
129
  collector << ")"
104
130
  collector
105
131
  end
@@ -277,6 +303,22 @@ module ArelExtensions
277
303
  collector
278
304
  end
279
305
 
306
+ def visit_ArelExtensions_Nodes_RegexpReplace o, collector
307
+ collector << "REGEXP_REPLACE("
308
+ visit o.left, collector
309
+ collector << Arel::Visitors::ToSql::COMMA
310
+ tab = o.pattern.inspect+ 'g' # Make it always global
311
+ pattern = tab.split('/')[1..-2].join('/')
312
+ flags = tab.split('/')[-1]
313
+ visit Arel::Nodes.build_quoted(pattern), collector
314
+ collector << Arel::Visitors::ToSql::COMMA
315
+ visit o.substitute, collector
316
+ collector << Arel::Visitors::ToSql::COMMA
317
+ visit Arel::Nodes.build_quoted(flags+"g"), collector
318
+ collector << ")"
319
+ collector
320
+ end
321
+
280
322
  def visit_ArelExtensions_Nodes_IsNull o, collector
281
323
  collector = visit o.expr, collector
282
324
  collector << ' IS NULL'
@@ -293,6 +335,7 @@ module ArelExtensions
293
335
  collector << "sum("
294
336
  collector = visit o.expr, collector
295
337
  collector << ")"
338
+ visit_Aggregate_For_AggregateFunction o, collector
296
339
  collector
297
340
  end
298
341
 
@@ -345,27 +388,28 @@ module ArelExtensions
345
388
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
346
389
  sign_length = ArelExtensions::Nodes::Length.new([sign])
347
390
 
348
- if o.scientific_notation
349
- number = ArelExtensions::Nodes::Concat.new([
350
- Arel::Nodes::NamedFunction.new('TRIM',[
351
- Arel::Nodes::NamedFunction.new('TO_CHAR',[
352
- col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
353
- Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
354
- ])]),
355
- o.type,
356
- Arel::Nodes::NamedFunction.new('TRIM',[
357
- Arel::Nodes::NamedFunction.new('TO_CHAR',[
358
- col.abs.log10.floor,
359
- Arel::Nodes.build_quoted('FM'+nines_before)
360
- ])])
361
- ])
362
- else
363
- number = Arel::Nodes::NamedFunction.new('TRIM',[
364
- Arel::Nodes::NamedFunction.new('TO_CHAR',[
365
- Arel::Nodes.build_quoted(col.abs),
366
- Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
367
- ])])
368
- end
391
+ number =
392
+ if o.scientific_notation
393
+ ArelExtensions::Nodes::Concat.new([
394
+ Arel::Nodes::NamedFunction.new('TRIM',[
395
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
396
+ col.abs/Arel::Nodes.build_quoted(10).pow(col.abs.log10.floor),
397
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
398
+ ])]),
399
+ o.type,
400
+ Arel::Nodes::NamedFunction.new('TRIM',[
401
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
402
+ col.abs.log10.floor,
403
+ Arel::Nodes.build_quoted('FM'+nines_before)
404
+ ])])
405
+ ])
406
+ else
407
+ Arel::Nodes::NamedFunction.new('TRIM',[
408
+ Arel::Nodes::NamedFunction.new('TO_CHAR',[
409
+ Arel::Nodes.build_quoted(col.abs),
410
+ Arel::Nodes.build_quoted('FM'+nines_before+'"'+comma+'"V'+nines_after)
411
+ ])])
412
+ end
369
413
 
370
414
  repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
371
415
  when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
@@ -420,6 +464,7 @@ module ArelExtensions
420
464
  collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
421
465
  visit o.left, collector
422
466
  collector << ")"
467
+ visit_Aggregate_For_AggregateFunction o, collector
423
468
  collector
424
469
  end
425
470
 
@@ -427,6 +472,7 @@ module ArelExtensions
427
472
  collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
428
473
  visit o.left, collector
429
474
  collector << ")"
475
+ visit_Aggregate_For_AggregateFunction o, collector
430
476
  collector
431
477
  end
432
478
 
@@ -438,7 +484,7 @@ module ArelExtensions
438
484
  if i != 0
439
485
  collector << Arel::Visitors::MySQL::COMMA
440
486
  end
441
- collector = visit v, collector
487
+ collector = visit v, collector
442
488
  end
443
489
  collector << '])'
444
490
  when Hash
@@ -193,18 +193,28 @@ module ArelExtensions
193
193
  collector
194
194
  end
195
195
 
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)
196
+ # CAST(
197
+ # CASE
198
+ # WHEN 3.42 >= 0 THEN CAST(3.42 AS INT)
199
+ # WHEN CAST(3.42 AS INT) = 3.42 THEN CAST(3.42 AS INT)
200
+ # ELSE CAST((3.42 - 1.0) AS INT)
201
+ # END
202
+ # AS FLOAT
203
+ # )
198
204
  def visit_ArelExtensions_Nodes_Floor o, collector
199
- collector << "CASE WHEN ROUND("
205
+ collector << "CAST(CASE WHEN "
200
206
  collector = visit o.left, collector
201
- collector << ", 1) > ROUND("
207
+ collector << " >= 0 THEN CAST("
202
208
  collector = visit o.left, collector
203
- collector << ") THEN ROUND("
209
+ collector << " AS INT) WHEN CAST("
210
+ collector = visit o.left, collector
211
+ collector << " AS INT) = "
212
+ collector = visit o.left, collector
213
+ collector << " THEN CAST("
204
214
  collector = visit o.left, collector
205
- collector << ") ELSE ROUND("
215
+ collector << " AS INT) ELSE CAST(("
206
216
  collector = visit o.left, collector
207
- collector << ") - 1 END"
217
+ collector << " - 1.0) AS INT) END AS FLOAT)"
208
218
  collector
209
219
  end
210
220
 
@@ -248,20 +258,20 @@ module ArelExtensions
248
258
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
249
259
  o.left.each_with_index do |row, idx|
250
260
  collector << 'SELECT '
251
- len = row.length - 1
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)
261
+ v = Arel::Nodes::Values.new(row, o.cols)
262
+ len = v.expressions.length - 1
263
+ v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
264
+ case value
265
+ when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
266
+ collector = visit value.as(attr.name), collector
267
+ else
268
+ collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
269
+ if idx == 0
270
+ collector << " AS "
271
+ collector << quote(attr.name)
272
+ end
262
273
  end
263
- end
264
- collector << Arel::Visitors::SQLite::COMMA unless i == len
274
+ collector << Arel::Visitors::SQLite::COMMA unless i == len
265
275
  }
266
276
  collector << ' UNION ALL ' unless idx == o.left.length - 1
267
277
  end
@@ -270,32 +280,36 @@ module ArelExtensions
270
280
  end
271
281
 
272
282
  def visit_ArelExtensions_Nodes_Union o, collector
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
283
+ collector =
284
+ if o.left.is_a?(Arel::SelectManager)
285
+ visit o.left.ast, collector
286
+ else
287
+ visit o.left, collector
288
+ end
278
289
  collector << " UNION "
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
290
+ collector =
291
+ if o.right.is_a?(Arel::SelectManager)
292
+ visit o.right.ast, collector
293
+ else
294
+ visit o.right, collector
295
+ end
284
296
  collector
285
297
  end
286
298
 
287
299
  def visit_ArelExtensions_Nodes_UnionAll o, collector
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
300
+ collector =
301
+ if o.left.is_a?(Arel::SelectManager)
302
+ visit o.left.ast, collector
303
+ else
304
+ visit o.left, collector
305
+ end
293
306
  collector << " UNION ALL "
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
307
+ collector =
308
+ if o.right.is_a?(Arel::SelectManager)
309
+ visit o.right.ast, collector
310
+ else
311
+ visit o.right, collector
312
+ end
299
313
  collector
300
314
  end
301
315
 
@@ -1,7 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- Arel::Visitors::ToSql.class_eval do
4
- Arel::Visitors::ToSql::COMMA = ", "
3
+ Arel::Visitors::ToSql.class_eval do
4
+ Arel::Visitors::ToSql::COMMA = ', ' unless defined?(Arel::Visitors::ToSql::COMMA)
5
5
 
6
6
  # Math Functions
7
7
  def visit_ArelExtensions_Nodes_Abs o, collector
@@ -53,14 +53,14 @@ module ArelExtensions
53
53
  collector << ")"
54
54
  collector
55
55
  end
56
-
56
+
57
57
  def visit_ArelExtensions_Nodes_Log10 o, collector
58
58
  collector << "LOG10("
59
59
  collector = visit o.left, collector
60
60
  collector << ")"
61
61
  collector
62
62
  end
63
-
63
+
64
64
  def visit_ArelExtensions_Nodes_Power o, collector
65
65
  collector << "POW("
66
66
  o.expressions.each_with_index { |arg, i|
@@ -71,6 +71,13 @@ module ArelExtensions
71
71
  collector
72
72
  end
73
73
 
74
+ def visit_ArelExtensions_Nodes_Sum o, collector
75
+ collector << "SUM("
76
+ collector = visit o.expr, collector
77
+ collector << ")"
78
+ collector
79
+ end
80
+
74
81
  # String functions
75
82
  def visit_ArelExtensions_Nodes_Concat o, collector
76
83
  collector << "CONCAT("
@@ -85,9 +92,9 @@ module ArelExtensions
85
92
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
86
93
  collector << "GROUP_CONCAT("
87
94
  collector = visit o.left, collector
88
- if o.right && o.right != 'NULL'
95
+ if o.separator && o.separator != 'NULL'
89
96
  collector << Arel::Visitors::ToSql::COMMA
90
- collector = visit o.right, collector
97
+ collector = visit o.separator, collector
91
98
  end
92
99
  collector << ")"
93
100
  collector
@@ -128,14 +135,26 @@ module ArelExtensions
128
135
 
129
136
  def visit_ArelExtensions_Nodes_Replace o, collector
130
137
  collector << "REPLACE("
131
- o.expressions.each_with_index { |arg, i|
132
- collector << Arel::Visitors::ToSql::COMMA unless i == 0
133
- collector = visit arg, collector
134
- }
138
+ visit o.left, collector
139
+ collector << Arel::Visitors::ToSql::COMMA
140
+ visit o.pattern, collector
141
+ collector << Arel::Visitors::ToSql::COMMA
142
+ visit o.substitute, collector
143
+ collector << ")"
144
+ collector
145
+ end
146
+
147
+ def visit_ArelExtensions_Nodes_RegexpReplace o, collector
148
+ collector << "REGEXP_REPLACE("
149
+ visit o.left, collector
150
+ collector << Arel::Visitors::ToSql::COMMA
151
+ visit Arel::Nodes.build_quoted(o.pattern.to_s), collector
152
+ collector << Arel::Visitors::ToSql::COMMA
153
+ visit o.substitute, collector
135
154
  collector << ")"
136
155
  collector
137
156
  end
138
-
157
+
139
158
  def visit_ArelExtensions_Nodes_Repeat o, collector
140
159
  collector << "REPEAT("
141
160
  o.expressions.each_with_index { |arg, i|
@@ -270,12 +289,12 @@ module ArelExtensions
270
289
  as_attr = Arel::Nodes::SqlLiteral.new('int')
271
290
  when :decimal, :float, :number
272
291
  as_attr = Arel::Nodes::SqlLiteral.new('float')
273
- when :datetime
292
+ when :datetime
274
293
  as_attr = Arel::Nodes::SqlLiteral.new('datetime')
275
294
  when :time
276
295
  as_attr = Arel::Nodes::SqlLiteral.new('time')
277
- when :binary
278
- as_attr = Arel::Nodes::SqlLiteral.new('binary')
296
+ when :binary
297
+ as_attr = Arel::Nodes::SqlLiteral.new('binary')
279
298
  else
280
299
  as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
281
300
  end
@@ -306,7 +325,7 @@ module ArelExtensions
306
325
  collector << ")"
307
326
  collector
308
327
  end
309
-
328
+
310
329
  def visit_ArelExtensions_Nodes_DateSub o, collector
311
330
  collector << "DATE_SUB("
312
331
  collector = visit o.left, collector
@@ -385,7 +404,7 @@ module ArelExtensions
385
404
  collector = visit o.left, collector
386
405
  collector << ") THEN "
387
406
  collector = visit o.right, collector
388
- if o.expressions[2]
407
+ if o.expressions[2]
389
408
  collector << " ELSE "
390
409
  collector = visit o.expressions[2], collector
391
410
  end
@@ -430,9 +449,9 @@ module ArelExtensions
430
449
  row_nb = o.left.length
431
450
  o.left.each_with_index do |row, idx|
432
451
  collector << '('
433
- len = row.length - 1
434
- row.each_with_index { |value, i|
435
- attr = o.cols[i]
452
+ v = Arel::Nodes::Values.new(row, o.cols)
453
+ len = v.expressions.length - 1
454
+ v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
436
455
  case value
437
456
  when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
438
457
  collector = visit value, collector
@@ -453,7 +472,7 @@ module ArelExtensions
453
472
  collector = visit o.right, collector
454
473
  collector
455
474
  end
456
-
475
+
457
476
  def visit_ArelExtensions_Nodes_UnionAll o, collector
458
477
  collector = visit o.left, collector
459
478
  collector << " UNION ALL "
@@ -490,25 +509,25 @@ module ArelExtensions
490
509
  visit Arel::Nodes.build_quoted(o.expr), collector
491
510
  end
492
511
 
493
- def visit_ArelExtensions_Nodes_FormattedNumber o, collector
512
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
494
513
  visit o.left, collector
495
514
  end
496
-
497
- remove_method(:visit_Arel_Nodes_LessThan) rescue nil
515
+
516
+ remove_method(:visit_Arel_Nodes_LessThan) rescue nil
498
517
  def visit_Arel_Nodes_LessThan o, collector
499
518
  collector = visit o.left, collector
500
519
  collector << " < "
501
520
  visit o.right, collector
502
521
  end
503
-
504
- def visit_ArelExtensions_Nodes_Std o, collector
522
+
523
+ def visit_ArelExtensions_Nodes_Std o, collector
505
524
  collector << "STD("
506
525
  visit o.left, collector
507
526
  collector << ")"
508
527
  collector
509
528
  end
510
-
511
- def visit_ArelExtensions_Nodes_Variance o, collector
529
+
530
+ def visit_ArelExtensions_Nodes_Variance o, collector
512
531
  collector << "VARIANCE("
513
532
  visit o.left, collector
514
533
  collector << ")"
@@ -526,40 +545,40 @@ module ArelExtensions
526
545
 
527
546
  alias_method :old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And
528
547
  def visit_Arel_Nodes_And o, collector
548
+ collector << '('
529
549
  case o.children.length
530
550
  when 0
531
551
  collector << '1=1' # but this should not happen
532
552
  when 1
533
553
  collector = visit o.children[0], collector
534
554
  else
535
- collector << '('
536
555
  o.children.each_with_index { |arg, i|
537
556
  if i != 0
538
557
  collector << ') AND ('
539
558
  end
540
559
  collector = visit arg, collector
541
560
  }
542
- collector << ')'
543
561
  end
562
+ collector << ')'
544
563
  collector
545
564
  end
546
565
 
547
566
  def visit_ArelExtensions_Nodes_Or o, collector
567
+ collector << '('
548
568
  case o.children.length
549
569
  when 0
550
570
  collector << '0=1' # but this should not happen
551
571
  when 1
552
572
  collector = visit o.children[0], collector
553
573
  else
554
- collector << '('
555
574
  o.children.each_with_index { |arg, i|
556
575
  if i != 0
557
576
  collector << ') OR ('
558
577
  end
559
578
  collector = visit arg, collector
560
579
  }
561
- collector << ')'
562
580
  end
581
+ collector << ')'
563
582
  collector
564
583
  end
565
584
 
@@ -93,6 +93,14 @@ module Arel
93
93
  ArelExtensions::Nodes::Duration.new(s.to_s+'i',expr)
94
94
  end
95
95
 
96
+ def self.true
97
+ Arel::Nodes::Equality.new(1,1)
98
+ end
99
+
100
+ def self.false
101
+ Arel::Nodes::Equality.new(1,0)
102
+ end
103
+
96
104
  end
97
105
 
98
106
  Arel::Attributes::Attribute.class_eval do
@@ -109,6 +117,12 @@ Arel::Nodes::Function.class_eval do
109
117
  include ArelExtensions::BooleanFunctions
110
118
  include ArelExtensions::NullFunctions
111
119
  include ArelExtensions::Predications
120
+
121
+ alias_method :old_as, :as
122
+ def as other
123
+ Arel::Nodes::As.new(self, Arel.sql(other))
124
+ end
125
+
112
126
  end
113
127
 
114
128
  Arel::Nodes::Unary.class_eval do
@@ -149,4 +163,9 @@ Arel::Nodes::As.class_eval do
149
163
  include ArelExtensions::Nodes
150
164
  end
151
165
 
152
-
166
+ Arel::Table.class_eval do
167
+ alias_method :old_alias, :alias
168
+ def alias(name = "#{self.name}_2")
169
+ name.blank? ? self : Arel::Nodes::TableAlias.new(self,name)
170
+ end
171
+ end
data/test/helper.rb CHANGED
@@ -15,4 +15,4 @@ class Object
15
15
  def must_be_like other
16
16
  gsub(/\s+/, ' ').strip.must_equal other.gsub(/\s+/, ' ').strip
17
17
  end
18
- end
18
+ end
data/test/real_db_test.rb CHANGED
@@ -29,7 +29,7 @@ def setup_db
29
29
  func.result = value1.index(value2)
30
30
  end
31
31
  end
32
- @cnx.drop_table(:users) rescue nil
32
+ @cnx.drop_table(:users) rescue nil
33
33
  @cnx.create_table :users do |t|
34
34
  t.column :age, :integer
35
35
  t.column :name, :string
@@ -65,10 +65,6 @@ module FakeRecord
65
65
  self
66
66
  end
67
67
 
68
- def in_clause_length
69
- 6
70
- end
71
-
72
68
  def quote thing, column = nil
73
69
  if column && !thing.nil?
74
70
  case column.type
@@ -22,7 +22,7 @@ module ArelExtensions
22
22
  it "< is equal lt" do
23
23
  compile(@table[:id] < 10).must_be_like('"users"."id" < 10')
24
24
  end
25
-
25
+
26
26
  it "<= is equal lteq" do
27
27
  compile(@table[:id] <= 10).must_be_like('"users"."id" <= 10')
28
28
  end
@@ -9,8 +9,8 @@ module ArelExtensions
9
9
  @table = Arel::Table.new(:users)
10
10
  @cols = ['name', 'comments', 'created_at']
11
11
  @data = [
12
- ['nom1', "sdfdsfdsfsdf", '2016-01-01'],
13
- ['nom2', "sdfdsfdsfsdf", '2016-01-01']
12
+ ['nom1', "sdfdsfdsfsdf", '2016-01-01'],
13
+ ['nom2', "sdfdsfdsfsdf", '2016-01-01']
14
14
  ]
15
15
  end
16
16
 
@@ -24,11 +24,11 @@ module ArelExtensions
24
24
 
25
25
  it "should import large set of data in Oracle" do
26
26
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
27
- insert_manager.bulk_insert(@cols, @data)
28
- sql = compile(insert_manager.ast)
29
- sql.must_be_like %Q[INSERT INTO "users" ("name", "comments", "created_at") ((SELECT 'nom1', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL) UNION ALL (SELECT 'nom2', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL))]
27
+ insert_manager.bulk_insert(@cols, @data)
28
+ sql = compile(insert_manager.ast)
29
+ sql.must_be_like %Q[INSERT INTO "users" ("name", "comments", "created_at") ((SELECT 'nom1', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL) UNION ALL (SELECT 'nom2', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL))]
30
30
  end
31
31
 
32
- end
32
+ end
33
33
  end
34
34
  end
@@ -11,11 +11,11 @@ module ArelExtensions
11
11
  Arel::Table.engine = @conn
12
12
  @cols = ['id', 'name', 'comments', 'created_at']
13
13
  @data = [
14
- [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
15
- [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
14
+ [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
15
+ [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
16
16
  ]
17
17
  end
18
-
18
+
19
19
  def compile node
20
20
  if Arel::VERSION.to_i > 5
21
21
  @visitor.accept(node, Arel::Collectors::SQLString.new).value
@@ -28,9 +28,9 @@ module ArelExtensions
28
28
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
29
29
  insert_manager.bulk_insert(@cols, @data)
30
30
  sql = compile(insert_manager.ast)
31
- sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") SELECT 23 AS 'id', 'nom1' AS 'name', 'sdfdsfdsfsdf' AS 'comments', '2016-01-01' AS 'created_at' UNION ALL SELECT 25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01']
31
+ sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") SELECT 23 AS 'id', 'nom1' AS 'name', 'sdfdsfdsfsdf' AS 'comments', '2016-01-01' AS 'created_at' UNION ALL SELECT 25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01']
32
32
  end
33
33
 
34
- end
34
+ end
35
35
  end
36
- end
36
+ end
@@ -10,8 +10,8 @@ module ArelExtensions
10
10
  @table = Arel::Table.new(:users)
11
11
  @cols = ['id', 'name', 'comments', 'created_at']
12
12
  @data = [
13
- [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
14
- [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
13
+ [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
14
+ [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
15
15
  ]
16
16
  end
17
17
 
@@ -26,12 +26,10 @@ module ArelExtensions
26
26
 
27
27
  it "should import large set of data using ToSql" do
28
28
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
29
- insert_manager.bulk_insert(@cols, @data)
30
- sql = compile(insert_manager.ast)
31
- sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'), (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01')]
29
+ insert_manager.bulk_insert(@cols, @data)
30
+ sql = compile(insert_manager.ast)
31
+ sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'), (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01')]
32
32
  end
33
-
34
-
35
- end
33
+ end
36
34
  end
37
- end
35
+ end