arel_extensions 1.5.2 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) 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 +28 -2
  13. data/README.md +90 -239
  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 -7
  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 -48
  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 +35 -78
  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 +192 -423
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -354
  84. data/lib/arel_extensions/visitors/oracle.rb +178 -221
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -257
  87. data/lib/arel_extensions/visitors/sqlite.rb +126 -140
  88. data/lib/arel_extensions/visitors/to_sql.rb +237 -299
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +31 -226
  91. data/test/database.yml +7 -15
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +117 -120
  94. data/test/support/fake_record.rb +3 -9
  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 +366 -711
  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 +37 -47
  108. data/.github/workflows/publish.yml +0 -29
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -403
  111. data/CONTRIBUTING.md +0 -102
  112. data/NEWS.md +0 -104
  113. data/bin/build +0 -15
  114. data/bin/compose +0 -6
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -44
  117. data/dev/compose.yaml +0 -71
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails4_2.gemfile +0 -38
  121. data/gemfiles/rails5.gemfile +0 -29
  122. data/gemfiles/rails6.gemfile +0 -33
  123. data/gemfiles/rails6_1.gemfile +0 -41
  124. data/gemfiles/rails7.gemfile +0 -41
  125. data/gemfiles/rails7_1.gemfile +0 -42
  126. data/gemfiles/rails7_2.gemfile +0 -41
  127. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  128. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  129. data/generate_gems.sh +0 -15
  130. data/lib/arel_extensions/aliases.rb +0 -14
  131. data/lib/arel_extensions/helpers.rb +0 -62
  132. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  133. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  134. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  135. data/lib/arel_extensions/nodes/select.rb +0 -10
  136. data/lib/arel_extensions/nodes/sum.rb +0 -7
  137. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  138. data/lib/arel_extensions/warning.rb +0 -42
  139. data/test/arelx_test_helper.rb +0 -92
  140. data/version_v1.rb +0 -3
  141. 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,60 +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
- sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
139
- collector =
140
- if 'NULL' != sep
141
- visit o.separator, collector
142
- else
143
- visit Arel.quoted(','), collector
144
- end
145
- collector << ') WITHIN GROUP (ORDER BY '
146
- if !o.order.blank?
147
- o.order.each_with_index do |order, i|
148
- 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
149
143
  collector = visit order, collector
150
144
  end
151
145
  else
152
146
  collector = visit o.left, collector
153
147
  end
154
- collector << '))'
148
+ collector << "))"
155
149
  collector
156
150
  end
157
151
 
158
152
  def visit_ArelExtensions_Nodes_Coalesce o, collector
159
- collector << 'COALESCE('
153
+ collector << "COALESCE("
160
154
  o.expressions.each_with_index { |arg, i|
161
- collector << COMMA if i != 0
155
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
162
156
  if i > 0 && o.left_node_type == :text
163
- if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
164
- collector << 'NULL'
157
+ if arg == '' || (arg.is_a?(Arel::Nodes::Quoted) && (arg.expr == ''))
158
+ collector << "NULL"
165
159
  else
166
160
  collector << 'TO_CLOB('
167
161
  collector = visit arg, collector
@@ -171,12 +165,12 @@ module ArelExtensions
171
165
  collector = visit arg, collector
172
166
  end
173
167
  }
174
- collector << ')'
168
+ collector << ")"
175
169
  collector
176
170
  end
177
171
 
178
172
  def visit_ArelExtensions_Nodes_MD5 o, collector
