arel_extensions 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/Gemfile +6 -6
  4. data/README.md +7 -4
  5. data/arel_extensions.gemspec +1 -1
  6. data/functions.html +2 -2
  7. data/gemfiles/rails4.gemfile +10 -10
  8. data/gemfiles/rails5.gemfile +10 -10
  9. data/lib/arel_extensions/attributes.rb +6 -6
  10. data/lib/arel_extensions/boolean_functions.rb +21 -0
  11. data/lib/arel_extensions/date_duration.rb +28 -25
  12. data/lib/arel_extensions/math.rb +42 -39
  13. data/lib/arel_extensions/math_functions.rb +6 -0
  14. data/lib/arel_extensions/nodes/ceil.rb +1 -0
  15. data/lib/arel_extensions/nodes/concat.rb +3 -1
  16. data/lib/arel_extensions/nodes/date_diff.rb +19 -16
  17. data/lib/arel_extensions/nodes/duration.rb +1 -2
  18. data/lib/arel_extensions/nodes/floor.rb +2 -0
  19. data/lib/arel_extensions/nodes/format.rb +6 -3
  20. data/lib/arel_extensions/nodes/function.rb +5 -1
  21. data/lib/arel_extensions/nodes/replace.rb +1 -0
  22. data/lib/arel_extensions/nodes/soundex.rb +1 -0
  23. data/lib/arel_extensions/nodes/trim.rb +2 -1
  24. data/lib/arel_extensions/nodes.rb +1 -29
  25. data/lib/arel_extensions/null_functions.rb +3 -0
  26. data/lib/arel_extensions/string_functions.rb +12 -0
  27. data/lib/arel_extensions/version.rb +1 -1
  28. data/lib/arel_extensions/visitors/mssql.rb +33 -13
  29. data/lib/arel_extensions/visitors/mysql.rb +29 -0
  30. data/lib/arel_extensions/visitors/oracle.rb +19 -16
  31. data/lib/arel_extensions/visitors/postgresql.rb +21 -2
  32. data/lib/arel_extensions/visitors/sqlite.rb +6 -0
  33. data/lib/arel_extensions.rb +3 -0
  34. data/test/visitors/test_oracle.rb +5 -7
  35. data/test/visitors/test_to_sql.rb +7 -0
  36. data/test/with_ar/all_agnostic_test.rb +29 -8
  37. metadata +3 -3
  38. data/lib/arel_extensions/nodes/sum.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a8e5c240fc0fe59c0b14a9709b6c065276475334
4
- data.tar.gz: f5caf5d24a636b49f39132e3817ed867dd803374
3
+ metadata.gz: 7d0b1c534a245cecea4ec121f0ab0744a8f2efdb
4
+ data.tar.gz: d1ee62f0e19d702485656fd16ec3ed99b8608fc2
5
5
  SHA512:
6
- metadata.gz: 2c1ffca0a92fb3d704b2f2ed2649cf6a8df2fb90e46602680aa5c894c9ffef0d6af726736da6de97b12d7ce09f88d4d087e4bf0f1e3d64ab4dec89c8a0c03f93
7
- data.tar.gz: 617784403ff3999277c8c60430294feaacba648366635d768f14347f2373fab2209c7dd097c72b1bb7ad0a9dcc9e7d9aad1c21976495943a20d317a2cee70467
6
+ metadata.gz: 152b5eafbeea38f4216436656d6e02a099bdeeed44b7f217ea9369ecf412ea32bcf130f577c1f0fcb5d37b6c267877a33b23963a1b9479c2faf2c4b67c7e5504
7
+ data.tar.gz: d7d5ce6cffcd349cfd6033fc2b2d11d349f5081cdde32b514e884e900a1a0dc25cd89373f42baefa9a7cf1a1d3a91d6573b13153af2804847f2a5b9d3c269179
data/.travis.yml CHANGED
@@ -20,7 +20,6 @@ services:
20
20
  before_script:
21
21
  - mysql -e 'create database arext_test;'
22
22
  - psql -c 'create database arext_test;' -U postgres
23
- # - $ORACLE_HOME/bin/sqlplus CREATE DB
24
23
  script:
25
24
  - gem build arel_extensions.gemspec
26
25
  - bundle exec rake test
data/Gemfile CHANGED
@@ -3,12 +3,12 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  group :test do
6
- gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
7
- gem "mysql2", :platform => [:ruby, :mswin, :mingw]
8
- gem "jdbc-sqlite3", :platform => :jruby
9
- gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
10
- gem "activerecord-jdbcmysql-adapter", :platform => :jruby
11
- gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
6
+ gem "sqlite3", :platforms => [:ruby, :mswin, :mingw]
7
+ gem "mysql2", :platforms => [:ruby, :mswin, :mingw]
8
+ gem "jdbc-sqlite3", :platforms => :jruby
9
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
10
+ gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
11
+ gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
12
12
 
13
13
  gem 'activesupport', '~> 4.0'
14
14
  gem 'activemodel', '~> 4.0'
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Arel Extensions
2
2
 
