arel_extensions 1.7.0 → 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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -8
  4. data/.rubocop.yml +4 -194
  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 +89 -265
  14. data/Rakefile +30 -50
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +17 -14
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +20 -0
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  22. data/gemfiles/rails5_1_4.gemfile +17 -19
  23. data/gemfiles/rails5_2.gemfile +17 -26
  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 -9
  30. data/lib/arel_extensions/boolean_functions.rb +16 -57
  31. data/lib/arel_extensions/common_sql_functions.rb +20 -21
  32. data/lib/arel_extensions/comparators.rb +28 -31
  33. data/lib/arel_extensions/date_duration.rb +13 -19
  34. data/lib/arel_extensions/insert_manager.rb +15 -22
  35. data/lib/arel_extensions/math.rb +70 -68
  36. data/lib/arel_extensions/math_functions.rb +52 -57
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +5 -6
  39. data/lib/arel_extensions/nodes/case.rb +27 -31
  40. data/lib/arel_extensions/nodes/cast.rb +12 -12
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +5 -4
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +22 -13
  45. data/lib/arel_extensions/nodes/date_diff.rb +70 -77
  46. data/lib/arel_extensions/nodes/duration.rb +5 -2
  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 +39 -50
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -2
  53. data/lib/arel_extensions/nodes/json.rb +47 -72
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
  56. data/lib/arel_extensions/nodes/locate.rb +3 -2
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +8 -6
  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 +3 -2
  62. data/lib/arel_extensions/nodes/repeat.rb +6 -4
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +7 -6
  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 -58
  68. data/lib/arel_extensions/nodes/then.rb +2 -2
  69. data/lib/arel_extensions/nodes/trim.rb +7 -5
  70. data/lib/arel_extensions/nodes/union.rb +9 -6
  71. data/lib/arel_extensions/nodes/union_all.rb +8 -5
  72. data/lib/arel_extensions/nodes/wday.rb +6 -2
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +6 -18
  75. data/lib/arel_extensions/predications.rb +49 -54
  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 +55 -110
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -3
  81. data/lib/arel_extensions/visitors/ibm_db.rb +36 -29
  82. data/lib/arel_extensions/visitors/mssql.rb +248 -493
  83. data/lib/arel_extensions/visitors/mysql.rb +244 -420
  84. data/lib/arel_extensions/visitors/oracle.rb +258 -311
  85. data/lib/arel_extensions/visitors/oracle12.rb +34 -20
  86. data/lib/arel_extensions/visitors/postgresql.rb +239 -350
  87. data/lib/arel_extensions/visitors/sqlite.rb +169 -191
  88. data/lib/arel_extensions/visitors/to_sql.rb +299 -371
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +32 -243
  91. data/test/database.yml +10 -20
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +120 -123
  94. data/test/support/fake_record.rb +3 -11
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +12 -12
  97. data/test/visitors/test_bulk_insert_sqlite.rb +14 -13
  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 +375 -912
  102. data/test/with_ar/insert_agnostic_test.rb +22 -28
  103. data/test/with_ar/test_bulk_sqlite.rb +17 -18
  104. data/test/with_ar/test_math_sqlite.rb +27 -27
  105. data/test/with_ar/test_string_mysql.rb +34 -32
  106. data/test/with_ar/test_string_sqlite.rb +35 -31
  107. metadata +64 -50
  108. data/.github/workflows/publish.yml +0 -30
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -452
  111. data/CONTRIBUTING.md +0 -102
  112. data/Makefile +0 -48
  113. data/NEWS.md +0 -131
  114. data/bin/build +0 -15
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -41
  117. data/dev/compose.yaml +0 -69
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails5.gemfile +0 -36
  121. data/gemfiles/rails6.gemfile +0 -40
  122. data/gemfiles/rails6_1.gemfile +0 -48
  123. data/gemfiles/rails7.gemfile +0 -48
  124. data/gemfiles/rails7_1.gemfile +0 -48
  125. data/gemfiles/rails7_2.gemfile +0 -47
  126. data/gemfiles/rails8.gemfile +0 -40
  127. data/gemfiles/rails8_1.gemfile +0 -41
  128. data/gemspecs/arel_extensions-v1.gemspec +0 -25
  129. data/gemspecs/arel_extensions-v2.gemspec +0 -25
  130. data/generate_gems.sh +0 -15
  131. data/lib/arel_extensions/aliases.rb +0 -14
  132. data/lib/arel_extensions/constants.rb +0 -13
  133. data/lib/arel_extensions/helpers.rb +0 -61
  134. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  135. data/lib/arel_extensions/nodes/byte_size.rb +0 -11
  136. data/lib/arel_extensions/nodes/char_length.rb +0 -11
  137. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  138. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  139. data/lib/arel_extensions/nodes/select.rb +0 -10
  140. data/lib/arel_extensions/nodes/sum.rb +0 -7
  141. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  142. data/lib/arel_extensions/warning.rb +0 -42
  143. data/test/arelx_test_helper.rb +0 -94
  144. data/test/config_loader.rb +0 -9
  145. data/version_v1.rb +0 -5
  146. data/version_v2.rb +0 -5
