arel_extensions 1.3.9 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -7
  4. data/.rubocop.yml +3 -67
  5. data/.travis/oracle/download.js +152 -0
  6. data/.travis/oracle/download.sh +30 -0
  7. data/.travis/oracle/download_ojdbc.js +116 -0
  8. data/.travis/oracle/install.sh +34 -0
  9. data/.travis/setup_accounts.sh +9 -0
  10. data/.travis/sqlite3/extension-functions.sh +6 -0
  11. data/.travis.yml +223 -0
  12. data/Gemfile +21 -16
  13. data/README.md +90 -282
  14. data/Rakefile +30 -48
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +14 -13
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +10 -10
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  22. data/gemfiles/rails5_1_4.gemfile +14 -14
  23. data/gemfiles/rails5_2.gemfile +14 -16
  24. data/init/mssql.sql +4 -4
  25. data/init/mysql.sql +38 -38
  26. data/init/oracle.sql +0 -0
  27. data/init/postgresql.sql +21 -21
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -4
  30. data/lib/arel_extensions/boolean_functions.rb +14 -53
  31. data/lib/arel_extensions/common_sql_functions.rb +17 -16
  32. data/lib/arel_extensions/comparators.rb +28 -27
  33. data/lib/arel_extensions/date_duration.rb +13 -17
  34. data/lib/arel_extensions/insert_manager.rb +15 -18
  35. data/lib/arel_extensions/math.rb +53 -55
  36. data/lib/arel_extensions/math_functions.rb +39 -46
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +2 -1
  39. data/lib/arel_extensions/nodes/case.rb +19 -20
  40. data/lib/arel_extensions/nodes/cast.rb +8 -10
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +4 -3
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +18 -9
  45. data/lib/arel_extensions/nodes/date_diff.rb +26 -42
  46. data/lib/arel_extensions/nodes/duration.rb +3 -0
  47. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  48. data/lib/arel_extensions/nodes/floor.rb +1 -1
  49. data/lib/arel_extensions/nodes/format.rb +8 -35
  50. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  51. data/lib/arel_extensions/nodes/function.rb +37 -42
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  53. data/lib/arel_extensions/nodes/json.rb +39 -52
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  56. data/lib/arel_extensions/nodes/locate.rb +2 -1
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +7 -5
  59. data/lib/arel_extensions/nodes/md5.rb +1 -0
  60. data/lib/arel_extensions/nodes/power.rb +5 -5
  61. data/lib/arel_extensions/nodes/rand.rb +1 -0
  62. data/lib/arel_extensions/nodes/repeat.rb +5 -3
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +6 -5
  65. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  66. data/lib/arel_extensions/nodes/std.rb +21 -18
  67. data/lib/arel_extensions/nodes/substring.rb +16 -8
  68. data/lib/arel_extensions/nodes/then.rb +1 -1
  69. data/lib/arel_extensions/nodes/trim.rb +6 -4
  70. data/lib/arel_extensions/nodes/union.rb +8 -5
  71. data/lib/arel_extensions/nodes/union_all.rb +7 -4
  72. data/lib/arel_extensions/nodes/wday.rb +4 -0
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +5 -19
  75. data/lib/arel_extensions/predications.rb +43 -44
  76. data/lib/arel_extensions/railtie.rb +5 -5
  77. data/lib/arel_extensions/set_functions.rb +7 -5
  78. data/lib/arel_extensions/string_functions.rb +29 -59
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -1
  81. data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
  82. data/lib/arel_extensions/visitors/mssql.rb +180 -375
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -350
  84. data/lib/arel_extensions/visitors/oracle.rb +178 -220
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -256
  87. data/lib/arel_extensions/visitors/sqlite.rb +126 -140
  88. data/lib/arel_extensions/visitors/to_sql.rb +237 -298
  89. data/lib/arel_extensions/visitors.rb +58 -82
  90. data/lib/arel_extensions.rb +31 -202
  91. data/test/database.yml +7 -15
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +116 -105
  94. data/test/support/fake_record.rb +3 -3
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +11 -11
  97. data/test/visitors/test_bulk_insert_sqlite.rb +13 -12
  98. data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
  99. data/test/visitors/test_oracle.rb +55 -55
  100. data/test/visitors/test_to_sql.rb +226 -419
  101. data/test/with_ar/all_agnostic_test.rb +365 -709
  102. data/test/with_ar/insert_agnostic_test.rb +21 -27
  103. data/test/with_ar/test_bulk_sqlite.rb +16 -17
  104. data/test/with_ar/test_math_sqlite.rb +26 -26
  105. data/test/with_ar/test_string_mysql.rb +33 -31
  106. data/test/with_ar/test_string_sqlite.rb +34 -30
  107. metadata +34 -37
  108. data/.github/workflows/publish.yml +0 -29
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -345
  111. data/NEWS.md +0 -62
  112. data/bin/build +0 -15
  113. data/bin/publish +0 -8
  114. data/dev/compose.yaml +0 -29
  115. data/gemfiles/rails4_2.gemfile +0 -38
  116. data/gemfiles/rails5.gemfile +0 -29
  117. data/gemfiles/rails6.gemfile +0 -30
  118. data/gemfiles/rails6_1.gemfile +0 -30
  119. data/gemfiles/rails7.gemfile +0 -23
  120. data/gemfiles/rails7_1.gemfile +0 -22
  121. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  122. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  123. data/generate_gems.sh +0 -15
  124. data/lib/arel_extensions/aliases.rb +0 -14
  125. data/lib/arel_extensions/helpers.rb +0 -57
  126. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  127. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  128. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  129. data/lib/arel_extensions/nodes/select.rb +0 -10
  130. data/lib/arel_extensions/nodes/sum.rb +0 -7
  131. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  132. data/test/arelx_test_helper.rb +0 -67
  133. data/version_v1.rb +0 -3
  134. data/version_v2.rb +0 -3
