arel_extensions 1.7.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 -8
  4. data/.rubocop.yml +4 -194
  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 +89 -265
  14. data/Rakefile +30 -50
  15. data/TODO +1 -0
  16. data/appveyor.yml +22 -60
  17. data/arel_extensions.gemspec +17 -14
  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 +17 -19
  23. data/gemfiles/rails5_2.gemfile +17 -26
  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 -9
  30. data/lib/arel_extensions/boolean_functions.rb +16 -57
  31. data/lib/arel_extensions/common_sql_functions.rb +20 -21
  32. data/lib/arel_extensions/comparators.rb +28 -31
  33. data/lib/arel_extensions/date_duration.rb +13 -19
  34. data/lib/arel_extensions/insert_manager.rb +15 -22
  35. data/lib/arel_extensions/math.rb +70 -68
  36. data/lib/arel_extensions/math_functions.rb +52 -57
  37. data/lib/arel_extensions/nodes/abs.rb +1 -0
  38. data/lib/arel_extensions/nodes/blank.rb +5 -6
  39. data/lib/arel_extensions/nodes/case.rb +27 -31
  40. data/lib/arel_extensions/nodes/cast.rb +12 -12
  41. data/lib/arel_extensions/nodes/ceil.rb +1 -1
  42. data/lib/arel_extensions/nodes/coalesce.rb +5 -4
  43. data/lib/arel_extensions/nodes/collate.rb +10 -9
  44. data/lib/arel_extensions/nodes/concat.rb +22 -13
  45. data/lib/arel_extensions/nodes/date_diff.rb +70 -77
  46. data/lib/arel_extensions/nodes/duration.rb +5 -2
  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 +39 -50
  52. data/lib/arel_extensions/nodes/is_null.rb +0 -2
  53. data/lib/arel_extensions/nodes/json.rb +47 -72
  54. data/lib/arel_extensions/nodes/length.rb +0 -5
  55. data/lib/arel_extensions/nodes/levenshtein_distance.rb +2 -2
  56. data/lib/arel_extensions/nodes/locate.rb +3 -2
  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 +3 -2
  62. data/lib/arel_extensions/nodes/repeat.rb +6 -4
  63. data/lib/arel_extensions/nodes/replace.rb +8 -16
  64. data/lib/arel_extensions/nodes/round.rb +7 -6
  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 -58
  68. data/lib/arel_extensions/nodes/then.rb +2 -2
  69. data/lib/arel_extensions/nodes/trim.rb +7 -5
  70. data/lib/arel_extensions/nodes/union.rb +9 -6
  71. data/lib/arel_extensions/nodes/union_all.rb +8 -5
  72. data/lib/arel_extensions/nodes/wday.rb +6 -2
  73. data/lib/arel_extensions/nodes.rb +1 -1
  74. data/lib/arel_extensions/null_functions.rb +6 -18
  75. data/lib/arel_extensions/predications.rb +49 -54
  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 +55 -110
  79. data/lib/arel_extensions/tasks.rb +6 -6
  80. data/lib/arel_extensions/version.rb +1 -3
  81. data/lib/arel_extensions/visitors/ibm_db.rb +36 -29
  82. data/lib/arel_extensions/visitors/mssql.rb +248 -493
  83. data/lib/arel_extensions/visitors/mysql.rb +244 -420
  84. data/lib/arel_extensions/visitors/oracle.rb +258 -311
  85. data/lib/arel_extensions/visitors/oracle12.rb +34 -20
  86. data/lib/arel_extensions/visitors/postgresql.rb +239 -350
  87. data/lib/arel_extensions/visitors/sqlite.rb +169 -191
  88. data/lib/arel_extensions/visitors/to_sql.rb +299 -371
  89. data/lib/arel_extensions/visitors.rb +62 -83
  90. data/lib/arel_extensions.rb +32 -243
  91. data/test/database.yml +10 -20
  92. data/test/helper.rb +18 -0
  93. data/test/real_db_test.rb +120 -123
  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 +375 -912
  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 +64 -50
  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 -48
  113. data/NEWS.md +0 -131
  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 -36
  121. data/gemfiles/rails6.gemfile +0 -40
  122. data/gemfiles/rails6_1.gemfile +0 -48
  123. data/gemfiles/rails7.gemfile +0 -48
  124. data/gemfiles/rails7_1.gemfile +0 -48
  125. data/gemfiles/rails7_2.gemfile +0 -47
  126. data/gemfiles/rails8.gemfile +0 -40
  127. data/gemfiles/rails8_1.gemfile +0 -41
  128. data/gemspecs/arel_extensions-v1.gemspec +0 -25
  129. data/gemspecs/arel_extensions-v2.gemspec +0 -25
  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 -5
  146. data/version_v2.rb +0 -5