@@ -1,385 +1,324 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
- class Arel::Visitors::ToSql
4
- COMMA = ', ' unless defined?(COMMA)
5
-
6
- # Escape properly the string expression expr.
7
- # Take care of escaping.
8
- def make_json_string(expr)
9
- Arel.quoted('"') \
10
- + expr
11
- .coalesce('')
12
- .replace('\\', '\\\\')
13
- .replace('"', '\"')
14
- .replace("\b", '\b')
15
- .replace("\f", '\f')
16
- .replace("\n", '\n')
17
- .replace("\r", '\r')
18
- .replace("\t", '\t') \
19
- + '"'
20
- end
21
-
22
- def make_json_null
23
- Arel.quoted('null')
24
- end
3
+ Arel::Visitors::ToSql.class_eval do
4
+ Arel::Visitors::ToSql::COMMA = ", "
25
5
 
26
6
  # Math Functions
27
- def visit_ArelExtensions_Nodes_Abs(o, collector)
28
- collector << 'ABS('
7
+ def visit_ArelExtensions_Nodes_Abs o, collector
8
+ collector << "ABS("
29
9
  o.expressions.each_with_index { |arg, i|
30
- collector << COMMA if i != 0
10
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
31
11
  collector = visit arg, collector
32
12
  }
33
- collector << ')'
13
+ collector << ")"
34
14
  collector
35
15
  end
36
16
 
37
- def visit_ArelExtensions_Nodes_Ceil(o, collector)
38
- collector << 'CEIL('
17
+ def visit_ArelExtensions_Nodes_Ceil o, collector
18
+ collector << "CEIL("
39
19
  o.expressions.each_with_index { |arg, i|
40
- collector << COMMA if i != 0
20
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
41
21
  collector = visit arg, collector
42
22
  }
43
- collector << ')'
23
+ collector << ")"
44
24
  collector
45
25
  end
46
26
 
47
- def visit_ArelExtensions_Nodes_Floor(o, collector)
48
- collector << 'FLOOR('
27
+ def visit_ArelExtensions_Nodes_Floor o, collector
28
+ collector << "FLOOR("
49
29
  o.expressions.each_with_index { |arg, i|
50
- collector << COMMA if i != 0
30
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
51
31
  collector = visit arg, collector
52
32
  }
53
- collector << ')'
33
+ collector << ")"
54
34
  collector
55
35
  end
56
36
 
57
- def visit_ArelExtensions_Nodes_Rand(o, collector)
58
- collector << 'RAND('
37
+ def visit_ArelExtensions_Nodes_Rand o, collector
38
+ collector << "RAND("
59
39
  o.expressions.each_with_index { |arg, i|
60
- collector << COMMA if i != 0
40
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
61
41
  collector = visit arg, collector
62
42
  }
63
- collector << ')'
43
+ collector << ")"
64
44
  collector
65
45
  end
66
46
 
67
- def visit_ArelExtensions_Nodes_Round(o, collector)
68
- collector << 'ROUND('
47
+ def visit_ArelExtensions_Nodes_Round o, collector
48
+ collector << "ROUND("
69
49
  o.expressions.each_with_index { |arg, i|
70
- collector << COMMA if i != 0
50
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
71
51
  collector = visit arg, collector
72
52
  }
73
- collector << ')'
53
+ collector << ")"
74
54
  collector
75
55
  end
76
-
77
- def visit_ArelExtensions_Nodes_Log10(o, collector)
78
- collector << 'LOG10('
56
+
57
+ def visit_ArelExtensions_Nodes_Log10 o, collector
58
+ collector << "LOG10("
79
59
  collector = visit o.left, collector
80
- collector << ')'
60
+ collector << ")"
81
61
  collector
82
62
  end
83
-
84
- def visit_ArelExtensions_Nodes_Power(o, collector)
85
- collector << 'POW('
63
+
64
+ def visit_ArelExtensions_Nodes_Power o, collector
65
+ collector << "POW("
86
66
  o.expressions.each_with_index { |arg, i|
87
- collector << COMMA if i != 0
67
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
88
68
  collector = visit arg, collector
89
69
  }
90
- collector << ')'
91
- collector
92
- end
93
-
94
- def visit_ArelExtensions_Nodes_Sum(o, collector)
95
- collector << 'SUM('
96
- collector = visit o.expr, collector
97
- collector << ')'
70
+ collector << ")"
98
71
  collector
99
72
  end
100
73
 
101
74
  # String functions