@@ -1,36 +1,36 @@
1
- # require 'oracle_visitor'
1
+ #require 'oracle_visitor'
2
2
  module ArelExtensions
3
3
  module Visitors
4
- class Arel::Visitors::Oracle
4
+ Arel::Visitors::Oracle.class_eval do
5
+
5
6
  SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
6
- DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
7
- DATE_FORMAT_DIRECTIVES = {
8
- '%Y' => 'YYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
9
- '%V' => 'IW', '%G' => 'IYYY', # ISO week number and year of week
10
- '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%a' => 'Dy', '%A' => 'Day', # day, weekday
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 = {
9
+ '%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
10
+ '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
11
11
  '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
12
12
  '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
13
13
  }
14
- NUMBER_COMMA_MAPPING = {'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', '}
14
+ Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
15
15
 
16
16
  def visit_ArelExtensions_Nodes_Log10 o, collector
17
- collector << 'LOG('
18
- o.expressions.each_with_index { |arg, i|
19
- collector << Arel::Visitors::ToSql::COMMA if i != 0
20
- collector = visit arg, collector
21
- }
22
- collector << ',10)'
23
- collector
17
+ collector << "LOG("
18
+ o.expressions.each_with_index { |arg, i|
19
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
20
+ collector = visit arg, collector
21
+ }
22
+ collector << ",10)"
23
+ collector
24
24
  end
25
25
 
26
26
  def visit_ArelExtensions_Nodes_Power o, collector
27
- collector << 'POWER('
28
- o.expressions.each_with_index { |arg, i|
29
- collector << Arel::Visitors::ToSql::COMMA if i != 0
30
- collector = visit arg, collector
31
- }
32
- collector << ')'
33
- collector
27
+ collector << "POWER("
28
+ o.expressions.each_with_index { |arg, i|
29
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
30
+ collector = visit arg, collector
31
+ }
32
+ collector << ")"
33
+ collector
34
34
  end
35
35
 
36
36
  def visit_ArelExtensions_Nodes_Concat o, collector
@@ -93,6 +93,7 @@ module ArelExtensions
93
93
  end
94
94
  end
95
95
 
96
+
96
97
  def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
97
98
  collector << 'LOWER('
98
99
  collector = visit o.left, collector
@@ -108,59 +109,53 @@ module ArelExtensions
108
109
  end
109
110
 
110
111
  def visit_ArelExtensions_Nodes_Collate o, collector
111
- if o.ai
112
- collector << 'NLSSORT('
113
- collector = visit o.expressions.first, collector
114
- collector << COMMA
115
- collector << "'NLS_SORT = BINARY_AI NLS_COMP = LINGUISTIC'"
116
- collector << ')'
117
- elsif o.ci
118
- collector << 'NLSSORT('
119
- collector = visit o.expressions.first, collector
120
- collector << COMMA
121
- collector << "'NLS_SORT = BINARY_CI NLS_COMP = LINGUISTIC'"
122
- collector << ')'
123
- else
124
- collector = visit o.expressions.first, collector
125
- end
126
- collector
112
+ if o.ai
113
+ collector << "NLSSORT("
114
+ collector = visit o.expressions.first, collector
115
+ collector << Arel::Visitors::Oracle::COMMA
116
+ collector << "'NLS_SORT = BINARY_AI NLS_COMP = LINGUISTIC'"
117
+ collector << ")"
118
+ elsif o.ci
119
+ collector << "NLSSORT("
120
+ collector = visit o.expressions.first, collector
121
+ collector << Arel::Visitors::Oracle::COMMA
122
+ collector << "'NLS_SORT = BINARY_CI NLS_COMP = LINGUISTIC'"
123
+ collector << ")"
124
+ else
125
+ collector = visit o.expressions.first, collector
127
126
  end
128
-
129
- def visit_Arel_Nodes_RollUp(o, collector)
130
- collector << "ROLLUP"
131
- grouping_array_or_grouping_element o, collector
127
+ collector
132
128
  end
133
129
 
134
130
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
135
- collector << '(LISTAGG('
131
+ collector << "(LISTAGG("
136
132
  collector = visit o.left, collector
137
- collector << COMMA
138
- collector =
139
- if o.separator && o.separator != 'NULL'
140
- visit o.separator, collector
141
- else
142
- visit Arel.quoted(','), collector
143
- end
144
- collector << ') WITHIN GROUP (ORDER BY '
145
- if !o.order.blank?
146
- o.order.each_with_index do |order, i|
147
- collector << COMMA if i != 0
133
+ collector << Arel::Visitors::Oracle::COMMA
134
+ if o.right && o.right != 'NULL'
135
+ collector = visit o.right, collector
136
+ else
137
+ collector = visit Arel::Nodes.build_quoted(','), collector
138
+ end
139
+ collector << ") WITHIN GROUP (ORDER BY "
140
+ if !o.orders.blank?
141
+ o.orders.each_with_index do |order,i|
142
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
148
143
  collector = visit order, collector
149
144
  end
150
145
  else
151
146
  collector = visit o.left, collector
152
147
  end
153
- collector << '))'
148
+ collector << "))"
154
149
  collector
155
150
  end
156
151
 
157
152
  def visit_ArelExtensions_Nodes_Coalesce o, collector
158
- collector << 'COALESCE('
153
+ collector << "COALESCE("
159
154
  o.expressions.each_with_index { |arg, i|
160
- collector << COMMA if i != 0
155
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
161
156
  if i > 0 && o.left_node_type == :text
162
- if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
163
- collector << 'NULL'
157
+ if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
158
+ collector << "NULL"
164
159
  else
165
160
  collector << 'TO_CLOB('
166
161
  collector = visit arg, collector
@@ -170,12 +165,12 @@ module ArelExtensions
170
165
  collector = visit arg, collector
171
166
  end
172
167
  }
173
- collector << ')'
168
+ collector << ")"
174
169
  collector
175
170
  end
176
171
 
177
172
  def visit_ArelExtensions_Nodes_MD5 o, collector
178
- collector << 'LOWER (RAWTOHEX (DBMS_OBFUSCATION_TOOLKIT.md5(input => UTL_I18N.STRING_TO_RAW('
173
+ collector << "LOWER (RAWTOHEX (DBMS_OBFUSCATION_TOOLKIT.md5(input => UTL_I18N.STRING_TO_RAW("
179
174
  collector = visit o.left, collector
180
175
  collector << ", 'AL32UTF8'))))"
181
176
  collector
@@ -190,7 +185,7 @@ module ArelExtensions
190
185
  collector << 'TO_DATE(' if lc
191
186
  collector = visit o.left, collector
192
187
  collector << ')' if lc
193
- collector << ' - '
188
+ collector << " - "
194
189
  collector << 'TO_DATE(' if rc
195
190
  collector = visit o.right, collector
196
191
  collector << ')' if rc
@@ -200,7 +195,7 @@ module ArelExtensions
200
195
  collector << 'TO_DATE(' if lc
201
196
  collector = visit o.left, collector
202
197
  collector << ')' if lc
203
- collector << COMMA
198
+ collector << Arel::Visitors::Oracle::COMMA
204
199
  collector << "'DDD') = "
205
200
  collector << 'TO_DATE(' if lc
206
201
  collector = visit o.left, collector
@@ -224,20 +219,20 @@ module ArelExtensions
224
219
  def visit_ArelExtensions_Nodes_Duration o, collector
225
220
  case o.left
226
221
  when 'wd', 'w'
227
- collector << 'TO_CHAR('
222
+ collector << "TO_CHAR("
228
223
  collector = visit o.right, collector
229
- collector << COMMA
230
- collector = visit Arel.quoted(DATE_MAPPING[o.left]), collector
224
+ collector << Arel::Visitors::Oracle::COMMA
225
+ collector = visit Arel::Nodes.build_quoted(Arel::Visitors::Oracle::DATE_MAPPING[o.left]), collector
231
226
  else
232
227
  right = case o.left
233
- when 'd', 'm', 'y'
228
+ when 'd','m','y'
234
229
  interval = 'DAY'
235
230
  o.right.cast(:date)
236
- when 'h', 'mn', 's'
231
+ when 'h','mn','s'
237
232
  interval = 'SECOND'
238
233
  o.right.cast(:datetime)
239
234
  when /i\z/
240
- interval = DATE_MAPPING[o.left[0..-2]]
235
+ interval = Arel::Visitors::Oracle::DATE_MAPPING[o.left[0..-2]]
241
236
  collector << '('
242
237
  collector = visit o.right, collector
243
238
  collector << ") * (INTERVAL '1' #{interval})"
@@ -246,10 +241,10 @@ module ArelExtensions
246
241
  interval = nil
247
242
  o.right
248
243
  end
249
- collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
244
+ collector << "EXTRACT(#{Arel::Visitors::Oracle::DATE_MAPPING[o.left]} FROM "
250
245
  collector = visit right, collector
251
246
  end
252
- collector << ')'
247
+ collector << ")"
253
248
  collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
254
249
  collector
255
250
  end
@@ -257,45 +252,35 @@ module ArelExtensions
257
252
  def visit_ArelExtensions_Nodes_Cast o, collector
258
253
  case o.as_attr
259
254
  when :string
260
- collector << 'TO_CHAR('
261
- collector = visit o.left, collector
262
- collector << ')'
263
- return collector
264
- when :text
265
- collector << 'TO_CLOB('
266
- collector = visit o.left, collector
267
- collector << ')'
268
- return collector
269
- when :ntext
270
- collector << 'TO_NCLOB('
255
+ collector << "TO_CHAR("
271
256
  collector = visit o.left, collector
272
- collector << ')'
257
+ collector << ")"
273
258
  return collector
274
259
  when :time
275
260
  if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
276
- collector << 'TO_DATE('
261
+ collector << "TO_DATE("
277
262
  collector = visit o.left, collector
278
263
  collector << ",'HH24:MI:SS')"
279
264
  else
280
- collector << 'TO_DATE(TO_CHAR('
265
+ collector << "TO_DATE(TO_CHAR("
281
266
  collector = visit o.left, collector
282
267
  collector << ",'HH24:MI:SS'),'HH24:MI:SS')"
283
268
  end
284
269
  return collector
285
270
  when :number, :decimal
286
- collector << 'TO_NUMBER('
271
+ collector << "TO_NUMBER("
287
272
  collector = visit o.left, collector
288
- collector << ')'
273
+ collector << ")"
289
274
  return collector
290
275
  when :datetime
291
276
  as_attr = Arel::Nodes::SqlLiteral.new('timestamp')
292
277
  when :date
293
278
  if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
294
- collector << 'TO_DATE('
279
+ collector << "TO_DATE("
295
280
  collector = visit o.left, collector
296
281
  collector << ",'YYYY-MM-DD')"
297
282
  else
298
- collector << 'TO_DATE(TO_CHAR('
283
+ collector << "TO_DATE(TO_CHAR("
299
284
  collector = visit o.left, collector
300
285
  collector << ",'YYYY-MM-DD'),'YYYY-MM-DD')"
301
286
  end
@@ -305,18 +290,18 @@ module ArelExtensions
305
290
  else
306
291
  as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
307
292
  end
308
- collector << 'CAST('
293
+ collector << "CAST("
309
294
  collector = visit o.left, collector
310
- collector << ' AS '
295
+ collector << " AS "
311
296
  collector = visit as_attr, collector
312
- collector << ')'
297
+ collector << ")"
313
298
  collector
314
299
  end
315
300
 
316
301
  def visit_ArelExtensions_Nodes_Length o, collector
317
- collector << "LENGTH#{o.bytewise ? 'B' : ''}("
302
+ collector << "LENGTH("
318
303
  collector = visit o.expr, collector
319
- collector << ')'
304
+ collector << ")"
320
305
  collector
321
306
  end
322
307
 
@@ -333,51 +318,51 @@ module ArelExtensions
333
318
  end
334
319
 
335
320
  def visit_ArelExtensions_Nodes_Rand o, collector
336
- collector << 'DBMS_RANDOM.VALUE('
321
+ collector << "DBMS_RANDOM.VALUE("
337
322
  if o.left && o.right
338
323
  collector = visit o.left, collector
339
- collector << COMMA
324
+ collector << Arel::Visitors::Oracle::COMMA
340
325
  collector = visit o.right, collector
341
326
  end
342
- collector << ')'
327
+ collector << ")"
343
328
  collector
344
329
  end
345
330
 
346
331
  def visit_Arel_Nodes_Regexp o, collector
347
- collector << ' REGEXP_LIKE('
332
+ collector << " REGEXP_LIKE("
348
333
  collector = visit o.left, collector
349
- collector << COMMA
334
+ collector << Arel::Visitors::Oracle::COMMA
350
335
  collector = visit o.right, collector
351
336
  collector << ')'
352
337
  collector
353
338
  end
354
339
 
355
340
  def visit_Arel_Nodes_NotRegexp o, collector
356
- collector << ' NOT REGEXP_LIKE('
341
+ collector << " NOT REGEXP_LIKE("
357
342
  collector = visit o.left, collector
358
- collector << COMMA
343
+ collector << Arel::Visitors::Oracle::COMMA
359
344
  collector = visit o.right, collector
360
345
  collector << ')'
361
346
  collector
362
347
  end
363
348
 
364
349
  def visit_ArelExtensions_Nodes_Locate o, collector
365
- collector << 'INSTR('
350
+ collector << "INSTR("
366
351
  o.expressions.each_with_index { |arg, i|
367
- collector << COMMA if i != 0
352
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
368
353
  collector = visit arg, collector
369
354
  }
370
- collector << ')'
355
+ collector << ")"
371
356
  collector
372
357
  end
373
358
 
374
359
  def visit_ArelExtensions_Nodes_Substring o, collector
375
- collector << 'SUBSTR('
360
+ collector << "SUBSTR("
376
361
  o.expressions.each_with_index { |arg, i|
377
- collector << COMMA if i != 0
362
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
378
363
  collector = visit arg, collector
379
364
  }
380
- collector << ')'
365
+ collector << ")"
381
366
  collector
382
367
  end
383
368
 
@@ -393,17 +378,17 @@ module ArelExtensions
393
378
  if o.type_of_attribute(o.left) == :text
394
379
  collector << 'dbms_lob.SUBSTR('
395
380
  collector = visit o.left, collector
396
- collector << COMMA
381
+ collector << Arel::Visitors::Oracle::COMMA
397
382
  collector << 'COALESCE(dbms_lob.GETLENGTH('
398
383
  collector = visit o.left, collector
399
- collector << '), 0)'
400
- collector << COMMA
384
+ collector << "), 0)"
385
+ collector << Arel::Visitors::Oracle::COMMA
401
386
  collector << '1)'
402
387
  else
403
388
  collector = visit o.left, collector
404
389
  end
405
390
  collector << ')' if o.left.is_a? ArelExtensions::Nodes::Trim
406
- collector << ')'
391
+ collector << ")"
407
392
  collector
408
393
  end
409
394
 
@@ -416,7 +401,7 @@ module ArelExtensions
416
401
  end
417
402
  collector << ' FROM '
418
403
  collector = visit o.left, collector
419
- collector << ')'
404
+ collector << ")"
420
405
  collector
421
406
  end
422
407
 
@@ -429,7 +414,7 @@ module ArelExtensions
429
414
  end
430
415
  collector << ' FROM '
431
416
  collector = visit o.left, collector
432
- collector << ')'
417
+ collector << ")"
433
418
  collector
434
419
  end
435
420
 
@@ -444,92 +429,80 @@ module ArelExtensions
444
429
  def visit_ArelExtensions_Nodes_DateAdd o, collector
445
430
  collector << '('
446
431
  collector = visit o.left, collector
447
- collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
432
+ collector << ' + '# (o.right.value >= 0 ? ' + ' : ' - ')
448
433
  collector = visit o.oracle_value(o.right), collector
449
434
  collector << ')'
450
435
  collector
451
436
  end
452
437
 
453
438
  def visit_ArelExtensions_Nodes_Format o, collector
454
- visit_ArelExtensions_Nodes_FormattedDate o, collector
455
- end
456
-
457
- def visit_ArelExtensions_Nodes_FormattedDate o, collector
458
- fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
459
- collector << 'TO_CHAR('
460
- collector << 'CAST(' if o.time_zone
439
+ collector << "TO_CHAR("
461
440
  collector = visit o.left, collector
462
- case o.time_zone
463
- when Hash
464
- src_tz, dst_tz = o.time_zone.first
465
- collector << ' as timestamp) at time zone '
466
- collector = visit Arel.quoted(src_tz), collector
467
- collector < ' at time zone '
468
- collector = visit Arel.quoted(dst_tz), collector
469
- when String
470
- collector << ' as timestamp) at time zone '
471
- collector = visit Arel.quoted(o.time_zone), collector
472
- end
473
- collector << COMMA
474
- collector = visit Arel.quoted(fmt), collector
475
- collector << ')'
441
+ collector << Arel::Visitors::Oracle::COMMA
442
+
443
+ f = o.iso_format.gsub(/\ (\w+)/, ' "\1"')
444
+ Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
445
+ collector = visit Arel::Nodes.build_quoted(f), collector
446
+
447
+ collector << ")"
476
448
  collector
477
449
  end
478
450
 
479
451
  def visit_ArelExtensions_Nodes_Repeat o, collector
480
- collector << 'LPAD('
481
- collector = visit o.expressions[0], collector # can't put empty string, otherwise it wouldn't work
452
+ collector << "LPAD("
453
+ collector = visit o.expressions[0], collector #can't put empty string, otherwise it wouldn't work
482
454
  collector << Arel::Visitors::ToSql::COMMA
483
455
  collector = visit o.expressions[1], collector
484
456
  collector << Arel::Visitors::ToSql::COMMA
485
457
  collector = visit o.expressions[0], collector
486
- collector << ')'
458
+ collector << ")"
487
459
  collector
488
460
  end
489
461
 
490
- # add primary_key if not present, avoid zip
462
+ # add primary_key if not present, avoid zip
491
463
  if Arel::VERSION.to_i < 7
492
464
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
493
- collector << '('
465
+ collector << "("
494
466
  o.left.each_with_index do |row, idx| # values
495
- collector << ' UNION ALL ' if idx != 0
496
- collector << '(SELECT '
497
- len = row.length - 1
498
- row.zip(o.cols).each_with_index { |(value, attr), i|
499
- case value
500
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
501
- collector = visit value, collector
502
- else
503
- collector << quote(value, attr && column_for(attr)).to_s
504
- end
505
- collector << COMMA unless i == len
467
+ collector << " UNION ALL " if idx != 0
468
+ collector << "(SELECT "
469
+ v = Arel::Nodes::Values.new(row, o.cols)
470
+ len = v.expressions.length - 1
471
+ v.expressions.each_with_index { |value, i|
472
+ case value
473
+ when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
474
+ collector = visit value, collector
475
+ else
476
+ attr = v.columns[i]
477
+ collector << quote(value, attr && column_for(attr)).to_s
478
+ end
479
+ collector << Arel::Visitors::Oracle::COMMA unless i == len
506
480
  }
507
481
  collector << ' FROM DUAL)'
508
482
  end
509
- collector << ')'
483
+ collector << ")"
510
484
  collector
511
485
  end
512
486
  else
513
487
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
514
- collector << '('
488
+ collector << "("
515
489
  o.left.each_with_index do |row, idx|
516
- collector << ' UNION ALL ' if idx != 0
517
- collector << '(SELECT '
490
+ collector << " UNION ALL " if idx != 0
491
+ collector << "(SELECT "
518
492
  len = row.length - 1
519
- row.zip(o.cols).each_with_index { |(value, attr), i|
493
+ row.each_with_index { |value, i|
494
+ attr = o.cols[i]
520
495
  case value
521
496
  when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
522
497
  collector = visit value, collector
523
- when Integer
524
- collector << value.to_s
525
498
  else
526
499
  collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
527
500
  end
528
- collector << COMMA unless i == len
501
+ collector << Arel::Visitors::Oracle::COMMA unless i == len
529
502
  }
530
503
  collector << ' FROM DUAL)'
531
504
  end
532
- collector << ')'
505
+ collector << ")"
533
506
  collector
534
507
  end
535
508
  end
@@ -539,7 +512,7 @@ module ArelExtensions
539
512
  if element.is_a?(Time)
540
513
  ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
541
514
  elsif element.is_a?(Arel::Attributes::Attribute)
542
- col = Arel.column_of(element.relation.table_name, element.name.to_s)
515
+ col = Arel::Table.engine.connection.schema_cache.columns_hash(element.relation.table_name)[element.name.to_s]
543
516
  if col && (col.type == :time)
544
517
  ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
545
518
  else
@@ -554,7 +527,7 @@ module ArelExtensions
554
527
  remove_method(:visit_Arel_Nodes_GreaterThanOrEqual) rescue nil
555
528
  def visit_Arel_Nodes_GreaterThanOrEqual o, collector
556
529
  collector = visit get_time_converted(o.left), collector
557
- collector << ' >= '
530
+ collector << " >= "
558
531
  collector = visit get_time_converted(o.right), collector
559
532
  collector
560
533
  end
@@ -562,7 +535,7 @@ module ArelExtensions
562
535
  remove_method(:visit_Arel_Nodes_GreaterThan) rescue nil
563
536
  def visit_Arel_Nodes_GreaterThan o, collector
564
537
  collector = visit get_time_converted(o.left), collector
565
- collector << ' > '
538
+ collector << " > "
566
539
  collector = visit get_time_converted(o.right), collector
567
540
  collector
568
541
  end
@@ -570,7 +543,7 @@ module ArelExtensions
570
543
  remove_method(:visit_Arel_Nodes_LessThanOrEqual) rescue nil
571
544
  def visit_Arel_Nodes_LessThanOrEqual o, collector
572
545
  collector = visit get_time_converted(o.left), collector
573
- collector << ' <= '
546
+ collector << " <= "
574
547
  collector = visit get_time_converted(o.right), collector
575
548
  collector
576
549
  end
@@ -578,30 +551,30 @@ module ArelExtensions
578
551
  remove_method(:visit_Arel_Nodes_LessThan) rescue nil
579
552
  def visit_Arel_Nodes_LessThan o, collector
580
553
  collector = visit get_time_converted(o.left), collector
581
- collector << ' < '
554
+ collector << " < "
582
555
  collector = visit get_time_converted(o.right), collector
583
556
  collector
584
557
  end
585
558
 
586
559
 
587
- alias_method(:old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement) rescue nil
560
+ alias_method :old_visit_Arel_Nodes_SelectStatement, :visit_Arel_Nodes_SelectStatement
588
561
  def visit_Arel_Nodes_SelectStatement o, collector
589
562
  if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
590
563
  o = o.dup
591
564
  o.orders = []
592
565
  end
593
- old_visit_Arel_Nodes_SelectStatement(o, collector)
566
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
594
567
  end
595
568
 
596
- alias_method(:old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias) rescue nil
569
+ alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
597
570
  def visit_Arel_Nodes_TableAlias o, collector
598
571
  if o.name.length > 30
599
- o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
572
+ o = Arel::Table.new(o.table_name).alias(Base64.urlsafe_encode64(Digest::MD5.new.digest(o.name)).tr('=', '').tr('-', '_'))
600
573
  end
601
- old_visit_Arel_Nodes_TableAlias(o, collector)
574
+ old_visit_Arel_Nodes_TableAlias(o,collector)
602
575
  end
603
576
 
604
- alias_method(:old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As) rescue nil
577
+ alias_method :old_visit_Arel_Nodes_As, :visit_Arel_Nodes_As
605
578
  def visit_Arel_Nodes_As o, collector
606
579
  if o.left.is_a?(Arel::Nodes::Binary)
607
580
  collector << '('
@@ -610,7 +583,7 @@ module ArelExtensions
610
583
  else
611
584
  collector = visit o.left, collector
612
585
  end
613
- quote = /(\A".*"\z)|\A[a-zA-Z_]*\z/.match?(o.right.to_s) ? '' : '"'
586
+ quote = o.right.to_s =~ /(\A["].*["]\z)|\A[a-zA-Z_]*\z/ ? '' : '"'
614
587
  collector << " AS #{quote}"
615
588
  collector = visit o.right, collector
616
589
  collector << "#{quote}"
@@ -621,7 +594,7 @@ module ArelExtensions
621
594
  visit_Arel_Nodes_As o, collector
622
595
  end
623
596
 
624
- alias_method(:old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute) rescue nil
597
+ alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
625
598
  def visit_Arel_Attributes_Attribute o, collector
626
599
  join_name = o.relation.table_alias || o.relation.name
627
600
  if join_name.length > 30
@@ -630,56 +603,52 @@ module ArelExtensions
630
603
  collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
631
604
  end
632
605
 
606
+
633
607
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
634
608
  col = o.left.coalesce(0)
635
- comma = NUMBER_COMMA_MAPPING[o.locale] || '.,'
609
+ comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
636
610
  comma_in_format = o.precision == 0 ? '' : 'D'
637
- nines_after = (1..o.precision - 1).map{'9'}.join('') + '0'
611
+ nines_after = (1..o.precision-1).map{'9'}.join('')+'0'
638
612
  if comma.length == 1
639
- options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma} '")
640
- nines_before = ('999' * 4 + '990')
613
+ options = Arel::Nodes.build_quoted("NLS_NUMERIC_CHARACTERS = '"+comma+" '")
614
+ nines_before = ("999"*4+"990")
641
615
  else
642
- options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma}'")
643
- nines_before = ('999G' * 4 + '990')
616
+ options = Arel::Nodes.build_quoted("NLS_NUMERIC_CHARACTERS = '"+comma+"'")
617
+ nines_before = ("999G"*4+"990")
644
618
  end
645
- sign = Arel.when(col < 0).
619
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
646
620
  then('-').
647
621
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
648
622
  sign_length = o.flags.include?('+') || o.flags.include?(' ') ?
649
- Arel.quoted(1) :
650
- Arel.when(col < 0).then(1).else(0)
623
+ Arel::Nodes.build_quoted(1) :
624
+ ArelExtensions::Nodes::Case.new.when(col<0).then(1).else(0)
651
625
 
652
626
  if o.scientific_notation
653
- number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
654
- Arel.quoted(col.abs),
655
- Arel.quoted("FM#{nines_before}#{comma_in_format}#{nines_after}EEEE"),
627
+ number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
628
+ Arel::Nodes.build_quoted(col.abs),
629
+ Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after+'EEEE'),
656
630
  options
657
631
  ])