3
+ [![Build Status](https://secure.travis-ci.org/Faveod/arel-extensions.svg)](http://travis-ci.org/Faveod/arel-extensions)
4
+
5
+
3
6
  Arel Extensions adds shortcuts, fixes and new ORM mappings (ruby to SQL) to Arel.
4
7
  It aims to ensure pure ruby syntax for the biggest number of usual cases.
5
8
  It allows to use more advanced SQL functions for any supported RDBMS.
@@ -17,13 +20,13 @@ t is an Arel::Table for table my_table
17
20
  ## Comparators
18
21
 
19
22
  ```ruby
20
- (t[:nb] > 42).to_sql # (same as (t[:nb].gt(42)).to_sql)
21
- # => my_table.nb > 42
23
+ (t[:date1] > t[:date2]).to_sql # (same as (t[:date1].gt(t[:date2])).to_sql)
24
+ # => my_table.date1 > my_table.date2
22
25
  ```
23
26
 
24
27
  ```ruby
25
- (t[:date1] > t[:date2]).to_sql # (same as (t[:date1].gt(t[:date2])).to_sql)
26
- # => my_table.date1 > my_table.date2
28
+ (t[:nb] > 42).to_sql # (same as (t[:nb].gt(42)).to_sql)
29
+ # => my_table.nb > 42
27
30
  ```
28
31
 
29
32
  ## Maths
@@ -4,7 +4,7 @@ $:.push File.expand_path("../lib", __FILE__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "arel_extensions"
7
- s.version = '0.8.5'
7
+ s.version = '0.8.6'
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Yann Azoury", "Mathilde Pechdimaldjian", "Félix Bellanger"]
10
10
  s.email = ["yann.azoury@faveod.com", "mathilde.pechdimaldjian@gmail.com", "felix.bellanger@faveod.com"]
data/functions.html CHANGED
@@ -332,7 +332,7 @@
332
332
  </tr>
333
333
  <tr>
334
334
  <th class="tg-9hbo" rowspan="2">Boolean <br>functions</th>
335
- <td class="tg-yw4l">OR ( ⋁ )<br>column.eq(var)column.eq(var)</td>
335
+ <td class="tg-yw4l">OR ( ⋁ )<br>column.eq(var).⋁(column.eq(var))</td>
336
336
  <td class="tg-baqh">✔</td>
337
337
  <td class="tg-baqh">✔</td>
338
338
  <td class="tg-baqh">✔</td>
@@ -341,7 +341,7 @@
341
341
  <td class="tg-baqh">✔</td>
342
342
  </tr>
343
343
  <tr>
344
- <td class="tg-yw4l">AND ( ⋀ )<br>column.eq(var)column.eq(var)</td>
344
+ <td class="tg-yw4l">AND ( ⋀ )<br>column.eq(var).⋀(column.eq(var))</td>
345
345
  <td class="tg-baqh">✔</td>
346
346
  <td class="tg-baqh">✔</td>
347
347
  <td class="tg-baqh">✔</td>
@@ -7,20 +7,20 @@ group :development, :test do
7
7
  gem 'activemodel', '~> 4.0'
8
8
  gem 'activerecord', '~> 4.0'
9
9
 
10
- gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
11
- gem "mysql2", :platform => [:ruby, :mswin, :mingw]
12
- gem "pg", :platform => [:ruby, :mswin, :mingw]
10
+ gem "sqlite3", :platforms => [:ruby, :mswin, :mingw]
11
+ gem "mysql2", :platforms => [:ruby, :mswin, :mingw]
12
+ gem "pg", :platforms => [:ruby, :mswin, :mingw]
13
13
 
14
- gem 'ruby-oci8', :platform => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
14
+ gem 'ruby-oci8', :platforms => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
15
15
  gem 'activerecord-oracle_enhanced-adapter', '~> 1.6.0' if ENV.has_key? 'ORACLE_HOME'
16
16
 
17
17
  # for JRuby
18
- gem 'activerecord-jdbc-adapter', platform: :jruby
19
- gem "jdbc-sqlite3", :platform => :jruby
20
- gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
21
- gem "activerecord-jdbcmysql-adapter", :platform => :jruby
22
- gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
23
- gem "activerecord-jdbcmssql-adapter", :platform => :jruby
18
+ gem 'activerecord-jdbc-adapter', :platforms => :jruby
19
+ gem "jdbc-sqlite3", :platforms => :jruby
20
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
21
+ gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
22
+ gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
23
+ gem "activerecord-jdbcmssql-adapter", :platforms => :jruby
24
24
  end
25
25
 
26
26
  gemspec :path => "../"
@@ -7,20 +7,20 @@ group :development, :test do
7
7
  gem 'activemodel', '~> 5'
8
8
  gem 'activerecord', '~> 5'
9
9
 
10
- gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
11
- gem "mysql2", :platform => [:ruby, :mswin, :mingw]
12
- gem "pg", :platform => [:ruby, :mswin, :mingw]
10
+ gem "sqlite3", :platforms => [:ruby, :mswin, :mingw]
11
+ gem "mysql2", :platforms => [:ruby, :mswin, :mingw]
12
+ gem "pg", :platforms => [:ruby, :mswin, :mingw]
13
13
 
14
- gem 'ruby-oci8', :platform => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
14
+ gem 'ruby-oci8', :platforms => [:ruby, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
15
15
  gem 'activerecord-oracle_enhanced-adapter', '~> 1.7.0' if ENV.has_key? 'ORACLE_HOME'
16
16
 
17
17
  # for JRuby
18
- gem 'activerecord-jdbc-adapter', platform: :jruby
19
- gem "jdbc-sqlite3", :platform => :jruby
20
- gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
21
- gem "activerecord-jdbcmysql-adapter", :platform => :jruby
22
- gem "activerecord-jdbcpostgresql-adapter", :platform => :jruby
23
- gem "activerecord-jdbcmssql-adapter", :platform => :jruby
18
+ gem 'activerecord-jdbc-adapter', :platforms => :jruby
19
+ gem "jdbc-sqlite3", :platforms => :jruby
20
+ gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
21
+ gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
22
+ gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
23
+ gem "activerecord-jdbcmssql-adapter", :platforms => :jruby
24
24
  end
25
25
 
26
26
  gemspec :path => "../"
@@ -7,12 +7,12 @@ require 'arel_extensions/string_functions'
7
7
 
8
8
  module ArelExtensions
9
9
  module Attributes
10
- include ArelExtensions::Comparators
11
- include ArelExtensions::DateDuration
12
- include ArelExtensions::Math
13
- include ArelExtensions::MathFunctions
14
- include ArelExtensions::NullFunctions
15
- include ArelExtensions::StringFunctions
10
+ include ArelExtensions::Comparators
11
+ include ArelExtensions::DateDuration
12
+ include ArelExtensions::Math
13
+ include ArelExtensions::MathFunctions
14
+ include ArelExtensions::NullFunctions
15
+ include ArelExtensions::StringFunctions
16
16
 
17
17
  def ==(other)
18
18
  Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
@@ -0,0 +1,21 @@
1
+ module ArelExtensions
2
+ module BooleanFunctions
3
+
4
+ def ⋀(other)
5
+ self.and(other)
6
+ end
7
+
8
+ def ⋁(other)
9
+ self.or(other)
10
+ end
11
+
12
+ end
13
+ end
14
+
15
+ Arel::Nodes::And.class_eval do
16
+ include ArelExtensions::BooleanFunctions
17
+ end
18
+
19
+ Arel::Nodes::Or.class_eval do
20
+ include ArelExtensions::BooleanFunctions
21
+ end
@@ -1,32 +1,35 @@
1
- module ArelExtensions
2
- module DateDuration
3
- #function returns the year (as a number) given a date value.
4
- def year
5
- ArelExtensions::Nodes::Duration.new "y", self
6
- end
1
+ require 'arel_extensions/nodes/duration'
2
+ require 'arel_extensions/nodes/wday'
7
3
 
8
- #function returns the month (as a number) given a date value.
9
- def month
10
- ArelExtensions::Nodes::Duration.new "m", self
11
- end
4
+ module ArelExtensions
5
+ module DateDuration
6
+ #function returns the year (as a number) given a date value.
7
+ def year
8
+ ArelExtensions::Nodes::Duration.new "y", self
9
+ end
12
10
 
13
- #function returns the week (as a number) given a date value.
14
- def week
15
- ArelExtensions::Nodes::Duration.new "w", self
16
- end
11
+ #function returns the month (as a number) given a date value.
12
+ def month
13
+ ArelExtensions::Nodes::Duration.new "m", self
14
+ end
17
15
 
18
- #function returns the month (as a number) given a date value.
19
- def day
20
- ArelExtensions::Nodes::Duration.new "d", self
21
- end
16
+ #function returns the week (as a number) given a date value.
17
+ def week
18
+ ArelExtensions::Nodes::Duration.new "w", self
19
+ end
22
20
 
23
- def wday
24
- ArelExtensions::Nodes::Duration.new 'wd', self
25
- end
21
+ #function returns the month (as a number) given a date value.
22
+ def day
23
+ ArelExtensions::Nodes::Duration.new "d", self
24
+ end
26
25
 
27
- def format(tpl)
28
- ArelExtensions::Nodes::Format.new [self, tpl]
29
- end
26
+ def wday
27
+ ArelExtensions::Nodes::Duration.new 'wd', self
28
+ end
30
29
 
30
+ def format(tpl)
31
+ ArelExtensions::Nodes::Format.new [self, tpl]
31
32
  end
32
- end
33
+
34
+ end
35
+ end
@@ -1,50 +1,53 @@
1
1
  require 'arel_extensions/nodes'
2
2
  require 'arel_extensions/nodes/concat'
3
3
 
4
+ require 'arel_extensions/nodes/date_diff'
5
+ require 'arel_extensions/nodes/duration'
6
+ require 'arel_extensions/nodes/wday'
7
+
4
8
  module ArelExtensions
5
- module Math
6
- #function + between
7
- #String and others (convert in string) allows you to concatenate 2 or more strings together.
8
- #Date and integer adds or subtracts a specified time interval from a date.
9
- def +(other)
10
- arg = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
11
- if arg == :integer || arg == :decimal || arg == :float
12
- if other.is_a?(String)
13
- other = other.to_i
14
- end
15
- Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
16
- elsif arg == :datetime || arg == :date
17
- ArelExtensions::Nodes::DateAdd.new [self, other]
18
- elsif arg == :string || arg == :text
19
- ArelExtensions::Nodes::Concat.new [self, other]
20
- end
21
- end
9
+ module Math
10
+ #function + between
11
+ #String and others (convert in string) allows you to concatenate 2 or more strings together.
12
+ #Date and integer adds or subtracts a specified time interval from a date.
13
+ def +(other)
14
+ arg = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
15
+ if arg == :integer
16
+ other = other.to_i if other.is_a?(String)
17
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
18
+ elsif arg == :decimal || arg == :float
19
+ other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
20
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
21
+ elsif arg == :datetime || arg == :date
22
+ ArelExtensions::Nodes::DateAdd.new [self, other]
23
+ elsif arg == :string || arg == :text
24
+ ArelExtensions::Nodes::Concat.new [self, other]
25
+ end
26
+ end
22
27
 
23
- #function returns the time between two dates
24
- #function returns the susbration between two int
25
- def -(other)
26
- arg = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
27
- if (arg == :date || arg == :datetime)
28
- case other
29
- when Arel::Attributes::Attribute
30
- arg2 = Arel::Table.engine.connection.schema_cache.columns_hash(other.relation.table_name)[other.name.to_s].type
31
- if arg2 == :date || arg2 == :datetime
32
- ArelExtensions::Nodes::DateDiff.new [self, other]
33
- else
34
- ArelExtensions::Nodes::DateSub.new self, other
35
- end
36
- when Arel::Nodes::Node, DateTime, Time, String, Date
28
+ #function returns the time between two dates
29
+ #function returns the susbration between two int
30
+ def -(other)
31
+ arg = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
32
+ if (arg == :date || arg == :datetime)
33
+ case other
34
+ when Arel::Attributes::Attribute
35
+ arg2 = Arel::Table.engine.connection.schema_cache.columns_hash(other.relation.table_name)[other.name.to_s].type
36
+ if arg2 == :date || arg2 == :datetime
37
37
  ArelExtensions::Nodes::DateDiff.new [self, other]
38
- when Fixnum
39
- ArelExtensions::Nodes::DateSub.new self, other
38
+ else
39
+ ArelExtensions::Nodes::DateSub.new [self, other]
40
40
  end
41
- else
42
- if other.is_a?(String)
43
- other = other.to_i
44
- end
45
- Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
41
+ when Arel::Nodes::Node, DateTime, Time, String, Date
42
+ ArelExtensions::Nodes::DateDiff.new [self, other]
43
+ when Fixnum
44
+ ArelExtensions::Nodes::DateSub.new [self, other]
46
45
  end
46
+ else
47
+ other = Arel.sql(other) if other.is_a?(String)# Arel should accept Float & BigDecimal!
48
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
47
49
  end
48
-
49
50
  end
51
+
52
+ end
50
53
  end
@@ -1,3 +1,9 @@
1
+ require 'arel_extensions/nodes/abs'
2
+ require 'arel_extensions/nodes/ceil'
3
+ require 'arel_extensions/nodes/floor'
4
+ require 'arel_extensions/nodes/round'
5
+ require 'arel_extensions/nodes/rand'
6
+
1
7
  module ArelExtensions
2
8
  module MathFunctions
3
9
 
@@ -1,6 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Ceil < Function
4
+ @@return_type = :number
4
5
  end
5
6
  end
6
7
  end
@@ -1,7 +1,8 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Concat < Function
4
-
4
+ @@return_type = :string
5
+
5
6
  def initialize expr
6
7
  tab = expr.map { |arg|
7
8
  convert_to_node(arg)
@@ -16,6 +17,7 @@ module ArelExtensions
16
17
  end
17
18
 
18
19
  class GroupConcat < Function
20
+ @@return_type = :string
19
21
 
20
22
  def initialize expr
21
23
  tab = expr.map { |arg|
@@ -3,7 +3,8 @@ require 'date'
3
3
  module ArelExtensions
4
4
  module Nodes
5
5
  class DateDiff < Function #difference entre colonne date et date string/date
6
- attr_accessor :date_type
6
+ attr_accessor :left_node_type
7
+ attr_accessor :right_node_type
7
8
 
8
9
  @@return_type = :integer # by default...
9
10
 
@@ -11,22 +12,31 @@ module ArelExtensions
11
12
  col = expr.first
12
13
  case col
13
14
  when Arel::Nodes::Node
14
- @date_type = Arel::Table.engine.connection.schema_cache.columns_hash(col.relation.table_name)[col.name.to_s].type
15
+ @left_node_type = type_of_attribute(col)
15
16
  when Date
16
- @date_type = :date
17
+ @left_node_type = :ruby_date
17
18
  when DateTime, Time
18
- @date_type = :datetime
19
+ @left_node_type = :ruby_time
20
+ end
21
+ case expr[1]
22
+ when Arel::Nodes::Node
23
+ @right_node_type = type_of_attribute(col)
24
+ when Date
25
+ @right_node_type = :ruby_date
26
+ when DateTime, Time
27
+ @right_node_type = :ruby_time
19
28
  end
20
29
  super [convert_to_date_node(col), convert_to_date_node(expr[1])]
21
30
  end
22
31
  end
23
32
 
24
33
  class DateAdd < Function
34
+ @@return_type = :date
25
35
  attr_accessor :date_type
26
36
 
27
37
  def initialize expr
28
38
  col = expr.first
29
- @date_type = Arel::Table.engine.connection.schema_cache.columns_hash(col.relation.table_name)[col.name.to_s].type
39
+ @date_type = type_of_attribute(col)
30
40
  tab = expr.map do |arg|
31
41
  convert(arg)
32
42
  end
@@ -104,18 +114,11 @@ module ArelExtensions
104
114
  end
105
115
  end
106
116
 
107
- class DateSub < Arel::Nodes::Node #difference entre colonne date et date string/date
108
- include Arel::Predications
109
- include Arel::WindowPredications
110
- include Arel::OrderPredications
111
- include Arel::AliasPredication
112
-
113
- attr_accessor :left, :right
117
+ class DateSub < Function #difference entre colonne date et date string/date
118
+ @@return_type = :integer
114
119
 
115
- def initialize(left, right, aliaz = nil)
116
- super()
117
- @left = left
118
- @right = convert_number(right)
120
+ def initialize(expr)
121
+ super [expr.first, convert_number(expr[1])]
119
122
  end
120
123
 
121
124
  def convert_number(object)
@@ -2,7 +2,6 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Duration < Arel::Nodes::Function
4
4
 
5
-
6
5
  def initialize left, right, aliaz = nil
7
6
  tab = Array.new
8
7
  tab << left
@@ -22,7 +21,7 @@ module ArelExtensions
22
21
 
23
22
 
24
23
  def as other
25
- Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
24
+ Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other.to_s)
26
25
  end
27
26
 
28
27
  end
@@ -1,6 +1,8 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Floor < Function
4
+ @@return_type = :number
5
+
4
6
  end
5
7
  end
6
8
  end
@@ -1,11 +1,14 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Format < Function
4
- attr_accessor :col_type
4
+ @@return_type = :string
5
+
6
+ attr_accessor :col_type, :iso_format
5
7
  def initialize expr
6
8
  col = expr.first
7
- @col_type = Arel::Table.engine.connection.schema_cache.columns_hash(col.relation.table_name)[col.name.to_s].type
8
- super [expr.first, convert_to_string_node(expr[1])]
9
+ @iso_format = expr[1]
10
+ @col_type = type_of_attribute(col)
11
+ super [col, convert_to_string_node(@iso_format)]
9
12
  end
10
13
  end
11
14
  end
@@ -25,6 +25,10 @@ module ArelExtensions
25
25
  @expressions[1]
26
26
  end
27
27
 
28
+ def type_of_attribute(att)
29
+ Arel::Table.engine.connection.schema_cache.columns_hash(att.relation.table_name)[att.name.to_s].type
30
+ end
31
+
28
32
  def convert_to_node(object)
29
33
  case object
30
34
  when Arel::Attributes::Attribute, Arel::Nodes::Node, Fixnum, Integer
@@ -51,7 +55,7 @@ module ArelExtensions
51
55
  when Fixnum, Integer
52
56
  Arel::Nodes.build_quoted(object.to_s)
53
57
  when Arel::Attributes::Attribute
54
- case Arel::Table.engine.connection.schema_cache.columns_hash(object.relation.table_name)[object.name.to_s].type
58
+ case self.type_of_attribute(object)
55
59
  when :date
56
60
  ArelExtensions::Nodes::Format.new [object, 'yyyy-mm-dd']
57
61
  else
@@ -1,6 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Replace < Function
4
+ @@return_type = :string
4
5
 
5
6
  def initialize expr
6
7
  tab = expr.map { |arg|
@@ -1,6 +1,7 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Soundex < Function
4
+ @@return_type = :string
4
5
  end
5
6
  end
6
7
  end
@@ -1,7 +1,8 @@
1
1
  module ArelExtensions
2
2
  module Nodes
3
3
  class Trim < Function
4
-
4
+ @@return_type = :string
5
+
5
6
  def initialize expr
6
7
  tab = expr.map { |arg|
7
8
  convert_to_node(arg)
@@ -1,29 +1 @@
1
- require 'arel_extensions/nodes/function'
2
- # Math functions
3
- require 'arel_extensions/nodes/abs'
4
- require 'arel_extensions/nodes/ceil'
5
- require 'arel_extensions/nodes/floor'
6
- require 'arel_extensions/nodes/round'
7
- require 'arel_extensions/nodes/rand'
8
- require 'arel_extensions/nodes/sum'
9
-
10
- # String functions
11
- require 'arel_extensions/nodes/concat' if Arel::VERSION.to_i < 7
12
- require 'arel_extensions/nodes/length'
13
- require 'arel_extensions/nodes/locate'
14
- require 'arel_extensions/nodes/matches'
15
- require 'arel_extensions/nodes/find_in_set'
16
- require 'arel_extensions/nodes/replace'
17
- require 'arel_extensions/nodes/soundex'
18
- require 'arel_extensions/nodes/trim'
19
- require 'arel_extensions/nodes/ltrim'
20
- require 'arel_extensions/nodes/rtrim'
21
- require 'arel_extensions/nodes/format'
22
-
23
- # Date functions
24
- require 'arel_extensions/nodes/date_diff'
25
- require 'arel_extensions/nodes/duration'
26
-
27
- require 'arel_extensions/nodes/coalesce'
28
- require 'arel_extensions/nodes/is_null'
29
- require 'arel_extensions/nodes/wday'
1
+ require 'arel_extensions/nodes/function'
@@ -1,3 +1,6 @@
1
+ require 'arel_extensions/nodes/coalesce'
2
+ require 'arel_extensions/nodes/is_null'
3
+
1
4
  module ArelExtensions
2
5
  module NullFunctions
3
6
 
@@ -1,3 +1,15 @@
1
+ require 'arel_extensions/nodes/concat' if Arel::VERSION.to_i < 7
2
+ require 'arel_extensions/nodes/length'
3
+ require 'arel_extensions/nodes/locate'
4
+ require 'arel_extensions/nodes/matches'
5
+ require 'arel_extensions/nodes/find_in_set'
6
+ require 'arel_extensions/nodes/replace'
7
+ require 'arel_extensions/nodes/soundex'
8
+ require 'arel_extensions/nodes/trim'
9
+ require 'arel_extensions/nodes/ltrim'
10
+ require 'arel_extensions/nodes/rtrim'
11
+ require 'arel_extensions/nodes/format'
12
+
1
13
  module ArelExtensions
2
14
  module StringFunctions
3
15
 
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module ArelExtensions
3
- VERSION = "0.8.5".freeze
3
+ VERSION = "0.8.6".freeze
4
4
  end
@@ -1,6 +1,12 @@
1
1
  module ArelExtensions
2
2
  module Visitors
3
3
  Arel::Visitors::MSSQL.class_eval do
4
+ Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
5
+ '%Y' => 'yy', '%C' => '', '%y' => 'yy', '%m' => 'mm', '%B' => '', '%b' => '', '%^b' => '', # year, month
6
+ '%d' => 'dd', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
7
+ '%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
8
+ '%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
9
+ }
4
10
 
5
11
  # Math Functions
6
12
  def visit_ArelExtensions_Nodes_Ceil o, collector
@@ -73,24 +79,38 @@ module ArelExtensions
73
79
  end
74
80
 
75
81
 
76
- def visit_ArelExtensions_Nodes_Locate o, collector
77
- collector << "CHARINDEX("
78
- collector = visit o.val, collector
82
+ def visit_ArelExtensions_Nodes_Locate o, collector
83
+ collector << "CHARINDEX("
84
+ collector = visit o.val, collector
79
85
  collector << ","
80
86
  collector = visit o.expr, collector
81
87
  collector << ")"
82
88
  collector
83
- end
89
+ end
90
+
91
+ def visit_ArelExtensions_Nodes_Format o, collector
92
+ collector << "CONCAT("
93
+
94
+ t = o.iso_format.split('%')
95
+ t.each_with_index {|str, i|
96
+ if i == 0 && f[0] != '%'
97
+ collector = visit Arel::Nodes.build_quoted(str), collector
98
+ elsif str.length > 0
99
+ if !Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]].blank?
100
+ collector << 'DATEPART('
101
+ collector << Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES['%' + str[0]]
102
+ collector << Arel::Visitors::MSSQL::COMMA
103
+ collector = visit o.left, collector
104
+ collector << ')'
105
+ if str.length > 1
106
+ collector << Arel::Visitors::MSSQL::COMMA
107
+ collector = visit Arel::Nodes.build_quoted(str.sub(/\A./, '')), collector
108
+ end
109
+ end
110
+ end
111
+ collector << Arel::Visitors::MSSQL::COMMA unless i < (t.length - 1)
112
+ }
84
113
 
85
- def visit_ArelExtensions_Nodes_IsNull o, collector
86
- collector << "ISNULL("
87
- collector = visit o.left, collector
88
- collector << ","
89
- if(o.right.is_a?(Arel::Attributes::Attribute))
90
- collector = visit o.right, collector
91
- else
92
- collector << "'#{o.right}'"
93
- end
94
114
  collector << ")"
95
115
  collector
96
116
  end
@@ -2,6 +2,12 @@ module ArelExtensions
2
2
  module Visitors
3
3
  Arel::Visitors::MySQL.class_eval do
4
4
  Arel::Visitors::MySQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'WEEKDAY'}
5
+ Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
6
+ '%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
7
+ '%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W', # day, weekday
8
+ '%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
9
+ '%M' => '%i', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => ''
10
+ }
5
11
 
6
12
  #String functions
7
13
  def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
@@ -75,6 +81,29 @@ module ArelExtensions
75
81
  collector << ")"
76
82
  collector
77
83
  end
84
+
85
+ def visit_ArelExtensions_Nodes_Format o, collector
86
+ case o.col_type
87
+ when :date, :datetime
88
+ collector << "DATE_FORMAT("
89
+ collector = visit o.left, collector
90
+ collector << Arel::Visitors::MySQL::COMMA
91
+ f = o.iso_format.dup
92
+ Arel::Visitors::MySQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
93
+ collector = visit Arel::Nodes.build_quoted(f), collector
94
+ collector << ")"
95
+ when :integer, :float, :decimal
96
+ collector << "FORMAT("
97
+ collector = visit o.left, collector
98
+ collector << Arel::Visitors::ToSql::COMMA
99
+ collector = visit o.right, collector
100
+ collector << ")"
101
+ else
102
+ collector = visit o.left, collector
103
+ end
104
+ collector
105
+ end
106
+
78
107
  def visit_ArelExtensions_Nodes_DateDiff o, collector
79
108
  collector << "DATEDIFF("
80
109
  collector = visit o.left, collector
@@ -2,6 +2,12 @@ module ArelExtensions
2
2
  module Visitors
3
3
  Arel::Visitors::Oracle.class_eval do
4
4
  Arel::Visitors::Oracle::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'IW', 'y' => 'YEAR', 'wd' => 'D'}
5
+ Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES = {
6
+ '%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
7
+ '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
8
+ '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
9
+ '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
10
+ }
5
11
 
6
12
  def visit_ArelExtensions_Nodes_Concat o, collector
7
13
  collector << '('
@@ -62,9 +68,13 @@ module ArelExtensions
62
68
 
63
69
  def visit_ArelExtensions_Nodes_DateDiff o, collector
64
70
  collector << '('
71
+ collector << 'TO_DATE(' unless o.left_node_type == :date || o.left_node_type == :datetime
65
72
  collector = visit o.left, collector
73
+ collector << ')' unless o.left_node_type == :date || o.left_node_type == :datetime
66
74
  collector << " - "
75
+ collector << 'TO_DATE(' unless o.right_node_type == :date || o.right_node_type == :datetime
67
76
  collector = visit o.right, collector
77
+ collector << ')' unless o.right_node_type == :date || o.right_node_type == :datetime
68
78
  collector << ')'
69
79
  collector
70
80
  end
@@ -182,22 +192,15 @@ module ArelExtensions
182
192
  end
183
193
 
184
194
  def visit_ArelExtensions_Nodes_Format o, collector
185
- case o.col_type
186
- when :date, :datetime
187
- collector << "TO_CHAR("
188
- collector = visit o.left, collector
189
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
190
- collector = visit o.right, collector
191
- collector << ")"
192
- when :integer, :float, :decimal
193
- collector << "FORMAT("
194
- collector = visit o.left, collector
195
- collector << Arel::Visitors::Oracle::COMMA unless i == 0
196
- collector = visit o.right, collector
197
- collector << ")"
198
- else
199
- collector = visit o.left, collector
200
- end
195
+ collector << "TO_CHAR("
196
+ collector = visit o.left, collector
197
+ collector << Arel::Visitors::Oracle::COMMA
198
+
199
+ f = o.iso_format.dup
200
+ Arel::Visitors::Oracle::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
201
+ collector = visit Arel::Nodes.build_quoted(f), collector
202
+
203
+ collector << ")"
201
204
  collector
202
205
  end
203
206
 
@@ -2,6 +2,12 @@ module ArelExtensions
2
2
  module Visitors
3
3
  Arel::Visitors::PostgreSQL.class_eval do
4
4
  Arel::Visitors::PostgreSQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW'}
5
+ Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES = {
6
+ '%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
7
+ '%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
8
+ '%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
9
+ '%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
10
+ }
5
11
 
6
12
  def visit_ArelExtensions_Nodes_Rand o, collector
7
13
  collector << "RANDOM("
@@ -72,6 +78,19 @@ module ArelExtensions
72
78
  collector
73
79
  end
74
80
 
81
+ def visit_ArelExtensions_Nodes_Format o, collector
82
+ collector << "TO_CHAR("
83
+ collector = visit o.left, collector
84
+ collector << Arel::Visitors::PostgreSQL::COMMA
85
+
86
+ f = o.iso_format.dup
87
+ Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES.each { |d, r| f.gsub!(d, r) }
88
+ collector = visit Arel::Nodes.build_quoted(f), collector
89
+
90
+ collector << ")"
91
+ collector
92
+ end
93
+
75
94
  def visit_ArelExtensions_Nodes_DateAdd o, collector
76
95
  collector = visit o.left, collector
77
96
  collector << (o.right.value >= 0 ? ' + ' : ' - ')
@@ -83,10 +102,10 @@ module ArelExtensions
83
102
  collector << "DATE_PART('day'"
84
103
  collector << Arel::Visitors::PostgreSQL::COMMA
85
104
  collector = visit o.left, collector
86
- collector << (o.date_type == :date ? '::date' : '::timestamp')
105
+ collector << (o.left_node_type == :date ? '::date' : '::timestamp')
87
106
  collector << " - "
88
107
  collector = visit o.right, collector
89
- collector << (o.date_type == :date ? '::date' : '::timestamp')
108
+ collector << (o.right_node_type == :date ? '::date' : '::timestamp')
90
109
  collector << ")"
91
110
  collector
92
111
  end
@@ -2,6 +2,12 @@ module ArelExtensions
2
2
  module Visitors
3
3
  Arel::Visitors::SQLite.class_eval do
4
4
  Arel::Visitors::SQLite::DATE_MAPPING = {'d' => '%d', 'm' => '%m', 'w' => '%W', 'y' => '%Y', 'wd' => '%w', 'M' => '%M'}
5
+ Arel::Visitors::SQLite::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
6
+ '%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
7
+ '%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W', # day, weekday
8
+ '%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
9
+ '%M' => '%M', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => '' # seconds, subseconds
10
+ }
5
11
 
