arel_extensions 1.3.5 → 2.0.0.rc3

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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -1
  3. data/.gitignore +6 -7
  4. data/.rubocop.yml +3 -67
  5. data/.travis/oracle/download.js +152 -0
  6. data/.travis/oracle/download.sh +30 -0
  7. data/.travis/oracle/download_ojdbc.js +116 -0
  8. data/.travis/oracle/install.sh +34 -0
  9. data/.travis/setup_accounts.sh +9 -0
  10. data/.travis/sqlite3/extension-functions.sh +6 -0
  11. data/.travis.yml +223 -0
  12. data/Gemfile +21 -16
  13. data/README.md +13 -125
  14. data/Rakefile +30 -41
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -51
  17. data/arel_extensions.gemspec +14 -14
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +10 -10
  20. data/gemfiles/rails4.gemfile +14 -14
  21. data/gemfiles/rails5_0.gemfile +14 -14
  22. data/gemfiles/rails5_1_4.gemfile +14 -14
  23. data/gemfiles/rails5_2.gemfile +14 -16
  24. data/init/mssql.sql +4 -4
  25. data/init/mysql.sql +38 -38
  26. data/init/oracle.sql +0 -0
  27. data/init/postgresql.sql +21 -21
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -4
  30. data/lib/arel_extensions/boolean_functions.rb +14 -53
  31. data/lib/arel_extensions/common_sql_functions.rb +17 -16
  32. data/lib/arel_extensions/comparators.rb +28 -27
  33. data/lib/arel_extensions/date_duration.rb +14 -13
  34. data/lib/arel_extensions/insert_manager.rb +15 -18
  35. data/lib/arel_extensions/math.rb +53 -55
  36. data/lib/arel_extensions/math_functions.rb +39 -46
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +2 -1
  39. data/lib/arel_extensions/nodes/case.rb +16 -16
  40. data/lib/arel_extensions/nodes/cast.rb +8 -10
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +4 -3
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +18 -9
  45. data/lib/arel_extensions/nodes/date_diff.rb +26 -42
  46. data/lib/arel_extensions/nodes/duration.rb +3 -0
  47. data/lib/arel_extensions/nodes/find_in_set.rb +1 -0
  48. data/lib/arel_extensions/nodes/floor.rb +1 -1
  49. data/lib/arel_extensions/nodes/format.rb +8 -35
  50. data/lib/arel_extensions/nodes/formatted_number.rb +23 -22
  51. data/lib/arel_extensions/nodes/function.rb +37 -42
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  53. data/lib/arel_extensions/nodes/json.rb +39 -48
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  56. data/lib/arel_extensions/nodes/locate.rb +2 -1
  57. data/lib/arel_extensions/nodes/log10.rb +2 -1
  58. data/lib/arel_extensions/nodes/matches.rb +7 -5
  59. data/lib/arel_extensions/nodes/md5.rb +1 -0
  60. data/lib/arel_extensions/nodes/power.rb +5 -5
  61. data/lib/arel_extensions/nodes/rand.rb +1 -0
  62. data/lib/arel_extensions/nodes/repeat.rb +5 -3
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +6 -5
  65. data/lib/arel_extensions/nodes/soundex.rb +15 -15
  66. data/lib/arel_extensions/nodes/std.rb +21 -18
  67. data/lib/arel_extensions/nodes/substring.rb +16 -8
  68. data/lib/arel_extensions/nodes/then.rb +1 -1
  69. data/lib/arel_extensions/nodes/trim.rb +6 -4
  70. data/lib/arel_extensions/nodes/union.rb +8 -5
  71. data/lib/arel_extensions/nodes/union_all.rb +7 -4
  72. data/lib/arel_extensions/nodes/wday.rb +4 -0
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +7 -5
  75. data/lib/arel_extensions/predications.rb +43 -44
  76. data/lib/arel_extensions/railtie.rb +5 -5
  77. data/lib/arel_extensions/set_functions.rb +7 -5
  78. data/lib/arel_extensions/string_functions.rb +29 -58
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -1
  81. data/lib/arel_extensions/visitors/ibm_db.rb +31 -24
  82. data/lib/arel_extensions/visitors/mssql.rb +181 -279
  83. data/lib/arel_extensions/visitors/mysql.rb +210 -280
  84. data/lib/arel_extensions/visitors/oracle.rb +180 -201
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -252
  87. data/lib/arel_extensions/visitors/sqlite.rb +126 -140
  88. data/lib/arel_extensions/visitors/to_sql.rb +237 -272
  89. data/lib/arel_extensions/visitors.rb +59 -75
  90. data/lib/arel_extensions.rb +31 -159
  91. data/test/database.yml +7 -15
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +116 -105
  94. data/test/support/fake_record.rb +3 -3
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +11 -11
  97. data/test/visitors/test_bulk_insert_sqlite.rb +13 -12
  98. data/test/visitors/test_bulk_insert_to_sql.rb +13 -11
  99. data/test/visitors/test_oracle.rb +55 -55
  100. data/test/visitors/test_to_sql.rb +226 -419
  101. data/test/with_ar/all_agnostic_test.rb +361 -578
  102. data/test/with_ar/insert_agnostic_test.rb +21 -27
  103. data/test/with_ar/test_bulk_sqlite.rb +16 -17
  104. data/test/with_ar/test_math_sqlite.rb +26 -26
  105. data/test/with_ar/test_string_mysql.rb +33 -31
  106. data/test/with_ar/test_string_sqlite.rb +34 -30
  107. metadata +22 -29
  108. data/.github/workflows/ruby.yml +0 -341
  109. data/gemfiles/rails6.gemfile +0 -30
  110. data/gemfiles/rails6_1.gemfile +0 -30
  111. data/gemfiles/rails7.gemfile +0 -23
  112. data/gemspecs/arel_extensions-v1.gemspec +0 -28
  113. data/gemspecs/arel_extensions-v2.gemspec +0 -28
  114. data/generate_gems.sh +0 -15
  115. data/lib/arel_extensions/aliases.rb +0 -14
  116. data/lib/arel_extensions/helpers.rb +0 -51
  117. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  118. data/lib/arel_extensions/nodes/sum.rb +0 -7
  119. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  120. data/test/arelx_test_helper.rb +0 -71
  121. data/version_v1.rb +0 -3
  122. data/version_v2.rb +0 -3
