arel_extensions 1.6.0 → 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 (146) 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 +28 -2
  13. data/README.md +91 -258
  14. data/Rakefile +30 -48
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +14 -13
  18. data/functions.html +3 -3
  19. data/gemfiles/rails3.gemfile +20 -0
  20. data/gemfiles/rails4.gemfile +29 -0
  21. data/gemfiles/rails5_0.gemfile +29 -0
  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 +25 -24
  28. data/init/sqlite.sql +0 -0
  29. data/lib/arel_extensions/attributes.rb +3 -7
  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 -29
  33. data/lib/arel_extensions/date_duration.rb +13 -17
  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 +19 -20
  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 -46
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  53. data/lib/arel_extensions/nodes/json.rb +39 -52
  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 +8 -6
  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 +5 -19
  75. data/lib/arel_extensions/predications.rb +44 -45
  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 +35 -91
  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 +194 -440
  83. data/lib/arel_extensions/visitors/mysql.rb +212 -368
  84. data/lib/arel_extensions/visitors/oracle.rb +179 -236
  85. data/lib/arel_extensions/visitors/oracle12.rb +31 -18
  86. data/lib/arel_extensions/visitors/postgresql.rb +173 -271
  87. data/lib/arel_extensions/visitors/sqlite.rb +127 -157
  88. data/lib/arel_extensions/visitors/to_sql.rb +238 -300
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +31 -235
  91. data/test/database.yml +10 -20
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +118 -121
  94. data/test/support/fake_record.rb +3 -11
  95. data/test/test_comparators.rb +17 -14
  96. data/test/visitors/test_bulk_insert_oracle.rb +12 -12
  97. data/test/visitors/test_bulk_insert_sqlite.rb +14 -13
  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 +370 -773
  102. data/test/with_ar/insert_agnostic_test.rb +22 -28
  103. data/test/with_ar/test_bulk_sqlite.rb +17 -18
  104. data/test/with_ar/test_math_sqlite.rb +27 -27
  105. data/test/with_ar/test_string_mysql.rb +34 -32
  106. data/test/with_ar/test_string_sqlite.rb +35 -31
  107. metadata +38 -52
  108. data/.github/workflows/publish.yml +0 -30
  109. data/.github/workflows/release.yml +0 -30
  110. data/.github/workflows/ruby.yml +0 -452
  111. data/CONTRIBUTING.md +0 -102
  112. data/Makefile +0 -18
  113. data/NEWS.md +0 -116
  114. data/bin/build +0 -15
  115. data/bin/publish +0 -8
  116. data/dev/arelx.dockerfile +0 -41
  117. data/dev/compose.yaml +0 -69
  118. data/dev/postgres.dockerfile +0 -5
  119. data/dev/rbenv +0 -189
  120. data/gemfiles/rails5.gemfile +0 -29
  121. data/gemfiles/rails6.gemfile +0 -34
  122. data/gemfiles/rails6_1.gemfile +0 -42
  123. data/gemfiles/rails7.gemfile +0 -42
  124. data/gemfiles/rails7_1.gemfile +0 -41
  125. data/gemfiles/rails7_2.gemfile +0 -41
  126. data/gemfiles/rails8.gemfile +0 -40
  127. data/gemfiles/rails8_1.gemfile +0 -41
  128. data/gemspecs/arel_extensions-v1.gemspec +0 -27
  129. data/gemspecs/arel_extensions-v2.gemspec +0 -27
  130. data/generate_gems.sh +0 -15
  131. data/lib/arel_extensions/aliases.rb +0 -14
  132. data/lib/arel_extensions/constants.rb +0 -13
  133. data/lib/arel_extensions/helpers.rb +0 -61
  134. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -13
  135. data/lib/arel_extensions/nodes/byte_size.rb +0 -11
  136. data/lib/arel_extensions/nodes/char_length.rb +0 -11
  137. data/lib/arel_extensions/nodes/formatted_date.rb +0 -42
  138. data/lib/arel_extensions/nodes/rollup.rb +0 -36
  139. data/lib/arel_extensions/nodes/select.rb +0 -10
  140. data/lib/arel_extensions/nodes/sum.rb +0 -7
  141. data/lib/arel_extensions/visitors/convert_format.rb +0 -37
  142. data/lib/arel_extensions/warning.rb +0 -42
  143. data/test/arelx_test_helper.rb +0 -94
  144. data/test/config_loader.rb +0 -9
  145. data/version_v1.rb +0 -3
  146. data/version_v2.rb +0 -3
@@ -2,12 +2,13 @@ require 'arel_extensions/nodes/then'
2
2
 
3
3
  module ArelExtensions
4
4
  module BooleanFunctions
5
+
5
6
  def ⋀(other)
6
7
  self.and(other)
7
8
  end
8
9
 
9
10
  def and *others
10
- Arel::Nodes::And.new self, others
11
+ Arel::Nodes::And.new([self]+ others.flatten)
11
12
  end
12
13
 
13
14
  def ⋁(other)
@@ -15,7 +16,12 @@ module ArelExtensions
15
16
  end
16
17
 
17
18
  def or *others
18
- Arel::Nodes::Or.new self, others
19
+ args = others.flatten
20
+ if args.length == 1
21
+ Arel::Nodes::Or.new(self, args.first)
22
+ else
23
+ ArelExtensions::Nodes::Or.new([self]+ args)
24
+ end
19
25
  end
20
26
 
21
27
  def then(t, f = nil)
@@ -24,61 +30,16 @@ module ArelExtensions
24
30
  end
25
31
  end
