arel_extensions 1.1.3 → 1.1.4
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/Gemfile +3 -3
- data/lib/arel_extensions/math.rb +2 -2
- data/lib/arel_extensions/nodes/case.rb +37 -3
- data/lib/arel_extensions/nodes/levenshtein_distance.rb +11 -0
- data/lib/arel_extensions/predications.rb +2 -2
- data/lib/arel_extensions/string_functions.rb +4 -0
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors.rb +1 -0
- data/lib/arel_extensions/visitors/mssql.rb +2 -3
- data/lib/arel_extensions/visitors/oracle.rb +3 -2
- data/lib/arel_extensions/visitors/oracle12.rb +68 -0
- data/lib/arel_extensions/visitors/to_sql.rb +12 -4
- data/test/visitors/test_to_sql.rb +8 -1
- data/test/with_ar/all_agnostic_test.rb +14 -3
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c605fff28ecad52dbb7519c17ea982844ecad5fc
|
4
|
+
data.tar.gz: ad640c79367460a9b06ce89bffd6ef587ec1f30d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f113a241aec0ab76d42be635e1db174f82c02e2f8bdb0f5320a02b92b84b9d237f8ac1c2da27411a8ced881bdd752cf61f7d60224eca2e62683befde0f90ec74
|
7
|
+
data.tar.gz: a60110f2acf2d1b46b2a576d2800fe1718b923c307e1691e960153c6cf72db8cce65e932fc5bac397af413b0dd1a8499a067522ad00080e76a34094837ec2a43
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -5,15 +5,15 @@ gemspec
|
|
5
5
|
group :development, :test do
|
6
6
|
gem "sqlite3", :platforms => [:mri, :mswin, :x64_mingw, :mingw]
|
7
7
|
gem "mysql2", '0.4.10', :platforms => [:mri, :mswin, :x64_mingw, :mingw]
|
8
|
-
gem "pg", :platforms => [:mri, :mingw, :x64_mingw, :mswin]
|
8
|
+
gem "pg", '< 1', :platforms => [:mri, :mingw, :x64_mingw, :mswin]
|
9
9
|
|
10
10
|
gem "jdbc-sqlite3", :platforms => :jruby
|
11
11
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
12
12
|
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
13
13
|
gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
|
14
14
|
|
15
|
-
gem "tiny_tds", '~> 1.3.0' ,:require => false, :platforms => [:mingw, :x64_mingw, :mswin]
|
16
|
-
gem "activerecord-sqlserver-adapter", '~> 4.2.0', :platforms => [:mingw, :x64_mingw, :mswin]
|
15
|
+
gem "tiny_tds", '~> 1.3.0' ,:require => false, :platforms => [:mri,:mingw, :x64_mingw, :mswin]
|
16
|
+
gem "activerecord-sqlserver-adapter", '~> 4.2.0', :platforms => [:mri, :mingw, :x64_mingw, :mswin]
|
17
17
|
|
18
18
|
gem 'ruby-oci8', :platforms => [:mri, :mswin, :x64_mingw, :mingw]
|
19
19
|
gem 'activerecord-oracle_enhanced-adapter', '~> 1.6.0'
|
data/lib/arel_extensions/math.rb
CHANGED
@@ -24,7 +24,7 @@ module ArelExtensions
|
|
24
24
|
else
|
25
25
|
return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
26
26
|
end
|
27
|
-
when ArelExtensions::Nodes::Function
|
27
|
+
when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
|
28
28
|
return case self.return_type
|
29
29
|
when :string, :text
|
30
30
|
self.concat(other)
|
@@ -72,7 +72,7 @@ module ArelExtensions
|
|
72
72
|
else
|
73
73
|
Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
|
74
74
|
end
|
75
|
-
when ArelExtensions::Nodes::Function
|
75
|
+
when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
|
76
76
|
case self.return_type
|
77
77
|
when :string, :text # ???
|
78
78
|
Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) # ??
|
@@ -4,6 +4,7 @@ module ArelExtensions
|
|
4
4
|
class Case < Arel::Nodes::Node
|
5
5
|
include Arel::Expressions
|
6
6
|
include Arel::OrderPredications
|
7
|
+
include ArelExtensions::Math
|
7
8
|
include ArelExtensions::Comparators
|
8
9
|
include ArelExtensions::Predications
|
9
10
|
include ArelExtensions::MathFunctions
|
@@ -17,19 +18,47 @@ module ArelExtensions
|
|
17
18
|
@conditions = []
|
18
19
|
@default = default
|
19
20
|
end
|
21
|
+
|
22
|
+
def return_type
|
23
|
+
obj = if @conditions.length > 0
|
24
|
+
@conditions.last.right
|
25
|
+
elsif @default
|
26
|
+
@default.expr
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
if obj.respond_to?(:return_type)
|
31
|
+
obj.return_type
|
32
|
+
else
|
33
|
+
case obj
|
34
|
+
when Integer, Float
|
35
|
+
:number
|
36
|
+
when Date, DateTime,Time
|
37
|
+
:datetime
|
38
|
+
when Arel::Attributes::Attribute
|
39
|
+
begin
|
40
|
+
Arel::Table.engine.connection.schema_cache.columns_hash(obj.relation.table_name)[obj.name.to_s].cast_type.type
|
41
|
+
rescue Exception
|
42
|
+
:string
|
43
|
+
end
|
44
|
+
else
|
45
|
+
:string
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
20
49
|
|
21
50
|
def when condition, expression = nil
|
22
|
-
@conditions << When.new(
|
51
|
+
@conditions << When.new(condition, expression)
|
23
52
|
self
|
24
53
|
end
|
25
54
|
|
26
55
|
def then expression
|
27
|
-
@conditions.last.right =
|
56
|
+
@conditions.last.right = expression
|
28
57
|
self
|
29
58
|
end
|
30
59
|
|
31
60
|
def else expression
|
32
|
-
@default = Else.new
|
61
|
+
@default = Else.new expression
|
33
62
|
self
|
34
63
|
end
|
35
64
|
|
@@ -67,8 +96,13 @@ module ArelExtensions
|
|
67
96
|
|
68
97
|
class Case < Arel::Nodes::Case
|
69
98
|
include Arel::Expressions
|
99
|
+
include Arel::OrderPredications
|
100
|
+
include ArelExtensions::Math
|
70
101
|
include ArelExtensions::Comparators
|
71
102
|
include ArelExtensions::Predications
|
103
|
+
include ArelExtensions::MathFunctions
|
104
|
+
include ArelExtensions::StringFunctions
|
105
|
+
include ArelExtensions::NullFunctions
|
72
106
|
|
73
107
|
end
|
74
108
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'arel_extensions/visitors/to_sql'
|
2
2
|
require 'arel_extensions/visitors/mysql'
|
3
3
|
require 'arel_extensions/visitors/oracle'
|
4
|
+
require 'arel_extensions/visitors/oracle12'
|
4
5
|
require 'arel_extensions/visitors/postgresql'
|
5
6
|
require 'arel_extensions/visitors/sqlite'
|
6
7
|
require 'arel_extensions/visitors/mssql'
|
@@ -461,15 +461,14 @@ module ArelExtensions
|
|
461
461
|
before = (!o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
462
462
|
middle = (o.flags.include?('0'))&&(!o.flags.include?('-')) ? repeated_char : ''
|
463
463
|
after = o.flags.include?('-') ? repeated_char : ''
|
464
|
-
full_number =
|
464
|
+
full_number =
|
465
465
|
ArelExtensions::Nodes::Concat.new([
|
466
466
|
before,
|
467
467
|
sign,
|
468
468
|
middle,
|
469
469
|
number,
|
470
470
|
after
|
471
|
-
])
|
472
|
-
)
|
471
|
+
])
|
473
472
|
collector = visit ArelExtensions::Nodes::Concat.new([Arel::Nodes.build_quoted(o.prefix),full_number,Arel::Nodes.build_quoted(o.suffix)]), collector
|
474
473
|
collector
|
475
474
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
#require 'oracle_visitor'
|
1
2
|
module ArelExtensions
|
2
3
|
module Visitors
|
3
|
-
Arel::Visitors::Oracle.class_eval do
|
4
|
+
Arel::Visitors::Oracle.class_eval do
|
5
|
+
|
4
6
|
SPECIAL_CHARS = {"\t" => 'CHR(9)', "\n" => 'CHR(10)', "\r" => 'CHR(13)'}
|
5
7
|
Arel::Visitors::Oracle::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
6
8
|
Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES = {
|
@@ -589,7 +591,6 @@ module ArelExtensions
|
|
589
591
|
end
|
590
592
|
|
591
593
|
|
592
|
-
|
593
594
|
end
|
594
595
|
end
|
595
596
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module ArelExtensions
|
2
|
+
module Visitors
|
3
|
+
if Arel::VERSION.to_i < 7
|
4
|
+
class Arel::Visitors::Oracle12 < Arel::Visitors::Oracle
|
5
|
+
|
6
|
+
|
7
|
+
def visit_Arel_Nodes_SelectStatement(o, collector)
|
8
|
+
# Oracle does not allow LIMIT clause with select for update
|
9
|
+
if o.limit && o.lock
|
10
|
+
raise ArgumentError, <<-MSG
|
11
|
+
'Combination of limit and lock is not supported.
|
12
|
+
because generated SQL statements
|
13
|
+
`SELECT FOR UPDATE and FETCH FIRST n ROWS` generates ORA-02014.`
|
14
|
+
MSG
|
15
|
+
end
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def visit_Arel_Nodes_SelectOptions(o, collector)
|
20
|
+
collector = maybe_visit o.offset, collector
|
21
|
+
collector = maybe_visit o.limit, collector
|
22
|
+
maybe_visit o.lock, collector
|
23
|
+
end
|
24
|
+
|
25
|
+
def visit_Arel_Nodes_Limit(o, collector)
|
26
|
+
collector << "FETCH FIRST "
|
27
|
+
collector = visit o.expr, collector
|
28
|
+
collector << " ROWS ONLY"
|
29
|
+
end
|
30
|
+
|
31
|
+
def visit_Arel_Nodes_Offset(o, collector)
|
32
|
+
collector << "OFFSET "
|
33
|
+
visit o.expr, collector
|
34
|
+
collector << " ROWS"
|
35
|
+
end
|
36
|
+
|
37
|
+
def visit_Arel_Nodes_Except(o, collector)
|
38
|
+
collector << "( "
|
39
|
+
collector = infix_value o, collector, " MINUS "
|
40
|
+
collector << " )"
|
41
|
+
end
|
42
|
+
|
43
|
+
def visit_Arel_Nodes_UpdateStatement(o, collector)
|
44
|
+
# Oracle does not allow ORDER BY/LIMIT in UPDATEs.
|
45
|
+
if o.orders.any? && o.limit.nil?
|
46
|
+
# However, there is no harm in silently eating the ORDER BY clause if no LIMIT has been provided,
|
47
|
+
# otherwise let the user deal with the error
|
48
|
+
o = o.dup
|
49
|
+
o.orders = []
|
50
|
+
end
|
51
|
+
|
52
|
+
super
|
53
|
+
end
|
54
|
+
|
55
|
+
def visit_Arel_Nodes_BindParam(o, collector)
|
56
|
+
collector.add_bind(o.value) { |i| ":a#{i}" }
|
57
|
+
end
|
58
|
+
|
59
|
+
def is_distinct_from(o, collector)
|
60
|
+
collector << "DECODE("
|
61
|
+
collector = visit [o.left, o.right, 0, 1], collector
|
62
|
+
collector << ")"
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -481,20 +481,20 @@ module ArelExtensions
|
|
481
481
|
if o.default
|
482
482
|
visit o.default, collector
|
483
483
|
collector << " "
|
484
|
-
end
|
484
|
+
end
|
485
485
|
collector << "END"
|
486
486
|
end
|
487
487
|
|
488
488
|
def visit_ArelExtensions_Nodes_When o, collector
|
489
489
|
collector << "WHEN "
|
490
|
-
visit o.left, collector
|
490
|
+
visit Arel::Nodes.build_quoted(o.left), collector
|
491
491
|
collector << " THEN "
|
492
|
-
visit o.right, collector
|
492
|
+
visit Arel::Nodes.build_quoted(o.right), collector
|
493
493
|
end
|
494
494
|
|
495
495
|
def visit_ArelExtensions_Nodes_Else o, collector
|
496
496
|
collector << "ELSE "
|
497
|
-
visit o.expr, collector
|
497
|
+
visit Arel::Nodes.build_quoted(o.expr), collector
|
498
498
|
end
|
499
499
|
|
500
500
|
|
@@ -524,6 +524,14 @@ module ArelExtensions
|
|
524
524
|
collector
|
525
525
|
end
|
526
526
|
|
527
|
+
def visit_ArelExtensions_Nodes_LevenshteinDistance o, collector
|
528
|
+
collector << "LEVENSHTEIN_DISTANCE("
|
529
|
+
collector = visit o.left, collector
|
530
|
+
collector << Arel::Visitors::ToSql::COMMA
|
531
|
+
collector = visit o.right, collector
|
532
|
+
collector << ')'
|
533
|
+
collector
|
534
|
+
end
|
527
535
|
|
528
536
|
end
|
529
537
|
end
|
@@ -69,7 +69,7 @@ module ArelExtensions
|
|
69
69
|
fake_table = Arel::Table.new('fake_tables')
|
70
70
|
|
71
71
|
compile(fake_table[:fake_att] - 42).must_be_like %{("fake_tables"."fake_att" - 42)}
|
72
|
-
compile(fake_table[:fake_att].coalesce(0) - 42).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
|
72
|
+
compile(fake_table[:fake_att].coalesce(0) - 42).must_be_like %{(COALESCE("fake_tables"."fake_att", 0) - 42)}
|
73
73
|
end
|
74
74
|
|
75
75
|
# String Functions
|
@@ -351,6 +351,13 @@ module ArelExtensions
|
|
351
351
|
.must_be_like %{((((LOCATE('test', "users"."name") + 1) + LOCATE('test', "users"."name")) - 1) + 1)}
|
352
352
|
end
|
353
353
|
|
354
|
+
it "should be possible to add and substract on some nodes" do
|
355
|
+
c = @table[:name]
|
356
|
+
compile(c.when(0,0).else(42) + 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END + 42)}
|
357
|
+
compile(c.when(0,0).else(42) - 42).must_be_like %{(CASE "users"."name" WHEN 0 THEN 0 ELSE 42 END - 42)}
|
358
|
+
compile(c.when(0,"0").else("42") + "42").must_be_like %{CONCAT(CASE "users"."name" WHEN 0 THEN '0' ELSE '42' END, '42')}
|
359
|
+
end
|
360
|
+
|
354
361
|
it "should be possible to desc and asc on functions" do
|
355
362
|
c = @table[:name]
|
356
363
|
compile(c.asc)
|
@@ -501,7 +501,12 @@ module ArelExtensions
|
|
501
501
|
|
502
502
|
# Case clause
|
503
503
|
def test_case
|
504
|
-
assert_equal 4, User.find_by_sql(@ut.project(@score.when(20.16).then(1).else(0).as('score_bin')).to_sql).sum(&:score_bin)
|
504
|
+
assert_equal 4, User.find_by_sql(@ut.project(@score.when(20.16).then(1).else(0).as('score_bin')).to_sql).sum(&:score_bin)
|
505
|
+
assert_equal 2, t(@arthur, @score.when(65.62,1).else(0)+1)
|
506
|
+
assert_equal 0, t(@arthur, @score.when(65.62,1).else(0)-1)
|
507
|
+
assert_equal "11", t(@arthur, @score.when(65.62).then("1").else("0")+"1")
|
508
|
+
assert_equal 66.62, t(@arthur, @score.when(65.62,@score).else(@score)+1)
|
509
|
+
assert_equal "65.621", t(@arthur, @score.when(65.62,@score.cast(:string)).else(@score.cast(:string))+1).tr('0','') #tr is here because of precision on cast for some DBMS
|
505
510
|
end
|
506
511
|
|
507
512
|
def test_format_numbers
|
@@ -523,8 +528,8 @@ module ArelExtensions
|
|
523
528
|
assert_includes ["$ 6,56e1 €","$ 6,56e+01 €"], t(@arthur, @score.format_number("$ %.2e €","fr_FR"))
|
524
529
|
assert_includes ["$ 6,56E1 €","$ 6,56E+01 €"], t(@arthur, @score.format_number("$ %.2E €","fr_FR"))
|
525
530
|
assert_includes ["$ 6,562E1 €","$ 6,562E+01 €"], t(@arthur, @score.format_number("$ %.3E €","fr_FR"))
|
526
|
-
assert_equal "123 456 765,6" , t(@arthur, (@score+123456700).format_number("%.1f","sv_SE"))
|
527
|
-
assert_equal "123456765,6" , t(@arthur, (@score+123456700).format_number("%.1f","fr_FR"))
|
531
|
+
assert_equal "123 456 765,6" , t(@arthur, (@score+123456700).format_number("%.1f","sv_SE")).gsub("\u00A0"," ") #some DBMS put no-break space here (it makes sense thus)
|
532
|
+
assert_equal "123456765,6" , t(@arthur, (@score+123456700).format_number("%.1f","fr_FR")).gsub("\u00A0","") #because SqlServer does it like no one else
|
528
533
|
assert_equal "123,456,765.6" , t(@arthur, (@score+123456700).format_number("%.1f","en_US"))
|
529
534
|
assert_equal " 123,456,765.6" , t(@arthur, (@score+123456700).format_number("%16.1f","en_US"))
|
530
535
|
assert_equal "$ 0,00 €" , t(@arthur, @score.when(65.62).then(Arel.sql("null")).else(1).format_number("$ %.2f €","fr_FR"))
|
@@ -666,7 +671,13 @@ module ArelExtensions
|
|
666
671
|
assert ( 537.0355 - t(User.where(nil), @score.variance(false))).abs < 0.01
|
667
672
|
assert ( 24.77408 - t(User.where(nil), @score.std)).abs < 0.01
|
668
673
|
assert ( 23.17403 - t(User.where(nil), @score.std(false))).abs < 0.01
|
674
|
+
|
669
675
|
end
|
676
|
+
|
677
|
+
#def test_levenshtein_distance
|
678
|
+
#assert 2, t(@arthur,@name.levenshtein_distance("Artour"))
|
679
|
+
#end
|
680
|
+
|
670
681
|
end
|
671
682
|
end
|
672
683
|
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.1.
|
4
|
+
version: 1.1.4
|
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-01-
|
13
|
+
date: 2019-01-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: arel
|
@@ -138,6 +138,7 @@ files:
|
|
138
138
|
- lib/arel_extensions/nodes/function.rb
|
139
139
|
- lib/arel_extensions/nodes/is_null.rb
|
140
140
|
- lib/arel_extensions/nodes/length.rb
|
141
|
+
- lib/arel_extensions/nodes/levenshtein_distance.rb
|
141
142
|
- lib/arel_extensions/nodes/locate.rb
|
142
143
|
- lib/arel_extensions/nodes/log10.rb
|
143
144
|
- lib/arel_extensions/nodes/matches.rb
|
@@ -166,6 +167,7 @@ files:
|
|
166
167
|
- lib/arel_extensions/visitors/mssql.rb
|
167
168
|
- lib/arel_extensions/visitors/mysql.rb
|
168
169
|
- lib/arel_extensions/visitors/oracle.rb
|
170
|
+
- lib/arel_extensions/visitors/oracle12.rb
|
169
171
|
- lib/arel_extensions/visitors/postgresql.rb
|
170
172
|
- lib/arel_extensions/visitors/sqlite.rb
|
171
173
|
- lib/arel_extensions/visitors/to_sql.rb
|
@@ -209,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
211
|
version: '0'
|
210
212
|
requirements: []
|
211
213
|
rubyforge_project:
|
212
|
-
rubygems_version: 2.5.2.
|
214
|
+
rubygems_version: 2.5.2.3
|
213
215
|
signing_key:
|
214
216
|
specification_version: 4
|
215
217
|
summary: Extending Arel
|