arel_extensions 2.0.21 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -2
- data/.github/workflows/publish.yml +29 -0
- data/.github/workflows/release.yml +30 -0
- data/.github/workflows/ruby.yml +377 -80
- data/.gitignore +7 -6
- data/.rubocop.yml +62 -1
- data/CONTRIBUTING.md +102 -0
- data/Gemfile +2 -23
- data/NEWS.md +89 -0
- data/README.md +228 -84
- data/Rakefile +11 -4
- data/TODO +0 -1
- data/appveyor.yml +60 -22
- data/arel_extensions.gemspec +11 -12
- data/bin/build +15 -0
- data/bin/compose +6 -0
- data/bin/publish +8 -0
- data/dev/arelx.dockerfile +44 -0
- data/dev/compose.yaml +71 -0
- data/dev/postgres.dockerfile +5 -0
- data/dev/rbenv +189 -0
- data/gemfiles/rails3.gemfile +10 -10
- data/gemfiles/rails4_2.gemfile +38 -0
- data/gemfiles/rails5.gemfile +29 -0
- data/gemfiles/rails5_1_4.gemfile +13 -13
- data/gemfiles/rails5_2.gemfile +16 -14
- data/gemfiles/rails6.gemfile +18 -15
- data/gemfiles/rails6_1.gemfile +18 -15
- data/gemfiles/rails7.gemfile +33 -0
- data/gemfiles/rails7_1.gemfile +33 -0
- data/gemfiles/rails7_2.gemfile +33 -0
- data/gemspecs/arel_extensions-v1.gemspec +12 -13
- data/gemspecs/arel_extensions-v2.gemspec +11 -12
- data/init/mssql.sql +0 -0
- data/init/mysql.sql +0 -0
- data/init/oracle.sql +0 -0
- data/init/postgresql.sql +0 -0
- data/init/sqlite.sql +0 -0
- data/lib/arel_extensions/aliases.rb +14 -0
- data/lib/arel_extensions/attributes.rb +10 -2
- data/lib/arel_extensions/boolean_functions.rb +2 -4
- data/lib/arel_extensions/common_sql_functions.rb +12 -12
- data/lib/arel_extensions/comparators.rb +14 -14
- data/lib/arel_extensions/date_duration.rb +14 -9
- data/lib/arel_extensions/helpers.rb +62 -0
- data/lib/arel_extensions/insert_manager.rb +19 -17
- data/lib/arel_extensions/math.rb +48 -45
- data/lib/arel_extensions/math_functions.rb +18 -18
- data/lib/arel_extensions/nodes/abs.rb +0 -0
- data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
- data/lib/arel_extensions/nodes/blank.rb +1 -1
- data/lib/arel_extensions/nodes/case.rb +10 -12
- data/lib/arel_extensions/nodes/cast.rb +6 -6
- data/lib/arel_extensions/nodes/ceil.rb +0 -0
- data/lib/arel_extensions/nodes/change_case.rb +0 -0
- data/lib/arel_extensions/nodes/coalesce.rb +1 -1
- data/lib/arel_extensions/nodes/collate.rb +9 -9
- data/lib/arel_extensions/nodes/concat.rb +2 -2
- data/lib/arel_extensions/nodes/date_diff.rb +33 -14
- data/lib/arel_extensions/nodes/duration.rb +0 -0
- data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
- data/lib/arel_extensions/nodes/floor.rb +0 -0
- data/lib/arel_extensions/nodes/format.rb +3 -2
- data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
- data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
- data/lib/arel_extensions/nodes/function.rb +22 -26
- data/lib/arel_extensions/nodes/is_null.rb +0 -0
- data/lib/arel_extensions/nodes/json.rb +15 -9
- data/lib/arel_extensions/nodes/length.rb +6 -0
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
- data/lib/arel_extensions/nodes/locate.rb +1 -1
- data/lib/arel_extensions/nodes/log10.rb +0 -0
- data/lib/arel_extensions/nodes/matches.rb +1 -1
- data/lib/arel_extensions/nodes/md5.rb +0 -0
- data/lib/arel_extensions/nodes/power.rb +0 -0
- data/lib/arel_extensions/nodes/rand.rb +0 -0
- data/lib/arel_extensions/nodes/repeat.rb +2 -2
- data/lib/arel_extensions/nodes/replace.rb +2 -10
- data/lib/arel_extensions/nodes/rollup.rb +36 -0
- data/lib/arel_extensions/nodes/round.rb +0 -0
- data/lib/arel_extensions/nodes/select.rb +10 -0
- data/lib/arel_extensions/nodes/soundex.rb +2 -2
- data/lib/arel_extensions/nodes/std.rb +0 -0
- data/lib/arel_extensions/nodes/substring.rb +1 -1
- data/lib/arel_extensions/nodes/sum.rb +0 -0
- data/lib/arel_extensions/nodes/then.rb +1 -1
- data/lib/arel_extensions/nodes/trim.rb +2 -2
- data/lib/arel_extensions/nodes/union.rb +5 -5
- data/lib/arel_extensions/nodes/union_all.rb +4 -4
- data/lib/arel_extensions/nodes/wday.rb +0 -0
- data/lib/arel_extensions/nodes.rb +0 -0
- data/lib/arel_extensions/null_functions.rb +16 -0
- data/lib/arel_extensions/predications.rb +10 -10
- data/lib/arel_extensions/railtie.rb +1 -1
- data/lib/arel_extensions/set_functions.rb +3 -3
- data/lib/arel_extensions/string_functions.rb +19 -10
- data/lib/arel_extensions/tasks.rb +2 -2
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/convert_format.rb +0 -0
- data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
- data/lib/arel_extensions/visitors/mssql.rb +394 -169
- data/lib/arel_extensions/visitors/mysql.rb +238 -151
- data/lib/arel_extensions/visitors/oracle.rb +170 -131
- data/lib/arel_extensions/visitors/oracle12.rb +16 -16
- data/lib/arel_extensions/visitors/postgresql.rb +170 -140
- data/lib/arel_extensions/visitors/sqlite.rb +88 -87
- data/lib/arel_extensions/visitors/to_sql.rb +185 -156
- data/lib/arel_extensions/visitors.rb +73 -60
- data/lib/arel_extensions.rb +173 -36
- data/test/arelx_test_helper.rb +49 -1
- data/test/database.yml +13 -7
- data/test/real_db_test.rb +101 -83
- data/test/support/fake_record.rb +8 -2
- data/test/test_comparators.rb +5 -5
- data/test/visitors/test_bulk_insert_oracle.rb +5 -5
- data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
- data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
- data/test/visitors/test_oracle.rb +14 -14
- data/test/visitors/test_to_sql.rb +121 -93
- data/test/with_ar/all_agnostic_test.rb +630 -320
- data/test/with_ar/insert_agnostic_test.rb +25 -18
- data/test/with_ar/test_bulk_sqlite.rb +11 -7
- data/test/with_ar/test_math_sqlite.rb +18 -14
- data/test/with_ar/test_string_mysql.rb +26 -22
- data/test/with_ar/test_string_sqlite.rb +26 -22
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +24 -26
- data/.travis/oracle/download.js +0 -152
- data/.travis/oracle/download.sh +0 -30
- data/.travis/oracle/download_ojdbc.js +0 -116
- data/.travis/oracle/install.sh +0 -34
- data/.travis/setup_accounts.sh +0 -9
- data/.travis/sqlite3/extension-functions.sh +0 -6
- data/.travis.yml +0 -193
- data/gemfiles/rails4.gemfile +0 -29
- data/gemfiles/rails5_0.gemfile +0 -29
@@ -14,7 +14,7 @@ module ArelExtensions
|
|
14
14
|
}.freeze
|
15
15
|
|
16
16
|
NUMBER_COMMA_MAPPING = {
|
17
|
-
'fr_FR' => {',' => ' ', '.' =>','}
|
17
|
+
'fr_FR' => {',' => ' ', '.' => ','}
|
18
18
|
}.freeze
|
19
19
|
|
20
20
|
# String functions
|
@@ -31,27 +31,27 @@ module ArelExtensions
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def visit_ArelExtensions_Nodes_AiMatches o, collector
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
collector = visit o.left.ai_collate, collector
|
35
|
+
collector << ' LIKE '
|
36
|
+
collector = visit o.right.ai_collate, collector
|
37
|
+
if o.escape
|
38
|
+
collector << ' ESCAPE '
|
39
|
+
visit o.escape, collector
|
40
|
+
else
|
41
|
+
collector
|
42
|
+
end
|
43
43
|
end
|
44
44
|
|
45
45
|
def visit_ArelExtensions_Nodes_AiIMatches o, collector
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
collector = visit o.left.collate(true, true), collector
|
47
|
+
collector << ' LIKE '
|
48
|
+
collector = visit o.right.collate(true, true), collector
|
49
|
+
if o.escape
|
50
|
+
collector << ' ESCAPE '
|
51
|
+
visit o.escape, collector
|
52
|
+
else
|
53
|
+
collector
|
54
|
+
end
|
55
55
|
end
|
56
56
|
|
57
57
|
def visit_ArelExtensions_Nodes_SMatches o, collector
|
@@ -94,11 +94,11 @@ module ArelExtensions
|
|
94
94
|
|
95
95
|
# Date operations
|
96
96
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
97
|
-
collector <<
|
97
|
+
collector << 'date('
|
98
98
|
collector = visit o.expressions.first, collector
|
99
99
|
collector << COMMA
|
100
100
|
collector = visit o.sqlite_value, collector
|
101
|
-
collector <<
|
101
|
+
collector << ')'
|
102
102
|
collector
|
103
103
|
end
|
104
104
|
|
@@ -110,28 +110,28 @@ module ArelExtensions
|
|
110
110
|
collector << ") - strftime('%s', "
|
111
111
|
collector = visit o.right, collector
|
112
112
|
else
|
113
|
-
collector <<
|
113
|
+
collector << 'julianday('
|
114
114
|
collector = visit o.left, collector
|
115
|
-
collector <<
|
115
|
+
collector << ') - julianday('
|
116
116
|
collector = visit o.right, collector
|
117
117
|
end
|
118
|
-
collector <<
|
118
|
+
collector << ')'
|
119
119
|
collector
|
120
120
|
end
|
121
121
|
|
122
122
|
def visit_ArelExtensions_Nodes_Duration o, collector
|
123
123
|
collector << "strftime('#{DATE_MAPPING[o.left]}'#{COMMA}"
|
124
124
|
collector = visit o.right, collector
|
125
|
-
collector <<
|
125
|
+
collector << ')'
|
126
126
|
collector
|
127
127
|
end
|
128
128
|
|
129
129
|
def visit_ArelExtensions_Nodes_Locate o, collector
|
130
|
-
collector <<
|
130
|
+
collector << 'instr('
|
131
131
|
collector = visit o.expr, collector
|
132
132
|
collector << COMMA
|
133
133
|
collector = visit o.right, collector
|
134
|
-
collector <<
|
134
|
+
collector << ')'
|
135
135
|
collector
|
136
136
|
end
|
137
137
|
|
@@ -141,17 +141,17 @@ module ArelExtensions
|
|
141
141
|
collector = visit arg, collector
|
142
142
|
collector << ' || ' unless i == o.expressions.length - 1
|
143
143
|
}
|
144
|
-
collector <<
|
144
|
+
collector << ')'
|
145
145
|
collector
|
146
146
|
end
|
147
147
|
|
148
148
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
149
|
-
collector <<
|
149
|
+
collector << 'SUBSTR('
|
150
150
|
o.expressions.each_with_index { |arg, i|
|
151
151
|
collector << COMMA if i != 0
|
152
152
|
collector = visit arg, collector
|
153
153
|
}
|
154
|
-
collector <<
|
154
|
+
collector << ')'
|
155
155
|
collector
|
156
156
|
end
|
157
157
|
|
@@ -162,32 +162,32 @@ module ArelExtensions
|
|
162
162
|
end
|
163
163
|
|
164
164
|
def visit_ArelExtensions_Nodes_IsNotNull o, collector
|
165
|
-
|
165
|
+
collector = visit o.expr, collector
|
166
166
|
collector << ' IS NOT NULL'
|
167
167
|
collector
|
168
168
|
end
|
169
169
|
|
170
170
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
171
|
-
collector <<
|
171
|
+
collector << 'RANDOM('
|
172
172
|
if o.left != nil && o.right != nil
|
173
173
|
collector = visit o.left, collector
|
174
174
|
collector << COMMA
|
175
175
|
collector = visit o.right, collector
|
176
176
|
end
|
177
|
-
collector <<
|
177
|
+
collector << ')'
|
178
178
|
collector
|
179
179
|
end
|
180
180
|
|
181
181
|
def visit_Arel_Nodes_Regexp o, collector
|
182
182
|
collector = visit o.left, collector
|
183
|
-
collector <<
|
183
|
+
collector << ' REGEXP'
|
184
184
|
collector = visit o.right, collector
|
185
185
|
collector
|
186
186
|
end
|
187
187
|
|
188
188
|
def visit_Arel_Nodes_NotRegexp o, collector
|
189
189
|
collector = visit o.left, collector
|
190
|
-
collector <<
|
190
|
+
collector << ' NOT REGEXP '
|
191
191
|
collector = visit o.right, collector
|
192
192
|
collector
|
193
193
|
end
|
@@ -195,7 +195,7 @@ module ArelExtensions
|
|
195
195
|
def visit_ArelExtensions_Nodes_Wday o, collector
|
196
196
|
collector << "STRFTIME('%w',"
|
197
197
|
collector = visit o.date, collector
|
198
|
-
collector <<
|
198
|
+
collector << ')'
|
199
199
|
collector
|
200
200
|
end
|
201
201
|
|
@@ -208,32 +208,32 @@ module ArelExtensions
|
|
208
208
|
# AS FLOAT
|
209
209
|
# )
|
210
210
|
def visit_ArelExtensions_Nodes_Floor o, collector
|
211
|
-
collector <<
|
211
|
+
collector << 'CAST(CASE WHEN '
|
212
212
|
collector = visit o.left, collector
|
213
|
-
collector <<
|
213
|
+
collector << ' >= 0 THEN CAST('
|
214
214
|
collector = visit o.left, collector
|
215
|
-
collector <<
|
215
|
+
collector << ' AS INT) WHEN CAST('
|
216
216
|
collector = visit o.left, collector
|
217
|
-
collector <<
|
217
|
+
collector << ' AS INT) = '
|
218
218
|
collector = visit o.left, collector
|
219
|
-
collector <<
|
219
|
+
collector << ' THEN CAST('
|
220
220
|
collector = visit o.left, collector
|
221
|
-
collector <<
|
221
|
+
collector << ' AS INT) ELSE CAST(('
|
222
222
|
collector = visit o.left, collector
|
223
|
-
collector <<
|
223
|
+
collector << ' - 1.0) AS INT) END AS FLOAT)'
|
224
224
|
collector
|
225
225
|
end
|
226
226
|
|
227
227
|
def visit_ArelExtensions_Nodes_Ceil o, collector
|
228
|
-
collector <<
|
228
|
+
collector << 'CASE WHEN ROUND('
|
229
229
|
collector = visit o.left, collector
|
230
|
-
collector <<
|
230
|
+
collector << ', 1) > ROUND('
|
231
231
|
collector = visit o.left, collector
|
232
|
-
collector <<
|
232
|
+
collector << ') THEN ROUND('
|
233
233
|
collector = visit o.left, collector
|
234
|
-
collector <<
|
234
|
+
collector << ') + 1 ELSE ROUND('
|
235
235
|
collector = visit o.left, collector
|
236
|
-
collector <<
|
236
|
+
collector << ') END'
|
237
237
|
collector
|
238
238
|
end
|
239
239
|
|
@@ -243,16 +243,16 @@ module ArelExtensions
|
|
243
243
|
collector << 'SELECT '
|
244
244
|
len = row.length - 1
|
245
245
|
row.zip(o.cols).each_with_index { |(value, attr), i|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
end
|
246
|
+
case value
|
247
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
248
|
+
collector = visit value.as(attr.name), collector
|
249
|
+
else
|
250
|
+
collector << quote(value, attr && column_for(attr)).to_s
|
251
|
+
if idx == 0
|
252
|
+
collector << ' AS '
|
253
|
+
collector << quote(attr.name)
|
255
254
|
end
|
255
|
+
end
|
256
256
|
collector << COMMA unless i == len
|
257
257
|
}
|
258
258
|
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
@@ -265,22 +265,22 @@ module ArelExtensions
|
|
265
265
|
collector << 'SELECT '
|
266
266
|
len = row.length - 1
|
267
267
|
row.zip(o.cols).each_with_index { |(value, attr), i|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
end
|
268
|
+
case value
|
269
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
270
|
+
collector = visit value.as(attr.name), collector
|
271
|
+
when Integer
|
272
|
+
collector << value.to_s
|
273
|
+
if idx == 0
|
274
|
+
collector << ' AS '
|
275
|
+
collector << quote(attr.name)
|
276
|
+
end
|
277
|
+
else
|
278
|
+
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
279
|
+
if idx == 0
|
280
|
+
collector << ' AS '
|
281
|
+
collector << quote(attr.name)
|
283
282
|
end
|
283
|
+
end
|
284
284
|
collector << COMMA unless i == len
|
285
285
|
}
|
286
286
|
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
@@ -296,7 +296,7 @@ module ArelExtensions
|
|
296
296
|
else
|
297
297
|
visit o.left, collector
|
298
298
|
end
|
299
|
-
collector <<
|
299
|
+
collector << ' UNION '
|
300
300
|
collector =
|
301
301
|
if o.right.is_a?(Arel::SelectManager)
|
302
302
|
visit o.right.ast, collector
|
@@ -313,7 +313,7 @@ module ArelExtensions
|
|
313
313
|
else
|
314
314
|
visit o.left, collector
|
315
315
|
end
|
316
|
-
collector <<
|
316
|
+
collector << ' UNION ALL '
|
317
317
|
collector =
|
318
318
|
if o.right.is_a?(Arel::SelectManager)
|
319
319
|
visit o.right.ast, collector
|
@@ -325,23 +325,23 @@ module ArelExtensions
|
|
325
325
|
|
326
326
|
def get_time_converted element
|
327
327
|
if element.is_a?(Time)
|
328
|
-
|
328
|
+
Arel::Nodes::NamedFunction.new('STRFTIME', [element, '%H:%M:%S'])
|
329
329
|
elsif element.is_a?(Arel::Attributes::Attribute)
|
330
|
-
col = Arel
|
330
|
+
col = Arel.column_of(element.relation.table_name, element.name.to_s)
|
331
331
|
if col && (col.type == :time)
|
332
|
-
|
332
|
+
Arel::Nodes::NamedFunction.new('STRFTIME', [element, '%H:%M:%S'])
|
333
333
|
else
|
334
|
-
|
334
|
+
element
|
335
335
|
end
|
336
336
|
else
|
337
|
-
|
337
|
+
element
|
338
338
|
end
|
339
339
|
end
|
340
340
|
|
341
341
|
remove_method(:visit_Arel_Nodes_GreaterThanOrEqual) rescue nil
|
342
342
|
def visit_Arel_Nodes_GreaterThanOrEqual o, collector
|
343
343
|
collector = visit get_time_converted(o.left), collector
|
344
|
-
collector <<
|
344
|
+
collector << ' >= '
|
345
345
|
collector = visit get_time_converted(o.right), collector
|
346
346
|
collector
|
347
347
|
end
|
@@ -349,7 +349,7 @@ module ArelExtensions
|
|
349
349
|
remove_method(:visit_Arel_Nodes_GreaterThan) rescue nil
|
350
350
|
def visit_Arel_Nodes_GreaterThan o, collector
|
351
351
|
collector = visit get_time_converted(o.left), collector
|
352
|
-
collector <<
|
352
|
+
collector << ' > '
|
353
353
|
collector = visit get_time_converted(o.right), collector
|
354
354
|
collector
|
355
355
|
end
|
@@ -357,7 +357,7 @@ module ArelExtensions
|
|
357
357
|
remove_method(:visit_Arel_Nodes_LessThanOrEqual) rescue nil
|
358
358
|
def visit_Arel_Nodes_LessThanOrEqual o, collector
|
359
359
|
collector = visit get_time_converted(o.left), collector
|
360
|
-
collector <<
|
360
|
+
collector << ' <= '
|
361
361
|
collector = visit get_time_converted(o.right), collector
|
362
362
|
collector
|
363
363
|
end
|
@@ -365,7 +365,7 @@ module ArelExtensions
|
|
365
365
|
remove_method(:visit_Arel_Nodes_LessThan) rescue nil
|
366
366
|
def visit_Arel_Nodes_LessThan o, collector
|
367
367
|
collector = visit get_time_converted(o.left), collector
|
368
|
-
collector <<
|
368
|
+
collector << ' < '
|
369
369
|
collector = visit get_time_converted(o.right), collector
|
370
370
|
collector
|
371
371
|
end
|
@@ -379,17 +379,18 @@ module ArelExtensions
|
|
379
379
|
else
|
380
380
|
collector = visit o.left, collector
|
381
381
|
end
|
382
|
-
|
382
|
+
sep = o.right.size > 1 && o.right[0] == '"' && o.right[-1] == '"' ? '' : '"'
|
383
|
+
collector << " AS #{sep}"
|
383
384
|
collector = visit o.right, collector
|
384
|
-
collector << "
|
385
|
+
collector << "#{sep}"
|
385
386
|
collector
|
386
387
|
end
|
387
388
|
|
388
389
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
389
|
-
format = Arel::Nodes::NamedFunction.new('printf',[Arel
|
390
|
+
format = Arel::Nodes::NamedFunction.new('printf', [Arel.quoted(o.original_string), o.left])
|
390
391
|
locale_map = NUMBER_COMMA_MAPPING[o.locale]
|
391
392
|
if locale_map
|
392
|
-
format = format.replace(',',locale_map[',']).replace('.',locale_map['.'])
|
393
|
+
format = format.replace(',', locale_map[',']).replace('.', locale_map['.'])
|
393
394
|
end
|
394
395
|
visit format, collector
|
395
396
|
collector
|