658
632
  if o.type == 'e'
659
- number = number.replace('E', 'e')
633
+ number = number.replace('E','e')
660
634
  end
661
635
  else
662
- number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
663
- Arel.quoted(col.abs),
664
- Arel.quoted("FM#{nines_before}#{comma_in_format}#{nines_after}"),
636
+ number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
637
+ Arel::Nodes.build_quoted(col.abs),
638
+ Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after),
665
639
  options
666
640
  ])
667
641
  end
668
642
 
669
- repeated_char =
670
- if o.width == 0
671
- Arel.quoted('')
672
- else
673
- Arel
674
- .when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
675
- .then(Arel.quoted(
676
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
677
- ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
678
- )
679
- .else('')
680
- end
681
- before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
682
- middle = o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
643
+ repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
644
+ when(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length)>0).
645
+ then(Arel::Nodes.build_quoted(
646
+ o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
647
+ ).repeat(Arel::Nodes.build_quoted(o.width).abs-(number.length+sign_length))
648
+ ).
649
+ else('')
650
+ before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
651
+ middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
683
652
  after = o.flags.include?('-') ? repeated_char : ''
684
653
  full_number = ArelExtensions::Nodes::Concat.new([
685
654
  before,
@@ -688,26 +657,26 @@ module ArelExtensions
688
657
  number,
689
658
  after
690
659
  ])