@@ -1,49 +1,49 @@
1
1
  module ArelExtensions
2
2
  class CommonSqlFunctions
3
+
3
4
  def initialize(cnx)
4
5
  @cnx = cnx
5
6
  if cnx && cnx.adapter_name =~ /sqlite/i && !$load_extension_disabled
6
7
  begin
7
8
  db = cnx.raw_connection
8
9
  db.enable_load_extension(1)
9
- db.load_extension('/usr/lib/sqlite3/pcre.so')
10
- db.load_extension('/usr/lib/sqlite3/extension-functions.so')
10
+ db.load_extension("/usr/lib/sqlite3/pcre.so")
11
+ db.load_extension("/usr/lib/sqlite3/extension-functions.so")
11
12
  db.enable_load_extension(0)
12
13
  rescue => e
13
14
  $load_extension_disabled = true
14
- puts "cannot load extensions #{e.inspect}"
15
+ puts "can not load extensions #{e.inspect}"
15
16
  end
16
17
  end
17
18
  end
18
19
 
19
20
  def add_sqlite_functions
20
21
  db = @cnx.raw_connection
21
- db.create_function('find_in_set', 1) do |func, val, list|
22
+ db.create_function("find_in_set", 1) do |func, val, list|
22
23
  case list
23
24
  when String
24
25
  i = list.split(',').index(val.to_s)
25
- func.result = i ? (i + 1) : 0
26
+ func.result = i ? (i+1) : 0
26
27
  when NilClass
27
28
  func.result = nil
28
29
  else
29
30
  i = list.to_s.split(',').index(val.to_s)
30
- func.result = i ? (i + 1) : 0
31
+ func.result = i ? (i+1) : 0
31
32
  end
32
33
  end
33
- db.create_function('instr', 1) do |func, value1, value2|
34
+ db.create_function("instr", 1) do |func, value1, value2|
34
35
  i = value1.to_s.index(value2.to_s)
35
- func.result = i ? (i + 1) : 0
36
- end rescue 'function instr already here (>= 3.8.5)'
36
+ func.result = i ? (i+1) : 0
37
+ end rescue "function instr already here (>= 3.8.5)"
37
38
  end
38
39
 
