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