691
- collector = visit ArelExtensions::Nodes::Concat.new([Arel.quoted(o.prefix), full_number, Arel.quoted(o.suffix)]), collector
660
+ collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
692
661
  collector
693
662
  end
694
663
 
695
664
  def visit_ArelExtensions_Nodes_Std o, collector
696
- collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
665
+ collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
697
666
  visit o.left, collector
698
- collector << ')'
667
+ collector << ")"
699
668
  collector
700
669
  end
701
670
 
702
671
  def visit_ArelExtensions_Nodes_Variance o, collector
703
- collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
672
+ collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
704
673
  visit o.left, collector
705
- collector << ')'
674
+ collector << ")"
706
675
  collector
707
676
  end
708
677
 
709
678
  def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
710
- collector << 'UTL_MATCH.edit_distance('
679
+ collector << "UTL_MATCH.edit_distance("
711
680
  collector = visit o.left, collector
712
681
  collector << Arel::Visitors::ToSql::COMMA
713
682
  collector = visit o.right, collector
@@ -715,17 +684,6 @@ module ArelExtensions
715
684
  collector
716
685
  end
717
686
 
718
- # Utilized by GroupingSet, Cube & RollUp visitors to
719
- # handle grouping aggregation semantics
720
- def grouping_array_or_grouping_element(o, collector)
721
- if o.expr.is_a? Array
722
- collector << "( "
723
- visit o.expr, collector
724
- collector << " )"
725
- else
726
- visit o.expr, collector
727
- end
728
- end
729
687
  end
730
688
  end
731
689
  end