@@ -1,23 +1,27 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'arel_extensions/nodes/then'
4
2
 
5
3
  module ArelExtensions
6
4
  module BooleanFunctions
5
+
7
6
  def ⋀(other)
8
7
  self.and(other)
9
8
  end
10
9
 
11
- def and(*others)
12
- Arel::Nodes::And.new self, others
10
+ def and *others
11
+ Arel::Nodes::And.new([self]+ others.flatten)
13
12
  end
14
13
 
15
14
  def ⋁(other)
16
15
  self.or(other)
17
16
  end
18
17
 
19
- def or(*others)
20
- Arel::Nodes::Or.new self, others
18
+ def or *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
21
25
  end
22
26
 
23
27
  def then(t, f = nil)
@@ -26,61 +30,16 @@ module ArelExtensions
26
30
  end
27
31
  end
28
32
 
29
- class Arel::Nodes::And
33
+ Arel::Nodes::And.class_eval do
30
34
  include ArelExtensions::BooleanFunctions
31
-
32
- def self.new(*children)
33
- children =
34
- children.flatten.map { |c|
35
- c.is_a?(self) ? c.children : c
36
- }.flatten
37
- super(children)
38
- end
39
35
  end
40
36
 
41
- # For some reason, Arel's And is properly defined as variadic (it
42
- # stores @children, and hashes it all). However Arel's Or is defined
43
- # as binary, with only @left and @right, and hashing only @left and @right.
44
- #
45
- # So reimplement its ctor and accessors.
46
-
47
- class Arel::Nodes::Or
37
+ Arel::Nodes::Or.class_eval do
48
38
  include ArelExtensions::BooleanFunctions
39
+ end
49
40
 
50
- attr_reader :children
51
-
52
- def self.new(*children)
53
- children =
54
- children.flatten.map { |c|
55
- c.is_a?(self) ? c.children : c
56
- }.flatten
57
- super
58
- end
59
-
60
- def initialize(*children)
61
- @children = children
62
- end
63
-
64
- def initialize_copy(other)
65
- super
66
- @children = other.children.copy if other.children
67
- end
68
-
69
- def left
70
- children.first
71
- end
72
-
73
- def right
74
- children[1]
75
- end
41
+ ArelExtensions::Nodes.const_set('Or',Class.new(Arel::Nodes::And)).class_eval do
42
+ include ArelExtensions::BooleanFunctions
43
+ end
76
44
 
77
- def hash
78
- children.hash
79
- end
80
45
 
81
- def eql?(other)
82
- self.class == other.class &&
83
- children == other.children
84
- end
85
- alias == eql?
86
- end
@@ -1,67 +1,66 @@
1
- # frozen_string_literal: true
2
-
3
1
  module ArelExtensions
4
2
  class CommonSqlFunctions
3
+
5
4
  def initialize(cnx)
6
5
  @cnx = cnx
7
6
  if cnx && cnx.adapter_name =~ /sqlite/i && !$load_extension_disabled
8
7
  begin
9
8
  db = cnx.raw_connection
10
9
  db.enable_load_extension(1)
11
- db.load_extension('/usr/lib/sqlite3/pcre.so')
12
- 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")
13
12
  db.enable_load_extension(0)
14
- rescue StandardError => e
13
+ rescue => e
15
14
  $load_extension_disabled = true
16
- puts "cannot load extensions #{e.inspect}"
15
+ puts "can not load extensions #{e.inspect}"
17
16
  end
18
17
  end
19
18
  end
20
19
 
21
20
  def add_sqlite_functions
22
21
  db = @cnx.raw_connection
23
- db.create_function('find_in_set', 1) do |func, val, list|
22
+ db.create_function("find_in_set", 1) do |func, val, list|
24
23
  case list
25
24
  when String
26
25
  i = list.split(',').index(val.to_s)
27
- func.result = i ? (i + 1) : 0
26
+ func.result = i ? (i+1) : 0
28
27
  when NilClass
29
28
  func.result = nil
30
29
  else
31
30
  i = list.to_s.split(',').index(val.to_s)
32
- func.result = i ? (i + 1) : 0
31
+ func.result = i ? (i+1) : 0
33
32
  end