102
- def visit_ArelExtensions_Nodes_Concat(o, collector)
103
- collector << 'CONCAT('
104
- o.expressions.each_with_index { |arg, i|
105
- collector << COMMA if i != 0
75
+ def visit_ArelExtensions_Nodes_Concat o, collector
76
+ collector << "CONCAT("
77
+ o.expressions.each_with_index { |arg, i|
78
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
106
79
  collector = visit arg, collector
107
80
  }
108
- collector << ')'
81
+ collector << ")"
109
82
  collector
110
83
  end
111
84
 
112
- def visit_ArelExtensions_Nodes_GroupConcat(o, collector)
113
- collector << 'GROUP_CONCAT('
85
+ def visit_ArelExtensions_Nodes_GroupConcat o, collector
86
+ collector << "GROUP_CONCAT("
114
87
  collector = visit o.left, collector
115
- sep = o.separator.is_a?(Arel::Nodes::Quoted) ? o.separator.expr : o.separator
116
- if 'NULL' != sep
117
- collector << COMMA
118
- collector = visit o.separator, collector
88
+ if o.right && o.right != 'NULL'
89
+ collector << Arel::Visitors::ToSql::COMMA
90
+ collector = visit o.right, collector
119
91
  end
120
- collector << ')'
92
+ collector << ")"
121
93
  collector
122
94
  end
123
95
 
124
- def visit_ArelExtensions_Nodes_MD5(o, collector)
125
- collector << 'MD5('
96
+ def visit_ArelExtensions_Nodes_MD5 o, collector
97
+ collector << "MD5("
126
98
  collector = visit o.left, collector
127
- collector << ')'
99
+ collector << ")"
128
100
  collector
129
101
  end
130
102
 
131
103
  def visit_ArelExtensions_Nodes_Length o, collector
132
- collector << "#{o.bytewise ? '' : 'CHAR_'}LENGTH("
104
+ collector << "LENGTH("
133
105
  collector = visit o.left, collector
134
- collector << ')'
106
+ collector << ")"
135
107
  collector
136
108
  end
137
109
 
138
- def visit_ArelExtensions_Nodes_Locate(o, collector)
139
- collector << 'LOCATE('
110
+ def visit_ArelExtensions_Nodes_Locate o, collector
111
+ collector << "LOCATE("
140
112
  collector = visit o.right, collector
141
- collector << COMMA
113
+ collector << Arel::Visitors::ToSql::COMMA
142
114
  collector = visit o.left, collector
143
- collector << ')'
115
+ collector << ")"
144
116
  collector
145
117
  end
146
118
 
147
- def visit_ArelExtensions_Nodes_Substring(o, collector)
148
- return visit(o.range_substring_node, collector) if o.range?
149
-
150
- collector << 'SUBSTRING('
119
+ def visit_ArelExtensions_Nodes_Substring o, collector
120
+ collector << "SUBSTRING("
151
121
  o.expressions.each_with_index { |arg, i|
152
- collector << COMMA if i != 0
122
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
153
123
  collector = visit arg, collector
154
124
  }
155
- collector << ')'
156
- collector
157
- end
158
-
159
- def visit_ArelExtensions_Nodes_Replace(o, collector)
160
- collector << 'REPLACE('
161
- visit o.left, collector
162
- collector << COMMA
163
- visit o.pattern, collector
164
- collector << COMMA
165
- visit o.substitute, collector
166
- collector << ')'
125
+ collector << ")"
167
126
  collector
168
127
  end
169
128
 
170
- def visit_ArelExtensions_Nodes_RegexpReplace(o, collector)
171
- collector << 'REGEXP_REPLACE('
172
- visit o.left, collector
173
- collector << COMMA
174
- visit Arel.quoted(o.pattern.to_s), collector
175
- collector << COMMA
176
- visit o.substitute, collector
177
- collector << ')'
129
+ def visit_ArelExtensions_Nodes_Replace o, collector
130
+ collector << "REPLACE("
131
+ o.expressions.each_with_index { |arg, i|
132
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
133
+ collector = visit arg, collector
134
+ }
135
+ collector << ")"
178
136
  collector
179
137
  end
180
-
181
- def visit_ArelExtensions_Nodes_Repeat(o, collector)
182
- collector << 'REPEAT('
138
+
139
+ def visit_ArelExtensions_Nodes_Repeat o, collector
140
+ collector << "REPEAT("
183
141
  o.expressions.each_with_index { |arg, i|
184
- collector << COMMA if i != 0
142
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
185
143
  collector = visit arg, collector
186
144
  }
187
- collector << ')'
145
+ collector << ")"
188
146
  collector
189
147
  end
190
148
 
191
- def visit_ArelExtensions_Nodes_FindInSet(o, collector)
192
- collector << 'FIND_IN_SET('
149
+ def visit_ArelExtensions_Nodes_FindInSet o, collector
150
+ collector << "FIND_IN_SET("
193
151
  o.expressions.each_with_index { |arg, i|
194
- collector << COMMA if i != 0
152
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
195
153
  collector = visit arg, collector
196
154
  }
197
- collector << ')'
155
+ collector << ")"
198
156
  collector
199
157
  end
200
158
 
201
- def visit_ArelExtensions_Nodes_Soundex(o, collector)
202
- collector << 'SOUNDEX('
159
+ def visit_ArelExtensions_Nodes_Soundex o, collector
160
+ collector << "SOUNDEX("
203
161
  o.expressions.each_with_index { |arg, i|
204
- collector << COMMA if i != 0
162
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
205
163
  collector = visit arg, collector
206
164
  }
207
- collector << ')'
165
+ collector << ")"
208
166
  collector
209
167
  end
210
168
 
211
- def visit_ArelExtensions_Nodes_Downcase(o, collector)
212
- collector << 'LOWER('
169
+ def visit_ArelExtensions_Nodes_Downcase o, collector
170
+ collector << "LOWER("
213
171
  o.expressions.each_with_index { |arg, i|
214
- collector << COMMA if i != 0
172
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
215
173
  collector = visit arg, collector
216
174
  }
217
- collector << ')'
175
+ collector << ")"
218
176
  collector
219
177
  end
220
178
 
221
- def visit_ArelExtensions_Nodes_Upcase(o, collector)
222
- collector << 'UPPER('
179
+ def visit_ArelExtensions_Nodes_Upcase o, collector
180
+ collector << "UPPER("
223
181
  o.expressions.each_with_index { |arg, i|
224
- collector << COMMA if i != 0
182
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
225
183
  collector = visit arg, collector
226
184
  }
227
- collector << ')'
185
+ collector << ")"
228
186
  collector
229
187
  end
230
188
 
231
- def visit_ArelExtensions_Nodes_Trim(o, collector)
232
- collector << 'TRIM('
189
+ def visit_ArelExtensions_Nodes_Trim o, collector
190
+ collector << "TRIM("
233
191
  o.expressions.each_with_index { |arg, i|
234
- collector << COMMA if i != 0
192
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
235
193
  collector = visit arg, collector
236
194
  }
237
- collector << ')'
195
+ collector << ")"
238
196
  collector
239
197
  end
240
198
 
241
- def visit_ArelExtensions_Nodes_Ltrim(o, collector)
242
- collector << 'LTRIM('
199
+ def visit_ArelExtensions_Nodes_Ltrim o, collector
200
+ collector << "LTRIM("
243
201
  o.expressions.each_with_index { |arg, i|
244
- collector << COMMA if i != 0
202
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
245
203
  collector = visit arg, collector
246
204
  }
247
- collector << ')'
205
+ collector << ")"
248
206
  collector
249
207
  end
250
208
 
251
- def visit_ArelExtensions_Nodes_Rtrim(o, collector)
252
- collector << 'RTRIM('
209
+ def visit_ArelExtensions_Nodes_Rtrim o, collector
210
+ collector << "RTRIM("
253
211
  o.expressions.each_with_index { |arg, i|
254
- collector << COMMA if i != 0
212
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
255
213
  collector = visit arg, collector
256
214
  }
257
- collector << ')'
215
+ collector << ")"
258
216
  collector
259
217
  end
260
218
 
261
- def visit_ArelExtensions_Nodes_Blank(o, collector)
262
- # visit o.left.coalesce('').trim.length.eq(0), collector
219
+ def visit_ArelExtensions_Nodes_Blank o, collector
220
+ #visit o.left.coalesce('').trim.length.eq(0), collector
263
221
  collector << 'LENGTH(TRIM(COALESCE('
264
222
  collector = visit o.expr, collector
265
- collector << COMMA
266
- collector = visit Arel.quoted(''), collector
267
- collector << '))) = 0'
223
+ collector << Arel::Visitors::ToSql::COMMA
224
+ collector = visit Arel::Nodes.build_quoted(''), collector
225
+ collector << "))) = 0"
268
226
  collector
269
227
  end
270
228
 
271
- def visit_ArelExtensions_Nodes_NotBlank(o, collector)
272
- # visit o.left.coalesce('').trim.length.gt(0), collector
229
+
230
+ def visit_ArelExtensions_Nodes_NotBlank o, collector
231
+ #visit o.left.coalesce('').trim.length.gt(0), collector
273
232
  collector << 'LENGTH(TRIM(COALESCE('
274
233
  collector = visit o.expr, collector
275
- collector << COMMA
276
- collector = visit Arel.quoted(''), collector
277
- collector << '))) > 0'
234
+ collector << Arel::Visitors::ToSql::COMMA
235
+ collector = visit Arel::Nodes.build_quoted(''), collector
236
+ collector << "))) > 0"
278
237
  collector
279
238
  end
280
239
 
281
- def visit_ArelExtensions_Nodes_Format(o, collector)
240
+ def visit_ArelExtensions_Nodes_Format o, collector
282
241
  case o.col_type
283
242
  when :date, :datetime, :time
284
- collector << 'STRFTIME('
243
+ collector << "STRFTIME("
285
244
  collector = visit o.right, collector
286
- collector << COMMA
245
+ collector << Arel::Visitors::ToSql::COMMA
287
246
  collector = visit o.left, collector
288
- collector << ')'
247
+ collector << ")"
289
248
  when :integer, :float, :decimal
290
- collector << 'FORMAT('
249
+ collector << "FORMAT("
291
250
  collector = visit o.left, collector
292
- collector << COMMA
251
+ collector << Arel::Visitors::ToSql::COMMA
293
252
  collector = visit o.right, collector
294
- collector << ')'
253
+ collector << ")"
295
254
  else
296
255
  collector = visit o.left, collector
297
256
  end
298
257
  collector
299
258
  end
300
259
 
301
- def visit_ArelExtensions_Nodes_FormattedDate(o, collector)
302
- case o.col_type
303
- when :date, :datetime, :time
304
- collector << 'STRFTIME('
305
- collector = visit o.right, collector
306
- collector << COMMA
307
- collector = visit o.left, collector
308
- collector << ')'
309
- when :integer, :float, :decimal
310
- collector << 'FORMAT('
311
- collector = visit o.left, collector
312
- collector << COMMA
313
- collector = visit o.right, collector
314
- collector << ')'
315
- else
316
- collector = visit o.left, collector
317
- end
318
- collector
319
- end
320
-
321
- # comparators
322
-
323
- def visit_ArelExtensions_Nodes_Cast(o, collector)
324
- as_attr =
325
- case o.as_attr
326
- when :binary then 'binary'
327
- when :datetime then 'datetime'
328
- when :decimal, :float, :number then 'float'
329
- when :int then 'int'
330
- when :string then 'char'
331
- when :text, :ntext then 'text'
332
- when :time then 'time'
333
- else o.as_attr.to_s
334
- end
260
+ #comparators
335
261
 
336
- collector << 'CAST('
262
+ def visit_ArelExtensions_Nodes_Cast o, collector
263
+ collector << "CAST("
337
264
  collector = visit o.left, collector
338
- collector << ' AS '
339
- collector = visit Arel::Nodes::SqlLiteral.new(as_attr), collector
340
- collector << ')'
265
+ collector << " AS "
266
+ case o.as_attr
267
+ when :string
268
+ as_attr = Arel::Nodes::SqlLiteral.new('char')
269
+ when :int
270
+ as_attr = Arel::Nodes::SqlLiteral.new('int')
271
+ when :decimal, :float, :number
272
+ as_attr = Arel::Nodes::SqlLiteral.new('float')
273
+ when :datetime
274
+ as_attr = Arel::Nodes::SqlLiteral.new('datetime')
275
+ when :time
276
+ as_attr = Arel::Nodes::SqlLiteral.new('time')
277
+ when :binary
278
+ as_attr = Arel::Nodes::SqlLiteral.new('binary')
279
+ else
280
+ as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
281
+ end
282
+ collector = visit as_attr, collector
283
+ collector << ")"
341
284
  collector
342
285
  end
343
286
 
344
- def visit_ArelExtensions_Nodes_Coalesce(o, collector)
345
- collector << 'COALESCE('
287
+ def visit_ArelExtensions_Nodes_Coalesce o, collector
288
+ collector << "COALESCE("
346
289
  o.expressions.each_with_index { |arg, i|
347
- collector << COMMA if i != 0
290
+ collector << Arel::Visitors::ToSql::COMMA unless i == 0
348
291
  collector = visit arg, collector
349
292
  }
350
- collector << ')'
293
+ collector << ")"
351
294
  collector
352
295
  end
353
296
 
354
- def visit_ArelExtensions_Nodes_DateDiff(o, collector)
355
- collector <<
356
- if %i[ruby_time datetime time].include?(o.left_node_type)
357
- 'TIMEDIFF('
358
- else
359
- 'DATEDIFF('
360
- end
297
+ def visit_ArelExtensions_Nodes_DateDiff o, collector
298
+ collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
299
+ 'TIMEDIFF('
300
+ else
301
+ 'DATEDIFF('
302
+ end
361
303
  collector = visit o.left, collector
362
- collector << COMMA
304
+ collector << Arel::Visitors::ToSql::COMMA
363
305
  collector = visit o.right, collector
364
- collector << ')'
306
+ collector << ")"
365
307
  collector
366
308
  end
367
-
368
- def visit_ArelExtensions_Nodes_DateSub(o, collector)
369
- collector << 'DATE_SUB('
309
+
310
+ def visit_ArelExtensions_Nodes_DateSub o, collector
311
+ collector << "DATE_SUB("
370
312
  collector = visit o.left, collector
371
- collector << COMMA
313
+ collector << Arel::Visitors::ToSql::COMMA
372
314
  collector = visit o.right, collector
373
- collector << ')'
315
+ collector << ")"
374
316
  collector
375
317
  end
376
318
 
377
- # override
319
+ # override
378
320
  remove_method(:visit_Arel_Nodes_As) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_As)
