arel_extensions 1.1.7 → 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|