179
- 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("
180
174
  collector = visit o.left, collector
181
175
  collector << ", 'AL32UTF8'))))"
182
176
  collector
@@ -191,7 +185,7 @@ module ArelExtensions
191
185
  collector << 'TO_DATE(' if lc
192
186
  collector = visit o.left, collector
193
187
  collector << ')' if lc
194
- collector << ' - '
188
+ collector << " - "
195
189
  collector << 'TO_DATE(' if rc
196
190
  collector = visit o.right, collector
197
191
  collector << ')' if rc
@@ -201,7 +195,7 @@ module ArelExtensions
201
195
  collector << 'TO_DATE(' if lc
202
196
  collector = visit o.left, collector
203
197
  collector << ')' if lc
204
- collector << COMMA
198
+ collector << Arel::Visitors::Oracle::COMMA
205
199
  collector << "'DDD') = "
206
200
  collector << 'TO_DATE(' if lc
207
201
  collector = visit o.left, collector
@@ -225,20 +219,20 @@ module ArelExtensions
225
219
  def visit_ArelExtensions_Nodes_Duration o, collector
226
220
  case o.left
227
221
  when 'wd', 'w'
228
- collector << 'TO_CHAR('
222
+ collector << "TO_CHAR("
229
223
  collector = visit o.right, collector
230
- collector << COMMA
231
- 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
232
226
  else
233
227
  right = case o.left
234
- when 'd', 'm', 'y'
228
+ when 'd','m','y'
235
229
  interval = 'DAY'
236
230
  o.right.cast(:date)
237
- when 'h', 'mn', 's'
231
+ when 'h','mn','s'
238
232
  interval = 'SECOND'
239
233
  o.right.cast(:datetime)
240
234
  when /i\z/
241
- interval = DATE_MAPPING[o.left[0..-2]]
235
+ interval = Arel::Visitors::Oracle::DATE_MAPPING[o.left[0..-2]]
242
236
  collector << '('
243
237
  collector = visit o.right, collector
244
238
  collector << ") * (INTERVAL '1' #{interval})"
@@ -247,10 +241,10 @@ module ArelExtensions
247
241
  interval = nil
248
242
  o.right
249
243
  end
250
- collector << "EXTRACT(#{DATE_MAPPING[o.left]} FROM "
244
+ collector << "EXTRACT(#{Arel::Visitors::Oracle::DATE_MAPPING[o.left]} FROM "
251
245
  collector = visit right, collector
252
246
  end
253
- collector << ')'
247
+ collector << ")"
254
248
  collector << " * (INTERVAL '1' #{interval})" if interval && o.with_interval
255
249
  collector
256
250
  end
@@ -258,45 +252,35 @@ module ArelExtensions
258
252
  def visit_ArelExtensions_Nodes_Cast o, collector
259
253
  case o.as_attr
260
254
  when :string
261
- collector << 'TO_CHAR('
262
- collector = visit o.left, collector
263
- collector << ')'
264
- return collector
265
- when :text
266
- collector << 'TO_CLOB('
267
- collector = visit o.left, collector
268
- collector << ')'
269
- return collector
270
- when :ntext
271
- collector << 'TO_NCLOB('
255
+ collector << "TO_CHAR("
272
256
  collector = visit o.left, collector
273
- collector << ')'
257
+ collector << ")"
274
258
  return collector
275
259
  when :time
276
260
  if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
277
- collector << 'TO_DATE('
261
+ collector << "TO_DATE("
278
262
  collector = visit o.left, collector
279
263
  collector << ",'HH24:MI:SS')"
280
264
  else
281
- collector << 'TO_DATE(TO_CHAR('
265
+ collector << "TO_DATE(TO_CHAR("
282
266
  collector = visit o.left, collector
283
267
  collector << ",'HH24:MI:SS'),'HH24:MI:SS')"
284
268
  end
285
269
  return collector
286
270
  when :number, :decimal
287
- collector << 'TO_NUMBER('
271
+ collector << "TO_NUMBER("
288
272
  collector = visit o.left, collector
289
- collector << ')'
273
+ collector << ")"
290
274
  return collector
291
275
  when :datetime
292
276
  as_attr = Arel::Nodes::SqlLiteral.new('timestamp')
293
277
  when :date
294
278
  if (o.left.respond_to?(:return_type) && o.left.return_type == :string) || o.left.is_a?(Arel::Nodes::Quoted)
295
- collector << 'TO_DATE('
279
+ collector << "TO_DATE("
296
280
  collector = visit o.left, collector
297
281
  collector << ",'YYYY-MM-DD')"
298
282
  else
299
- collector << 'TO_DATE(TO_CHAR('
283
+ collector << "TO_DATE(TO_CHAR("
300
284
  collector = visit o.left, collector
301
285
  collector << ",'YYYY-MM-DD'),'YYYY-MM-DD')"
302
286
  end
@@ -306,18 +290,18 @@ module ArelExtensions
306
290
  else
307
291
  as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
308
292
  end
309
- collector << 'CAST('
293
+ collector << "CAST("
310
294
  collector = visit o.left, collector
311
- collector << ' AS '
295
+ collector << " AS "
312
296
  collector = visit as_attr, collector
313
- collector << ')'
297
+ collector << ")"
314
298
  collector
315
299
  end
316
300
 
317
301
  def visit_ArelExtensions_Nodes_Length o, collector
318
- collector << "LENGTH#{o.bytewise ? 'B' : ''}("
302
+ collector << "LENGTH("
319
303
  collector = visit o.expr, collector
320
- collector << ')'
304
+ collector << ")"
321
305
  collector
322
306
  end
323
307
 
@@ -334,51 +318,51 @@ module ArelExtensions
334
318
  end
335
319
 
336
320
  def visit_ArelExtensions_Nodes_Rand o, collector
337
- collector << 'DBMS_RANDOM.VALUE('
321
+ collector << "DBMS_RANDOM.VALUE("
338
322
  if o.left && o.right
339
323
  collector = visit o.left, collector
340
- collector << COMMA
324
+ collector << Arel::Visitors::Oracle::COMMA
341
325
  collector = visit o.right, collector
342
326
  end
343
- collector << ')'
327
+ collector << ")"
344
328
  collector
345
329
  end
346
330
 
347
331
  def visit_Arel_Nodes_Regexp o, collector
348
- collector << ' REGEXP_LIKE('
332
+ collector << " REGEXP_LIKE("
349
333
  collector = visit o.left, collector
350
- collector << COMMA
334
+ collector << Arel::Visitors::Oracle::COMMA
351
335
  collector = visit o.right, collector
352
336
  collector << ')'
353
337
  collector
354
338
  end
355
339
 
356
340
  def visit_Arel_Nodes_NotRegexp o, collector
357
- collector << ' NOT REGEXP_LIKE('
341
+ collector << " NOT REGEXP_LIKE("
358
342
  collector = visit o.left, collector
359
- collector << COMMA
343
+ collector << Arel::Visitors::Oracle::COMMA
360
344
  collector = visit o.right, collector
361
345
  collector << ')'
362
346
  collector
363
347
  end
364
348
 
365
349
  def visit_ArelExtensions_Nodes_Locate o, collector
366
- collector << 'INSTR('
350
+ collector << "INSTR("
367
351
  o.expressions.each_with_index { |arg, i|
368
- collector << COMMA if i != 0
352
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
369
353
  collector = visit arg, collector
370
354
  }
371
- collector << ')'
355
+ collector << ")"
372
356
  collector
373
357
  end
374
358
 
375
359
  def visit_ArelExtensions_Nodes_Substring o, collector
376
- collector << 'SUBSTR('
360
+ collector << "SUBSTR("
377
361
  o.expressions.each_with_index { |arg, i|
378
- collector << COMMA if i != 0
362
+ collector << Arel::Visitors::Oracle::COMMA unless i == 0
379
363
  collector = visit arg, collector
380
364
  }
381
- collector << ')'
365
+ collector << ")"
382
366
  collector
383
367
  end
384
368
 
@@ -394,17 +378,17 @@ module ArelExtensions
394
378
  if o.type_of_attribute(o.left) == :text
395
379
  collector << 'dbms_lob.SUBSTR('
396
380
  collector = visit o.left, collector
397
- collector << COMMA
381
+ collector << Arel::Visitors::Oracle::COMMA
398
382
  collector << 'COALESCE(dbms_lob.GETLENGTH('
399
383
  collector = visit o.left, collector
400
- collector << '), 0)'
401
- collector << COMMA
384
+ collector << "), 0)"
385
+ collector << Arel::Visitors::Oracle::COMMA
402
386
  collector << '1)'
403
387
  else
404
388
  collector = visit o.left, collector
405
389
  end
406
390
  collector << ')' if o.left.is_a? ArelExtensions::Nodes::Trim
407
- collector << ')'
391
+ collector << ")"
408
392
  collector
409
393
  end
410
394
 
@@ -417,7 +401,7 @@ module ArelExtensions
417
401
  end
418
402
  collector << ' FROM '
419
403
  collector = visit o.left, collector
420
- collector << ')'
404
+ collector << ")"
421
405
  collector
422
406
  end
423
407
 
@@ -430,7 +414,7 @@ module ArelExtensions
430
414
  end
431
415
  collector << ' FROM '
432
416
  collector = visit o.left, collector
433
- collector << ')'
417
+ collector << ")"
434
418
  collector
435
419
  end
436
420
 
@@ -445,92 +429,80 @@ module ArelExtensions
445
429
  def visit_ArelExtensions_Nodes_DateAdd o, collector
446
430
  collector << '('
447
431
  collector = visit o.left, collector
448
- collector << ' + ' # (o.right.value >= 0 ? ' + ' : ' - ')
432
+ collector << ' + '# (o.right.value >= 0 ? ' + ' : ' - ')
449
433
  collector = visit o.oracle_value(o.right), collector
450
434
  collector << ')'
451
435
  collector
452
436
  end
453
437
 
454
438
  def visit_ArelExtensions_Nodes_Format o, collector
455
- visit_ArelExtensions_Nodes_FormattedDate o, collector
456
- end
457
-
458
- def visit_ArelExtensions_Nodes_FormattedDate o, collector
459
- fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
460
- collector << 'TO_CHAR('
461
- collector << 'CAST(' if o.time_zone
439
+ collector << "TO_CHAR("
462
440
  collector = visit o.left, collector
463
- case o.time_zone
464
- when Hash
465
- src_tz, dst_tz = o.time_zone.first
466
- collector << ' as timestamp) at time zone '
467
- collector = visit Arel.quoted(src_tz), collector
468
- collector < ' at time zone '
469
- collector = visit Arel.quoted(dst_tz), collector
470
- when String
471
- collector << ' as timestamp) at time zone '
472
- collector = visit Arel.quoted(o.time_zone), collector
473
- end
474
- collector << COMMA
475
- collector = visit Arel.quoted(fmt), collector
476
- 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 << ")"
477
448
  collector
478
449
  end
479
450
 
480
451
  def visit_ArelExtensions_Nodes_Repeat o, collector
481
- collector << 'LPAD('
482
- 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
483
454
  collector << Arel::Visitors::ToSql::COMMA
484
455
  collector = visit o.expressions[1], collector
485
456
  collector << Arel::Visitors::ToSql::COMMA
486
457
  collector = visit o.expressions[0], collector
487
- collector << ')'
458
+ collector << ")"
488
459
  collector
489
460
  end
490
461
 
491
- # add primary_key if not present, avoid zip
462
+ # add primary_key if not present, avoid zip
492
463
  if Arel::VERSION.to_i < 7
493
464
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
494
- collector << '('
465
+ collector << "("
495
466
  o.left.each_with_index do |row, idx| # values
496
- collector << ' UNION ALL ' if idx != 0
497
- collector << '(SELECT '
498
- len = row.length - 1
499
- row.zip(o.cols).each_with_index { |(value, attr), i|
500
- case value
501
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
502
- collector = visit value, collector
503
- else
504
- collector << quote(value, attr && column_for(attr)).to_s
505
- end
506
- 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
507
480
  }
508
481
  collector << ' FROM DUAL)'
509
482
  end
510
- collector << ')'
483
+ collector << ")"
511
484
  collector
512
485
  end
513
486
  else
514
487
  def visit_ArelExtensions_InsertManager_BulkValues o, collector
515
- collector << '('
488
+ collector << "("
516
489
  o.left.each_with_index do |row, idx|
517
- collector << ' UNION ALL ' if idx != 0
518
- collector << '(SELECT '
490
+ collector << " UNION ALL " if idx != 0
491
+ collector << "(SELECT "
519
492
  len = row.length - 1
520
- row.zip(o.cols).each_with_index { |(value, attr), i|
493
+ row.each_with_index { |value, i|
494
+ attr = o.cols[i]
521
495
  case value
522
496
  when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
523
497
  collector = visit value, collector
524
- when Integer
525
- collector << value.to_s
526
498
  else
527
499
  collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
528
500
  end
529
- collector << COMMA unless i == len
501
+ collector << Arel::Visitors::Oracle::COMMA unless i == len
530
502
  }
531
503
  collector << ' FROM DUAL)'
532
504
  end
533
- collector << ')'
505
+ collector << ")"
534
506
  collector
535
507
  end
536
508
  end
@@ -540,7 +512,7 @@ module ArelExtensions
540
512
  if element.is_a?(Time)
541
513
  ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
542
514
  elsif element.is_a?(Arel::Attributes::Attribute)
543
- 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]
544
516
  if col && (col.type == :time)
545
517
  ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
546
518
  else
@@ -555,7 +527,7 @@ module ArelExtensions
555
527
  remove_method(:visit_Arel_Nodes_GreaterThanOrEqual) rescue nil
556
528
  def visit_Arel_Nodes_GreaterThanOrEqual o, collector
557
529
  collector = visit get_time_converted(o.left), collector
558
- collector << ' >= '
530
+ collector << " >= "
559
531
  collector = visit get_time_converted(o.right), collector
560
532
  collector
561
533
  end
@@ -563,7 +535,7 @@ module ArelExtensions
563
535
  remove_method(:visit_Arel_Nodes_GreaterThan) rescue nil
564
536
  def visit_Arel_Nodes_GreaterThan o, collector
565
537
  collector = visit get_time_converted(o.left), collector
566
- collector << ' > '
538
+ collector << " > "
567
539
  collector = visit get_time_converted(o.right), collector
568
540
  collector
569
541
  end
@@ -571,7 +543,7 @@ module ArelExtensions
571
543
  remove_method(:visit_Arel_Nodes_LessThanOrEqual) rescue nil
572
544
  def visit_Arel_Nodes_LessThanOrEqual o, collector
573
545
  collector = visit get_time_converted(o.left), collector
574
- collector << ' <= '
546
+ collector << " <= "
575
547
  collector = visit get_time_converted(o.right), collector
576
548
  collector
577
549
  end
@@ -579,30 +551,30 @@ module ArelExtensions
579
551
  remove_method(:visit_Arel_Nodes_LessThan) rescue nil
580
552
  def visit_Arel_Nodes_LessThan o, collector
581
553
  collector = visit get_time_converted(o.left), collector
582
- collector << ' < '
554
+ collector << " < "
583
555
  collector = visit get_time_converted(o.right), collector
584
556
  collector
585
557
  end
586
558
 
587
559
 
588
- 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
589
561
  def visit_Arel_Nodes_SelectStatement o, collector
590
562
  if !(collector.value.blank? || (collector.value.is_a?(Array) && collector.value[0].blank?)) && o.limit.blank? && o.offset.blank?
591
563
  o = o.dup
592
564
  o.orders = []
593
565
  end
594
- old_visit_Arel_Nodes_SelectStatement(o, collector)
566
+ old_visit_Arel_Nodes_SelectStatement(o,collector)
595
567
  end
596
568
 
597
- 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
598
570
  def visit_Arel_Nodes_TableAlias o, collector
599
571
  if o.name.length > 30
600
- 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('-', '_'))
601
573
  end