379
- def visit_Arel_Nodes_As(o, collector)
380
- if o.left.respond_to?(:alias)
381
- o.left.alias = nil
382
- end
321
+ def visit_Arel_Nodes_As o, collector
383
322
  if o.left.is_a?(Arel::Nodes::Binary)
384
323
  collector << '('
385
324
  collector = visit o.left, collector
@@ -387,25 +326,28 @@ module ArelExtensions
387
326
  else
388
327
  collector = visit o.left, collector
389
328
  end
390
- collector << ' AS '
391
- visit o.right, collector
329
+ collector << " AS "
330
+ collector = visit o.right, collector
331
+ collector
392
332
  end
393
333
 
394
334
  remove_method(:visit_Arel_Nodes_Regexp) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_Regexp)
395
- def visit_Arel_Nodes_Regexp(o, collector)
335
+ def visit_Arel_Nodes_Regexp o, collector
396
336
  collector = visit o.left, collector
397
- collector << ' REGEXP '
398
- visit o.right, collector
337
+ collector << " REGEXP "
338
+ collector = visit o.right, collector
339
+ collector
399
340
  end
400
341
 
401
342
  remove_method(:visit_Arel_Nodes_NotRegexp) rescue nil # if Arel::Visitors::ToSql.method_defined?(:visit_Arel_Nodes_NotRegexp)
