arel_extensions 1.0.1 → 1.0.2
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 +43 -34
- data/Gemfile +1 -1
- data/README.md +10 -0
- data/gemfiles/rails4.gemfile +2 -2
- data/gemfiles/rails5_0.gemfile +1 -1
- data/gemfiles/{rails5.gemfile → rails5_1_4.gemfile} +5 -4
- data/gemfiles/rails5_2_beta.gemfile +30 -0
- data/lib/arel_extensions.rb +13 -0
- data/lib/arel_extensions/attributes.rb +2 -0
- data/lib/arel_extensions/nodes.rb +1 -0
- data/lib/arel_extensions/nodes/as.rb +1 -1
- data/lib/arel_extensions/nodes/case.rb +69 -0
- data/lib/arel_extensions/nodes/date_diff.rb +2 -4
- data/lib/arel_extensions/nodes/function.rb +1 -1
- data/lib/arel_extensions/nodes/soundex.rb +1 -1
- data/lib/arel_extensions/predications.rb +9 -0
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +1 -1
- data/lib/arel_extensions/visitors/mysql.rb +1 -1
- data/lib/arel_extensions/visitors/oracle.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +11 -1
- data/lib/arel_extensions/visitors/sqlite.rb +10 -0
- data/lib/arel_extensions/visitors/to_sql.rb +33 -5
- data/test/visitors/test_to_sql.rb +39 -2
- data/test/with_ar/all_agnostic_test.rb +32 -9
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b227ca895990c123d78d688d01f00a27a563b70
|
|
4
|
+
data.tar.gz: 21bc450f1776d263294b6d56523adb59843825bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42e41791d3c25cb5c3a5900b992ee7e22e813bdb278406b3dc3eeaa02ec2477d76696c4abb50a93956f1b9bf55be5ef8234e96720bbcfc47de53afb8b5fb3ab3
|
|
7
|
+
data.tar.gz: 07fd67e1b8fe666bdff49c2baeae98d828cacfc0ae6a6b049e98850df6db4c0b24c370350feb973fb0b9f04e633955fb4375f33e020910a0b896f9629bfde300
|
data/.travis.yml
CHANGED
|
@@ -3,24 +3,25 @@ sudo: required
|
|
|
3
3
|
cache:
|
|
4
4
|
bundler: true
|
|
5
5
|
directories:
|
|
6
|
-
- $
|
|
6
|
+
- $ORACLE_HOME
|
|
7
7
|
before_install:
|
|
8
|
-
- chmod +x .travis/sqlite3/extension-functions.sh
|
|
9
|
-
- chmod +x .travis/oracle/download.sh
|
|
10
|
-
- chmod +x .travis/oracle/install.sh
|
|
11
|
-
- chmod +x .travis/setup_accounts.sh
|
|
8
|
+
- chmod +x .travis/sqlite3/extension-functions.sh
|
|
9
|
+
- chmod +x .travis/oracle/download.sh
|
|
10
|
+
- chmod +x .travis/oracle/install.sh
|
|
11
|
+
- chmod +x .travis/setup_accounts.sh
|
|
12
|
+
- sudo apt-get install -y sqlite3-pcre curl
|
|
13
|
+
- .travis/sqlite3/extension-functions.sh
|
|
14
|
+
- .travis/oracle/download.sh
|
|
15
|
+
- .travis/oracle/install.sh
|
|
16
|
+
- .travis/setup_accounts.sh
|
|
12
17
|
install:
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- .travis/oracle/download.sh
|
|
16
|
-
- .travis/oracle/install.sh
|
|
17
|
-
- .travis/setup_accounts.sh
|
|
18
|
-
- gem install bundler
|
|
19
|
-
- bundle install
|
|
18
|
+
- gem install bundler
|
|
19
|
+
- bundle install
|
|
20
20
|
gemfile:
|
|
21
21
|
- gemfiles/rails4.gemfile
|
|
22
22
|
- gemfiles/rails5_0.gemfile
|
|
23
|
-
- gemfiles/
|
|
23
|
+
- gemfiles/rails5_1_4.gemfile
|
|
24
|
+
- gemfiles/rails5_2_beta.gemfile
|
|
24
25
|
services:
|
|
25
26
|
- mysql
|
|
26
27
|
- postgresql
|
|
@@ -78,8 +79,6 @@ matrix:
|
|
|
78
79
|
jdk: openjdk7
|
|
79
80
|
- rvm: ruby-head
|
|
80
81
|
jdk: openjdk7
|
|
81
|
-
- rvm: jruby-head
|
|
82
|
-
jdk: openjdk7
|
|
83
82
|
- rvm: rbx-2
|
|
84
83
|
jdk: oraclejdk8
|
|
85
84
|
- rvm: 2.0.0
|
|
@@ -93,39 +92,49 @@ matrix:
|
|
|
93
92
|
- rvm: 2.4.0
|
|
94
93
|
jdk: oraclejdk8
|
|
95
94
|
- rvm: ruby-head
|
|
96
|
-
jdk: oraclejdk8
|
|
95
|
+
jdk: oraclejdk8
|
|
96
|
+
- rvm: jruby-head
|
|
97
|
+
jdk: openjdk7
|
|
97
98
|
- rvm: 2.0.0
|
|
98
|
-
gemfile: gemfiles/
|
|
99
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
|
99
100
|
- rvm: 2.1
|
|
100
|
-
gemfile: gemfiles/
|
|
101
|
-
- rvm: rbx-2
|
|
102
|
-
gemfile: gemfiles/rails5.gemfile
|
|
101
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
|
103
102
|
- rvm: ruby-head
|
|
104
103
|
gemfile: gemfiles/rails4.gemfile
|
|
105
104
|
- rvm: 2.0.0
|
|
106
105
|
gemfile: gemfiles/rails5_0.gemfile
|
|
107
106
|
- rvm: 2.1
|
|
108
|
-
gemfile: gemfiles/rails5_0.gemfile
|
|
109
|
-
- rvm:
|
|
110
|
-
gemfile: gemfiles/
|
|
107
|
+
gemfile: gemfiles/rails5_0.gemfile
|
|
108
|
+
- rvm: jruby-9.0.5.0
|
|
109
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
|
110
|
+
- rvm: 2.0.0
|
|
111
|
+
gemfile: gemfiles/rails5_2_beta.gemfile
|
|
112
|
+
- rvm: 2.1
|
|
113
|
+
gemfile: gemfiles/rails5_2_beta.gemfile
|
|
114
|
+
- rvm: jruby-9.0.5.0
|
|
115
|
+
gemfile: gemfiles/rails5_2_beta.gemfile
|
|
116
|
+
- rvm: jruby-head
|
|
117
|
+
gemfile: gemfiles/rails5_2_beta.gemfile
|
|
111
118
|
allow_failures:
|
|
112
119
|
- rvm: rbx-2
|
|
113
|
-
gemfile: gemfiles/rails4.gemfile
|
|
120
|
+
gemfile: gemfiles/rails4.gemfile
|
|
114
121
|
- rvm: rbx-2
|
|
115
|
-
gemfile: gemfiles/rails5_0.gemfile
|
|
116
|
-
- rvm: jruby-9.0.5.0
|
|
117
|
-
gemfile: gemfiles/rails5_0.gemfile
|
|
118
|
-
- rvm: jruby-head
|
|
119
|
-
gemfile: gemfiles/rails5_0.gemfile
|
|
122
|
+
gemfile: gemfiles/rails5_0.gemfile
|
|
120
123
|
- rvm: rbx-2
|
|
121
|
-
gemfile: gemfiles/
|
|
122
|
-
- rvm:
|
|
123
|
-
gemfile: gemfiles/
|
|
124
|
-
- rvm: jruby-head
|
|
125
|
-
gemfile: gemfiles/rails5.gemfile
|
|
124
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
|
125
|
+
- rvm: rbx-2
|
|
126
|
+
gemfile: gemfiles/rails5_2_beta.gemfile
|
|
126
127
|
- rvm: jruby-head
|
|
127
128
|
gemfile: gemfiles/rails4.gemfile
|
|
128
129
|
jdk: oraclejdk9
|
|
130
|
+
- rvm: jruby-head
|
|
131
|
+
gemfile: gemfiles/rails5_0.gemfile
|
|
132
|
+
jdk: oraclejdk9
|
|
133
|
+
- rvm: rbx-2
|
|
134
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
|
135
|
+
- rvm: jruby-head
|
|
136
|
+
gemfile: gemfiles/rails5_1_4.gemfile
|
|
137
|
+
jdk: oraclejdk9
|
|
129
138
|
bundler_args: "--jobs 3 --retry 2"
|
|
130
139
|
notifications:
|
|
131
140
|
email:
|
data/Gemfile
CHANGED
|
@@ -5,7 +5,7 @@ gemspec
|
|
|
5
5
|
group :development, :test do
|
|
6
6
|
gem "sqlite3", :platforms => [:mri, :mswin, :x64_mingw, :mingw]
|
|
7
7
|
gem "mysql2", :platforms => [:mri, :mswin, :x64_mingw, :mingw]
|
|
8
|
-
gem "pg", :platforms => [:mri, :mingw, :x64_mingw, :mswin]
|
|
8
|
+
gem "pg", '< 1.0.0', :platforms => [:mri, :mingw, :x64_mingw, :mswin]
|
|
9
9
|
|
|
10
10
|
gem "jdbc-sqlite3", :platforms => :jruby
|
|
11
11
|
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
data/README.md
CHANGED
|
@@ -133,6 +133,16 @@ t[:birthdate].format('%Y-%m-%d').to_sql
|
|
|
133
133
|
# => (SELECT * FROM my_table WHERE name='str') UNION (SELECT * FROM my_table WHERE name='test')
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
+
## Case clause
|
|
137
|
+
|
|
138
|
+
Arel-extensions allows to use functions on case clause
|
|
139
|
+
|
|
140
|
+
```ruby
|
|
141
|
+
(t[:name].when("smith").then(1).when("doe").then(2).else(0).sum.to_sql
|
|
142
|
+
# => SUM(CASE "my_table"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
|
|
136
146
|
## Stored Procedures and User-defined functions
|
|
137
147
|
|
|
138
148
|
To optimize queries, some classical functions are defined in databases missing any alternative native functions.
|
data/gemfiles/rails4.gemfile
CHANGED
|
@@ -9,7 +9,7 @@ group :development, :test do
|
|
|
9
9
|
|
|
10
10
|
gem "sqlite3", :platforms => [:mri, :mswin, :mingw]
|
|
11
11
|
gem "mysql2", :platforms => [:mri, :mswin, :mingw]
|
|
12
|
-
gem "pg", :platforms => [:mri, :mingw]
|
|
12
|
+
gem "pg",'< 1.0.0', :platforms => [:mri, :mingw]
|
|
13
13
|
|
|
14
14
|
gem "tiny_tds", :platforms => [:mri, :mingw, :mswin] if RUBY_PLATFORM =~ /windows/
|
|
15
15
|
gem "activerecord-sqlserver-adapter", '~> 4.2.0', :platforms => [:mri, :mingw, :mswin] if RUBY_PLATFORM =~ /windows/
|
|
@@ -26,4 +26,4 @@ group :development, :test do
|
|
|
26
26
|
gem "activerecord-jdbcmssql-adapter", :platforms => :jruby
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
gemspec :path => "../"
|
|
29
|
+
gemspec :path => "../"
|
data/gemfiles/rails5_0.gemfile
CHANGED
|
@@ -9,7 +9,7 @@ group :development, :test do
|
|
|
9
9
|
|
|
10
10
|
gem "sqlite3", :platforms => [:mri, :mswin, :mingw]
|
|
11
11
|
gem "mysql2", :platforms => [:mri, :mswin, :mingw]
|
|
12
|
-
gem "pg", :platforms => [:mri, :mingw]
|
|
12
|
+
gem "pg",'< 1.0.0', :platforms => [:mri, :mingw]
|
|
13
13
|
|
|
14
14
|
gem "tiny_tds", :platforms => [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
|
|
15
15
|
# gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
source "https://rubygems.org"
|
|
2
2
|
|
|
3
|
+
gem 'rails', '~> 5.1.4'
|
|
3
4
|
gem 'arel', '~> 8'
|
|
4
5
|
|
|
5
6
|
group :development, :test do
|
|
6
|
-
gem 'activesupport', '~> 5'
|
|
7
|
-
gem 'activemodel', '~> 5'
|
|
8
|
-
gem 'activerecord', '~> 5'
|
|
7
|
+
gem 'activesupport', '~> 5.1.4'
|
|
8
|
+
gem 'activemodel', '~> 5.1.4'
|
|
9
|
+
gem 'activerecord', '~> 5.1.4'
|
|
9
10
|
|
|
10
11
|
gem "sqlite3", :platforms => [:mri, :mswin, :mingw]
|
|
11
12
|
gem "mysql2", :platforms => [:mri, :mswin, :mingw]
|
|
12
|
-
gem "pg", :platforms => [:mri, :mingw]
|
|
13
|
+
gem "pg",'< 1.0.0', :platforms => [:mri, :mingw]
|
|
13
14
|
|
|
14
15
|
gem "tiny_tds", :platforms => [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
|
|
15
16
|
# gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
source "https://rubygems.org"
|
|
2
|
+
|
|
3
|
+
gem 'rails', '~> 5.2.0.beta2'
|
|
4
|
+
gem 'arel', '~> 9'
|
|
5
|
+
|
|
6
|
+
group :development, :test do
|
|
7
|
+
gem 'activesupport', '~> 5.2.0.beta2'
|
|
8
|
+
gem 'activemodel', '~> 5.2.0.beta2'
|
|
9
|
+
gem 'activerecord', '~> 5.2.0.beta2'
|
|
10
|
+
|
|
11
|
+
gem "sqlite3", :platforms => [:mri, :mswin, :mingw]
|
|
12
|
+
gem "mysql2", :platforms => [:mri, :mswin, :mingw]
|
|
13
|
+
gem "pg",'< 1.0.0', :platforms => [:mri, :mingw]
|
|
14
|
+
|
|
15
|
+
gem "tiny_tds", :platforms => [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
|
|
16
|
+
# gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
|
17
|
+
|
|
18
|
+
gem 'ruby-oci8', :platforms => [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
|
|
19
|
+
gem 'activerecord-oracle_enhanced-adapter', '~> 5.2.0.beta1' if ENV.has_key? 'ORACLE_HOME'
|
|
20
|
+
|
|
21
|
+
# for JRuby
|
|
22
|
+
gem 'activerecord-jdbc-adapter', :github => 'jruby/activerecord-jdbc-adapter', :tag => 'v51.0', :platforms => :jruby
|
|
23
|
+
gem "jdbc-sqlite3", :platforms => :jruby
|
|
24
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
|
25
|
+
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
|
26
|
+
gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
|
|
27
|
+
gem "activerecord-jdbcmssql-adapter", :platforms => :jruby
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
gemspec :path => "../"
|
data/lib/arel_extensions.rb
CHANGED
|
@@ -9,6 +9,7 @@ require 'arel_extensions/railtie' if defined?(Rails::Railtie)
|
|
|
9
9
|
# pure Arel internals improvements
|
|
10
10
|
Arel::Nodes::Binary.class_eval do
|
|
11
11
|
include Arel::AliasPredication
|
|
12
|
+
include Arel::Expressions
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
Arel::Nodes::Unary.class_eval do
|
|
@@ -28,6 +29,13 @@ Arel::Nodes::Function.class_eval do
|
|
|
28
29
|
include Arel::Expressions
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
if Arel::VERSION.to_i >= 7
|
|
33
|
+
Arel::Nodes::Case.class_eval do
|
|
34
|
+
include Arel::Math
|
|
35
|
+
include Arel::Expressions
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
31
39
|
require 'arel_extensions/version'
|
|
32
40
|
require 'arel_extensions/attributes'
|
|
33
41
|
require 'arel_extensions/visitors'
|
|
@@ -48,6 +56,8 @@ require 'arel_extensions/common_sql_functions'
|
|
|
48
56
|
require 'arel_extensions/nodes/union'
|
|
49
57
|
require 'arel_extensions/nodes/union_all'
|
|
50
58
|
require 'arel_extensions/nodes/as'
|
|
59
|
+
require 'arel_extensions/nodes/case'
|
|
60
|
+
require 'arel_extensions/predications'
|
|
51
61
|
|
|
52
62
|
|
|
53
63
|
|
|
@@ -69,6 +79,7 @@ Arel::Nodes::Function.class_eval do
|
|
|
69
79
|
include ArelExtensions::StringFunctions
|
|
70
80
|
include ArelExtensions::BooleanFunctions
|
|
71
81
|
include ArelExtensions::NullFunctions
|
|
82
|
+
include ArelExtensions::Predications
|
|
72
83
|
end
|
|
73
84
|
|
|
74
85
|
Arel::Nodes::Unary.class_eval do
|
|
@@ -76,6 +87,7 @@ Arel::Nodes::Unary.class_eval do
|
|
|
76
87
|
include ArelExtensions::Attributes
|
|
77
88
|
include ArelExtensions::MathFunctions
|
|
78
89
|
include ArelExtensions::Comparators
|
|
90
|
+
include ArelExtensions::Predications
|
|
79
91
|
end
|
|
80
92
|
|
|
81
93
|
Arel::Nodes::Binary.class_eval do
|
|
@@ -84,6 +96,7 @@ Arel::Nodes::Binary.class_eval do
|
|
|
84
96
|
include ArelExtensions::MathFunctions
|
|
85
97
|
include ArelExtensions::Comparators
|
|
86
98
|
include ArelExtensions::BooleanFunctions
|
|
99
|
+
include ArelExtensions::Predications
|
|
87
100
|
end
|
|
88
101
|
|
|
89
102
|
Arel::Nodes::Equality.class_eval do
|
|
@@ -4,6 +4,7 @@ require 'arel_extensions/math'
|
|
|
4
4
|
require 'arel_extensions/math_functions'
|
|
5
5
|
require 'arel_extensions/null_functions'
|
|
6
6
|
require 'arel_extensions/string_functions'
|
|
7
|
+
require 'arel_extensions/predications'
|
|
7
8
|
|
|
8
9
|
module ArelExtensions
|
|
9
10
|
module Attributes
|
|
@@ -13,6 +14,7 @@ module ArelExtensions
|
|
|
13
14
|
include ArelExtensions::MathFunctions
|
|
14
15
|
include ArelExtensions::NullFunctions
|
|
15
16
|
include ArelExtensions::StringFunctions
|
|
17
|
+
include ArelExtensions::Predications
|
|
16
18
|
|
|
17
19
|
def ==(other)
|
|
18
20
|
Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module ArelExtensions
|
|
2
|
+
module Nodes
|
|
3
|
+
if Arel::VERSION.to_i < 7
|
|
4
|
+
class Case < Arel::Nodes::Node
|
|
5
|
+
include ArelExtensions::Predications
|
|
6
|
+
include Arel::Expressions
|
|
7
|
+
|
|
8
|
+
attr_accessor :case, :conditions, :default
|
|
9
|
+
|
|
10
|
+
def initialize expression = nil, default = nil
|
|
11
|
+
@case = expression
|
|
12
|
+
@conditions = []
|
|
13
|
+
@default = default
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def when condition, expression = nil
|
|
17
|
+
@conditions << When.new(Arel::Nodes.build_quoted(condition), expression)
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def then expression
|
|
22
|
+
@conditions.last.right = Arel::Nodes.build_quoted(expression)
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def else expression
|
|
27
|
+
@default = Else.new Arel::Nodes.build_quoted(expression)
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def initialize_copy other
|
|
32
|
+
super
|
|
33
|
+
@case = @case.clone if @case
|
|
34
|
+
@conditions = @conditions.map { |x| x.clone }
|
|
35
|
+
@default = @default.clone if @default
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def hash
|
|
39
|
+
[@case, @conditions, @default].hash
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def eql? other
|
|
43
|
+
self.class == other.class &&
|
|
44
|
+
self.case == other.case &&
|
|
45
|
+
self.conditions == other.conditions &&
|
|
46
|
+
self.default == other.default
|
|
47
|
+
end
|
|
48
|
+
alias :== :eql?
|
|
49
|
+
|
|
50
|
+
def as other
|
|
51
|
+
ArelExtensions::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class When < Arel::Nodes::Binary # :nodoc:
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Else < Arel::Nodes::Unary # :nodoc:
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
else
|
|
62
|
+
|
|
63
|
+
class Case < Arel::Nodes::Case
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -62,10 +62,8 @@ module ArelExtensions
|
|
|
62
62
|
def mysql_value(v = nil)
|
|
63
63
|
v ||= self.expressions.last
|
|
64
64
|
if defined?(ActiveSupport::Duration) && ActiveSupport::Duration === v
|
|
65
|
-
if @date_type == :date
|
|
66
|
-
Arel.sql(
|
|
67
|
-
elsif @date_type == :datetime
|
|
68
|
-
Arel.sql((v.value >= 0 ? 'INTERVAL ' : 'INTERVAL -') + v.inspect.sub(/s\Z/, ''))
|
|
65
|
+
if @date_type == :date || @date_type == :datetime
|
|
66
|
+
Arel.sql('INTERVAL %s' % v.inspect.sub(/s\Z/, ''))
|
|
69
67
|
end
|
|
70
68
|
else
|
|
71
69
|
v
|
|
@@ -307,7 +307,7 @@ module ArelExtensions
|
|
|
307
307
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
308
308
|
collector << "(LISTAGG("
|
|
309
309
|
collector = visit o.left, collector
|
|
310
|
-
if o.right
|
|
310
|
+
if o.right && o.right != 'NULL'
|
|
311
311
|
collector << Arel::Visitors::Oracle::COMMA
|
|
312
312
|
collector = visit o.right, collector
|
|
313
313
|
end
|
|
@@ -47,7 +47,7 @@ module ArelExtensions
|
|
|
47
47
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
48
48
|
collector << "GROUP_CONCAT("
|
|
49
49
|
collector = visit o.left, collector
|
|
50
|
-
if o.right
|
|
50
|
+
if o.right && o.right != 'NULL'
|
|
51
51
|
collector << ' SEPARATOR '
|
|
52
52
|
collector = visit o.right, collector
|
|
53
53
|
end
|
|
@@ -47,7 +47,7 @@ module ArelExtensions
|
|
|
47
47
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
48
48
|
collector << "(LISTAGG("
|
|
49
49
|
collector = visit o.left, collector
|
|
50
|
-
if o.right
|
|
50
|
+
if o.right && o.right != 'NULL'
|
|
51
51
|
collector << Arel::Visitors::Oracle::COMMA
|
|
52
52
|
collector = visit o.right, collector
|
|
53
53
|
end
|
|
@@ -35,12 +35,22 @@ module ArelExtensions
|
|
|
35
35
|
collector = visit o.right, collector
|
|
36
36
|
collector
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
def visit_ArelExtensions_Nodes_Concat o, collector
|
|
40
|
+
collector << '('
|
|
41
|
+
o.expressions.each_with_index { |arg, i|
|
|
42
|
+
collector = visit arg, collector
|
|
43
|
+
collector << ' || ' unless i == o.expressions.length - 1
|
|
44
|
+
}
|
|
45
|
+
collector << ")"
|
|
46
|
+
collector
|
|
47
|
+
end
|
|
38
48
|
|
|
39
49
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
40
50
|
collector << "array_to_string(array_agg("
|
|
41
51
|
collector = visit o.left, collector
|
|
42
52
|
collector << ")"
|
|
43
|
-
if o.right
|
|
53
|
+
if o.right && o.right != 'NULL'
|
|
44
54
|
collector << Arel::Visitors::PostgreSQL::COMMA
|
|
45
55
|
collector = visit o.right, collector
|
|
46
56
|
else
|
|
@@ -77,6 +77,16 @@ module ArelExtensions
|
|
|
77
77
|
collector
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
+
def visit_ArelExtensions_Nodes_Concat o, collector
|
|
81
|
+
collector << '('
|
|
82
|
+
o.expressions.each_with_index { |arg, i|
|
|
83
|
+
collector = visit arg, collector
|
|
84
|
+
collector << ' || ' unless i == o.expressions.length - 1
|
|
85
|
+
}
|
|
86
|
+
collector << ")"
|
|
87
|
+
collector
|
|
88
|
+
end
|
|
89
|
+
|
|
80
90
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
|
81
91
|
collector << "SUBSTR("
|
|
82
92
|
o.expressions.each_with_index { |arg, i|
|
|
@@ -55,10 +55,10 @@ module ArelExtensions
|
|
|
55
55
|
|
|
56
56
|
# String functions
|
|
57
57
|
def visit_ArelExtensions_Nodes_Concat o, collector
|
|
58
|
-
collector <<
|
|
59
|
-
|
|
58
|
+
collector << "CONCAT("
|
|
59
|
+
o.expressions.each_with_index { |arg, i|
|
|
60
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == 0
|
|
60
61
|
collector = visit arg, collector
|
|
61
|
-
collector << ' || ' unless i == o.expressions.length - 1
|
|
62
62
|
}
|
|
63
63
|
collector << ")"
|
|
64
64
|
collector
|
|
@@ -67,7 +67,7 @@ module ArelExtensions
|
|
|
67
67
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
|
68
68
|
collector << "GROUP_CONCAT("
|
|
69
69
|
collector = visit o.left, collector
|
|
70
|
-
if o.right
|
|
70
|
+
if o.right && o.right != 'NULL'
|
|
71
71
|
collector << Arel::Visitors::ToSql::COMMA
|
|
72
72
|
collector = visit o.right, collector
|
|
73
73
|
end
|
|
@@ -406,7 +406,35 @@ module ArelExtensions
|
|
|
406
406
|
end
|
|
407
407
|
end
|
|
408
408
|
|
|
409
|
-
|
|
409
|
+
def visit_ArelExtensions_Nodes_Case o, collector
|
|
410
|
+
collector << "CASE "
|
|
411
|
+
if o.case
|
|
412
|
+
visit o.case, collector
|
|
413
|
+
collector << " "
|
|
414
|
+
end
|
|
415
|
+
o.conditions.each do |condition|
|
|
416
|
+
visit condition, collector
|
|
417
|
+
collector << " "
|
|
418
|
+
end
|
|
419
|
+
if o.default
|
|
420
|
+
visit o.default, collector
|
|
421
|
+
collector << " "
|
|
422
|
+
end
|
|
423
|
+
collector << "END"
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
def visit_ArelExtensions_Nodes_When o, collector
|
|
427
|
+
collector << "WHEN "
|
|
428
|
+
visit o.left, collector
|
|
429
|
+
collector << " THEN "
|
|
430
|
+
visit o.right, collector
|
|
431
|
+
end
|
|
410
432
|
|
|
433
|
+
def visit_ArelExtensions_Nodes_Else o, collector
|
|
434
|
+
collector << "ELSE "
|
|
435
|
+
visit o.expr, collector
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
end
|
|
411
439
|
end
|
|
412
440
|
end
|
|
@@ -58,8 +58,8 @@ module ArelExtensions
|
|
|
58
58
|
# String Functions
|
|
59
59
|
it "should accept functions on strings" do
|
|
60
60
|
c = @table[:name]
|
|
61
|
-
compile(c + 'test').must_be_like %{("users"
|
|
62
|
-
compile(c + 'test' + ' chain').must_be_like %{("users"
|
|
61
|
+
compile(c + 'test').must_be_like %{CONCAT(\"users\".\"name\", 'test')}
|
|
62
|
+
compile(c + 'test' + ' chain').must_be_like %{CONCAT(\"users\".\"name\", 'test', ' chain')}
|
|
63
63
|
compile(c.length).must_be_like %{LENGTH("users"."name")}
|
|
64
64
|
compile(c.length.round + 42).must_be_like %{(ROUND(LENGTH("users"."name")) + 42)}
|
|
65
65
|
compile(c.locate('test')).must_be_like %{LOCATE('test', "users"."name")}
|
|
@@ -110,6 +110,10 @@ module ArelExtensions
|
|
|
110
110
|
compile(c.idoes_not_match('%test%')).must_be_like %{"users"."name" NOT ILIKE '%test%'}
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
it "should accept comparators on functions" do
|
|
114
|
+
c = @table[:name]
|
|
115
|
+
#compile(c.soundex == 'test').must_be_like %{SOUNDEX("users"."name") = 'test'}
|
|
116
|
+
end
|
|
113
117
|
|
|
114
118
|
# Maths
|
|
115
119
|
# DateDiff
|
|
@@ -138,6 +142,15 @@ module ArelExtensions
|
|
|
138
142
|
sql = compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]]))
|
|
139
143
|
sql.must_match %{DATEDIFF('2015-06-02', "users"."updated_at")}
|
|
140
144
|
end
|
|
145
|
+
|
|
146
|
+
it "should diff between date col and duration" do
|
|
147
|
+
d1 = 10
|
|
148
|
+
d2 = -10
|
|
149
|
+
compile(@table[:created_at] - d1).
|
|
150
|
+
must_match %{DATE_SUB("users"."created_at", 10)}
|
|
151
|
+
compile(@table[:created_at] - d2).
|
|
152
|
+
must_match %{DATE_SUB("users"."created_at", -10)}
|
|
153
|
+
end
|
|
141
154
|
|
|
142
155
|
it "should accept operators on dates with numbers" do
|
|
143
156
|
c = @table[:created_at]
|
|
@@ -165,6 +178,13 @@ module ArelExtensions
|
|
|
165
178
|
).must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(TIMEDIFF("users"."updated_at", '2000-03-31 00:00:00 UTC')))}
|
|
166
179
|
end
|
|
167
180
|
|
|
181
|
+
it "should accept aggregator like GROUP CONCAT" do
|
|
182
|
+
@table.project(@table[:first_name].group_concat).group(@table[:last_name]).to_sql
|
|
183
|
+
.must_be_like %{SELECT GROUP_CONCAT("users"."first_name") FROM "users" GROUP BY "users"."last_name"}
|
|
184
|
+
@table.project(@table[:first_name].group_concat('++')).group(@table[:last_name]).to_sql
|
|
185
|
+
.must_be_like %{SELECT GROUP_CONCAT("users"."first_name", '++') FROM "users" GROUP BY "users"."last_name"}
|
|
186
|
+
end
|
|
187
|
+
|
|
168
188
|
# Unions
|
|
169
189
|
it "should accept union operators on queries and union nodes" do
|
|
170
190
|
c = @table.project(@table[:name])
|
|
@@ -199,6 +219,23 @@ module ArelExtensions
|
|
|
199
219
|
|
|
200
220
|
end
|
|
201
221
|
|
|
222
|
+
|
|
223
|
+
puts "AREL VERSION : " + Arel::VERSION.to_s
|
|
224
|
+
|
|
225
|
+
# Case
|
|
226
|
+
it "should accept case clause" do
|
|
227
|
+
@table[:name].when("smith").then("cool").when("doe").then("fine").else("uncool").to_sql
|
|
228
|
+
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 'cool' WHEN 'doe' THEN 'fine' ELSE 'uncool' END}
|
|
229
|
+
@table[:name].when("smith").then(1).when("doe").then(2).else(0).to_sql
|
|
230
|
+
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
|
|
231
|
+
ArelExtensions::Nodes::Case.new.when(@table[:name] == "smith").then(1).when(@table[:name] == "doe").then(2).else(0).to_sql
|
|
232
|
+
.must_be_like %{CASE WHEN "users"."name" = 'smith' THEN 1 WHEN "users"."name" = 'doe' THEN 2 ELSE 0 END}
|
|
233
|
+
ArelExtensions::Nodes::Case.new(@table[:name]).when("smith").then(1).when("doe").then(2).else(0).to_sql
|
|
234
|
+
.must_be_like %{CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END}
|
|
235
|
+
@table[:name].when("smith").then(1).when("doe").then(2).else(0).sum.to_sql
|
|
236
|
+
.must_be_like %{SUM(CASE "users"."name" WHEN 'smith' THEN 1 WHEN 'doe' THEN 2 ELSE 0 END)}
|
|
237
|
+
end
|
|
238
|
+
|
|
202
239
|
end
|
|
203
240
|
end
|
|
204
241
|
end
|
|
@@ -147,15 +147,23 @@ module ArelExtensions
|
|
|
147
147
|
|
|
148
148
|
# String Functions
|
|
149
149
|
def test_concat
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
assert_equal 'Camille Camille', t(@camille, @name + ' ' + @name)
|
|
151
|
+
assert_equal 'Laure 2', t(@laure, @name + ' ' + 2)
|
|
152
|
+
assert_equal 'Test Laure', t(@laure, Arel::Nodes.build_quoted('Test ') + @name)
|
|
153
|
+
skip "TODO: find a way... to do group_concat/listagg in SQL Server" if @env_db == 'mssql'
|
|
154
|
+
if @env_db == 'postgresql'
|
|
155
|
+
assert_equal "Lucas Sophie", t(User.reorder(nil).from(User.select(:name).where(:name => ['Lucas', 'Sophie']).reorder(:name).as('user_tests')), @name.group_concat(' '))
|
|
156
|
+
assert_equal "Lucas,Sophie", t(User.reorder(nil).from(User.select(:name).where(:name => ['Lucas', 'Sophie']).reorder(:name).as('user_tests')), @name.group_concat(','))
|
|
157
|
+
assert_equal "Lucas Sophie", t(User.reorder(nil).from(User.select(:name).where(:name => ['Lucas', 'Sophie']).reorder(:name).as('user_tests')), @name.group_concat)
|
|
158
|
+
else
|
|
159
|
+
assert_equal "Lucas Sophie", t(User.where(:name => ['Lucas', 'Sophie']).reorder(:name), @name.group_concat(' '))
|
|
160
|
+
assert_equal "Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie']).reorder(:name), @name.group_concat(','))
|
|
161
|
+
if @env_db == 'oracle'
|
|
162
|
+
assert_equal "LucasSophie", t(User.where(:name => ['Lucas', 'Sophie']).reorder(:name), @name.group_concat)
|
|
163
|
+
else
|
|
164
|
+
assert_equal "Lucas,Sophie", t(User.where(:name => ['Lucas', 'Sophie']).reorder(:name), @name.group_concat)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
159
167
|
end
|
|
160
168
|
|
|
161
169
|
def test_length
|
|
@@ -361,6 +369,17 @@ module ArelExtensions
|
|
|
361
369
|
else
|
|
362
370
|
assert_includes [nil, 0, 'f', false], t(@lucas, (@updated_at - Time.utc(2014, 3, 3, 12, 41, 18)) < -1)
|
|
363
371
|
end
|
|
372
|
+
if @env_db == 'mysql'
|
|
373
|
+
date1 = Date.new(2016, 5, 23)
|
|
374
|
+
durPos = 10.years
|
|
375
|
+
durNeg = -10.years
|
|
376
|
+
date2 = date1 + durPos
|
|
377
|
+
date3 = date1 - durPos
|
|
378
|
+
# Pull Request #5 tests
|
|
379
|
+
assert_includes [date2,"2026-05-23"], t(@test,(@created_at + durPos))
|
|
380
|
+
assert_includes [date3,"2006-05-23"], t(@test,(@created_at + durNeg))
|
|
381
|
+
# we test with the ruby object or the string because some adapters don't return an object Date
|
|
382
|
+
end
|
|
364
383
|
end
|
|
365
384
|
end
|
|
366
385
|
|
|
@@ -435,6 +454,10 @@ module ArelExtensions
|
|
|
435
454
|
assert_equal 3, User.select('*').from((@ut.project(@age).where(@age.eq(20)).union_all(@ut.project(@age).where(@age.eq(20))).union_all(@ut.project(@age).where(@age.eq(21)))).as('my_union')).length
|
|
436
455
|
end
|
|
437
456
|
|
|
457
|
+
# Case clause
|
|
458
|
+
def test_case
|
|
459
|
+
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)
|
|
460
|
+
end
|
|
438
461
|
|
|
439
462
|
end
|
|
440
463
|
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.0.2
|
|
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:
|
|
13
|
+
date: 2018-01-16 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: arel
|
|
@@ -101,8 +101,9 @@ files:
|
|
|
101
101
|
- functions.html
|
|
102
102
|
- gemfiles/rails3.gemfile
|
|
103
103
|
- gemfiles/rails4.gemfile
|
|
104
|
-
- gemfiles/rails5.gemfile
|
|
105
104
|
- gemfiles/rails5_0.gemfile
|
|
105
|
+
- gemfiles/rails5_1_4.gemfile
|
|
106
|
+
- gemfiles/rails5_2_beta.gemfile
|
|
106
107
|
- init/mssql.sql
|
|
107
108
|
- init/mysql.sql
|
|
108
109
|
- init/oracle.sql
|
|
@@ -121,6 +122,7 @@ files:
|
|
|
121
122
|
- lib/arel_extensions/nodes/abs.rb
|
|
122
123
|
- lib/arel_extensions/nodes/as.rb
|
|
123
124
|
- lib/arel_extensions/nodes/blank.rb
|
|
125
|
+
- lib/arel_extensions/nodes/case.rb
|
|
124
126
|
- lib/arel_extensions/nodes/ceil.rb
|
|
125
127
|
- lib/arel_extensions/nodes/change_case.rb
|
|
126
128
|
- lib/arel_extensions/nodes/coalesce.rb
|
|
@@ -146,6 +148,7 @@ files:
|
|
|
146
148
|
- lib/arel_extensions/nodes/union_all.rb
|
|
147
149
|
- lib/arel_extensions/nodes/wday.rb
|
|
148
150
|
- lib/arel_extensions/null_functions.rb
|
|
151
|
+
- lib/arel_extensions/predications.rb
|
|
149
152
|
- lib/arel_extensions/railtie.rb
|
|
150
153
|
- lib/arel_extensions/set_functions.rb
|
|
151
154
|
- lib/arel_extensions/string_functions.rb
|