6
12
  #String functions
7
13
  def visit_ArelExtensions_Nodes_IMatches o, collector # insensitive on ASCII
@@ -33,6 +33,7 @@ require 'arel_extensions/nodes'
33
33
  require 'arel_extensions/comparators'
34
34
  require 'arel_extensions/date_duration'
35
35
  require 'arel_extensions/null_functions'
36
+ require 'arel_extensions/boolean_functions'
36
37
  require 'arel_extensions/math'
37
38
  require 'arel_extensions/math_functions'
38
39
  require 'arel_extensions/string_functions'
@@ -55,6 +56,7 @@ Arel::Nodes::Function.class_eval do
55
56
  include ArelExtensions::DateDuration
56
57
  include ArelExtensions::MathFunctions
57
58
  include ArelExtensions::StringFunctions
59
+ include ArelExtensions::BooleanFunctions
58
60
  end
59
61
 
60
62
  Arel::Nodes::Unary.class_eval do
@@ -69,6 +71,7 @@ Arel::Nodes::Binary.class_eval do
69
71
  include ArelExtensions::Attributes
70
72
  include ArelExtensions::MathFunctions
71
73
  include ArelExtensions::Comparators
74
+ include ArelExtensions::BooleanFunctions
72
75
  end
73
76
 
74
77
  Arel::Nodes::Equality.class_eval do