402
- def visit_Arel_Nodes_NotRegexp(o, collector)
343
+ def visit_Arel_Nodes_NotRegexp o, collector
403
344
  collector = visit o.left, collector
404
- collector << ' NOT REGEXP '
405
- visit o.right, collector
345
+ collector << " NOT REGEXP "
346
+ collector = visit o.right, collector
347
+ collector
406
348
  end
407
349
 
408
- def visit_ArelExtensions_Nodes_IMatches(o, collector)
350
+ def visit_ArelExtensions_Nodes_IMatches o, collector
409
351
  collector = infix_value o, collector, ' ILIKE '
410
352
  if o.escape
411
353
  collector << ' ESCAPE '
@@ -415,7 +357,7 @@ module ArelExtensions
415
357
  end
416
358
  end
417
359
 
418
- def visit_ArelExtensions_Nodes_IDoesNotMatch(o, collector)
360
+ def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
419
361
  collector = infix_value o, collector, ' NOT ILIKE '
420
362
  if o.escape
421
363
  collector << ' ESCAPE '
@@ -424,169 +366,169 @@ module ArelExtensions
424
366
  collector
425
367
  end
426
368
 
427
- def visit_ArelExtensions_Nodes_IsNull(o, collector)
428
- collector << 'ISNULL('
369
+ def visit_ArelExtensions_Nodes_IsNull o, collector
370
+ collector << "ISNULL("
429
371
  collector = visit o.expr, collector
