arel_extensions 1.0.8 → 1.1.0
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/.travis.yml +1 -1
- data/README.md +5 -0
- data/lib/arel_extensions.rb +9 -0
- data/lib/arel_extensions/math.rb +33 -25
- data/lib/arel_extensions/math_functions.rb +2 -2
- data/lib/arel_extensions/nodes/case.rb +1 -0
- data/lib/arel_extensions/nodes/concat.rb +43 -30
- data/lib/arel_extensions/nodes/function.rb +2 -1
- data/lib/arel_extensions/string_functions.rb +6 -1
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +0 -23
- data/lib/arel_extensions/visitors/oracle.rb +39 -31
- data/lib/arel_extensions/visitors/postgresql.rb +22 -4
- data/test/visitors/test_bulk_insert_oracle.rb +5 -5
- data/test/visitors/test_to_sql.rb +32 -2
- data/test/with_ar/all_agnostic_test.rb +16 -2
- data/test/with_ar/insert_agnostic_test.rb +1 -1
- metadata +4 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b42393f60593054c04105afad4f4500dc826cd93
|
4
|
+
data.tar.gz: 383b4bc32619fe292c7f7ba31f867f1f49c8da80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a724f2bd5c6d6ecedf567d44cc5d9be29f4270043b9d816b0090e19fce6380af13af3e5d4930f5252add2b4542d58ff7f6a21c202e1a5001665c7aa10b9aee3
|
7
|
+
data.tar.gz: 29f68d3d37bee531b23098ccace43491c42d781f719c451d1a7bbbaa4c0067b54abbf356940be7f955ad72984a07132e59e1bc4b8cea0f061e0abeb7099c416b
|
data/.travis.yml
CHANGED
@@ -12,7 +12,7 @@ before_install:
|
|
12
12
|
- sudo apt-get install -y sqlite3-pcre curl
|
13
13
|
- .travis/sqlite3/extension-functions.sh
|
14
14
|
- .travis/oracle/download.sh
|
15
|
-
- .travis/oracle/install.sh
|
15
|
+
- sh -ex .travis/oracle/install.sh
|
16
16
|
- .travis/setup_accounts.sh
|
17
17
|
install:
|
18
18
|
- gem install bundler
|
data/README.md
CHANGED
@@ -72,6 +72,11 @@ With Arel Extensions:
|
|
72
72
|
```
|
73
73
|
|
74
74
|
Other functions : ABS, RAND, ROUND, FLOOR, CEIL, FORMAT
|
75
|
+
Exemples :
|
76
|
+
```ruby
|
77
|
+
t[:price].format_number("%07.2f €","fr_FR")
|
78
|
+
# equivalent to 'sprintf("%07.2f €",price)' plus locale management
|
79
|
+
```
|
75
80
|
|
76
81
|
## String operations
|
77
82
|
|
data/lib/arel_extensions.rb
CHANGED
@@ -12,6 +12,10 @@ Arel::Nodes::Binary.class_eval do
|
|
12
12
|
include Arel::Expressions
|
13
13
|
end
|
14
14
|
|
15
|
+
Arel::Nodes::Casted.class_eval do
|
16
|
+
include Arel::AliasPredication
|
17
|
+
end
|
18
|
+
|
15
19
|
Arel::Nodes::Unary.class_eval do
|
16
20
|
include Arel::Math
|
17
21
|
include Arel::AliasPredication
|
@@ -21,6 +25,7 @@ end
|
|
21
25
|
Arel::Nodes::Grouping.class_eval do
|
22
26
|
include Arel::Math
|
23
27
|
include Arel::AliasPredication
|
28
|
+
include Arel::OrderPredications
|
24
29
|
include Arel::Expressions
|
25
30
|
end
|
26
31
|
|
@@ -67,6 +72,10 @@ module Arel
|
|
67
72
|
def self.rand
|
68
73
|
ArelExtensions::Nodes::Rand.new
|
69
74
|
end
|
75
|
+
|
76
|
+
def self.shorten s
|
77
|
+
Base64.urlsafe_encode64(Digest::MD5.new.digest(s)).tr('=', '').tr('-', '_')
|
78
|
+
end
|
70
79
|
end
|
71
80
|
|
72
81
|
Arel::Attributes::Attribute.class_eval do
|
data/lib/arel_extensions/math.rb
CHANGED
@@ -15,51 +15,59 @@ module ArelExtensions
|
|
15
15
|
#String and others (convert in string) allows you to concatenate 2 or more strings together.
|
16
16
|
#Date and integer adds or subtracts a specified time interval from a date.
|
17
17
|
def +(other)
|
18
|
-
|
19
|
-
|
18
|
+
case self
|
19
|
+
when Arel::Nodes::Quoted
|
20
|
+
return self.concat(other)
|
21
|
+
when Arel::Nodes::Grouping
|
20
22
|
if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
|
21
|
-
return
|
23
|
+
return self.concat(other)
|
22
24
|
else
|
23
25
|
return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
24
26
|
end
|
25
|
-
|
26
|
-
if self.is_a?(ArelExtensions::Nodes::Function)
|
27
|
+
when ArelExtensions::Nodes::Function
|
27
28
|
return case self.return_type
|
28
29
|
when :string, :text
|
29
|
-
|
30
|
+
self.concat(other)
|
30
31
|
when :integer, :decimal, :float, :number, :int
|
31
32
|
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
32
33
|
when :date, :datetime
|
33
34
|
ArelExtensions::Nodes::DateAdd.new [self, other]
|
34
35
|
else
|
35
|
-
|
36
|
+
self.concat(other)
|
36
37
|
end
|
37
|
-
|
38
|
-
if self.is_a?(Arel::Nodes::Function)
|
38
|
+
when Arel::Nodes::Function
|
39
39
|
return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
40
|
-
end
|
41
|
-
col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
|
42
|
-
if (!col) #if the column doesn't exist in the database
|
43
|
-
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
|
44
40
|
else
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
41
|
+
col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
|
42
|
+
if (!col) #if the column doesn't exist in the database
|
43
|
+
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
|
44
|
+
else
|
45
|
+
arg = col.type
|
46
|
+
if arg == :integer || (!arg)
|
47
|
+
other = other.to_i if other.is_a?(String)
|
48
|
+
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
49
|
+
elsif arg == :decimal || arg == :float
|
50
|
+
other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
|
51
|
+
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
52
|
+
elsif arg == :datetime || arg == :date
|
53
|
+
ArelExtensions::Nodes::DateAdd.new [self, other]
|
54
|
+
elsif arg == :string || arg == :text
|
55
|
+
self.concat(other)
|
56
|
+
end
|
57
|
+
end
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
61
|
#function returns the time between two dates
|
61
62
|
#function returns the substraction between two ints
|
62
63
|
def -(other)
|
64
|
+
if self.is_a?(Arel::Nodes::Grouping)
|
65
|
+
if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
|
66
|
+
return Arel::Nodes::Grouping.new(ArelExtensions::Nodes::DateSub.new [self, other])
|
67
|
+
else
|
68
|
+
return Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
|
69
|
+
end
|
70
|
+
end
|
63
71
|
return case self.return_type
|
64
72
|
when :string, :text # ???
|
65
73
|
Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) # ??
|
@@ -59,7 +59,7 @@ module ArelExtensions
|
|
59
59
|
# function returning a number at a specific format
|
60
60
|
def format_number format_string, locale=nil
|
61
61
|
begin
|
62
|
-
sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
|
62
|
+
sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
|
63
63
|
m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
|
64
64
|
opts = {
|
65
65
|
:prefix => m[1],
|
@@ -73,7 +73,7 @@ module ArelExtensions
|
|
73
73
|
}
|
74
74
|
# opts = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
|
75
75
|
ArelExtensions::Nodes::FormattedNumber.new [self,opts]
|
76
|
-
rescue
|
76
|
+
rescue Exception => e
|
77
77
|
Arel::Nodes.build_quoted('Wrong Format')
|
78
78
|
end
|
79
79
|
end
|
@@ -1,40 +1,53 @@
|
|
1
|
-
module ArelExtensions
|
2
|
-
|
3
|
-
|
4
|
-
RETURN_TYPE = :string
|
5
|
-
|
6
|
-
def initialize expr
|
7
|
-
tab = expr.map { |arg|
|
8
|
-
convert_to_node(arg)
|
9
|
-
}
|
10
|
-
return super(tab)
|
11
|
-
end
|
12
|
-
|
13
|
-
#def +(other)
|
14
|
-
# return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
15
|
-
#end
|
16
|
-
|
17
|
-
def concat(other)
|
18
|
-
return ArelExtensions::Nodes::Concat.new(self.expressions + [other])
|
19
|
-
end
|
1
|
+
module ArelExtensions::Nodes
|
2
|
+
class Concat < Function
|
3
|
+
RETURN_TYPE = :string
|
20
4
|
|
5
|
+
def initialize expr
|
6
|
+
tab = expr.map { |arg|
|
7
|
+
# flatten nested concats.
|
8
|
+
node = convert_to_node(arg)
|
9
|
+
if node.is_a?(Concat)
|
10
|
+
node.expressions
|
11
|
+
else
|
12
|
+
node
|
13
|
+
end
|
14
|
+
}.flatten.reduce([]) { | res, b |
|
15
|
+
# concatenate successive literal strings.
|
16
|
+
if b.is_a?(Arel::Nodes::Quoted) && b.expr == ""
|
17
|
+
res
|
18
|
+
elsif res.last && res.last.is_a?(Arel::Nodes::Quoted) && b.is_a?(Arel::Nodes::Quoted)
|
19
|
+
res[-1] = Arel::Nodes.build_quoted(res.last.expr + b.expr)
|
20
|
+
else
|
21
|
+
res << b
|
22
|
+
end
|
23
|
+
res
|
24
|
+
}
|
25
|
+
super(tab)
|
21
26
|
end
|
22
27
|
|
23
|
-
|
24
|
-
|
28
|
+
#def +(other)
|
29
|
+
# Concat.new(self.expressions + [other])
|
30
|
+
#end
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
+
def concat(other)
|
33
|
+
Concat.new(self.expressions + [other])
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
32
37
|
|
33
|
-
|
34
|
-
|
35
|
-
#end
|
38
|
+
class GroupConcat < Function
|
39
|
+
RETURN_TYPE = :string
|
36
40
|
|
41
|
+
def initialize expr
|
42
|
+
tab = expr.map { |arg|
|
43
|
+
convert_to_node(arg)
|
44
|
+
}
|
45
|
+
super(tab)
|
37
46
|
end
|
38
47
|
|
48
|
+
#def +(other)
|
49
|
+
# return Concat.new([self, other])
|
50
|
+
#end
|
51
|
+
|
39
52
|
end
|
40
53
|
end
|
@@ -4,7 +4,8 @@ module ArelExtensions
|
|
4
4
|
module Nodes
|
5
5
|
class Function < Arel::Nodes::Function
|
6
6
|
include Arel::Math
|
7
|
-
include Arel::Expressions
|
7
|
+
include Arel::Expressions
|
8
|
+
include Arel::OrderPredications
|
8
9
|
include ArelExtensions::Predications
|
9
10
|
|
10
11
|
RETURN_TYPE = :string # by default...
|
@@ -108,7 +108,12 @@ module ArelExtensions
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def concat other
|
111
|
-
ArelExtensions::Nodes::Concat.new [self, other]
|
111
|
+
res = ArelExtensions::Nodes::Concat.new [self, other]
|
112
|
+
if res.expressions.length == 1
|
113
|
+
res.expressions.first
|
114
|
+
else
|
115
|
+
res
|
116
|
+
end
|
112
117
|
end
|
113
118
|
|
114
119
|
def group_concat sep = nil
|
@@ -65,29 +65,6 @@ module ArelExtensions
|
|
65
65
|
collector
|
66
66
|
end
|
67
67
|
|
68
|
-
# Deprecated
|
69
|
-
def visit_ArelExtensions_Nodes_ConcatOld o, collector
|
70
|
-
arg = o.left.relation.engine.columns.find{|c| c.name == o.left.name.to_s}.type
|
71
|
-
if(o.right.is_a?(Arel::Attributes::Attribute))
|
72
|
-
collector = visit o.left, collector
|
73
|
-
collector << ' + '
|
74
|
-
collector = visit o.right, collector
|
75
|
-
collector
|
76
|
-
elsif ( arg == :date || arg == :datetime)
|
77
|
-
collector << "DATEADD(day"
|
78
|
-
collector << Arel::Visitors::MSSQL::COMMA
|
79
|
-
collector = visit o.right, collector
|
80
|
-
collector << Arel::Visitors::MSSQL::COMMA
|
81
|
-
collector = visit o.left, collector
|
82
|
-
collector
|
83
|
-
else
|
84
|
-
collector = visit o.left, collector
|
85
|
-
collector << " + '"
|
86
|
-
collector = visit o.right, collector
|
87
|
-
collector
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
68
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
92
69
|
collector << "CONCAT("
|
93
70
|
o.expressions.each_with_index { |arg, i|
|
@@ -394,21 +394,10 @@ module ArelExtensions
|
|
394
394
|
# add primary_key if not present, avoid zip
|
395
395
|
if Arel::VERSION.to_i < 7
|
396
396
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
397
|
-
|
398
|
-
table = collector.value.sub(/\AINSERT INTO/, '')
|
399
|
-
into = " INTO#{table}"
|
400
|
-
collector = Arel::Collectors::SQLString.new
|
401
|
-
collector << "INSERT ALL\n"
|
402
|
-
pk_name = @connection.primary_key(o.cols.first.relation.name)
|
403
|
-
if pk_name
|
404
|
-
pk_missing = !o.cols.detect{|c| c.name == pk_name }
|
405
|
-
into.sub!(/\(/, %Q[("#{pk_name.upcase}", ]) if pk_missing
|
406
|
-
else
|
407
|
-
pk_missing = false
|
408
|
-
end
|
397
|
+
collector << "("
|
409
398
|
o.left.each_with_index do |row, idx| # values
|
410
|
-
|
411
|
-
collector << "
|
399
|
+
collector << " UNION ALL " if idx != 0
|
400
|
+
collector << "(SELECT "
|
412
401
|
v = Arel::Nodes::Values.new(row, o.cols)
|
413
402
|
len = v.expressions.length - 1
|
414
403
|
v.expressions.each_with_index { |value, i|
|
@@ -421,19 +410,17 @@ module ArelExtensions
|
|
421
410
|
end
|
422
411
|
collector << Arel::Visitors::Oracle::COMMA unless i == len
|
423
412
|
}
|
424
|
-
collector << ')'
|
413
|
+
collector << ' FROM DUAL)'
|
425
414
|
end
|
426
|
-
collector <<
|
415
|
+
collector << ")"
|
427
416
|
collector
|
428
417
|
end
|
429
418
|
else
|
430
419
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
431
|
-
|
432
|
-
into = " INTO#{table}"
|
433
|
-
collector = Arel::Collectors::SQLString.new
|
434
|
-
collector << "INSERT ALL\n"
|
420
|
+
collector << "("
|
435
421
|
o.left.each_with_index do |row, idx|
|
436
|
-
|
422
|
+
collector << " UNION ALL " if idx != 0
|
423
|
+
collector << "(SELECT "
|
437
424
|
v = Arel::Nodes::Values.new(row, o.cols)
|
438
425
|
len = v.expressions.length - 1
|
439
426
|
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
@@ -445,9 +432,9 @@ module ArelExtensions
|
|
445
432
|
end
|
446
433
|
collector << Arel::Visitors::Oracle::COMMA unless i == len
|
447
434
|
}
|
448
|
-
collector << ')'
|
435
|
+
collector << ' FROM DUAL)'
|
449
436
|
end
|
450
|
-
collector <<
|
437
|
+
collector << ")"
|
451
438
|
collector
|
452
439
|
end
|
453
440
|
end
|
@@ -455,18 +442,17 @@ module ArelExtensions
|
|
455
442
|
|
456
443
|
def get_time_converted element
|
457
444
|
if element.is_a?(Time)
|
458
|
-
|
445
|
+
ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
|
459
446
|
elsif element.is_a?(Arel::Attributes::Attribute)
|
460
447
|
col = Arel::Table.engine.connection.schema_cache.columns_hash(element.relation.table_name)[element.name.to_s]
|
461
448
|
if col && (col.type == :time)
|
462
|
-
|
449
|
+
ArelExtensions::Nodes::Format.new [element, '%H:%M:%S']
|
463
450
|
else
|
464
|
-
|
451
|
+
element
|
465
452
|
end
|
466
453
|
else
|
467
|
-
|
454
|
+
element
|
468
455
|
end
|
469
|
-
return res
|
470
456
|
end
|
471
457
|
|
472
458
|
|
@@ -511,10 +497,30 @@ module ArelExtensions
|
|
511
497
|
end
|
512
498
|
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
513
499
|
end
|
500
|
+
|
501
|
+
alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
|
502
|
+
def visit_Arel_Nodes_TableAlias o, collector
|
503
|
+
if o.name.length > 30
|
504
|
+
o = Arel::Table.new(o.table_name).alias(Base64.urlsafe_encode64(Digest::MD5.new.digest(o.name)).tr('=', '').tr('-', '_'))
|
505
|
+
end
|
506
|
+
old_visit_Arel_Nodes_TableAlias(o,collector)
|
507
|
+
end
|
508
|
+
|
509
|
+
|
510
|
+
alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
|
511
|
+
def visit_Arel_Attributes_Attribute o, collector
|
512
|
+
join_name = o.relation.table_alias || o.relation.name
|
513
|
+
if join_name.length > 30
|
514
|
+
join_name = Arel.shorten(join_name)
|
515
|
+
end
|
516
|
+
collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
|
517
|
+
end
|
518
|
+
|
514
519
|
|
515
520
|
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
516
521
|
col = o.left
|
517
|
-
comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
|
522
|
+
comma = Arel::Visitors::Oracle::NUMBER_COMMA_MAPPING[o.locale] || '.,'
|
523
|
+
comma_in_format = o.precision == 0 ? '' : 'D'
|
518
524
|
options = Arel::Nodes.build_quoted("NLS_NUMERIC_CHARACTERS = '"+comma+"'")
|
519
525
|
nines_after = (1..o.precision).map{'9'}.join('')
|
520
526
|
nines_before = (1..16).map{'9'}.join('')
|
@@ -528,7 +534,7 @@ module ArelExtensions
|
|
528
534
|
if o.scientific_notation
|
529
535
|
number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
530
536
|
Arel::Nodes.build_quoted(col.abs),
|
531
|
-
Arel::Nodes.build_quoted('FM'+nines_before+
|
537
|
+
Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after+'EEEE'),
|
532
538
|
options
|
533
539
|
])
|
534
540
|
if o.type == 'e'
|
@@ -537,7 +543,7 @@ module ArelExtensions
|
|
537
543
|
else
|
538
544
|
number = Arel::Nodes::NamedFunction.new('TO_CHAR',[
|
539
545
|
Arel::Nodes.build_quoted(col.abs),
|
540
|
-
Arel::Nodes.build_quoted('FM'+nines_before+
|
546
|
+
Arel::Nodes.build_quoted('FM'+nines_before+comma_in_format+nines_after),
|
541
547
|
options
|
542
548
|
])
|
543
549
|
end
|
@@ -566,6 +572,8 @@ module ArelExtensions
|
|
566
572
|
end
|
567
573
|
|
568
574
|
|
575
|
+
|
576
|
+
|
569
577
|
end
|
570
578
|
end
|
571
579
|
end
|
@@ -279,9 +279,9 @@ module ArelExtensions
|
|
279
279
|
collector
|
280
280
|
end
|
281
281
|
|
282
|
-
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
282
|
+
def visit_ArelExtensions_Nodes_FormattedNumber o, collector
|
283
283
|
col = o.left
|
284
|
-
comma = Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] || '.'
|
284
|
+
comma = o.precision == 0 ? '' : (Arel::Visitors::PostgreSQL::NUMBER_COMMA_MAPPING[o.locale] || '.')
|
285
285
|
nines_after = (1..o.precision).map{'9'}.join('')
|
286
286
|
nines_before = (1..16).map{'9'}.join('')
|
287
287
|
sign = ArelExtensions::Nodes::Case.new.when(col<0).
|
@@ -327,8 +327,8 @@ module ArelExtensions
|
|
327
327
|
after
|
328
328
|
])
|
329
329
|
)
|
330
|
-
collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
|
331
|
-
collector
|
330
|
+
collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
|
331
|
+
collector
|
332
332
|
end
|
333
333
|
|
334
334
|
|
@@ -341,6 +341,24 @@ module ArelExtensions
|
|
341
341
|
old_visit_Arel_Nodes_SelectStatement(o,collector)
|
342
342
|
end
|
343
343
|
|
344
|
+
alias_method :old_visit_Arel_Nodes_TableAlias, :visit_Arel_Nodes_TableAlias
|
345
|
+
def visit_Arel_Nodes_TableAlias o, collector
|
346
|
+
if o.name.length > 63
|
347
|
+
o = Arel::Table.new(o.table_name).alias(Arel.shorten(o.name))
|
348
|
+
end
|
349
|
+
old_visit_Arel_Nodes_TableAlias(o,collector)
|
350
|
+
end
|
351
|
+
|
352
|
+
alias_method :old_visit_Arel_Attributes_Attribute, :visit_Arel_Attributes_Attribute
|
353
|
+
def visit_Arel_Attributes_Attribute o, collector
|
354
|
+
join_name = o.relation.table_alias || o.relation.name
|
355
|
+
if join_name.length > 63
|
356
|
+
join_name = Arel.shorten(join_name)
|
357
|
+
end
|
358
|
+
collector << "#{quote_table_name join_name}.#{quote_column_name o.name}"
|
359
|
+
end
|
360
|
+
|
361
|
+
|
344
362
|
end
|
345
363
|
end
|
346
364
|
end
|
@@ -7,10 +7,10 @@ module ArelExtensions
|
|
7
7
|
@conn = FakeRecord::Base.new
|
8
8
|
@visitor = Arel::Visitors::Oracle.new @conn.connection
|
9
9
|
@table = Arel::Table.new(:users)
|
10
|
-
@cols = ['
|
10
|
+
@cols = ['name', 'comments', 'created_at']
|
11
11
|
@data = [
|
12
|
-
[
|
13
|
-
[
|
12
|
+
['nom1', "sdfdsfdsfsdf", '2016-01-01'],
|
13
|
+
['nom2', "sdfdsfdsfsdf", '2016-01-01']
|
14
14
|
]
|
15
15
|
end
|
16
16
|
|
@@ -26,9 +26,9 @@ module ArelExtensions
|
|
26
26
|
insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
|
27
27
|
insert_manager.bulk_insert(@cols, @data)
|
28
28
|
sql = compile(insert_manager.ast)
|
29
|
-
sql.must_be_like %Q[INSERT
|
29
|
+
sql.must_be_like %Q[INSERT INTO "users" ("name", "comments", "created_at") ((SELECT 'nom1', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL) UNION ALL (SELECT 'nom2', 'sdfdsfdsfsdf', '2016-01-01' FROM DUAL))]
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
33
33
|
end
|
34
|
-
end
|
34
|
+
end
|
@@ -63,7 +63,6 @@ module ArelExtensions
|
|
63
63
|
it "should accept functions on strings" do
|
64
64
|
c = @table[:name]
|
65
65
|
compile(c + 'test').must_be_like %{CONCAT(\"users\".\"name\", 'test')}
|
66
|
-
compile(c + 'test' + ' chain').must_be_like %{CONCAT(CONCAT(\"users\".\"name\", 'test'), ' chain')}
|
67
66
|
compile(c.length).must_be_like %{LENGTH("users"."name")}
|
68
67
|
#puts (c.length.round + 42).inspect
|
69
68
|
compile(c.length.round + 42).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
|
@@ -82,6 +81,13 @@ module ArelExtensions
|
|
82
81
|
compile(c + '0').must_be_like %{CONCAT("users"."name", '0')}
|
83
82
|
compile(c.substring(1) + '0').must_be_like %{CONCAT(SUBSTRING("users"."name", 1), '0')}
|
84
83
|
compile(c.substring(1) + c.substring(2)).must_be_like %{CONCAT(SUBSTRING("users"."name", 1), SUBSTRING("users"."name", 2))}
|
84
|
+
compile(c.concat(c).concat(c)).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
|
85
|
+
compile(c + c + c).must_be_like %{CONCAT("users"."name", "users"."name", "users"."name")}
|
86
|
+
|
87
|
+
# some optimization on concat
|
88
|
+
compile(c + 'test' + ' chain').must_be_like %{CONCAT(\"users\".\"name\", 'test chain')}
|
89
|
+
compile(Arel::Nodes.build_quoted('test') + ' chain').must_be_like %{'test chain'}
|
90
|
+
compile(c + '' + c).must_be_like %{CONCAT(\"users\".\"name\", \"users\".\"name\")}
|
85
91
|
end
|
86
92
|
|
87
93
|
# Comparators
|
@@ -302,7 +308,7 @@ module ArelExtensions
|
|
302
308
|
.must_be_like %{(CAST("users"."id" AS int) + 2)}
|
303
309
|
end
|
304
310
|
|
305
|
-
it "should be possible to
|
311
|
+
it "should be possible to have nil element in the function NIL" do
|
306
312
|
compile(@table[:id].in(nil))
|
307
313
|
.must_be_like %{ISNULL("users"."id")}
|
308
314
|
compile(@table[:id].in([nil]))
|
@@ -319,6 +325,30 @@ module ArelExtensions
|
|
319
325
|
.must_be_like %{"users"."id" IN (1, 2)}
|
320
326
|
|
321
327
|
end
|
328
|
+
|
329
|
+
it "should be possible to add and substract as much as we want" do
|
330
|
+
c = @table[:name]
|
331
|
+
compile(c.locate('test')+1)
|
332
|
+
.must_be_like %{(LOCATE('test', "users"."name") + 1)}
|
333
|
+
compile(c.locate('test')-1)
|
334
|
+
.must_be_like %{(LOCATE('test', "users"."name") - 1)}
|
335
|
+
compile(c.locate('test')+c.locate('test'))
|
336
|
+
.must_be_like %{(LOCATE('test', "users"."name") + LOCATE('test', "users"."name"))}
|
337
|
+
compile(c.locate('test')+1+c.locate('test')-1 + 1)
|
338
|
+
.must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should be possible to desc and asc on functions" do
|
342
|
+
c = @table[:name]
|
343
|
+
compile(c.asc)
|
344
|
+
.must_be_like %{"users"."name" ASC}
|
345
|
+
compile(c.substring(2).asc)
|
346
|
+
.must_be_like %{SUBSTRING("users"."name", 2) ASC}
|
347
|
+
compile(c.substring(2).desc)
|
348
|
+
.must_be_like %{SUBSTRING("users"."name", 2) DESC}
|
349
|
+
compile((c.locate('test')+1).asc)
|
350
|
+
.must_be_like %{(LOCATE('test', "users"."name") + 1) ASC}
|
351
|
+
end
|
322
352
|
|
323
353
|
puts "AREL VERSION : " + Arel::VERSION.to_s
|
324
354
|
end
|
@@ -507,9 +507,12 @@ module ArelExtensions
|
|
507
507
|
def test_format_numbers
|
508
508
|
#score of Arthur = 65.62
|
509
509
|
skip " Works with SQLite if the version used knows printf" if @env_db = $sqlite
|
510
|
+
|
511
|
+
assert_equal "Wrong Format" , t(@arthur, @score.format_number("$ %...234.6F €","fr_FR"))
|
510
512
|
assert_equal "AZERTY65,62" , t(@arthur, @score.format_number("AZERTY%.2f","fr_FR"))
|
511
513
|
assert_equal "65,62AZERTY" , t(@arthur, @score.format_number("%.2fAZERTY","fr_FR"))
|
512
514
|
assert_equal "$ 65.62 €" , t(@arthur, @score.format_number("$ %.2f €","en_US"))
|
515
|
+
assert_equal "$ 66 €" , t(@arthur, @score.format_number("$ %.0f €","en_US"))
|
513
516
|
assert_equal "$ 0065,62 €" , t(@arthur, @score.format_number("$ %07.2f €","fr_FR"))
|
514
517
|
assert_equal "$ 65,62 €" , t(@arthur, @score.format_number("$ %-07.2f €","fr_FR"))
|
515
518
|
assert_equal "$ 65,62 €" , t(@arthur, @score.format_number("$ %-7.2f €","fr_FR"))
|
@@ -519,8 +522,7 @@ module ArelExtensions
|
|
519
522
|
assert_equal "$ +065,62 €" , t(@arthur, @score.format_number("$ %0+7.2f €","fr_FR"))
|
520
523
|
assert_includes ["$ 6,56e1 €","$ 6,56e+01 €"], t(@arthur, @score.format_number("$ %.2e €","fr_FR"))
|
521
524
|
assert_includes ["$ 6,56E1 €","$ 6,56E+01 €"], t(@arthur, @score.format_number("$ %.2E €","fr_FR"))
|
522
|
-
assert_includes ["$ 6,562E1 €","$ 6,562E+01 €"], t(@arthur, @score.format_number("$ %.3E €","fr_FR"))
|
523
|
-
assert_equal "Wrong Format" , t(@arthur, @score.format_number("$ %...234.6F €","fr_FR"))
|
525
|
+
assert_includes ["$ 6,562E1 €","$ 6,562E+01 €"], t(@arthur, @score.format_number("$ %.3E €","fr_FR"))
|
524
526
|
end
|
525
527
|
|
526
528
|
def test_accent_insensitive
|
@@ -563,6 +565,7 @@ module ArelExtensions
|
|
563
565
|
assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("arretez")).then("1").else("0"))
|
564
566
|
assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrete")).then("1").else("0"))
|
565
567
|
assert_equal "0", t(@arthur,ArelExtensions::Nodes::Case.new.when(@comments.smatches("Arrêté")).then("1").else("0"))
|
568
|
+
|
566
569
|
end
|
567
570
|
|
568
571
|
def test_subquery_with_order
|
@@ -633,6 +636,17 @@ module ArelExtensions
|
|
633
636
|
#assert_equal true , @test.where(@age.not_in([nil,1,2])).blank?
|
634
637
|
end
|
635
638
|
|
639
|
+
def test_alias_shortened
|
640
|
+
if ['postgresql','oracle'].include?(@env_db)
|
641
|
+
new_alias = Arel.shorten('azerty' * 15)
|
642
|
+
at = User.arel_table.alias('azerty' * 15)
|
643
|
+
assert_equal "\"user_tests\" \"#{new_alias}\"".downcase, User.arel_table.alias('azerty' * 15).to_sql.downcase
|
644
|
+
assert_equal '"user_tests" "u"'.downcase, User.arel_table.alias('u').to_sql.downcase
|
645
|
+
assert_equal %Q[SELECT "#{new_alias}"."id" FROM "user_tests" "#{new_alias}"].downcase,
|
646
|
+
User.select(at[:id]).from(at).to_sql.downcase
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
636
650
|
end
|
637
651
|
end
|
638
652
|
end
|
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.0
|
4
|
+
version: 1.1.0
|
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: 2018-
|
13
|
+
date: 2018-08-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: arel
|
@@ -208,26 +208,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
208
208
|
version: '0'
|
209
209
|
requirements: []
|
210
210
|
rubyforge_project:
|
211
|
-
rubygems_version: 2.
|
211
|
+
rubygems_version: 2.5.2.1
|
212
212
|
signing_key:
|
213
213
|
specification_version: 4
|
214
214
|
summary: Extending Arel
|
215
|
-
test_files:
|
216
|
-
- test/database.yml
|
217
|
-
- test/helper.rb
|
218
|
-
- test/real_db_test.rb
|
219
|
-
- test/support/alter_system_user_password.sql
|
220
|
-
- test/support/create_oracle_enhanced_users.sql
|
221
|
-
- test/support/fake_record.rb
|
222
|
-
- test/test_comparators.rb
|
223
|
-
- test/visitors/test_bulk_insert_oracle.rb
|
224
|
-
- test/visitors/test_bulk_insert_sqlite.rb
|
225
|
-
- test/visitors/test_bulk_insert_to_sql.rb
|
226
|
-
- test/visitors/test_oracle.rb
|
227
|
-
- test/visitors/test_to_sql.rb
|
228
|
-
- test/with_ar/all_agnostic_test.rb
|
229
|
-
- test/with_ar/insert_agnostic_test.rb
|
230
|
-
- test/with_ar/test_bulk_sqlite.rb
|
231
|
-
- test/with_ar/test_math_sqlite.rb
|
232
|
-
- test/with_ar/test_string_mysql.rb
|
233
|
-
- test/with_ar/test_string_sqlite.rb
|
215
|
+
test_files: []
|