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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8fb8d8ac5e42220d4b332dc7cee83a9c433990a8
4
- data.tar.gz: 415ccf89692668308acf7a126388fff77dd8b559
3
+ metadata.gz: 6b227ca895990c123d78d688d01f00a27a563b70
4
+ data.tar.gz: 21bc450f1776d263294b6d56523adb59843825bb
5
5
  SHA512:
6
- metadata.gz: 5ecb5d555985e025765b3287c5a5aaefe28f5bb6ebce3e04d719aef43b232f51f821308181a360857768f963bd323daf5407c8720fdf09f9157e2bc56cbd1f4c
7
- data.tar.gz: 15db9820090448c55de632f7bc524aa86e3954efe8d904e03f2fcf3291d962d4f3705d52b896a7b0fe85459602b432a1db334e7d1ec7fe09fefac375106f424e
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
- - $ORACLE_DOWNLOAD_DIR
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
- - sudo apt-get install -y sqlite3-pcre curl
14
- - .travis/sqlite3/extension-functions.sh
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/rails5.gemfile
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/rails5.gemfile
99
+ gemfile: gemfiles/rails5_1_4.gemfile
99
100
  - rvm: 2.1
100
- gemfile: gemfiles/rails5.gemfile
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: rbx-2
110
- gemfile: gemfiles/rails5_0.gemfile
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/rails5.gemfile
122
- - rvm: jruby-9.0.5.0
123
- gemfile: gemfiles/rails5.gemfile
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.
@@ -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 => "../"
@@ -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 => "../"
@@ -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)
@@ -1 +1,2 @@
1
1
  require 'arel_extensions/nodes/function'
2
+
@@ -4,7 +4,7 @@ module ArelExtensions
4
4
 
5
5
  def initialize left,right
6
6
  return super(left,right)
7
- end
7
+ end
8
8
  end
9
9
  end
10
10
  end
@@ -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((v.value >= 0 ? 'INTERVAL ' : 'INTERVAL -') + v.inspect.sub(/s\Z/, ''))
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
@@ -127,7 +127,7 @@ module ArelExtensions
127
127
  raise(ArgumentError, "#{object.class} can not be converted to NUMBER arg")
128
128
  end
129
129
  end
130
-
130
+
131
131
  end
132
132
  end
133
133
  end
@@ -1,6 +1,6 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
- class Soundex < Function
3
+ class Soundex < Function
4
4
  @@return_type = :string
5
5
  end
6
6
  end
@@ -0,0 +1,9 @@
1
+ module ArelExtensions
2
+ module Predications
3
+ if Arel::VERSION.to_i < 7
4
+ def when right
5
+ ArelExtensions::Nodes::Case.new(self).when(right)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module ArelExtensions
2
- VERSION = "1.0.1".freeze
2
+ VERSION = "1.0.2".freeze
3
3
  end
@@ -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
- o.expressions.each_with_index { |arg, i|
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
- end
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"."name" || 'test')}
62
- compile(c + 'test' + ' chain').must_be_like %{("users"."name" || 'test' || ' chain')}
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
- 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
- else
157
- assert_equal "Lucas Sophie", t(User.where(:name => ['Lucas', 'Sophie']).reorder(:name), @name.group_concat(' '))
158
- end
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.1
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: 2017-12-19 00:00:00.000000000 Z
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