430
- collector << ')'
372
+ collector << ")"
431
373
  collector
432
374
  end
433
375
 
434
- def visit_ArelExtensions_Nodes_IsNotNull(o, collector)
435
- collector << 'NOT ISNULL('
436
- collector = visit o.expr, collector
437
- collector << ')'
438
- collector
376
+ def visit_ArelExtensions_Nodes_IsNotNull o, collector
377
+ collector << "NOT ISNULL("
378
+ collector = visit o.expr, collector
379
+ collector << ")"
380
+ collector
439
381
  end
440
382
 
441
- def visit_ArelExtensions_Nodes_Then(o, collector)
442
- collector << 'CASE WHEN ('
383
+ def visit_ArelExtensions_Nodes_Then o, collector
384
+ collector << "CASE WHEN ("
443
385
  collector = visit o.left, collector
444
- collector << ') THEN '
386
+ collector << ") THEN "
445
387
  collector = visit o.right, collector
446
- if o.expressions[2]
447
- collector << ' ELSE '
388
+ if o.expressions[2]
389
+ collector << " ELSE "
448
390
  collector = visit o.expressions[2], collector
449
391
  end
450
- collector << ' END'
392
+ collector << " END"
451
393
  collector
452
394
  end
453
395
 
454
396
  # Date operations
455
- def visit_ArelExtensions_Nodes_DateAdd(o, collector)
456
- collector << 'DATE_ADD('
397
+ def visit_ArelExtensions_Nodes_DateAdd o, collector
398
+ collector << "DATE_ADD("
457
399
  collector = visit o.left, collector
458
- collector << COMMA
400
+ collector << Arel::Visitors::ToSql::COMMA
459
401
  collector = visit o.sqlite_value(o.right), collector
460
402
  collector << ')'
461
403
  collector
462
404
  end
463
405
 
464
- if AREL_VERSION < V7
465
- def visit_ArelExtensions_InsertManager_BulkValues(o, collector)
406
+ if Arel::VERSION.to_i < 7
407
+ def visit_ArelExtensions_InsertManager_BulkValues o, collector
466
408
  collector << 'VALUES '
467
409
  row_nb = o.left.length
468
410
  o.left.each_with_index do |row, idx|
469
411
  collector << '('
470
- len = row.length - 1
471
- row.zip(o.cols).each_with_index { |(value, attr), i|
472
- case value
473
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
474
- collector = visit value, collector
475
- else
476
- collector << quote(value, attr && column_for(attr)).to_s
477
- end
478
- collector << COMMA unless i == len
412
+ v = Arel::Nodes::Values.new(row, o.cols)
413
+ len = v.expressions.length - 1
414
+ v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
415
+ case value
416
+ when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
417
+ collector = visit value, collector
418
+ else
419
+ collector << quote(value, attr && column_for(attr)).to_s
420
+ end
421
+ collector << Arel::Visitors::ToSql::COMMA unless i == len
479
422
  }
480
- collector << (idx == row_nb - 1 ? ')' : '), ')
423
+ collector << (idx == row_nb-1 ? ')' : '), ')
481
424
  end
482
425
  collector
483
426
  end
484
427
  else
485
- def visit_ArelExtensions_InsertManager_BulkValues(o, collector)
428
+ def visit_ArelExtensions_InsertManager_BulkValues o, collector
486
429
  collector << 'VALUES '
487
430
  row_nb = o.left.length
488
431
  o.left.each_with_index do |row, idx|
489
432
  collector << '('
490
433
  len = row.length - 1
