arel_extensions 1.1.7 → 1.1.8
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/lib/arel_extensions/nodes/concat.rb +18 -19
- data/lib/arel_extensions/nodes/md5.rb +8 -0
- data/lib/arel_extensions/string_functions.rb +35 -21
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +59 -47
- data/lib/arel_extensions/visitors/mysql.rb +23 -16
- data/lib/arel_extensions/visitors/oracle.rb +86 -70
- data/lib/arel_extensions/visitors/postgresql.rb +21 -15
- data/lib/arel_extensions/visitors/to_sql.rb +7 -0
- data/test/visitors/test_to_sql.rb +2 -0
- data/test/with_ar/all_agnostic_test.rb +19 -17
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcbd0d968a06d04df7d1b214a72aeaf46dd9e950
|
4
|
+
data.tar.gz: 717c053e7925a4d4ec6c1aa43d7db95a928224ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c47c4d2544182c27b7effe868a157545d3bb9b16096ebf0c9078373d3682a008a7e481d30f2a2d2a2bf40e1f1b6ea2431e08a8129b07998bf90f005e0eb9173a
|
7
|
+
data.tar.gz: 4817767ae9f17846f9909a1f7ceadaddd4ca9745d65c64b50be06184e31ddfc93ae55ac9c27e4b0d97fbc1c91fd14c805f298d2414a9b77130c4737bf3489e8a
|
@@ -14,7 +14,7 @@ module ArelExtensions::Nodes
|
|
14
14
|
}.flatten.reduce([]) { | res, b |
|
15
15
|
# concatenate successive literal strings.
|
16
16
|
if b.is_a?(Arel::Nodes::Quoted) && b.expr == ""
|
17
|
-
|
17
|
+
res
|
18
18
|
elsif res.last && res.last.is_a?(Arel::Nodes::Quoted) && b.is_a?(Arel::Nodes::Quoted)
|
19
19
|
res[-1] = Arel::Nodes.build_quoted(res.last.expr + b.expr)
|
20
20
|
else
|
@@ -25,18 +25,14 @@ module ArelExtensions::Nodes
|
|
25
25
|
super(tab)
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
#def +(other)
|
38
|
-
# Concat.new(self.expressions + [other])
|
39
|
-
#end
|
28
|
+
def self.new expr
|
29
|
+
o = super(expr)
|
30
|
+
if o.expressions.length == 1
|
31
|
+
o.expressions[0]
|
32
|
+
else
|
33
|
+
o
|
34
|
+
end
|
35
|
+
end
|
40
36
|
|
41
37
|
def concat(other)
|
42
38
|
Concat.new(self.expressions + [other])
|
@@ -47,16 +43,19 @@ module ArelExtensions::Nodes
|
|
47
43
|
class GroupConcat < Function
|
48
44
|
RETURN_TYPE = :string
|
49
45
|
|
46
|
+
attr_accessor :orders
|
47
|
+
|
50
48
|
def initialize expr
|
51
49
|
tab = expr.map { |arg|
|
52
|
-
|
53
|
-
|
50
|
+
if arg.is_a?(Array)
|
51
|
+
@orders = arg
|
52
|
+
nil
|
53
|
+
else
|
54
|
+
convert_to_node(arg)
|
55
|
+
end
|
56
|
+
}.compact
|
54
57
|
super(tab)
|
55
58
|
end
|
56
59
|
|
57
|
-
#def +(other)
|
58
|
-
# return Concat.new([self, other])
|
59
|
-
#end
|
60
|
-
|
61
60
|
end
|
62
61
|
end
|
@@ -14,7 +14,8 @@ require 'arel_extensions/nodes/repeat'
|
|
14
14
|
require 'arel_extensions/nodes/cast'
|
15
15
|
require 'arel_extensions/nodes/collate'
|
16
16
|
require 'arel_extensions/nodes/levenshtein_distance'
|
17
|
-
|
17
|
+
require 'arel_extensions/nodes/md5'
|
18
|
+
|
18
19
|
|
19
20
|
module ArelExtensions
|
20
21
|
module StringFunctions
|
@@ -38,7 +39,7 @@ module ArelExtensions
|
|
38
39
|
def substring start, len = nil
|
39
40
|
ArelExtensions::Nodes::Substring.new [self, start, len]
|
40
41
|
end
|
41
|
-
|
42
|
+
|
42
43
|
def [](start, ind = nil)
|
43
44
|
start += 1 if start.is_a?(Integer)
|
44
45
|
if start.is_a?(Range)
|
@@ -78,29 +79,29 @@ module ArelExtensions
|
|
78
79
|
def idoes_not_match_all others, escape = nil
|
79
80
|
grouping_all :idoes_not_match, others, escape
|
80
81
|
end
|
81
|
-
|
82
|
+
|
82
83
|
def ai_matches other # accent insensitive & case sensitive
|
83
84
|
ArelExtensions::Nodes::AiMatches.new(self,other)
|
84
85
|
end
|
85
|
-
|
86
|
+
|
86
87
|
def ai_imatches other # accent insensitive & case insensitive
|
87
88
|
ArelExtensions::Nodes::AiIMatches.new(self,other)
|
88
89
|
end
|
89
|
-
|
90
|
+
|
90
91
|
def smatches other # accent sensitive & case sensitive
|
91
92
|
ArelExtensions::Nodes::SMatches.new(self,other)
|
92
93
|
end
|
93
|
-
|
94
|
+
|
94
95
|
def ai_collate
|
95
|
-
|
96
|
+
ArelExtensions::Nodes::Collate.new(self,nil,true,false)
|
96
97
|
end
|
97
|
-
|
98
|
+
|
98
99
|
def ci_collate
|
99
|
-
|
100
|
+
ArelExtensions::Nodes::Collate.new(self,nil,false,true)
|
100
101
|
end
|
101
|
-
|
102
|
+
|
102
103
|
def collate ai=false,ci=false, option=nil
|
103
|
-
|
104
|
+
ArelExtensions::Nodes::Collate.new(self,option,ai,ci)
|
104
105
|
end
|
105
106
|
|
106
107
|
#REPLACE function replaces a sequence of characters in a string with another set of characters, not case-sensitive.
|
@@ -108,12 +109,22 @@ module ArelExtensions
|
|
108
109
|
ArelExtensions::Nodes::Replace.new [self, left, right]
|
109
110
|
end
|
110
111
|
|
111
|
-
|
112
|
-
|
113
|
-
|
112
|
+
def concat other
|
113
|
+
ArelExtensions::Nodes::Concat.new [self, other]
|
114
|
+
end
|
114
115
|
|
115
|
-
|
116
|
-
|
116
|
+
#concat elements of a group, separated by sep and ordered by a list of Ascending or Descending
|
117
|
+
def group_concat sep = nil, *orders
|
118
|
+
order_tabs = [orders].flatten.map{ |o|
|
119
|
+
if o.is_a?(Arel::Nodes::Ascending) || o.is_a?(Arel::Nodes::Descending)
|
120
|
+
o
|
121
|
+
elsif o.respond_to?(:asc)
|
122
|
+
o.asc
|
123
|
+
else
|
124
|
+
nil
|
125
|
+
end
|
126
|
+
}.compact
|
127
|
+
ArelExtensions::Nodes::GroupConcat.new [self, sep, order_tabs]
|
117
128
|
end
|
118
129
|
|
119
130
|
#Function returns a string after removing left, right or the both prefixes or suffixes int argument
|
@@ -146,16 +157,19 @@ module ArelExtensions
|
|
146
157
|
end
|
147
158
|
|
148
159
|
def repeat other = 1
|
149
|
-
|
160
|
+
ArelExtensions::Nodes::Repeat.new [self, other]
|
150
161
|
end
|
151
162
|
|
152
163
|
def levenshtein_distance other
|
153
|
-
|
164
|
+
ArelExtensions::Nodes::LevenshteinDistance.new [self, other]
|
154
165
|
end
|
155
166
|
|
156
|
-
|
157
|
-
|
158
|
-
|
167
|
+
def edit_distance other
|
168
|
+
ArelExtensions::Nodes::LevenshteinDistance.new [self, other]
|
169
|
+
end
|
159
170
|
|
171
|
+
def md5
|
172
|
+
ArelExtensions::Nodes::MD5.new [self]
|
173
|
+
end
|
160
174
|
end
|
161
175
|
end
|
@@ -311,7 +311,7 @@ module ArelExtensions
|
|
311
311
|
end
|
312
312
|
end
|
313
313
|
|
314
|
-
|
314
|
+
def visit_ArelExtensions_Nodes_AiMatches o, collector
|
315
315
|
collector = visit o.left.ai_collate, collector
|
316
316
|
collector << ' LIKE '
|
317
317
|
collector = visit o.right.ai_collate, collector
|
@@ -321,9 +321,9 @@ module ArelExtensions
|
|
321
321
|
else
|
322
322
|
collector
|
323
323
|
end
|
324
|
-
|
324
|
+
end
|
325
325
|
|
326
|
-
|
326
|
+
def visit_ArelExtensions_Nodes_AiIMatches o, collector
|
327
327
|
collector = visit o.left.collate(true,true), collector
|
328
328
|
collector << ' LIKE '
|
329
329
|
collector = visit o.right.collate(true,true), collector
|
@@ -333,9 +333,9 @@ module ArelExtensions
|
|
333
333
|
else
|
334
334
|
collector
|
335
335
|
end
|
336
|
-
|
336
|
+
end
|
337
337
|
|
338
|
-
|
338
|
+
def visit_ArelExtensions_Nodes_SMatches o, collector
|
339
339
|
collector = visit o.left.collate, collector
|
340
340
|
collector << ' LIKE '
|
341
341
|
collector = visit o.right.collate, collector
|
@@ -345,27 +345,24 @@ module ArelExtensions
|
|
345
345
|
else
|
346
346
|
collector
|
347
347
|
end
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
348
|
+
end
|
349
|
+
|
350
|
+
def visit_ArelExtensions_Nodes_Collate o, collector
|
351
|
+
if o.ai && o.ci
|
352
|
+
collector = visit o.expressions.first, collector
|
353
|
+
collector << ' COLLATE Latin1_General_CI_AI'
|
354
|
+
elsif o.ai
|
355
|
+
collector = visit o.expressions.first, collector
|
356
|
+
collector << ' COLLATE Latin1_General_CS_AI'
|
357
|
+
elsif o.ci
|
358
|
+
collector = visit o.expressions.first, collector
|
359
|
+
collector << ' COLLATE Latin1_General_CI_AS'
|
360
|
+
else
|
361
|
+
collector = visit o.expressions.first, collector
|
362
|
+
collector << ' COLLATE Latin1_General_CS_AS'
|
363
|
+
end
|
364
364
|
collector
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
365
|
+
end
|
369
366
|
|
370
367
|
# SQL Server does not know about REGEXP
|
371
368
|
def visit_Arel_Nodes_Regexp o, collector
|
@@ -382,42 +379,57 @@ module ArelExtensions
|
|
382
379
|
|
383
380
|
# TODO;
|
384
381
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
385
|
-
collector << "(
|
382
|
+
collector << "(STRING_AGG("
|
386
383
|
collector = visit o.left, collector
|
384
|
+
collector << Arel::Visitors::Oracle::COMMA
|
387
385
|
if o.right && o.right != 'NULL'
|
388
|
-
collector << Arel::Visitors::Oracle::COMMA
|
389
386
|
collector = visit o.right, collector
|
387
|
+
else
|
388
|
+
collector = visit Arel::Nodes.build_quoted(','), collector
|
390
389
|
end
|
391
390
|
collector << ") WITHIN GROUP (ORDER BY "
|
392
|
-
|
391
|
+
if !o.orders.blank?
|
392
|
+
o.orders.each_with_index do |order,i|
|
393
|
+
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
394
|
+
collector = visit order, collector
|
395
|
+
end
|
396
|
+
else
|
397
|
+
collector = visit o.left, collector
|
398
|
+
end
|
393
399
|
collector << "))"
|
394
400
|
collector
|
395
401
|
end
|
396
|
-
|
397
|
-
|
398
|
-
|
402
|
+
|
403
|
+
def visit_ArelExtensions_Nodes_MD5 o, collector
|
404
|
+
collector << "LOWER(CONVERT(NVARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR,"
|
405
|
+
collector = visit o.left, collector
|
406
|
+
collector << ")),2))"
|
407
|
+
collector
|
408
|
+
end
|
409
|
+
|
410
|
+
def visit_ArelExtensions_Nodes_Cast o, collector
|
399
411
|
collector << "CAST("
|
400
412
|
collector = visit o.left, collector
|
401
413
|
collector << " AS "
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
414
|
+
case o.as_attr
|
415
|
+
when :string
|
416
|
+
as_attr = Arel::Nodes::SqlLiteral.new('varchar')
|
417
|
+
when :time
|
418
|
+
as_attr = Arel::Nodes::SqlLiteral.new('time')
|
419
|
+
when :number
|
420
|
+
as_attr = Arel::Nodes::SqlLiteral.new('int')
|
421
|
+
when :datetime
|
422
|
+
as_attr = Arel::Nodes::SqlLiteral.new('datetime')
|
423
|
+
when :binary
|
424
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
425
|
+
else
|
426
|
+
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
427
|
+
end
|
416
428
|
collector = visit as_attr, collector
|
417
429
|
collector << ")"
|
418
430
|
collector
|
419
|
-
|
420
|
-
|
431
|
+
end
|
432
|
+
|
421
433
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
422
434
|
col = o.left.coalesce(0)
|
423
435
|
locale = Arel::Nodes.build_quoted(o.locale.tr('_','-'))
|
@@ -120,25 +120,32 @@ module ArelExtensions
|
|
120
120
|
collector
|
121
121
|
end
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
123
|
+
def visit_ArelExtensions_Nodes_Concat o, collector
|
124
|
+
collector << "CONCAT("
|
125
|
+
o.expressions.each_with_index { |arg, i|
|
126
|
+
collector << Arel::Visitors::MySQL::COMMA unless i == 0
|
127
|
+
if (arg.is_a?(Numeric)) || (arg.is_a?(Arel::Attributes::Attribute))
|
128
|
+
collector << "CAST("
|
129
|
+
collector = visit arg, collector
|
130
|
+
collector << " AS char)"
|
131
|
+
else
|
132
|
+
collector = visit arg, collector
|
133
|
+
end
|
134
|
+
}
|
135
|
+
collector << ")"
|
136
|
+
collector
|
137
|
+
end
|
138
138
|
|
139
139
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
140
140
|
collector << "GROUP_CONCAT("
|
141
141
|
collector = visit o.left, collector
|
142
|
+
if !o.orders.blank?
|
143
|
+
collector << ' ORDER BY '
|
144
|
+
o.orders.each_with_index do |order,i|
|
145
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
146
|
+
collector = visit order, collector
|
147
|
+
end
|
148
|
+
end
|
142
149
|
if o.right && o.right != 'NULL'
|
143
150
|
collector << ' SEPARATOR '
|
144
151
|
collector = visit o.right, collector
|
@@ -197,7 +204,7 @@ module ArelExtensions
|
|
197
204
|
when :integer, :float, :decimal
|
198
205
|
collector << "FORMAT("
|
199
206
|
collector = visit o.left, collector
|
200
|
-
collector << Arel::Visitors::ToSql::COMMA
|
207
|
+
collector << Arel::Visitors::ToSql::COMMA
|
201
208
|
collector << '2'
|
202
209
|
collector << Arel::Visitors::ToSql::COMMA
|
203
210
|
collector = visit o.right, collector
|
@@ -2,7 +2,7 @@
|
|
2
2
|
module ArelExtensions
|
3
3
|
module Visitors
|
4
4
|
Arel::Visitors::Oracle.class_eval do
|
5
|
-
|
5
|
+
|
6
6
|
SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
|
7
7
|
Arel::Visitors::Oracle::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
8
8
|
Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES = {
|
@@ -12,8 +12,8 @@ module ArelExtensions
|
|
12
12
|
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
13
13
|
}
|
14
14
|
Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING = { 'en_US' => '.,', 'fr_FR' => ',', 'sv_SE' => ', ' }
|
15
|
-
|
16
|
-
|
15
|
+
|
16
|
+
def visit_ArelExtensions_Nodes_Log10 o, collector
|
17
17
|
collector << "LOG("
|
18
18
|
o.expressions.each_with_index { |arg, i|
|
19
19
|
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
@@ -21,9 +21,9 @@ module ArelExtensions
|
|
21
21
|
}
|
22
22
|
collector << ",10)"
|
23
23
|
collector
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
end
|
25
|
+
|
26
|
+
def visit_ArelExtensions_Nodes_Power o, collector
|
27
27
|
collector << "POWER("
|
28
28
|
o.expressions.each_with_index { |arg, i|
|
29
29
|
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
@@ -31,8 +31,8 @@ module ArelExtensions
|
|
31
31
|
}
|
32
32
|
collector << ")"
|
33
33
|
collector
|
34
|
-
|
35
|
-
|
34
|
+
end
|
35
|
+
|
36
36
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
37
37
|
collector << '('
|
38
38
|
o.expressions.each_with_index { |arg, i|
|
@@ -44,7 +44,7 @@ module ArelExtensions
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def visit_ArelExtensions_Nodes_IMatches o, collector
|
47
|
-
|
47
|
+
collector << 'LOWER('
|
48
48
|
collector = visit o.left, collector
|
49
49
|
collector << ') LIKE LOWER('
|
50
50
|
collector = visit o.right, collector
|
@@ -82,7 +82,7 @@ module ArelExtensions
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def visit_ArelExtensions_Nodes_SMatches o, collector
|
85
|
-
|
85
|
+
collector = visit o.left, collector
|
86
86
|
collector << ' LIKE '
|
87
87
|
collector = visit o.right, collector
|
88
88
|
if o.escape
|
@@ -107,23 +107,23 @@ module ArelExtensions
|
|
107
107
|
collector
|
108
108
|
end
|
109
109
|
end
|
110
|
-
|
111
|
-
def visit_ArelExtensions_Nodes_Collate o, collector
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
110
|
+
|
111
|
+
def visit_ArelExtensions_Nodes_Collate o, 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
|
126
|
+
end
|
127
127
|
collector
|
128
128
|
end
|
129
129
|
|
@@ -131,12 +131,21 @@ module ArelExtensions
|
|
131
131
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
132
132
|
collector << "(LISTAGG("
|
133
133
|
collector = visit o.left, collector
|
134
|
+
collector << Arel::Visitors::Oracle::COMMA
|
134
135
|
if o.right && o.right != 'NULL'
|
135
|
-
collector << Arel::Visitors::Oracle::COMMA
|
136
136
|
collector = visit o.right, collector
|
137
|
+
else
|
138
|
+
collector = visit Arel::Nodes.build_quoted(','), collector
|
137
139
|
end
|
138
140
|
collector << ") WITHIN GROUP (ORDER BY "
|
139
|
-
|
141
|
+
if !o.orders.blank?
|
142
|
+
o.orders.each_with_index do |order,i|
|
143
|
+
collector << Arel::Visitors::Oracle::COMMA unless i == 0
|
144
|
+
collector = visit order, collector
|
145
|
+
end
|
146
|
+
else
|
147
|
+
collector = visit o.left, collector
|
148
|
+
end
|
140
149
|
collector << "))"
|
141
150
|
collector
|
142
151
|
end
|
@@ -159,7 +168,14 @@ module ArelExtensions
|
|
159
168
|
}
|
160
169
|
collector << ")"
|
161
170
|
collector
|
162
|
-
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def visit_ArelExtensions_Nodes_MD5 o, collector
|
174
|
+
collector << "LOWER (RAWTOHEX (DBMS_OBFUSCATION_TOOLKIT.md5(input => UTL_I18N.STRING_TO_RAW("
|
175
|
+
collector = visit o.left, collector
|
176
|
+
collector << ", 'AL32UTF8'))))"
|
177
|
+
collector
|
178
|
+
end
|
163
179
|
|
164
180
|
# :date is not possible in Oracle since this type does not really exist
|
165
181
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
@@ -203,31 +219,31 @@ module ArelExtensions
|
|
203
219
|
collector << ")"
|
204
220
|
collector
|
205
221
|
end
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
222
|
+
|
223
|
+
def visit_ArelExtensions_Nodes_Cast o, collector
|
224
|
+
case o.as_attr
|
225
|
+
when :string
|
226
|
+
as_attr = Arel::Nodes::SqlLiteral.new('varchar(255)')
|
227
|
+
when :time
|
228
|
+
left = Arel::Nodes::NamedFunction.new('TO_CHAR',[o.left,Arel::Nodes.build_quoted('HH24:MI:SS')])
|
229
|
+
collector = visit left, collector
|
230
|
+
return collector
|
231
|
+
when :number
|
232
|
+
as_attr = Arel::Nodes::SqlLiteral.new('int')
|
233
|
+
when :datetime
|
234
|
+
as_attr = Arel::Nodes::SqlLiteral.new('timestamp')
|
235
|
+
when :binary
|
236
|
+
as_attr = Arel::Nodes::SqlLiteral.new('binary')
|
237
|
+
else
|
238
|
+
as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
|
239
|
+
end
|
240
|
+
collector << "CAST("
|
225
241
|
collector = visit o.left, collector
|
226
242
|
collector << " AS "
|
227
243
|
collector = visit as_attr, collector
|
228
244
|
collector << ")"
|
229
245
|
collector
|
230
|
-
|
246
|
+
end
|
231
247
|
|
232
248
|
|
233
249
|
|
@@ -384,11 +400,11 @@ module ArelExtensions
|
|
384
400
|
|
385
401
|
def visit_ArelExtensions_Nodes_Repeat o, collector
|
386
402
|
collector << "LPAD("
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
403
|
+
collector = visit o.expressions[0], collector #can't put empty string, otherwise it wouldn't work
|
404
|
+
collector << Arel::Visitors::ToSql::COMMA
|
405
|
+
collector = visit o.expressions[1], collector
|
406
|
+
collector << Arel::Visitors::ToSql::COMMA
|
407
|
+
collector = visit o.expressions[0], collector
|
392
408
|
collector << ")"
|
393
409
|
collector
|
394
410
|
end
|
@@ -396,9 +412,9 @@ module ArelExtensions
|
|
396
412
|
# add primary_key if not present, avoid zip
|
397
413
|
if Arel::VERSION.to_i < 7
|
398
414
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
399
|
-
|
415
|
+
collector << "("
|
400
416
|
o.left.each_with_index do |row, idx| # values
|
401
|
-
|
417
|
+
collector << " UNION ALL " if idx != 0
|
402
418
|
collector << "(SELECT "
|
403
419
|
v = Arel::Nodes::Values.new(row, o.cols)
|
404
420
|
len = v.expressions.length - 1
|
@@ -419,20 +435,20 @@ module ArelExtensions
|
|
419
435
|
end
|
420
436
|
else
|
421
437
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
422
|
-
|
438
|
+
collector << "("
|
423
439
|
o.left.each_with_index do |row, idx|
|
424
|
-
|
440
|
+
collector << " UNION ALL " if idx != 0
|
425
441
|
collector << "(SELECT "
|
426
442
|
v = Arel::Nodes::Values.new(row, o.cols)
|
427
443
|
len = v.expressions.length - 1
|
428
444
|
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
445
|
+
case value
|
446
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
447
|
+
collector = visit value, collector
|
448
|
+
else
|
449
|
+
collector << (attr && attr.able_to_type_cast? ? quote(attr.type_cast_for_database(value)) : quote(value).to_s)
|
450
|
+
end
|
451
|
+
collector << Arel::Visitors::Oracle::COMMA unless i == len
|
436
452
|
}
|
437
453
|
collector << ' FROM DUAL)'
|
438
454
|
end
|
@@ -542,17 +558,17 @@ module ArelExtensions
|
|
542
558
|
number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
543
559
|
Arel::Nodes.build_quoted(col.abs),
|
544
560
|
Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after+'EEEE'),
|
545
|
-
options
|
546
|
-
])
|
561
|
+
options
|
562
|
+
])
|
547
563
|
if o.type == 'e'
|
548
564
|
number = number.replace('E','e')
|
549
565
|
end
|
550
|
-
else
|
566
|
+
else
|
551
567
|
number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
552
568
|
Arel::Nodes.build_quoted(col.abs),
|
553
569
|
Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after),
|
554
570
|
options
|
555
|
-
])
|
571
|
+
])
|
556
572
|
end
|
557
573
|
|
558
574
|
repeated_char = (o.width == 0) ? Arel::Nodes.build_quoted('') : ArelExtensions::Nodes::Case.new().
|
@@ -71,13 +71,19 @@ module ArelExtensions
|
|
71
71
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
72
72
|
collector << "array_to_string(array_agg("
|
73
73
|
collector = visit o.left, collector
|
74
|
+
if !o.orders.blank?
|
75
|
+
collector << ' ORDER BY '
|
76
|
+
o.orders.each_with_index do |order,i|
|
77
|
+
collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
|
78
|
+
collector = visit order, collector
|
79
|
+
end
|
80
|
+
end
|
74
81
|
collector << ")"
|
82
|
+
collector << Arel::Visitors::PostgreSQL::COMMA
|
75
83
|
if o.right && o.right != 'NULL'
|
76
|
-
collector << Arel::Visitors::PostgreSQL::COMMA
|
77
84
|
collector = visit o.right, collector
|
78
85
|
else
|
79
|
-
collector
|
80
|
-
collector = visit Arel::Nodes.build_quoted(' '), collector
|
86
|
+
collector = visit Arel::Nodes.build_quoted(','), collector
|
81
87
|
end
|
82
88
|
collector << ")"
|
83
89
|
collector
|
@@ -168,19 +174,19 @@ module ArelExtensions
|
|
168
174
|
collector
|
169
175
|
end
|
170
176
|
end
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
177
|
+
|
178
|
+
def visit_ArelExtensions_Nodes_Collate o, collector
|
179
|
+
if o.ai
|
180
|
+
collector << "unaccent("
|
181
|
+
collector = visit o.expressions.first, collector
|
182
|
+
collector << ")"
|
183
|
+
elsif o.ci
|
184
|
+
collector = visit o.expressions.first, collector
|
185
|
+
else
|
186
|
+
collector = visit o.expressions.first, collector
|
187
|
+
end
|
182
188
|
collector
|
183
|
-
|
189
|
+
end
|
184
190
|
|
185
191
|
def visit_ArelExtensions_Nodes_DateAdd o, collector
|
186
192
|
collector = visit o.left, collector
|
@@ -92,6 +92,13 @@ module ArelExtensions
|
|
92
92
|
collector
|
93
93
|
end
|
94
94
|
|
95
|
+
def visit_ArelExtensions_Nodes_MD5 o, collector
|
96
|
+
collector << "MD5("
|
97
|
+
collector = visit o.left, collector
|
98
|
+
collector << ")"
|
99
|
+
collector
|
100
|
+
end
|
101
|
+
|
95
102
|
def visit_ArelExtensions_Nodes_Length o, collector
|
96
103
|
collector << "LENGTH("
|
97
104
|
collector = visit o.left, collector
|
@@ -101,6 +101,8 @@ module ArelExtensions
|
|
101
101
|
compile(c + 'test' + ' chain').must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
|
102
102
|
compile(Arel::Nodes.build_quoted('test') + ' chain').must_be_like %{'test chain'}
|
103
103
|
compile(c + '' + c).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
|
104
|
+
|
105
|
+
compile(c.md5).must_be_like %{MD5(\"users\".\"name\")}
|
104
106
|
end
|
105
107
|
|
106
108
|
# Comparators
|
@@ -150,23 +150,19 @@ module ArelExtensions
|
|
150
150
|
|
151
151
|
# String Functions
|
152
152
|
def test_concat
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
else
|
167
|
-
assert_equal "Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie']).reorder(:name), @name.group_concat)
|
168
|
-
end
|
169
|
-
end
|
153
|
+
assert_equal 'Camille Camille', t(@camille, @name + ' ' + @name)
|
154
|
+
assert_equal 'Laure 2', t(@laure, @name + ' ' + 2)
|
155
|
+
assert_equal 'Test Laure', t(@laure, Arel::Nodes.build_quoted('Test ') + @name)
|
156
|
+
|
157
|
+
assert_equal "Lucas Sophie", t(User.where(:name => ['Lucas', 'Sophie']), @name.group_concat(' '))
|
158
|
+
assert_equal "Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie']), @name.group_concat(','))
|
159
|
+
assert_equal "Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie']), @name.group_concat)
|
160
|
+
|
161
|
+
skip "No order in group_concat in SqlLite" if $sqlite
|
162
|
+
assert_equal "Arthur,Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@name.asc))
|
163
|
+
assert_equal "Sophie,Lucas,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@name.desc))
|
164
|
+
assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',[@score.asc,@name.asc]))
|
165
|
+
assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@score.asc,@name.asc))
|
170
166
|
end
|
171
167
|
|
172
168
|
def test_length
|
@@ -175,6 +171,12 @@ module ArelExtensions
|
|
175
171
|
assert_equal 42, t(@laure, @name.length + 37)
|
176
172
|
end
|
177
173
|
|
174
|
+
def test_md5
|
175
|
+
skip "Sqlite can't do md5" if $sqlite
|
176
|
+
assert_equal "e2cf99ca82a7e829d2a4ac85c48154d0", t(@camille, @name.md5)
|
177
|
+
assert_equal "c3d41bf5efb468a1bcce53bd53726c85", t(@lucas, @name.md5)
|
178
|
+
end
|
179
|
+
|
178
180
|
def test_locate
|
179
181
|
skip "Sqlite version can't load extension for locate" if $sqlite && $load_extension_disabled
|
180
182
|
assert_equal 1, t(@camille, @name.locate("C"))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arel_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yann Azoury
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-02-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: arel
|
@@ -142,6 +142,7 @@ files:
|
|
142
142
|
- lib/arel_extensions/nodes/locate.rb
|
143
143
|
- lib/arel_extensions/nodes/log10.rb
|
144
144
|
- lib/arel_extensions/nodes/matches.rb
|
145
|
+
- lib/arel_extensions/nodes/md5.rb
|
145
146
|
- lib/arel_extensions/nodes/power.rb
|
146
147
|
- lib/arel_extensions/nodes/rand.rb
|
147
148
|
- lib/arel_extensions/nodes/repeat.rb
|