@@ -57,38 +57,36 @@ module ArelExtensions
57
57
  compile(c.idoes_not_match('%test%')).must_be_like %{LOWER("users"."name") NOT LIKE LOWER('%test%')}
58
58
  end
59
59
 
60
-
61
60
  # Maths
62
61
  # DateDiff
63
62
  it "should diff date col and date" do
64
- compile(@table[:created_at] - Date.new(2016, 3, 31)).must_match %{"users"."created_at" - '2016-03-31'}
63
+ compile(@table[:created_at] - Date.new(2016, 3, 31)).must_match %{TO_DATE("users"."created_at") - TO_DATE('2016-03-31')}
65
64
  end
66
65
 
67
66
  it "should diff date col and datetime col" do
68
- compile(@table[:created_at] - @table[:updated_at]).must_match %{"users"."created_at" - "users"."updated_at"}
67
+ compile(@table[:created_at] - @table[:updated_at]).must_match %{TO_DATE("users"."created_at") - TO_DATE("users"."updated_at")}
69
68
  end
70
69
 
71
70
  it "should diff date col and datetime col with AS" do
72
71
  sql = compile((@table[:updated_at] - @table[:created_at]).as('new_name'))
73
- sql.must_be_like %{("users"."updated_at" - "users"."created_at") AS new_name}
72
+ sql.must_be_like %{(TO_DATE("users"."updated_at") - TO_DATE("users"."created_at")) AS new_name}
74
73
  end