34
33
  end
35
- db.create_function('instr', 1) do |func, value1, value2|
34
+ db.create_function("instr", 1) do |func, value1, value2|
36
35
  i = value1.to_s.index(value2.to_s)
37
- func.result = i ? (i + 1) : 0
38
- 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)"
39
38
  end
40
39
 
41
40
  def add_sql_functions(env_db = nil)
42
41
  env_db ||= @cnx.adapter_name
43
- env_db = 'mysql' if /mysql/i.match?(env_db)
44
- if /sqlite/i.match?(env_db)
42
+ if env_db =~ /sqlite/i
45
43
  begin
46
44
  add_sqlite_functions
47
- rescue StandardError => e
48
- puts "cannot add sqlite functions #{e.inspect}"
45
+ rescue => e
46
+ puts "can not add sqlite functions #{e.inspect}"
49
47
  end
50
48
  end
51
49
  if File.exist?("init/#{env_db}.sql")
52
50
  sql = File.read("init/#{env_db}.sql")
53
51
  if env_db == 'mssql'
54
- sql.split(/^GO\s*$/).each { |str|
52
+ sql.split(/^GO\s*$/).each {|str|
55
53
  @cnx.execute(str.strip) unless str.blank?
56
54
  }
57
- elsif env_db == 'mysql'
58
- sql.split('$$')[1..-2].each { |str|
59
- @cnx.execute(str.strip) unless str.strip.blank?
60
- }
55
+ elsif env_db == 'mysql'
56
+ sql.split("$$")[1..-2].each { |str|
57
+ @cnx.execute(str.strip) unless str.strip.blank?
58
+ }
61
59
  else
62
60
  @cnx.execute(sql) unless sql.blank?
63
61
  end
64
62
  end
65
63
  end
64
+
66
65
  end
67
66
  end
@@ -1,62 +1,59 @@
1
- # frozen_string_literal: true
2
-
3
1
  module ArelExtensions
4
2
  module Comparators
3
+
5
4
  def >(other)
6
- Arel::Nodes::GreaterThan.new self, Arel.quoted(other, self)
5
+ Arel::Nodes::GreaterThan.new self, Arel::Nodes.build_quoted(other, self)
7
6
  end
8
7
 
9
8
  def >=(other)
10
- Arel::Nodes::GreaterThanOrEqual.new self, Arel.quoted(other, self)
9
+ Arel::Nodes::GreaterThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
11
10
  end
12
11
 
13
12
  def <(other)
14
- Arel::Nodes::LessThan.new self, Arel.quoted(other, self)
13
+ Arel::Nodes::LessThan.new self, Arel::Nodes.build_quoted(other, self)
15
14
  end
16
15
 
17
16
  def <=(other)
18
- Arel::Nodes::LessThanOrEqual.new self, Arel.quoted(other, self)
17
+ Arel::Nodes::LessThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
19
18
  end
20
19
 
21
- # REGEXP function
22
- # Pattern matching using regular expressions
20
+
21
+ #REGEXP function
22
+ #Pattern matching using regular expressions
23
23
  def =~(other)
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
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
28
28
  end
29
29
 
30
- alias regex_matches =~
31
-
32
- # NOT_REGEXP function
33
- # Negation of Regexp
30
+ #NOT_REGEXP function
31
+ #Negation of Regexp
34
32
  def !~(other)
35
- # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
36
- # if arg == :string || arg == :text
37
- Arel::Nodes::NotRegexp.new self, convert_regexp(other)
38
- # 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
39
37
  end
40
38
 
41
39
  private
42
-
43
- # Function used for not_regexp.
40
+ #Function use for not_regexp
44
41
  def convert_regexp(other)
45
42
  case other
46
43
  when String
47
- # Do nothing.
44
+ #Do nothing
48
45
  when Regexp
49
- other = other.source.gsub('\A', '^')
50
- other.gsub!('\z', '$')
51
- other.gsub!('\Z', '$')
52
- other.gsub!('\d', '[0-9]')
53
- other.gsub!('\D', '[^0-9]')
54
- other.gsub!('\w', '[0-9A-Za-z]')
55
- 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_]')
56
52
  else
57
53
  raise(ArgumentError)
58
54
  end
59
- Arel.quoted(other, self)
55
+ Arel::Nodes.build_quoted(other, self)
60
56
  end
57
+
61
58
  end
62
59
  end
