arel_extensions 1.5.3 → 2.0.0.rc3

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.
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 +25 -24
  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 -29
  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 +36 -82
  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 -721
  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 -30
  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 -109
  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 -34
  123. data/gemfiles/rails6_1.gemfile +0 -42
  124. data/gemfiles/rails7.gemfile +0 -42
  125. data/gemfiles/rails7_1.gemfile +0 -41
  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