602
- old_visit_Arel_Nodes_TableAlias(o, collector)
574
+ old_visit_Arel_Nodes_TableAlias(o,collector)
603
575
  end
604
576
 
605
- 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
606
578
  def visit_Arel_Nodes_As o, collector
607
579
  if o.left.is_a?(Arel::Nodes::Binary)
608
580
  collector << '('
@@ -611,7 +583,7 @@ module ArelExtensions
611
583
  else
612
584
  collector = visit o.left, collector
613
585
  end
614
- 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/ ? '' : '"'
615
587
  collector << " AS #{quote}"
616
588
  collector = visit o.right, collector
617
589
  collector << "#{quote}"
@@ -622,7 +594,7 @@ module ArelExtensions
622
594
  visit_Arel_Nodes_As o, collector
623
595
  end
624
596
 
625
- 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
626
598
  def visit_Arel_Attributes_Attribute o, collector
627
599
  join_name = o.relation.table_alias || o.relation.name
628
600
  if join_name.length > 30
@@ -631,56 +603,52 @@ module ArelExtensions
631
603
  collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
632
604
  end
633
605
 
606
+
634
607
  def visit_ArelExtensions_Nodes_FormattedNumber o, collector
635
608
  col = o.left.coalesce(0)
636
- comma = NUMBER_COMMA_MAPPING[o.locale] || '.,'
609
+ comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
637
610
  comma_in_format = o.precision == 0 ? '' : 'D'