@@ -1,30 +1,27 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'arel_extensions/nodes/format'
4
- require 'arel_extensions/nodes/formatted_date'
5
2
  require 'arel_extensions/nodes/duration'
6
3
  require 'arel_extensions/nodes/wday'
7
4
 
8
5
  module ArelExtensions
9
6
  module DateDuration
10
- # function returns the year (as a number) given a date value.
7
+ #function returns the year (as a number) given a date value.
11
8
  def year
12
- ArelExtensions::Nodes::Duration.new 'y', self
9
+ ArelExtensions::Nodes::Duration.new "y", self
13
10
  end
14
11
 
15
- # function returns the month (as a number) given a date value.
12
+ #function returns the month (as a number) given a date value.
16
13
  def month
17
- ArelExtensions::Nodes::Duration.new 'm', self
14
+ ArelExtensions::Nodes::Duration.new "m", self
18
15
  end
19
16
 
20
- # function returns the week (as a number) given a date value.
17
+ #function returns the week (as a number) given a date value.
21
18
  def week
22
- ArelExtensions::Nodes::Duration.new 'w', self
19
+ ArelExtensions::Nodes::Duration.new "w", self
23
20
  end
24
21
 
25
- # function returns the month (as a number) given a date value.
22
+ #function returns the month (as a number) given a date value.
26
23
  def day
27
- ArelExtensions::Nodes::Duration.new 'd', self
24
+ ArelExtensions::Nodes::Duration.new "d", self
28
25
  end
29
26
 
30
27
  def wday
@@ -32,23 +29,20 @@ module ArelExtensions
32
29
  end
33
30
 
34
31
  def hour
35
- ArelExtensions::Nodes::Duration.new 'h', self
32
+ ArelExtensions::Nodes::Duration.new "h", self
36
33
  end
37
34
 
38
35
  def minute
39
- ArelExtensions::Nodes::Duration.new 'mn', self
36
+ ArelExtensions::Nodes::Duration.new "mn", self
40
37
  end
41
38
 
42
39
  def second
43
- ArelExtensions::Nodes::Duration.new 's', self
40
+ ArelExtensions::Nodes::Duration.new "s", self
44
41
  end
45
42
 
46
- def format(tpl, time_zone = nil)
47
- ArelExtensions::Nodes::Format.new [self, tpl, time_zone]
43
+ def format(tpl)
44
+ ArelExtensions::Nodes::Format.new [self, tpl]
48
45
  end
49
46
 
50
- def format_date(tpl, time_zone = nil)
51
- ArelExtensions::Nodes::FormattedDate.new [self, tpl, time_zone]
52
- end
53
47
  end
54
48
  end
@@ -1,40 +1,33 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'arel'
4
2
 
5
3
  module ArelExtensions
6
4
  module InsertManager
7
- def bulk_insert(cols, data)
8
- raise ArgumentError, 'cols must be present' if cols.blank?
9
5
 
10
- columns =
11
- case cols.first
6
+ def bulk_insert(cols, data)
7
+ case cols.first
8
+ when String, Symbol
9
+ cols.each { |c|
10
+ @ast.columns << @ast.relation[c]
11
+ }
12
12
  when Array
13
- case cols.first.first
14
- when Arel::Attributes::Attribute
15
- cols
16
- when String, Symbol
17
- cols.map { |c| [@ast.relation[c.first]] }
18
- else
19
- 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
20
17
  end
21
- when String, Symbol
22
- cols.map { |c| @ast.relation[c] }
23
- else
24
- raise ArgumentError, "cols has an invalid type: #{cols.first.class}"
25
- end
26
- self.values = BulkValues.new(columns, data)
27
- @ast.columns = columns
18
+ when NilClass
19
+ @ast.columns = @ast.relation.columns
20
+ end
21
+ self.values = BulkValues.new(@ast.columns, data)
28
22
  end
29
23
 
30
24
  class BulkValues < Arel::Nodes::Node
31
25
  attr_accessor :left, :cols
32
-
33
26
  def initialize(cols, values)
34
- super()
35
27
  @left = values
36
28
  @cols = cols
37
29
  end
38
30
  end
31
+
39
32
  end
40
33
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'arel_extensions/nodes'
4
2
  require 'arel_extensions/nodes/function'
5
3
  require 'arel_extensions/nodes/concat'
@@ -13,106 +11,111 @@ require 'arel_extensions/nodes/union_all'
13
11
 
14
12
  module ArelExtensions
15
13
  module Math