491
- row.zip(o.cols).each_with_index { |(value, attr), i|
492
- case value
493
- when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
494
- collector = visit value, collector
495
- when Integer
496
- collector << value.to_s
497
- else
498
- collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
499
- end
500
- collector << COMMA unless i == len
434
+ row.each_with_index { |value, i|
435
+ attr = o.cols[i]
436
+ case value
437
+ when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
438
+ collector = visit value, collector
439
+ else
440
+ collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
441
+ end
442
+ collector << Arel::Visitors::ToSql::COMMA unless i == len
501
443
  }
502
- collector << (idx == row_nb - 1 ? ')' : '), ')
444
+ collector << (idx == row_nb-1 ? ')' : '), ')
503
445
  end
504
446
  collector
505
447
  end
506
448
  end
507
449
 
508
- def visit_ArelExtensions_Nodes_Union(o, collector)
450
+ def visit_ArelExtensions_Nodes_Union o, collector
509
451
  collector = visit o.left, collector
510
- collector << ' UNION '
511
- visit o.right, collector
452
+ collector << " UNION "
453
+ collector = visit o.right, collector
454
+ collector
512
455
  end
513
-
514
- def visit_ArelExtensions_Nodes_UnionAll(o, collector)
456
+
457
+ def visit_ArelExtensions_Nodes_UnionAll o, collector
515
458
  collector = visit o.left, collector
516
- collector << ' UNION ALL '
517
- visit o.right, collector
459
+ collector << " UNION ALL "
460
+ collector = visit o.right, collector
461
+ collector
518
462
  end
519
463
 
520
- def visit_ArelExtensions_Nodes_Case(o, collector)
521
- collector << 'CASE '
464
+ def visit_ArelExtensions_Nodes_Case o, collector
465
+ collector << "CASE "
522
466
  if o.case
523
467
  visit o.case, collector
524
- collector << ' '
468
+ collector << " "
525
469
  end
526
470
  o.conditions.each do |condition|
527
471
  visit condition, collector
528
- collector << ' '
472
+ collector << " "
529
473
  end
530
474
  if o.default
531
475
  visit o.default, collector
532
- collector << ' '
476
+ collector << " "
533
477
  end
534
- collector << 'END'
478
+ collector << "END"
535
479
  end
536
480
 
537
- def visit_ArelExtensions_Nodes_Case_When(o, collector)
538
- collector << 'WHEN '
539
- visit Arel.quoted(o.left), collector
540
- collector << ' THEN '
541
- visit Arel.quoted(o.right), collector
481
+ def visit_ArelExtensions_Nodes_Case_When o, collector
482
+ collector << "WHEN "
483
+ visit Arel::Nodes.build_quoted(o.left), collector
484
+ collector << " THEN "
485
+ visit Arel::Nodes.build_quoted(o.right), collector
542
486
  end
543
487
 
544
- def visit_ArelExtensions_Nodes_Case_Else(o, collector)
545
- collector << 'ELSE '
546
- visit Arel.quoted(o.expr), collector
488
+ def visit_ArelExtensions_Nodes_Case_Else o, collector
489
+ collector << "ELSE "
490
+ visit Arel::Nodes.build_quoted(o.expr), collector
547
491
  end
548
492
 
549
- def visit_ArelExtensions_Nodes_FormattedNumber(o, collector)
493
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
550
494
  visit o.left, collector
551
495
  end
552
-
553
- remove_method(:visit_Arel_Nodes_LessThan) rescue nil
554
- def visit_Arel_Nodes_LessThan(o, collector)
496
+
497
+ remove_method(:visit_Arel_Nodes_LessThan) rescue nil
498
+ def visit_Arel_Nodes_LessThan o, collector
555
499
  collector = visit o.left, collector
556
- collector << ' < '
500
+ collector << " < "
557
501
  visit o.right, collector
558
502
  end
559
-
560
- def visit_ArelExtensions_Nodes_Std(o, collector)
561
- collector << 'STD('
503
+
504
+ def visit_ArelExtensions_Nodes_Std o, collector
505
+ collector << "STD("
562
506
  visit o.left, collector
563
- collector << ')'
507
+ collector << ")"
564
508
  collector
565
509
  end
566
-
567
- def visit_ArelExtensions_Nodes_Variance(o, collector)
568
- collector << 'VARIANCE('
510
+
511
+ def visit_ArelExtensions_Nodes_Variance o, collector
512
+ collector << "VARIANCE("
569
513
  visit o.left, collector
570
- collector << ')'
514
+ collector << ")"
571
515
  collector
572
516
  end
573
517
 
574
- def visit_ArelExtensions_Nodes_LevenshteinDistance(o, collector)
575
- collector << 'LEVENSHTEIN_DISTANCE('
518
+ def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
519
+ collector << "LEVENSHTEIN_DISTANCE("
576
520
  collector = visit o.left, collector
577
- collector << COMMA
521
+ collector << Arel::Visitors::ToSql::COMMA
578
522
  collector = visit o.right, collector
579
523
  collector << ')'
580
524
  collector
581
525
  end
582
526
 
583
- # Boolean logic.
584
-
585
- alias old_visit_Arel_Nodes_And visit_Arel_Nodes_And rescue nil
586
- def visit_Arel_Nodes_And(o, collector)
527
+ alias_method :old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And
528
+ def visit_Arel_Nodes_And o, collector
587
529
  case o.children.length
588
530
  when 0
589
- collector << '1 = 1' # but this should not happen
531
+ collector << '1=1' # but this should not happen
590
532
  when 1
591
533
  collector = visit o.children[0], collector
592
534
  else
@@ -602,111 +544,97 @@ module ArelExtensions
602
544
  collector
603
545
  end
604
546
 
605
- alias old_visit_Arel_Nodes_Or visit_Arel_Nodes_Or rescue nil
606
- def visit_Arel_Nodes_Or(o, collector)
547
+ def visit_ArelExtensions_Nodes_Or o, collector
607
548
  case o.children.length
608
549
  when 0
609
- collector << '1 = 0' # but this should not happen
550
+ collector << '0=1' # but this should not happen
610
551
  when 1
611
552
  collector = visit o.children[0], collector
612
553
  else
613
- collector << '('
614
- o.children.each_with_index { |arg, i|
615
- if i != 0
616
- collector << ') OR ('
617
- end
618
- collector = visit arg, collector
619
- }
620
- collector << ')'
554
+ collector << '('
555
+ o.children.each_with_index { |arg, i|
556
+ if i != 0
557
+ collector << ') OR ('
558
+ end
559
+ collector = visit arg, collector
560
+ }
561
+ collector << ')'
621
562
  end
622
563
  collector
623
564
  end
624
565
 
625
- def json_value(o, v)
626
- case o.type_of_node(v)
627
- when :numeric
628
- # A bare numeric literal (e.g. `{ col => 1 }`) is never NULL, so it is
629
- # emitted as-is rather than run through `is_null`/`coalesce`.
630
- Arel.quoted(v)
631
- when :boolean
632
- # A literal boolean is never NULL: emit the JSON token directly.
633
- # A boolean column is null-checked and rendered as true/false. `eq(true)` rather than the
634
- # bare column, because T-SQL (mssql) requires a proper boolean predicate in WHEN.
635
- if o.boolean_literal?(v)
636
- Arel.quoted((v.is_a?(Arel::Nodes::Quoted) ? v.expr : v).to_s)
637
- else
638
- Arel.when(v.is_null).then(make_json_null).else(Arel.when(v.eq(true)).then('true').else('false'))
639
- end
640
- when :string
641
- Arel.when(v.is_null).then(make_json_null).else(make_json_string(v))
642
- when :date
643
- s = v.format('%Y-%m-%d')
644
- Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
645
- when :datetime
646
- s = v.format('%Y-%m-%dT%H:%M:%S')
647
- Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
648
- when :time
649
- s = v.format('%H:%M:%S')
650
- Arel.when(s.is_null).then(make_json_null).else(make_json_string(s))
651
- when :nil
652
- make_json_null
653
- else
654
- ArelExtensions::Nodes::Cast.new([v, :string]).coalesce(make_json_null)
655
- end
566
+ alias_method :old_visit_Arel_Nodes_Or, :visit_Arel_Nodes_Or
567
+ def visit_Arel_Nodes_Or o, collector
568
+ collector << '('
569
+ collector = visit o.left, collector
570
+ collector << ') OR ('
571
+ collector = visit o.right, collector
572
+ collector << ')'
573
+ collector
656
574
  end
657
575
 
658
- def visit_ArelExtensions_Nodes_Json(o, collector)
576
+ def visit_ArelExtensions_Nodes_Json o,collector
659
577
  case o.dict
660
578
  when Array
661
- res = Arel.quoted('[')
662
- o.dict.each.with_index do |v, i|
579
+ res = Arel::Nodes.build_quoted('[')
580
+ o.dict.each.with_index do |v,i|
663
581
  if i != 0
664
582
  res += ', '
665
583
  end
666
- res += json_value(o, v)
584
+ if (v.is_a?(Arel::Attributes::Attribute) && o.type_of_attribute(v) == :string) || (v.return_type == :string)
585
+ res = res + '"' + v + '"'
586
+ else
587
+ res += v
588
+ end
667
589
  end
668
590
  res += ']'
669
591
  collector = visit res, collector
670
592
  when Hash
671
- res = Arel.quoted('{')
672
- o.dict.each.with_index do |(k, v), i|
593
+ res = Arel::Nodes.build_quoted('{')
594
+ o.dict.each.with_index do |(k,v),i|
673
595
  if i != 0
674
596
  res += ', '
675
597
  end
676
- res += make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])) + ': '
677
- res += json_value(o, v)
598
+ res += Arel::Nodes.build_quoted('"')+k + '": '
599
+ if (v.is_a?(Arel::Attributes::Attribute) && o.type_of_attribute(v) == :string) || (v.respond_to?(:return_type) && v.return_type == :string)
600
+ res = res + '"' + v + '"'
601
+ else
602
+ res += v
603
+ end
678
604
  end