75
74
 
76
75
  it "should diff between time values" do
77
76
  d2 = Time.new(2015,6,1)
78
77
  d1 = DateTime.new(2015,6,2)
79
78
  sql = compile(ArelExtensions::Nodes::DateDiff.new([d1,d2]))
80
- sql.must_match("'2015-06-02' - '2015-06-01'")
79
+ sql.must_match("TO_DATE('2015-06-02') - TO_DATE('2015-06-01')")
81
80
  end
82
81
 
83
82
  it "should diff between time values and time col" do
84
83
  d1 = DateTime.new(2015,6,2)
85
84
  sql = compile(ArelExtensions::Nodes::DateDiff.new([d1, @table[:updated_at]]))
86
- sql.must_match %{'2015-06-02' - "users"."updated_at"}
85
+ sql.must_match %{TO_DATE('2015-06-02') - TO_DATE("users"."updated_at")}
87
86
  end
88
87
 
89
88
  it "should accept operators on dates with numbers" do
90
89
  c = @table[:created_at]
91
- # u = @table[:updated_at]
92
90
  compile(c - 42).must_be_like %{DATE_SUB("users"."created_at", 42)}
93
91
  compile(c - @table[:id]).must_be_like %{DATE_SUB("users"."created_at", "users"."id")}
94
92
  end