39
40
  def add_sql_functions(env_db = nil)
40
41
  env_db ||= @cnx.adapter_name
41
- env_db = 'mysql' if /mysql/i.match?(env_db)
42
- if /sqlite/i.match?(env_db)
42
+ if env_db =~ /sqlite/i
43
43
  begin
44
44
  add_sqlite_functions
45
45
  rescue => e
46
- puts "cannot add sqlite functions #{e.inspect}"
46
+ puts "can not add sqlite functions #{e.inspect}"
47
47
  end
48
48
  end
49
49
  if File.exist?("init/#{env_db}.sql")
@@ -52,14 +52,15 @@ module ArelExtensions
52
52
  sql.split(/^GO\s*$/).each {|str|
53
53
  @cnx.execute(str.strip) unless str.blank?
54
54
  }
55
- elsif env_db == 'mysql'
56
- sql.split('$$')[1..-2].each { |str|
57
- @cnx.execute(str.strip) unless str.strip.blank?
58
- }
55
+ elsif env_db == 'mysql'
56
+ sql.split("$$")[1..-2].each { |str|
57
+ @cnx.execute(str.strip) unless str.strip.blank?
58
+ }
59
59
  else
60
60
  @cnx.execute(sql) unless sql.blank?
61
61
  end
62
62
  end
63
63
  end
64
+
64
65
  end
65
66
  end
@@ -1,58 +1,59 @@
1
1
  module ArelExtensions
2
2
  module Comparators
3
+
3
4
  def >(other)
4
- Arel::Nodes::GreaterThan.new self, Arel.quoted(other, self)
5
+ Arel::Nodes::GreaterThan.new self, Arel::Nodes.build_quoted(other, self)
5
6
  end
6
7
 
7
8
  def >=(other)
8
- Arel::Nodes::GreaterThanOrEqual.new self, Arel.quoted(other, self)
9
+ Arel::Nodes::GreaterThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
9
10
  end
10
11
 
11
12
  def <(other)
12
- Arel::Nodes::LessThan.new self, Arel.quoted(other, self)
13
+ Arel::Nodes::LessThan.new self, Arel::Nodes.build_quoted(other, self)
13
14
  end
14
15
 
15
16
  def <=(other)
16
- Arel::Nodes::LessThanOrEqual.new self, Arel.quoted(other, self)
17
+ Arel::Nodes::LessThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
17
18
  end
18
19
 
19
- # REGEXP function
20
- # Pattern matching using regular expressions
20
+
21
+ #REGEXP function
22
+ #Pattern matching using regular expressions
21
23
  def =~(other)
22
- # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
23
- # if arg == :string || arg == :text
24
- Arel::Nodes::Regexp.new self, convert_regexp(other)
25
- # end
24
+ # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
25
+ # if arg == :string || arg == :text
26
+ Arel::Nodes::Regexp.new self, convert_regexp(other)
27
+ # end
26
28
  end
27
29
 
28
- # NOT_REGEXP function
29
- # Negation of Regexp
30
+ #NOT_REGEXP function
31
+ #Negation of Regexp
30
32
  def !~(other)
31
- # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
32
- # if arg == :string || arg == :text
33
- Arel::Nodes::NotRegexp.new self, convert_regexp(other)
34
- # end
33
+ # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
34
+ # if arg == :string || arg == :text
35
+ Arel::Nodes::NotRegexp.new self, convert_regexp(other)
36
+ # end
35
37
  end
36
38
 
37
39
  private
38
-
39
- # Function used for not_regexp.
40
+ #Function use for not_regexp
40
41
  def convert_regexp(other)
41
42
  case other
42
43
  when String
43
- # Do nothing.
44
+ #Do nothing
44
45
  when Regexp
45
- other = other.source.gsub('\A', '^')
46
- other.gsub!('\z', '$')
47
- other.gsub!('\Z', '$')
48
- other.gsub!('\d', '[0-9]')
49
- other.gsub!('\D', '[^0-9]')
50
- other.gsub!('\w', '[0-9A-Za-z]')
51
- other.gsub!('\W', '[^A-Za-z0-9_]')
46
+ other = other.source.gsub('\A','^')
47
+ other.gsub!('\Z','$')
48
+ other.gsub!('\d','[0-9]')
49
+ other.gsub!('\D','[^0-9]')
50
+ other.gsub!('\w','[0-9A-Za-z]')
51
+ other.gsub!('\W','[^A-Za-z0-9_]')
52
52
  else