638
- nines_after = (1..o.precision - 1).map{'9'}.join('') + '0'
611
+ nines_after = (1..o.precision-1).map{'9'}.join('')+'0'
639
612
  if comma.length == 1
640
- options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma} '")
641
- nines_before = ('999' * 4 + '990')
613
+ options = Arel::Nodes.build_quoted("NLS_NUMERIC_CHARACTERS = '"+comma+" '")
614
+ nines_before = ("999"*4+"990")
642
615
  else
643
- options = Arel.quoted("NLS_NUMERIC_CHARACTERS = '#{comma}'")
644
- nines_before = ('999G' * 4 + '990')
616
+ options = Arel::Nodes.build_quoted("NLS_NUMERIC_CHARACTERS = '"+comma+"'")
617
+ nines_before = ("999G"*4+"990")
645
618
  end
646
- sign = Arel.when(col < 0).
619
+ sign = ArelExtensions::Nodes::Case.new.when(col<0).
647
620
  then('-').
648
621
  else(o.flags.include?('+') ? '+' : (o.flags.include?(' ') ? ' ' : ''))
649
622
  sign_length = o.flags.include?('+') || o.flags.include?(' ') ?
650
- Arel.quoted(1) :
651
- 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)
652
625
 
653
626
  if o.scientific_notation