@@ -144,6 +144,13 @@ module ArelExtensions
144
144
  compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
145
145
  compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
146
146
  compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
147
+ end
148
+
149
+ it "should manage complex formulas" do
150
+ c = @table[:name]
151
+ compile(
152
+ (c.length / 42).round(2).floor > (@table[:updated_at] - Date.new(2000, 3, 31)).abs.ceil
153
+ ).must_be_like %{FLOOR(ROUND(LENGTH("users"."name") / 42, 2)) > CEIL(ABS(DATEDIFF("users"."updated_at", '2000-03-31')))}
147
154
  end
148
155
 
149
156
  end
@@ -64,9 +64,9 @@ module ArelExtensions
64
64
  end
65
65
 
66
66
  def setup
67
- d = Date.new(2016,05,23)
67
+ d = Date.new(2016, 5, 23)
68
68
  setup_db
69
- u = User.create :age => 5, :name => "Lucas", :created_at => d, :score => 20.16
69
+ u = User.create :age => 5, :name => "Lucas", :created_at => d, :score => 20.16, :updated_at => Time.utc(2014, 3, 3, 12, 42)
70
70
  @lucas = User.where(:id => u.id)
71
71
  u = User.create :age => 15, :name => "Sophie", :created_at => d, :score => 20.16