26
32
 
27
- class Arel::Nodes::And
33
+ Arel::Nodes::And.class_eval do
28
34
  include ArelExtensions::BooleanFunctions
29
-
30
- def self.new *children
31
- children =
32
- children.flatten.map { |c|
33
- c.is_a?(self) ? c.children : c
34
- }.flatten
35
- super(children)
36
- end
37
35
  end
38
36
 
39
- # For some reason, Arel's And is properly defined as variadic (it
40
- # stores @children, and hashes it all). However Arel's Or is defined
41
- # as binary, with only @left and @right, and hashing only @left and @right.
42
- #
43
- # So reimplement its ctor and accessors.
44
-
45
- class Arel::Nodes::Or
37
+ Arel::Nodes::Or.class_eval do
46
38
  include ArelExtensions::BooleanFunctions
39
+ end
47
40
 
48
- attr_reader :children
49
-
50
- def self.new *children
51
- children =
52
- children.flatten.map { |c|
53
- c.is_a?(self) ? c.children : c
54
- }.flatten
55
- super(*children)
56
- end
57
-
58
- def initialize *children
59
- @children = children
60
- end
61
-
62
- def initialize_copy(other)
63
- super
64
- @children = other.children.copy if other.children
65
- end
66
-
67
- def left
68
- children.first
69
- end
70
-
71
- def right
72
- children[1]
73
- end
41
+ ArelExtensions::Nodes.const_set('Or',Class.new(Arel::Nodes::And)).class_eval do
42
+ include ArelExtensions::BooleanFunctions
43
+ end
74
44
 
75
- def hash
76
- children.hash
77
- end
78
45
 
79
- def eql?(other)
80
- self.class == other.class &&
81
- children == other.children
82
- end
83
- alias :== :eql?
84
- end
@@ -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,60 +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
- alias regex_matches =~
29
-
30
- # NOT_REGEXP function
31
- # Negation of Regexp
30
+ #NOT_REGEXP function
31
+ #Negation of Regexp
32
32
  def !~(other)
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
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
37
37
  end
38
38
 
39
39
  private
40
-
41
- # Function used for not_regexp.
40
+ #Function use for not_regexp
42
41
  def convert_regexp(other)
43
42
  case other
44
43
  when String
45
- # Do nothing.
44
+ #Do nothing
46
45
  when Regexp
47
- other = other.source.gsub('\A', '^')
48
- other.gsub!('\z', '$')
49
- other.gsub!('\Z', '$')
50
- other.gsub!('\d', '[0-9]')
51
- other.gsub!('\D', '[^0-9]')
52
- other.gsub!('\w', '[0-9A-Za-z]')
53
- 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_]')
54
52
  else
55
53
  raise(ArgumentError)
56
54
  end
57
- Arel.quoted(other, self)
55
+ Arel::Nodes.build_quoted(other, self)
58
56
  end
57
+
59
58
  end
60
59
  end
@@ -1,28 +1,27 @@
1
1
  require 'arel_extensions/nodes/format'
2
- require 'arel_extensions/nodes/formatted_date'
3
2
  require 'arel_extensions/nodes/duration'
4
3
  require 'arel_extensions/nodes/wday'
5
4
 
6
5
  module ArelExtensions
7
6
  module DateDuration
8
- # function returns the year (as a number) given a date value.
7
+ #function returns the year (as a number) given a date value.
9
8
  def year
10
- ArelExtensions::Nodes::Duration.new 'y', self
9
+ ArelExtensions::Nodes::Duration.new "y", self
11
10
  end
12
11
 
13
- # function returns the month (as a number) given a date value.
12
+ #function returns the month (as a number) given a date value.
14
13
  def month
15
- ArelExtensions::Nodes::Duration.new 'm', self
14
+ ArelExtensions::Nodes::Duration.new "m", self
16
15
  end
17
16
 
18
- # function returns the week (as a number) given a date value.
17
+ #function returns the week (as a number) given a date value.
19
18
  def week
20
- ArelExtensions::Nodes::Duration.new 'w', self
19
+ ArelExtensions::Nodes::Duration.new "w", self
21
20
  end
22
21
 
23
- # function returns the month (as a number) given a date value.
22
+ #function returns the month (as a number) given a date value.
24
23
  def day
25
- ArelExtensions::Nodes::Duration.new 'd', self
24
+ ArelExtensions::Nodes::Duration.new "d", self
26
25
  end
27
26
 
28
27
  def wday
@@ -30,23 +29,20 @@ module ArelExtensions
30
29
  end
31
30
 
32
31
  def hour
33
- ArelExtensions::Nodes::Duration.new 'h', self
32
+ ArelExtensions::Nodes::Duration.new "h", self
34
33
  end
35
34
 
36
35
  def minute
37
- ArelExtensions::Nodes::Duration.new 'mn', self
36
+ ArelExtensions::Nodes::Duration.new "mn", self
38
37
  end
39
38
 
40
39
  def second
41
- ArelExtensions::Nodes::Duration.new 's', self
40
+ ArelExtensions::Nodes::Duration.new "s", self
42
41
  end
43
42
 
44
- def format(tpl, time_zone = nil)
45
- ArelExtensions::Nodes::Format.new [self, tpl, time_zone]
43
+ def format(tpl)
44
+ ArelExtensions::Nodes::Format.new [self, tpl]
46
45
  end
47
46
 
48
- def format_date(tpl, time_zone = nil)
49
- ArelExtensions::Nodes::FormattedDate.new [self, tpl, time_zone]
50
- end
51
47
  end
52
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