16
- # function + between
17
- # String and others (convert in string) allows you to concatenate 2 or more strings together.
18
- # 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.
19
17
  def +(other)
20
18
  case self
21
- when Arel::Nodes::Quoted
22
- concat(other)
23
- when Arel::Nodes::Grouping
24
- if expr.left.is_a?(String) || expr.right.is_a?(String)
25
- concat(other)
26
- else
27
- Arel.grouping(Arel::Nodes::Addition.new(self, other))
28
- end
29
- when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
30
- case 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
+ when :string, :text
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
- concat(other)
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 is_a?(Arel::Attribute) && respond_to?(:type_caster) && able_to_type_cast?
43
- type_caster
44
- elsif respond_to?(:relation)
45
- Arel.column_of(relation.table_name, name.to_s)
46
- end
47
- if col
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))
48
+ else
48
49
  arg = col.type
49
- if arg == :integer || !arg
50
+ if arg == :integer || (!arg)
50
51
  other = other.to_i if other.is_a?(String)
51
- Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
52
- elsif %i[decimal float].include?(arg)
52
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
53
+ elsif arg == :decimal || arg == :float
53
54
  other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
54
- Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
55
- elsif %i[datetime date].include?(arg)
55
+ Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
56
+ elsif arg == :datetime || arg == :date
56
57
  ArelExtensions::Nodes::DateAdd.new [self, other]
57
- elsif %i[string text].include?(arg)
58
- concat(other)
58
+ elsif arg == :string || arg == :text
59
+ self.concat(other)
59
60
  end
60
- else
61
- Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
62
61
  end
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
- if expr.left.is_a?(Date) || expr.left.is_a?(DateTime)
72
- Arel.grouping(ArelExtensions::Nodes::DateSub.new([self, Arel.quoted(other)]))
70
+ if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
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
- case return_type
76
+ case self.return_type
77
+ when :string, :text # ???
78
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) # ??
79
+ when :integer, :decimal, :float, :number
80
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
78
81
  when :date, :datetime
79
- ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)]
82
+ ArelExtensions::Nodes::DateSub.new [self, other]
80
83
  else
81
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
84
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
82
85
  end
83
86
  when Arel::Nodes::Function
84
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
87
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
85
88
  else
86
- col =
87
- if is_a?(Arel::Attribute) && respond_to?(:type_caster) && able_to_type_cast?
88
- type_caster
89
- elsif respond_to?(:relation)
90
- Arel.column_of(relation.table_name, name.to_s)
91
- end
92
- if col
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))
96
+ else
93
97
  arg = col.type
94
- if %i[date datetime].include?(arg)
98
+ if (arg == :date || arg == :datetime)
95
99
  case other
96
100
  when Arel::Attributes::Attribute
97
- col2 =
98
- if other.is_a?(Arel::Attribute) && other.respond_to?(:type_caster) && other.able_to_type_cast?
99
- other.type_caster
100
- elsif other.respond_to?(:relation)
101
- Arel.column_of(other.relation.table_name, other.name.to_s)
102
- end
103
- if col2
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
107
+ ArelExtensions::Nodes::DateSub.new [self, other]
108
+ else
104
109
  arg2 = col2.type
105
- if %i[date datetime].include?(arg2)
110
+ if arg2 == :date || arg2 == :datetime
106
111
  ArelExtensions::Nodes::DateDiff.new [self, other]
107
112
  else
108
113
  ArelExtensions::Nodes::DateSub.new [self, other]
109
114
  end
110
- else
111
- ArelExtensions::Nodes::DateSub.new [self, other]
112
115
  end
113
116
  when Arel::Nodes::Node, DateTime, Time, String, Date
114
117
  ArelExtensions::Nodes::DateDiff.new [self, other]
115
- when ArelExtensions::Nodes::Duration, Integer
118
+ when ArelExtensions::Nodes::Duration, Integer
116
119
  ArelExtensions::Nodes::DateSub.new [self, other]
117
120
  else # ActiveSupport::Duration
118
121
  ArelExtensions::Nodes::DateAdd.new [self, -other]
@@ -120,17 +123,16 @@ module ArelExtensions
120
123
  else
121
124
  case other
122
125
  when Integer, Float, BigDecimal
123
- 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)))
124
127
  when String
125
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
128
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
126
129
  else
127
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
130
+ Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other))
128
131
  end
129
132
  end
130
- else
131
- Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
132
133
  end
133
134
  end
134
135
  end
136
+
135
137
  end
136
138
  end