72
72
  @sophie = User.where(:id => u.id)
@@ -87,6 +87,7 @@ module ArelExtensions
87
87
  @name = User.arel_table[:name]
88
88
  @score = User.arel_table[:score]
89
89
  @created_at = User.arel_table[:created_at]
90
+ @updated_at = User.arel_table[:updated_at]
90
91
  @comments = User.arel_table[:comments]
91
92
  @price = Product.arel_table[:price]
92
93
  end
@@ -174,7 +175,7 @@ module ArelExtensions
174
175
  end
175
176
 
176
177
  def test_string_comparators
177
- skip "Oracle can't use math operators to compare strings, any function to do that?" if @env_db == 'oracle'
178
+ skip "Oracle can't use math operators to compare strings" if @env_db == 'oracle' # use GREATEST ?
178
179
  if @env_db == 'postgresql' # may return real boolean
179
180
  assert t(@neg, @name >= 'Mest') == true || t(@neg, @name >= 'Mest') == 't' # depends of ar version
180
181
  assert t(@neg, @name <= (@name + 'Z')) == true || t(@neg, @name <= (@name + 'Z')) == 't'
@@ -218,6 +219,11 @@ module ArelExtensions
218
219
  assert_equal "", t(@myung, @name.rtrim(@name))
219
220
  end