654
- number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
655
- Arel.quoted(col.abs),
656
- 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'),
657
630
  options
658
631
  ])
659
632
  if o.type == 'e'
660
- number = number.replace('E', 'e')
633
+ number = number.replace('E','e')
661
634
  end
662
635
  else
663
- number = Arel::Nodes::NamedFunction.new('TO_CHAR', [
664
- Arel.quoted(col.abs),
665
- 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),
666
639
  options
667
640
  ])
668
641
  end
669
642
 
670
- repeated_char =
671
- if o.width == 0
672
- Arel.quoted('')
673
- else
674
- Arel
675
- .when(Arel.quoted(o.width).abs - (number.length + sign_length) > 0)
676
- .then(Arel.quoted(
677
- o.flags.include?('-') ? ' ' : (o.flags.include?('0') ? '0' : ' ')
678
- ).repeat(Arel.quoted(o.width).abs - (number.length + sign_length))
679
- )
680
- .else('')
681
- end
682
- before = !o.flags.include?('0') && !o.flags.include?('-') ? repeated_char : ''
683
- 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 : ''
684
652
  after = o.flags.include?('-') ? repeated_char : ''
685
653
  full_number = ArelExtensions::Nodes::Concat.new([
686
654
  before,
@@ -689,26 +657,26 @@ module ArelExtensions
689
657
  number,
690
658
  after
691
659
  ])