53
53
  raise(ArgumentError)
54
54
  end
55
- Arel.quoted(other, self)
55
+ Arel::Nodes.build_quoted(other, self)
56
56
  end
57
+
57
58
  end
58
59
  end
@@ -4,24 +4,24 @@ require 'arel_extensions/nodes/wday'
4
4
 
5
5
  module ArelExtensions
6
6
  module DateDuration
7
- # function returns the year (as a number) given a date value.
7
+ #function returns the year (as a number) given a date value.
8
8
  def year
9
- ArelExtensions::Nodes::Duration.new 'y', self
9
+ ArelExtensions::Nodes::Duration.new "y", self
10
10
  end
11
11
 
12
- # function returns the month (as a number) given a date value.
12
+ #function returns the month (as a number) given a date value.
13
13
  def month
14
- ArelExtensions::Nodes::Duration.new 'm', self
14
+ ArelExtensions::Nodes::Duration.new "m", self
15
15
  end
16
16
 
17
- # function returns the week (as a number) given a date value.
17
+ #function returns the week (as a number) given a date value.
18
18
  def week
19
- ArelExtensions::Nodes::Duration.new 'w', self
19
+ ArelExtensions::Nodes::Duration.new "w", self
20
20
  end
21
21
 
22
- # function returns the month (as a number) given a date value.
22
+ #function returns the month (as a number) given a date value.
23
23
  def day
24
- ArelExtensions::Nodes::Duration.new 'd', self
24
+ ArelExtensions::Nodes::Duration.new "d", self
25
25
  end
26
26
 
27
27
  def wday
@@ -29,19 +29,20 @@ module ArelExtensions
29
29
  end
30
30
 
31
31
  def hour
32
- ArelExtensions::Nodes::Duration.new 'h', self
32
+ ArelExtensions::Nodes::Duration.new "h", self
33
33
  end
34
34
 
35
35
  def minute
36
- ArelExtensions::Nodes::Duration.new 'mn', self
36
+ ArelExtensions::Nodes::Duration.new "mn", self
37
37
  end
38
38
 
39
39
  def second
40
- ArelExtensions::Nodes::Duration.new 's', self
40
+ ArelExtensions::Nodes::Duration.new "s", self
41
41
  end
42
42
 
43
- def format(tpl, time_zone = nil)
44
- ArelExtensions::Nodes::Format.new [self, tpl, time_zone]
43
+ def format(tpl)
44
+ ArelExtensions::Nodes::Format.new [self, tpl]
45
45
  end
46
+
46
47
  end
47
48
  end
@@ -2,35 +2,32 @@ require 'arel'
2
2
 
3
3
  module ArelExtensions
4
4
  module InsertManager
5
+
5
6
  def bulk_insert(cols, data)
6
- raise ArgumentError, 'cols must be present' if cols.blank?
7
- columns =
8
- case cols.first
7
+ case cols.first
8
+ when String, Symbol
9
+ cols.each { |c|
10
+ @ast.columns << @ast.relation[c]
11
+ }
9
12
  when Array
10
- case cols.first.first
11
- when Arel::Attributes::Attribute
12
- cols
13
- when String, Symbol
14
- cols.map {|c| [@ast.relation[c.first]] }
15
- else
16
- raise ArgumentError, "cols has an invalid type: #{cols.first.first.class}"
13
+ if String === cols.first.first
14
+ @ast.columns = cols.map {|c| [@ast.relation[c.first]] }
15
+ elsif Arel::Attributes::Attribute == cols.first.first
16
+ @ast.columns = cols
17
17
  end
18
- when String, Symbol
19
- cols.map { |c| @ast.relation[c] }
20
- else
21
- raise ArgumentError, "cols has an invalid type: #{cols.first.class}"
22
- end
23
- self.values = BulkValues.new(columns, data)
24
- @ast.columns = columns
18
+ when NilClass
19
+ @ast.columns = @ast.relation.columns
20
+ end
21
+ self.values = BulkValues.new(@ast.columns, data)
25
22
  end
26
23
 
27
24
  class BulkValues < Arel::Nodes::Node