220
221
 
222
+ def test_format
223
+ assert_equal '2016-05-23', t(@lucas, @created_at.format('%Y-%m-%d'))
224
+ assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S'))
225
+ end
226
+
221
227
  def test_coalesce
222
228
  if @env_db == 'postgresql'
223
229
  assert_equal 100, t(@test, @age.coalesce(100))
@@ -241,7 +247,7 @@ module ArelExtensions
241
247
  end
242
248
 
243
249
  def test_date_comparator
244
- d = Date.new(2016,05,23)
250
+ d = Date.new(2016, 5, 23)
245
251
  assert_equal 0, User.where(@created_at < d).count
246
252
  assert_equal 8, User.where(@created_at >= d).count
247
253
  end
@@ -261,6 +267,11 @@ module ArelExtensions
261
267
  assert_equal 0, User.where(@created_at.day.eq("05")).count
262
268
  end
263
269
 
270
+ def test_cast_types
271
+ skip "not implemented yet"
272
+ assert_equal true, t(@arthur, @score =~ /22/)
273
+ end
274
+
264
275
  def test_is_null
265
276
  assert_equal "Test", User.where(@age.is_null).select(@name).first.name
266
277
  end
@@ -286,14 +297,16 @@ module ArelExtensions
286
297
  end
287
298
 
288
299
 
289
- def test_math_moins
290
- d = Date.new(2016,05,20)
300
+ def test_math_minus
301
+ d = Date.new(2016, 5, 20)
291
302
  #Datediff
292
- assert_equal 8, User.where((@created_at - User.arel_table[:created_at]).eq(0)).count
293
- assert_equal 3, @laure.select((User.arel_table[:created_at] - d).as("res")).first.res.abs.to_i
303
+ assert_equal 8, User.where((@created_at - @created_at).eq(0)).count
304
+ assert_equal 3, @laure.select((@created_at - d).as("res")).first.res.abs.to_i
294
305
  #Substraction
295
306
  assert_equal 0, User.where((@age - 10).eq(50)).count
296
307
  assert_equal 0, User.where((@age - "10").eq(50)).count
308
+ # assert_equal 0, User.where((@age - 9.5).eq(50.5)).count # should work: TODO
309
+ assert_equal 0, User.where((@age - "9.5").eq(50.5)).count
297
310
  end
298
311
 
299
312
  def test_wday
@@ -302,6 +315,14 @@ module ArelExtensions
302
315
  assert_equal 0, User.select(d.wday).as("res").first.to_i
303
316
  end
304
317
 
318
+ # Boolean functions
319
+ def test_boolean_functions
320
+ assert_equal 1, @laure.where(
321
+ (@score.round > 19).⋀(@score.round < 21).⋁(@score.round(1) >= 20.1)
322
+ ).count
323
+ end
324
+
325
+
305
326
  end
306
327
  end
307
328
  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: 0.8.5
4
+ version: 0.8.6
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: 2016-09-04 00:00:00.000000000 Z
13
+ date: 2016-09-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: arel
@@ -102,6 +102,7 @@ files:
102
102
  - init/sqlite.sql
103
103
  - lib/arel_extensions.rb
104
104
  - lib/arel_extensions/attributes.rb
105
+ - lib/arel_extensions/boolean_functions.rb
105
106
  - lib/arel_extensions/comparators.rb
106
107
  - lib/arel_extensions/date_duration.rb
107
108
  - lib/arel_extensions/insert_manager.rb
@@ -128,7 +129,6 @@ files:
128
129
  - lib/arel_extensions/nodes/round.rb
129
130
  - lib/arel_extensions/nodes/rtrim.rb
130
131
  - lib/arel_extensions/nodes/soundex.rb
131
- - lib/arel_extensions/nodes/sum.rb
132
132
  - lib/arel_extensions/nodes/trim.rb
133
133
  - lib/arel_extensions/nodes/wday.rb
134
134
  - lib/arel_extensions/null_functions.rb
@@ -1,23 +0,0 @@
1
- module ArelExtensions
2
- module Nodes
3
- class Sum < Arel::Nodes::Function
4
-
5
-
6
- def initialize other, aliaz = nil
7
- tab = Array.new
8
- tab << other
9
- super(tab, aliaz)
10
- end
11
-
12
- def expr
13
- @expressions.first
14
- end
15
-
16
-
17
- def as other
18
- Arel::Nodes::As.new self, Arel::Nodes::SqlLiteral.new(other)
19
- end
20
-
21
- end
22
- end
23
- end