arel_extensions 0.8.5 → 0.8.6

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.
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