692
- 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
693
661
  collector
694
662
  end
695
663
 
696
664
  def visit_ArelExtensions_Nodes_Std o, collector
697
- collector << (o.unbiased_estimator ? 'STDDEV_SAMP(' : 'STDDEV_POP(')
665
+ collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
698
666
  visit o.left, collector
699
- collector << ')'
667
+ collector << ")"
700
668
  collector
701
669
  end
702
670
 
703
671
  def visit_ArelExtensions_Nodes_Variance o, collector
704
- collector << (o.unbiased_estimator ? 'VAR_SAMP(' : 'VAR_POP(')
672
+ collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
705
673
  visit o.left, collector
706
- collector << ')'
674
+ collector << ")"
707
675
  collector
708
676
  end
709
677
 
710
678
  def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
711
- collector << 'UTL_MATCH.edit_distance('
679
+ collector << "UTL_MATCH.edit_distance("
712
680
  collector = visit o.left, collector
713
681
  collector << Arel::Visitors::ToSql::COMMA
714
682
  collector = visit o.right, collector
@@ -716,17 +684,6 @@ module ArelExtensions
716
684
  collector
717
685
  end
718
686
 
719
- # Utilized by GroupingSet, Cube & RollUp visitors to
720
- # handle grouping aggregation semantics
721
- def grouping_array_or_grouping_element(o, collector)
722
- if o.expr.is_a? Array
723
- collector << "( "
724
- visit o.expr, collector
725
- collector << " )"
726
- else
727
- visit o.expr, collector
728
- end
729
- end
730
687
  end
731
688
  end
732
689
  end