28
25
  attr_accessor :left, :cols
29
-
30
26
  def initialize(cols, values)
31
27
  @left = values
32
28
  @cols = cols
33
29
  end
34
30
  end
31
+
35
32
  end
36
33
  end
@@ -11,49 +11,48 @@ require 'arel_extensions/nodes/union_all'
11
11
 
12
12
  module ArelExtensions
13
13
  module Math
14
- # function + between
15
- # String and others (convert in string) allows you to concatenate 2 or more strings together.
16
- # Date and integer adds or subtracts a specified time interval from a date.
14
+ #function + between
15
+ #String and others (convert in string) allows you to concatenate 2 or more strings together.
16
+ #Date and integer adds or subtracts a specified time interval from a date.
17
17
  def +(other)
18
18
  case self
19
- when Arel::Nodes::Quoted
20
- self.concat(other)
21
- when Arel::Nodes::Grouping
22
- if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
23
- self.concat(other)
24
- else
25
- Arel.grouping(Arel::Nodes::Addition.new self, other)
26
- end
27
- when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
28
- case self.return_type
19
+ when Arel::Nodes::Quoted
20
+ return self.concat(other)
21
+ when Arel::Nodes::Grouping
22
+ if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
23
+ return self.concat(other)
24
+ else
25
+ return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
26
+ end
27
+ when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
28
+ return case self.return_type
29
29
  when :string, :text
30
30
  self.concat(other)
31
31
  when :integer, :decimal, :float, :number, :int
32
- Arel.grouping(Arel::Nodes::Addition.new self, other)
32
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
33
33
  when :date, :datetime
34
34
  ArelExtensions::Nodes::DateAdd.new [self, other]
35
35
  else
36
36
  self.concat(other)
37
37
  end
38
- when Arel::Nodes::Function
39
- Arel.grouping(Arel::Nodes::Addition.new self, other)
38
+ when Arel::Nodes::Function
39
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
40
40
  else
41
- col =
42
- if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
43
- self.type_caster
44
- else
45
- Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
46
- end
47
- if !col # if the column doesn't exist in the database
48
- Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
41
+ begin
42
+ col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
43
+ rescue Exception
44
+ col = nil
45
+ end
46
+ if (!col) #if the column doesn't exist in the database
47
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other))
49
48
  else
50
49
  arg = col.type
51
- if arg == :integer || !arg
50
+ if arg == :integer || (!arg)
52
51
  other = other.to_i if other.is_a?(String)
53
- Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
52
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
54
53
  elsif arg == :decimal || arg == :float
55
54
  other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
56
- Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
55
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
57
56
  elsif arg == :datetime || arg == :date
58
57
  ArelExtensions::Nodes::DateAdd.new [self, other]
59
58
  elsif arg == :string || arg == :text
@@ -63,50 +62,48 @@ module ArelExtensions
63
62
  end
64
63
  end
65
64
 
66
- # function returns the time between two dates
67
- # function returns the substraction between two ints
65
+ #function returns the time between two dates
66
+ #function returns the substraction between two ints
68
67
  def -(other)
69
68
  case self
70
69
  when Arel::Nodes::Grouping
71
70
  if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
72
- Arel.grouping(ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)])
71
+ Arel::Nodes::Grouping.new(ArelExtensions::Nodes::DateSub.new [self, other])
73
72
  else
74
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
73
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
75
74
  end
76
75
  when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
77
76
  case self.return_type
78
77
  when :string, :text # ???
79
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other))) # ??
78
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) # ??
80
79
  when :integer, :decimal, :float, :number
81
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
80
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
82
81
  when :date, :datetime
83
- ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)]
82
+ ArelExtensions::Nodes::DateSub.new [self, other]
84
83
  else
85
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
84
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
86
85
  end
87
86
  when Arel::Nodes::Function
88
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
87
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
89
88
  else
90
- col =
91
- if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
92
- self.type_caster
93
- else
94
- Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
95
- end
96
- if !col # if the column doesn't exist in the database
97
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
89
+ begin
90
+ col = Arel::Table.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s]
91
+ rescue Exception
92
+ col = nil
93
+ end
94
+ if (!col) #if the column doesn't exist in the database
95
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
98
96
  else
99
97
  arg = col.type
100
98
  if (arg == :date || arg == :datetime)
