arel_extensions 2.0.11 → 2.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +102 -0
- data/.travis.yml +2 -0
- data/Gemfile +10 -10
- data/Rakefile +4 -4
- data/gemfiles/rails3.gemfile +9 -9
- data/gemfiles/rails4.gemfile +13 -13
- data/gemfiles/rails5_0.gemfile +13 -13
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +13 -13
- data/gemfiles/rails6.gemfile +13 -13
- data/gemfiles/rails6_1.gemfile +30 -0
- data/gemspecs/arel_extensions-v1.gemspec +28 -0
- data/{gemspec_v2 → gemspecs}/arel_extensions-v2.gemspec +0 -0
- data/generate_gems.sh +4 -3
- data/lib/arel_extensions.rb +6 -4
- data/lib/arel_extensions/attributes.rb +0 -0
- data/lib/arel_extensions/boolean_functions.rb +21 -5
- data/lib/arel_extensions/common_sql_functions.rb +2 -4
- data/lib/arel_extensions/comparators.rb +11 -14
- data/lib/arel_extensions/date_duration.rb +4 -5
- data/lib/arel_extensions/insert_manager.rb +16 -17
- data/lib/arel_extensions/math.rb +8 -9
- data/lib/arel_extensions/math_functions.rb +18 -20
- data/lib/arel_extensions/nodes/abs.rb +0 -1
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -1
- data/lib/arel_extensions/nodes/blank.rb +0 -1
- data/lib/arel_extensions/nodes/case.rb +3 -4
- data/lib/arel_extensions/nodes/cast.rb +4 -2
- data/lib/arel_extensions/nodes/ceil.rb +1 -1
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +0 -1
- data/lib/arel_extensions/nodes/collate.rb +0 -1
- data/lib/arel_extensions/nodes/concat.rb +2 -4
- data/lib/arel_extensions/nodes/date_diff.rb +7 -8
- data/lib/arel_extensions/nodes/duration.rb +0 -1
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -1
- data/lib/arel_extensions/nodes/floor.rb +1 -1
- data/lib/arel_extensions/nodes/format.rb +27 -1
- data/lib/arel_extensions/nodes/formatted_number.rb +0 -1
- data/lib/arel_extensions/nodes/function.rb +18 -15
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +11 -17
- data/lib/arel_extensions/nodes/length.rb +0 -1
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +0 -0
- data/lib/arel_extensions/nodes/locate.rb +0 -1
- data/lib/arel_extensions/nodes/log10.rb +1 -2
- data/lib/arel_extensions/nodes/matches.rb +0 -2
- data/lib/arel_extensions/nodes/md5.rb +0 -1
- data/lib/arel_extensions/nodes/power.rb +0 -1
- data/lib/arel_extensions/nodes/rand.rb +0 -1
- data/lib/arel_extensions/nodes/repeat.rb +0 -2
- data/lib/arel_extensions/nodes/replace.rb +0 -2
- data/lib/arel_extensions/nodes/round.rb +0 -1
- data/lib/arel_extensions/nodes/soundex.rb +0 -1
- data/lib/arel_extensions/nodes/std.rb +4 -5
- data/lib/arel_extensions/nodes/substring.rb +0 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +0 -0
- data/lib/arel_extensions/nodes/trim.rb +0 -2
- data/lib/arel_extensions/nodes/union.rb +0 -2
- data/lib/arel_extensions/nodes/union_all.rb +0 -2
- data/lib/arel_extensions/nodes/wday.rb +0 -4
- data/lib/arel_extensions/null_functions.rb +3 -5
- data/lib/arel_extensions/predications.rb +5 -6
- data/lib/arel_extensions/railtie.rb +5 -5
- data/lib/arel_extensions/set_functions.rb +0 -2
- data/lib/arel_extensions/string_functions.rb +21 -22
- data/lib/arel_extensions/tasks.rb +1 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +68 -60
- data/lib/arel_extensions/visitors/convert_format.rb +37 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +4 -11
- data/lib/arel_extensions/visitors/mssql.rb +49 -44
- data/lib/arel_extensions/visitors/mysql.rb +65 -67
- data/lib/arel_extensions/visitors/oracle.rb +58 -55
- data/lib/arel_extensions/visitors/oracle12.rb +2 -3
- data/lib/arel_extensions/visitors/postgresql.rb +41 -34
- data/lib/arel_extensions/visitors/sqlite.rb +23 -18
- data/lib/arel_extensions/visitors/to_sql.rb +56 -47
- data/test/arelx_test_helper.rb +0 -2
- data/test/database.yml +2 -0
- data/test/real_db_test.rb +27 -42
- data/test/support/fake_record.rb +1 -1
- data/test/test_comparators.rb +0 -4
- data/test/visitors/test_bulk_insert_oracle.rb +0 -1
- data/test/visitors/test_bulk_insert_sqlite.rb +0 -2
- data/test/visitors/test_oracle.rb +1 -2
- data/test/visitors/test_to_sql.rb +16 -25
- data/test/with_ar/all_agnostic_test.rb +135 -139
- data/test/with_ar/insert_agnostic_test.rb +0 -2
- data/test/with_ar/test_bulk_sqlite.rb +0 -4
- data/test/with_ar/test_math_sqlite.rb +4 -8
- data/test/with_ar/test_string_mysql.rb +1 -5
- data/test/with_ar/test_string_sqlite.rb +1 -5
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- 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
|
-
|
8
|
-
|
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
|
-
|
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
|
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
|
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 <<
|
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 <<
|
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
|
-
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
226
|
-
collector = visit Arel::Nodes.build_quoted(
|
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 =
|
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(#{
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
390
|
+
collector << COMMA
|
383
391
|
collector << 'COALESCE(dbms_lob.GETLENGTH('
|
384
392
|
collector = visit o.left, collector
|
385
393
|
collector << "), 0)"
|
386
|
-
collector <<
|
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 <<
|
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
|
-
|
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
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
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 <<
|
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
|
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
|
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
|
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
|
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 =
|
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
|
-
|
5
|
-
|
6
|
-
'
|
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
|
-
|
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 <<
|
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
|
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
|
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
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
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 <<
|
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
|
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 <<
|
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' #{
|
282
|
+
collector << " * (INTERVAL '1' #{DATE_MAPPING[o.left[0..-2]]})"
|
277
283
|
return collector
|
278
284
|
end
|
279
285
|
end
|
280
|
-
collector << "EXTRACT(#{
|
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 <<
|
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 ? '' : (
|
382
|
-
thousand_separator =
|
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
|
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
|
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
|
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
|