679
605
  res += '}'
680
606
  collector = visit res, collector
681
607
  else
682
- collector = visit(o.boolean_literal?(o.dict) ? Arel.quoted(o.dict.expr.to_s) : o.dict, collector)
608
+ collector = visit o.dict, collector
683
609
  end
684
610
  collector
685
611
  end
686
612
 
687
- def visit_ArelExtensions_Nodes_JsonGroup(o, collector)
613
+ def visit_ArelExtensions_Nodes_JsonGroup o, collector
688
614
  if o.as_array
689
- res =
690
- Arel.quoted('[') \
691
- + (o.orders ? o.dict.group_concat(', ', order: Array(o.orders)) : o.dict.group_concat(', ')).coalesce('') \
692
- + ']'
615
+ res = Arel::Nodes.build_quoted('[') + (o.orders ? o.dict.group_concat(', ',o.orders) : o.dict.group_concat(', ')) + ']'
693
616
  collector = visit res, collector
694
617
  else
695
- res = Arel.quoted('{')
618
+ res = Arel::Nodes.build_quoted('{')
696
619
  orders = o.orders || o.dict.keys
697
- o.dict.each.with_index do |(k, v), i|
620
+ o.dict.each.with_index do |(k,v),i|
698
621
  if i != 0
699
- res += ', '
622
+ res = res + ', '
623
+ end
624
+ kv = Arel::Nodes.build_quoted('"')+k + '": '
625
+ if (v.is_a?(Arel::Attributes::Attribute) && o.type_of_attribute(v) == :string) || (v.respond_to?(:return_type) && v.return_type == :string)
626
+ kv = kv + '"' + v + '"'
627
+ else
628
+ kv += v
700
629
  end
701
- kv = make_json_string(ArelExtensions::Nodes::Cast.new([k, :string])) + ': '
702
- kv += json_value(o, v)
703
- res += kv.group_concat(', ', order: Array(orders)).coalesce('')
630
+ res = res + kv.group_concat(', ',orders)
704
631
  end
705
- res += '}'
632
+ res = res + '}'
706
633
  collector = visit res, collector
707
634
  end
708
635
  collector
709
636
  end
637
+
710
638
  end
711
639
  end
712
640
  end