101
99
  case other
102
100
  when Arel::Attributes::Attribute
103
- col2 =
104
- if other.is_a?(Arel::Attribute) && other.respond_to?(:type_caster) && other.able_to_type_cast?
105
- other.type_caster
106
- else
107
- Arel.column_of(other.relation.table_name, other.name.to_s) if other.respond_to?(:relation)
108
- end
109
- if !col2 # if the column doesn't exist in the database
101
+ begin
102
+ col2 = Arel::Table.engine.connection.schema_cache.columns_hash(other.relation.table_name)[other.name.to_s]
103
+ rescue Exception
104
+ col2 = nil
105
+ end
106
+ if (!col2) #if the column doesn't exist in the database
110
107
  ArelExtensions::Nodes::DateSub.new [self, other]
111
108
  else
112
109
  arg2 = col2.type
@@ -118,7 +115,7 @@ module ArelExtensions
118
115
  end
119
116
  when Arel::Nodes::Node, DateTime, Time, String, Date
120
117
  ArelExtensions::Nodes::DateDiff.new [self, other]
121
- when ArelExtensions::Nodes::Duration, Integer
118
+ when ArelExtensions::Nodes::Duration, Integer
122
119
  ArelExtensions::Nodes::DateSub.new [self, other]
123
120
  else # ActiveSupport::Duration
124
121
  ArelExtensions::Nodes::DateAdd.new [self, -other]
@@ -126,15 +123,16 @@ module ArelExtensions
126
123
  else
127
124
  case other
128
125
  when Integer, Float, BigDecimal
129
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other.to_s)))
126
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, Arel.sql(other.to_s)))
130
127
  when String
131
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
128
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
132
129
  else
133
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
130
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
134
131
  end
135
132
  end
136
133
  end
137
134
  end
138
135
  end
136
+
139
137
  end
140
138
  end
@@ -7,15 +7,15 @@ require 'arel_extensions/nodes/formatted_number'
7
7
  require 'arel_extensions/nodes/log10'
8
8
  require 'arel_extensions/nodes/power'
9
9
  require 'arel_extensions/nodes/std'
10
- require 'arel_extensions/nodes/sum'
11
10
 
12
11
  module ArelExtensions
13
12
  module MathFunctions
13
+
14
14
  # Arel does not handle Decimal literal properly
15
15
  def * other
16
16
  case other
17
17
  when Float, BigDecimal
18
- super(Arel.quoted(other))
18
+ super(Arel::Nodes.build_quoted(other))
19
19
  else
20
20
  super(other)
21
21
  end
@@ -25,7 +25,7 @@ module ArelExtensions
25
25
  def / other
26
26
  case other
27
27
  when Float, BigDecimal
28
- super(Arel.quoted(other))
28
+ super(Arel::Nodes.build_quoted(other))
29
29
  else
30
30
  super(other)
31
31
  end
@@ -33,86 +33,79 @@ module ArelExtensions
33
33
 
34
34
  # Abs function returns the absolute value of a number passed as argument #
35
35
  def abs
36
- ArelExtensions::Nodes::Abs.new [self]
36
+ ArelExtensions::Nodes::Abs.new [self]
37
37
  end
38
38
 
39
39
  # will rounded up any positive or negative decimal value within the function upwards #
40
40
  def ceil
41
- ArelExtensions::Nodes::Ceil.new [self]
41
+ ArelExtensions::Nodes::Ceil.new [self]
42
42
  end
43
43
 
44
44
  # function rounded up any positive or negative decimal value down to the next least integer
45
45
  def floor
46
- ArelExtensions::Nodes::Floor.new [self]
46
+ ArelExtensions::Nodes::Floor.new [self]
47
47
  end
48
48
 
49
- # function gives the base 10 log
49
+ # function gives the base 10 log
50
50
  def log10
51
- ArelExtensions::Nodes::Log10.new [self]
51
+ ArelExtensions::Nodes::Log10.new [self]
52
52
  end
53
53
 
54
54
  # function gives the power of a number
55
55
  def pow exposant = 0
56
- ArelExtensions::Nodes::Power.new [self, exposant]
56
+ ArelExtensions::Nodes::Power.new [self,exposant]
57
57
  end
58
58
 
59
59
  # function gives the power of a number
60
60
  def power exposant = 0
61
- ArelExtensions::Nodes::Power.new [self, exposant]
61
+ ArelExtensions::Nodes::Power.new [self,exposant]
62
62
  end
63
63
 
64
64
  # Aggregate Functions
65
- def std opts = {unbiased: true}
66
- ArelExtensions::Nodes::Std.new self, **opts
67
- end
68
-
69
- def variance opts = {unbiased: true}
70
- ArelExtensions::Nodes::Variance.new self, **opts
65
+ def std unbiased = true
66
+ ArelExtensions::Nodes::Std.new [self,unbiased]
71
67
  end
72
68
 
73
- def sum opts = {unbiased: true}
74
- if Gem::Version.new(Arel::VERSION) >= Gem::Version.new('9.0.0')
75
- Arel::Nodes::Sum.new [self]
76
- else
77
- ArelExtensions::Nodes::Sum.new self, **opts
78
- end
69
+ def variance unbiased = true
70
+ ArelExtensions::Nodes::Variance.new [self,unbiased]
79
71
  end
80
72
 
81
- # function that can be invoked to produce random numbers between 0 and 1
82
- # def rand seed = nil
83
- # ArelExtensions::Nodes::Rand.new [seed]
84
- # end
85
- alias_method(:random, :rand) rescue nil
73
+ #function that can be invoked to produce random numbers between 0 and 1
74
+ # def rand seed = nil
75
+ # ArelExtensions::Nodes::Rand.new [seed]
76
+ # end
77
+ alias_method :random, :rand
86
78
 
87
- # function is used to round a numeric field to the number of decimals specified
79
+ #function is used to round a numeric field to the number of decimals specified
88
80
  def round precision = nil
89
- if precision
90
- ArelExtensions::Nodes::Round.new [self, precision]
91
- else
92
- ArelExtensions::Nodes::Round.new [self]
93
- end
81
+ if precision
82
+ ArelExtensions::Nodes::Round.new [self, precision]
83
+ else
84
+ ArelExtensions::Nodes::Round.new [self]
85
+ end
94
86
  end
95
87
 
96
88
  # function returning a number at a specific format
97
- def format_number format_string, locale = nil
89
+ def format_number format_string, locale=nil
98
90
  begin
99
- sprintf(format_string, 0) # this line is to get the right error message if the format_string is not correct
91
+ sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
100
92
  m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
101
93
  opts = {
102
- prefix: m[1],
103
- flags: m[2].split(//).uniq.join,
104
- width: m[3].to_i,
105
- precision: m[4] != '' ? m[4].to_i : 6,
106
- type: m[5],
107
- suffix: m[6],
108
- locale: locale,
109
- original_string: format_string
94
+ :prefix => m[1],
95
+ :flags => m[2].split(//).uniq.join,
96
+ :width => m[3].to_i,
97
+ :precision => m[4] != '' ? m[4].to_i : 6,
98
+ :type => m[5],
99
+ :suffix => m[6],
100
+ :locale => locale,
101
+ :original_string => format_string
110
102
  }
111
- # opts = {locale: 'fr_FR', type: "e"/"f"/"d", prefix: "$ ", suffix: " %", flags: " +-#0", width: 5, precision: 6}
112
- ArelExtensions::Nodes::FormattedNumber.new [self, opts]
103
+ # opts = {:locale => 'fr_FR', :type => "e"/"f"/"d", :prefix => "$ ", :suffix => " %", :flags => " +-#0", :width => 5, :precision => 6}
104
+ ArelExtensions::Nodes::FormattedNumber.new [self,opts]
113
105
  rescue Exception
114
- Arel.quoted('Wrong Format')
106
+ Arel::Nodes.build_quoted('Wrong Format')
115
107
  end
116
108
  end
109
+
117
110
  end
118
111
  end
@@ -2,6 +2,7 @@ module ArelExtensions
2
2
  module Nodes
3
3
  class Abs < Function
4
4
  RETURN_TYPE = :number
5
+
5
6
  end
6
7
  end
7
8
  end
@@ -16,8 +16,9 @@ module ArelExtensions
16
16
  RETURN_TYPE = :boolean
17
17
 
18
18
  def initialize expr
19
- super expr.first
19
+ super expr.first
20
20
  end
21
21
  end
22
+
22
23
  end
23
24
  end