arel_extensions 2.0.21 → 2.2.2

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 (138) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -2
  3. data/.github/workflows/publish.yml +29 -0
  4. data/.github/workflows/release.yml +30 -0
  5. data/.github/workflows/ruby.yml +377 -80
  6. data/.gitignore +7 -6
  7. data/.rubocop.yml +62 -1
  8. data/CONTRIBUTING.md +102 -0
  9. data/Gemfile +2 -23
  10. data/NEWS.md +89 -0
  11. data/README.md +228 -84
  12. data/Rakefile +11 -4
  13. data/TODO +0 -1
  14. data/appveyor.yml +60 -22
  15. data/arel_extensions.gemspec +11 -12
  16. data/bin/build +15 -0
  17. data/bin/compose +6 -0
  18. data/bin/publish +8 -0
  19. data/dev/arelx.dockerfile +44 -0
  20. data/dev/compose.yaml +71 -0
  21. data/dev/postgres.dockerfile +5 -0
  22. data/dev/rbenv +189 -0
  23. data/gemfiles/rails3.gemfile +10 -10
  24. data/gemfiles/rails4_2.gemfile +38 -0
  25. data/gemfiles/rails5.gemfile +29 -0
  26. data/gemfiles/rails5_1_4.gemfile +13 -13
  27. data/gemfiles/rails5_2.gemfile +16 -14
  28. data/gemfiles/rails6.gemfile +18 -15
  29. data/gemfiles/rails6_1.gemfile +18 -15
  30. data/gemfiles/rails7.gemfile +33 -0
  31. data/gemfiles/rails7_1.gemfile +33 -0
  32. data/gemfiles/rails7_2.gemfile +33 -0
  33. data/gemspecs/arel_extensions-v1.gemspec +12 -13
  34. data/gemspecs/arel_extensions-v2.gemspec +11 -12
  35. data/init/mssql.sql +0 -0
  36. data/init/mysql.sql +0 -0
  37. data/init/oracle.sql +0 -0
  38. data/init/postgresql.sql +0 -0
  39. data/init/sqlite.sql +0 -0
  40. data/lib/arel_extensions/aliases.rb +14 -0
  41. data/lib/arel_extensions/attributes.rb +10 -2
  42. data/lib/arel_extensions/boolean_functions.rb +2 -4
  43. data/lib/arel_extensions/common_sql_functions.rb +12 -12
  44. data/lib/arel_extensions/comparators.rb +14 -14
  45. data/lib/arel_extensions/date_duration.rb +14 -9
  46. data/lib/arel_extensions/helpers.rb +62 -0
  47. data/lib/arel_extensions/insert_manager.rb +19 -17
  48. data/lib/arel_extensions/math.rb +48 -45
  49. data/lib/arel_extensions/math_functions.rb +18 -18
  50. data/lib/arel_extensions/nodes/abs.rb +0 -0
  51. data/lib/arel_extensions/nodes/aggregate_function.rb +0 -0
  52. data/lib/arel_extensions/nodes/blank.rb +1 -1
  53. data/lib/arel_extensions/nodes/case.rb +10 -12
  54. data/lib/arel_extensions/nodes/cast.rb +6 -6
  55. data/lib/arel_extensions/nodes/ceil.rb +0 -0
  56. data/lib/arel_extensions/nodes/change_case.rb +0 -0
  57. data/lib/arel_extensions/nodes/coalesce.rb +1 -1
  58. data/lib/arel_extensions/nodes/collate.rb +9 -9
  59. data/lib/arel_extensions/nodes/concat.rb +2 -2
  60. data/lib/arel_extensions/nodes/date_diff.rb +33 -14
  61. data/lib/arel_extensions/nodes/duration.rb +0 -0
  62. data/lib/arel_extensions/nodes/find_in_set.rb +0 -0
  63. data/lib/arel_extensions/nodes/floor.rb +0 -0
  64. data/lib/arel_extensions/nodes/format.rb +3 -2
  65. data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
  66. data/lib/arel_extensions/nodes/formatted_number.rb +2 -2
  67. data/lib/arel_extensions/nodes/function.rb +22 -26
  68. data/lib/arel_extensions/nodes/is_null.rb +0 -0
  69. data/lib/arel_extensions/nodes/json.rb +15 -9
  70. data/lib/arel_extensions/nodes/length.rb +6 -0
  71. data/lib/arel_extensions/nodes/levenshtein_distance.rb +1 -1
  72. data/lib/arel_extensions/nodes/locate.rb +1 -1
  73. data/lib/arel_extensions/nodes/log10.rb +0 -0
  74. data/lib/arel_extensions/nodes/matches.rb +1 -1
  75. data/lib/arel_extensions/nodes/md5.rb +0 -0
  76. data/lib/arel_extensions/nodes/power.rb +0 -0
  77. data/lib/arel_extensions/nodes/rand.rb +0 -0
  78. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  79. data/lib/arel_extensions/nodes/replace.rb +2 -10
  80. data/lib/arel_extensions/nodes/rollup.rb +36 -0
  81. data/lib/arel_extensions/nodes/round.rb +0 -0
  82. data/lib/arel_extensions/nodes/select.rb +10 -0
  83. data/lib/arel_extensions/nodes/soundex.rb +2 -2
  84. data/lib/arel_extensions/nodes/std.rb +0 -0
  85. data/lib/arel_extensions/nodes/substring.rb +1 -1
  86. data/lib/arel_extensions/nodes/sum.rb +0 -0
  87. data/lib/arel_extensions/nodes/then.rb +1 -1
  88. data/lib/arel_extensions/nodes/trim.rb +2 -2
  89. data/lib/arel_extensions/nodes/union.rb +5 -5
  90. data/lib/arel_extensions/nodes/union_all.rb +4 -4
  91. data/lib/arel_extensions/nodes/wday.rb +0 -0
  92. data/lib/arel_extensions/nodes.rb +0 -0
  93. data/lib/arel_extensions/null_functions.rb +16 -0
  94. data/lib/arel_extensions/predications.rb +10 -10
  95. data/lib/arel_extensions/railtie.rb +1 -1
  96. data/lib/arel_extensions/set_functions.rb +3 -3
  97. data/lib/arel_extensions/string_functions.rb +19 -10
  98. data/lib/arel_extensions/tasks.rb +2 -2
  99. data/lib/arel_extensions/version.rb +1 -1
  100. data/lib/arel_extensions/visitors/convert_format.rb +0 -0
  101. data/lib/arel_extensions/visitors/ibm_db.rb +20 -20
  102. data/lib/arel_extensions/visitors/mssql.rb +394 -169
  103. data/lib/arel_extensions/visitors/mysql.rb +238 -151
  104. data/lib/arel_extensions/visitors/oracle.rb +170 -131
  105. data/lib/arel_extensions/visitors/oracle12.rb +16 -16
  106. data/lib/arel_extensions/visitors/postgresql.rb +170 -140
  107. data/lib/arel_extensions/visitors/sqlite.rb +88 -87
  108. data/lib/arel_extensions/visitors/to_sql.rb +185 -156
  109. data/lib/arel_extensions/visitors.rb +73 -60
  110. data/lib/arel_extensions.rb +173 -36
  111. data/test/arelx_test_helper.rb +49 -1
  112. data/test/database.yml +13 -7
  113. data/test/real_db_test.rb +101 -83
  114. data/test/support/fake_record.rb +8 -2
  115. data/test/test_comparators.rb +5 -5
  116. data/test/visitors/test_bulk_insert_oracle.rb +5 -5
  117. data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
  118. data/test/visitors/test_bulk_insert_to_sql.rb +5 -5
  119. data/test/visitors/test_oracle.rb +14 -14
  120. data/test/visitors/test_to_sql.rb +121 -93
  121. data/test/with_ar/all_agnostic_test.rb +630 -320
  122. data/test/with_ar/insert_agnostic_test.rb +25 -18
  123. data/test/with_ar/test_bulk_sqlite.rb +11 -7
  124. data/test/with_ar/test_math_sqlite.rb +18 -14
  125. data/test/with_ar/test_string_mysql.rb +26 -22
  126. data/test/with_ar/test_string_sqlite.rb +26 -22
  127. data/version_v1.rb +1 -1
  128. data/version_v2.rb +1 -1
  129. metadata +24 -26
  130. data/.travis/oracle/download.js +0 -152
  131. data/.travis/oracle/download.sh +0 -30
  132. data/.travis/oracle/download_ojdbc.js +0 -116
  133. data/.travis/oracle/install.sh +0 -34
  134. data/.travis/setup_accounts.sh +0 -9
  135. data/.travis/sqlite3/extension-functions.sh +0 -6
  136. data/.travis.yml +0 -193
  137. data/gemfiles/rails4.gemfile +0 -29
  138. data/gemfiles/rails5_0.gemfile +0 -29
@@ -0,0 +1,33 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 7.0.1'
4
+
5
+ group :development, :test do
6
+ gem 'ruby-lsp', platforms: %i[mri]
7
+ gem 'debug', platforms: %i[mri]
8
+
9
+ gem 'activesupport', '~> 7.0.1'
10
+ gem 'activemodel', '~> 7.0.1'
11
+ gem 'activerecord', '~> 7.0.1'
12
+
13
+ gem 'sqlite3', '~> 1.4', platforms: [:mri]
14
+ gem 'mysql2', '~>0.5', platforms: [:mri]
15
+ gem 'pg', '~> 1.1', platforms: [:mri]
16
+
17
+ gem 'tiny_tds', platforms: %i[mri mingw x64_mingw mswin]
18
+ gem 'activerecord-sqlserver-adapter', '~> 7.0.7', platforms: %i[mri mingw x64_mingw mswin]
19
+ gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw]
20
+
21
+ gem 'ruby-oci8', platforms: %i[mri mswin mingw] if ENV.has_key? 'ORACLE_HOME'
22
+ gem 'activerecord-oracle_enhanced-adapter', '~> 6.0.0' if ENV.has_key? 'ORACLE_HOME'
23
+
24
+ # for JRuby
25
+ gem 'jdbc-mssql', platforms: :jruby, require: true
26
+ gem 'jdbc-sqlite3', platform: :jruby
27
+ gem 'activerecord-jdbc-alt-adapter', '~> 70.0', platform: :jruby, require: true
28
+ gem 'activerecord-jdbcmysql-adapter', platforms: :jruby
29
+ gem 'activerecord-jdbcpostgresql-adapter', platforms: :jruby
30
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby
31
+ end
32
+
33
+ gemspec path: Dir.pwd
@@ -0,0 +1,33 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 7.1'
4
+
5
+ group :development, :test do
6
+ gem 'ruby-lsp', platforms: %i[mri]
7
+ gem 'debug', platforms: %i[mri]
8
+
9
+ gem 'activesupport', '~> 7.1'
10
+ gem 'activemodel', '~> 7.1'
11
+ gem 'activerecord', '~> 7.1'
12
+
13
+ gem 'sqlite3', '~> 1.6', platforms: [:mri]
14
+ gem 'mysql2', '~>0.5', platforms: [:mri]
15
+ gem 'pg', '~> 1.5', platforms: [:mri]
16
+
17
+ gem 'tiny_tds', platforms: %i[mri mingw x64_mingw mswin]
18
+ gem 'activerecord-sqlserver-adapter', '~> 7.1.0.beta1', platforms: %i[mri mingw x64_mingw mswin]
19
+ gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw]
20
+
21
+ gem 'ruby-oci8', platforms: %i[mri mswin mingw] if ENV.has_key? 'ORACLE_HOME'
22
+ gem 'activerecord-oracle_enhanced-adapter', '~> 7.0.0' if ENV.has_key? 'ORACLE_HOME'
23
+
24
+ # for JRuby
25
+ gem 'jdbc-mssql', platforms: :jruby, require: true
26
+ gem 'jdbc-sqlite3', platform: :jruby
27
+ gem 'activerecord-jdbc-alt-adapter', '~> 71.0.0.alpha1', platform: :jruby, require: true
28
+ gem 'activerecord-jdbcmysql-adapter', platforms: :jruby
29
+ gem 'activerecord-jdbcpostgresql-adapter', platforms: :jruby
30
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby
31
+ end
32
+
33
+ gemspec path: Dir.pwd
@@ -0,0 +1,33 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 7.2'
4
+
5
+ group :development, :test do
6
+ gem 'ruby-lsp', platforms: %i[mri]
7
+ gem 'debug', platforms: %i[mri]
8
+
9
+ gem 'activesupport', '~> 7.2'
10
+ gem 'activemodel', '~> 7.2'
11
+ gem 'activerecord', '~> 7.2'
12
+
13
+ gem 'sqlite3', '~> 1.6', platforms: [:mri]
14
+ gem 'mysql2', '~>0.5', platforms: [:mri]
15
+ gem 'pg', '~> 1.5', platforms: [:mri]
16
+
17
+ gem 'tiny_tds', platforms: %i[mri mingw x64_mingw mswin]
18
+ gem 'activerecord-sqlserver-adapter', '~> 7.2', platforms: %i[mri mingw x64_mingw mswin]
19
+ gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw]
20
+
21
+ gem 'ruby-oci8', platforms: %i[mri mswin mingw] if ENV.has_key? 'ORACLE_HOME'
22
+ gem 'activerecord-oracle_enhanced-adapter', '~> 7.0.0' if ENV.has_key? 'ORACLE_HOME'
23
+
24
+ # for JRuby
25
+ gem 'jdbc-mssql', platforms: :jruby, require: true
26
+ gem 'jdbc-sqlite3', platform: :jruby
27
+ # gem 'activerecord-jdbc-alt-adapter', '~> 71.0.0.alpha1', platform: :jruby, require: true
28
+ gem 'activerecord-jdbcmysql-adapter', platforms: :jruby
29
+ gem 'activerecord-jdbcpostgresql-adapter', platforms: :jruby
30
+ gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby
31
+ end
32
+
33
+ gemspec path: Dir.pwd
@@ -1,28 +1,27 @@
1
- $:.push File.expand_path("../lib", __FILE__)
2
- require "arel_extensions/version"
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'arel_extensions/version'
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "arel_extensions"
5
+ s.name = 'arel_extensions'
6
6
  s.version = ArelExtensions::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.authors = ["Yann Azoury", "Félix Bellanger", "Julien Delporte"]
9
- s.email = ["yann.azoury@faveod.com", "felix.bellanger@faveod.com", "julien.delporte@faveod.com"]
10
- s.homepage = "https://github.com/Faveod/arel-extensions"
11
- s.description = "Adds new features to Arel"
12
- s.summary = "Extending Arel"
8
+ s.authors = ['Yann Azoury', 'Félix Bellanger', 'Julien Delporte']
9
+ s.email = ['yann.azoury@faveod.com', 'felix.bellanger@faveod.com', 'julien.delporte@faveod.com']
10
+ s.homepage = 'https://github.com/Faveod/arel-extensions'
11
+ s.description = 'Adds new features to Arel'
12
+ s.summary = 'Extending Arel'
13
13
  s.license = 'MIT'
14
14
 
15
- s.rdoc_options = ["--main", "README.md"]
16
- s.extra_rdoc_files = ["MIT-LICENSE.txt", "README.md", 'functions.html']
15
+ s.rdoc_options = ['--main', 'README.md']
16
+ s.extra_rdoc_files = ['MIT-LICENSE.txt', 'README.md', 'functions.html']
17
17
 
18
18
  # Manifest
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
- s.require_paths = ["lib"]
21
+ s.require_paths = ['lib']
22
22
 
23
23
  s.add_dependency('arel', '>= 6.0')
24
24
 
25
25
  s.add_development_dependency('minitest', '~> 5.9')
26
- s.add_development_dependency('rdoc', '~> 4.0')
27
26
  s.add_development_dependency('rake', '~> 12.3.3')
28
- end
27
+ end
@@ -1,28 +1,27 @@
1
- $:.push File.expand_path("../lib", __FILE__)
2
- require "arel_extensions/version"
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'arel_extensions/version'
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "arel_extensions"
5
+ s.name = 'arel_extensions'
6
6
  s.version = ArelExtensions::VERSION
7
7
  s.platform = Gem::Platform::RUBY
8
- s.authors = ["Yann Azoury", "Félix Bellanger", "Julien Delporte"]
9
- s.email = ["yann.azoury@faveod.com", "felix.bellanger@faveod.com", "julien.delporte@faveod.com"]
10
- s.homepage = "https://github.com/Faveod/arel-extensions"
11
- s.description = "Adds new features to Arel"
12
- s.summary = "Extending Arel"
8
+ s.authors = ['Yann Azoury', 'Félix Bellanger', 'Julien Delporte']
9
+ s.email = ['yann.azoury@faveod.com', 'felix.bellanger@faveod.com', 'julien.delporte@faveod.com']
10
+ s.homepage = 'https://github.com/Faveod/arel-extensions'
11
+ s.description = 'Adds new features to Arel'
12
+ s.summary = 'Extending Arel'
13
13
  s.license = 'MIT'
14
14
 
15
- s.rdoc_options = ["--main", "README.md"]
16
- s.extra_rdoc_files = ["MIT-LICENSE.txt", "README.md", 'functions.html']
15
+ s.rdoc_options = ['--main', 'README.md']
16
+ s.extra_rdoc_files = ['MIT-LICENSE.txt', 'README.md', 'functions.html']
17
17
 
18
18
  # Manifest
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
- s.require_paths = ["lib"]
21
+ s.require_paths = ['lib']
22
22
 
23
23
  s.add_dependency('activerecord', '>= 6.0')
24
24
 
25
25
  s.add_development_dependency('minitest', '~> 5.9')
26
- s.add_development_dependency('rdoc', '~> 4.0')
27
26
  s.add_development_dependency('rake', '~> 12.3.3')
28
27
  end
data/init/mssql.sql CHANGED
File without changes
data/init/mysql.sql CHANGED
File without changes
data/init/oracle.sql CHANGED
File without changes
data/init/postgresql.sql CHANGED
File without changes
data/init/sqlite.sql CHANGED
File without changes
@@ -0,0 +1,14 @@
1
+ module ArelExtensions
2
+ module Aliases
3
+
4
+ # Install an alias, if present.
5
+ def xas other
6
+ if other.present?
7
+ Arel::Nodes::As.new(self, Arel.sql(other))
8
+ else
9
+ self
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -1,3 +1,4 @@
1
+ require 'arel_extensions/aliases'
1
2
  require 'arel_extensions/math'
2
3
  require 'arel_extensions/comparators'
3
4
  require 'arel_extensions/date_duration'
@@ -8,6 +9,7 @@ require 'arel_extensions/predications'
8
9
 
9
10
  module ArelExtensions
10
11
  module Attributes
12
+ include ArelExtensions::Aliases
11
13
  include ArelExtensions::Math
12
14
  include ArelExtensions::Comparators
13
15
  include ArelExtensions::DateDuration
@@ -17,11 +19,17 @@ module ArelExtensions
17
19
  include ArelExtensions::Predications
18
20
 
19
21
  def ==(other)
20
- Arel::Nodes::Equality.new self, Arel::Nodes.build_quoted(other, self)
22
+ if Gem::Version.create(ArelExtensions::VERSION) >= Gem::Version.create('2.2')
23
+ warn("#{caller(1..1).first} arel_extensions: `==` is now deprecated and will be removed soon. Use `.eq` instead.")
24
+ end
25
+ Arel::Nodes::Equality.new self, Arel.quoted(other, self)
21
26
  end
22
27
 
23
28
  def !=(other)
24
- Arel::Nodes::NotEqual.new self, Arel::Nodes.build_quoted(other, self)
29
+ if Gem::Version.create(ArelExtensions::VERSION) >= Gem::Version.create('2.2')
30
+ warn("#{caller(1..1).first} arel_extensions: `!=` is now deprecated and will be removed soon. Use `.not_eq` instead.")
31
+ end
32
+ Arel::Nodes::NotEqual.new self, Arel.quoted(other, self)
25
33
  end
26
34
  end
27
35
  end
@@ -1,5 +1,3 @@
1
- # coding: utf-8
2
-
3
1
  require 'arel_extensions/nodes/then'
4
2
 
5
3
  module ArelExtensions
@@ -32,7 +30,7 @@ class Arel::Nodes::And
32
30
  def self.new *children
33
31
  children =
34
32
  children.flatten.map { |c|
35
- c.is_a?(self) ? c.children : c
33
+ c.is_a?(self) ? c.children : c
36
34
  }.flatten
37
35
  super(children)
38
36
  end
@@ -52,7 +50,7 @@ class Arel::Nodes::Or
52
50
  def self.new *children
53
51
  children =
54
52
  children.flatten.map { |c|
55
- c.is_a?(self) ? c.children : c
53
+ c.is_a?(self) ? c.children : c
56
54
  }.flatten
57
55
  super(*children)
58
56
  end
@@ -6,8 +6,8 @@ module ArelExtensions
6
6
  begin
7
7
  db = cnx.raw_connection
8
8
  db.enable_load_extension(1)
9
- db.load_extension("/usr/lib/sqlite3/pcre.so")
10
- db.load_extension("/usr/lib/sqlite3/extension-functions.so")
9
+ db.load_extension('/usr/lib/sqlite3/pcre.so')
10
+ db.load_extension('/usr/lib/sqlite3/extension-functions.so')
11
11
  db.enable_load_extension(0)
12
12
  rescue => e
13
13
  $load_extension_disabled = true
@@ -18,28 +18,28 @@ module ArelExtensions
18
18
 
19
19
  def add_sqlite_functions
20
20
  db = @cnx.raw_connection
21
- db.create_function("find_in_set", 1) do |func, val, list|
21
+ db.create_function('find_in_set', 1) do |func, val, list|
22
22
  case list
23
23
  when String
24
24
  i = list.split(',').index(val.to_s)
25
- func.result = i ? (i+1) : 0
25
+ func.result = i ? (i + 1) : 0
26
26
  when NilClass
27
27
  func.result = nil
28
28
  else
29
29
  i = list.to_s.split(',').index(val.to_s)
30
- func.result = i ? (i+1) : 0
30
+ func.result = i ? (i + 1) : 0
31
31
  end
32
32
  end
33
- db.create_function("instr", 1) do |func, value1, value2|
33
+ db.create_function('instr', 1) do |func, value1, value2|
34
34
  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)"
35
+ func.result = i ? (i + 1) : 0
36
+ end rescue 'function instr already here (>= 3.8.5)'
37
37
  end
38
38
 
39
39
  def add_sql_functions(env_db = nil)
40
40
  env_db ||= @cnx.adapter_name
41
- env_db = 'mysql' if env_db =~ /mysql/i
42
- if env_db =~ /sqlite/i
41
+ env_db = 'mysql' if /mysql/i.match?(env_db)
42
+ if /sqlite/i.match?(env_db)
43
43
  begin
44
44
  add_sqlite_functions
45
45
  rescue => e
@@ -52,8 +52,8 @@ 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|
55
+ elsif env_db == 'mysql'
56
+ sql.split('$$')[1..-2].each { |str|
57
57
  @cnx.execute(str.strip) unless str.strip.blank?
58
58
  }
59
59
  else
@@ -1,19 +1,19 @@
1
1
  module ArelExtensions
2
2
  module Comparators
3
3
  def >(other)
4
- Arel::Nodes::GreaterThan.new self, Arel::Nodes.build_quoted(other, self)
4
+ Arel::Nodes::GreaterThan.new self, Arel.quoted(other, self)
5
5
  end
6
6
 
7
7
  def >=(other)
8
- Arel::Nodes::GreaterThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
8
+ Arel::Nodes::GreaterThanOrEqual.new self, Arel.quoted(other, self)
9
9
  end
10
10
 
11
11
  def <(other)
12
- Arel::Nodes::LessThan.new self, Arel::Nodes.build_quoted(other, self)
12
+ Arel::Nodes::LessThan.new self, Arel.quoted(other, self)
13
13
  end
14
14
 
15
15
  def <=(other)
16
- Arel::Nodes::LessThanOrEqual.new self, Arel::Nodes.build_quoted(other, self)
16
+ Arel::Nodes::LessThanOrEqual.new self, Arel.quoted(other, self)
17
17
  end
18
18
 
19
19
  # REGEXP function
@@ -21,7 +21,7 @@ module ArelExtensions
21
21
  def =~(other)
22
22
  # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
23
23
  # if arg == :string || arg == :text
24
- Arel::Nodes::Regexp.new self, convert_regexp(other)
24
+ Arel::Nodes::Regexp.new self, convert_regexp(other)
25
25
  # end
26
26
  end
27
27
 
@@ -30,7 +30,7 @@ module ArelExtensions
30
30
  def !~(other)
31
31
  # arg = self.relation.engine.connection.schema_cache.columns_hash(self.relation.table_name)[self.name.to_s].type
32
32
  # if arg == :string || arg == :text
33
- Arel::Nodes::NotRegexp.new self, convert_regexp(other)
33
+ Arel::Nodes::NotRegexp.new self, convert_regexp(other)
34
34
  # end
35
35
  end
36
36
 
@@ -42,17 +42,17 @@ module ArelExtensions
42
42
  when String
43
43
  # Do nothing.
44
44
  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_]')
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_]')
52
52
  else
53
53
  raise(ArgumentError)
54
54
  end
55
- Arel::Nodes.build_quoted(other, self)
55
+ Arel.quoted(other, self)
56
56
  end
57
57
  end
58
58
  end
@@ -1,4 +1,5 @@
1
1
  require 'arel_extensions/nodes/format'
2
+ require 'arel_extensions/nodes/formatted_date'
2
3
  require 'arel_extensions/nodes/duration'
3
4
  require 'arel_extensions/nodes/wday'
4
5
 
@@ -6,22 +7,22 @@ module ArelExtensions
6
7
  module DateDuration
7
8
  # function returns the year (as a number) given a date value.
8
9
  def year
9
- ArelExtensions::Nodes::Duration.new "y", self
10
+ ArelExtensions::Nodes::Duration.new 'y', self
10
11
  end
11
12
 
12
13
  # function returns the month (as a number) given a date value.
13
14
  def month
14
- ArelExtensions::Nodes::Duration.new "m", self
15
+ ArelExtensions::Nodes::Duration.new 'm', self
15
16
  end
16
17
 
17
18
  # function returns the week (as a number) given a date value.
18
19
  def week
19
- ArelExtensions::Nodes::Duration.new "w", self
20
+ ArelExtensions::Nodes::Duration.new 'w', self
20
21
  end
21
22
 
22
23
  # function returns the month (as a number) given a date value.
23
24
  def day
24
- ArelExtensions::Nodes::Duration.new "d", self
25
+ ArelExtensions::Nodes::Duration.new 'd', self
25
26
  end
26
27
 
27
28
  def wday
@@ -29,19 +30,23 @@ module ArelExtensions
29
30
  end
30
31
 
31
32
  def hour
32
- ArelExtensions::Nodes::Duration.new "h", self
33
+ ArelExtensions::Nodes::Duration.new 'h', self
33
34
  end
34
35
 
35
36
  def minute
36
- ArelExtensions::Nodes::Duration.new "mn", self
37
+ ArelExtensions::Nodes::Duration.new 'mn', self
37
38
  end
38
39
 
39
40
  def second
40
- ArelExtensions::Nodes::Duration.new "s", self
41
+ ArelExtensions::Nodes::Duration.new 's', self
41
42
  end
42
43
 
43
- def format(tpl)
44
- ArelExtensions::Nodes::Format.new [self, tpl]
44
+ def format(tpl, time_zone = nil)
45
+ ArelExtensions::Nodes::Format.new [self, tpl, time_zone]
46
+ end
47
+
48
+ def format_date(tpl, time_zone = nil)
49
+ ArelExtensions::Nodes::FormattedDate.new [self, tpl, time_zone]
45
50
  end
46
51
  end
47
52
  end
@@ -0,0 +1,62 @@
1
+ module ArelExtensions
2
+
3
+ #
4
+ # column_of
5
+ #
6
+ # Before the creation of these methods, getting the column name was done
7
+ # uniquely through the code found in `column_of_via_arel_table`.
8
+ #
9
+ # This turned out to be unreliable, most notably when using adapters that do
10
+ # not come with activerecord standard batteries. SQL Server is the most
11
+ # notorious example.
12
+ #
13
+ # Currently, we're using a needlessly complicated way to address this issue.
14
+ # Different versions of activerecord are behaving differently; the public APIs
15
+ # do not seem to come with any guarantees, so we need to be sure that we're
16
+ # coveing all these cases.
17
+
18
+ def self.column_of_via_arel_table(table_name, column_name)
19
+ Arel::Table.engine.connection.schema_cache.columns_hash(table_name)[column_name]
20
+ rescue NoMethodError
21
+ nil
22
+ rescue => e
23
+ warn("Warning: Unexpected exception caught while fetching column name for #{table_name}.#{column_name} in `column_of_via_arel_table`\n#{e.class}")
24
+ warn(e.backtrace)
25
+ nil
26
+ end
27
+
28
+ def self.column_of(table_name, column_name)
29
+ pool = ActiveRecord::Base.connection.pool
30
+ use_arel_table = !ActiveRecord::Base.connected? || \
31
+ (pool.respond_to?(:schema_cache) && pool.schema_cache.nil?)
32
+
33
+ if use_arel_table
34
+ column_of_via_arel_table(table_name, column_name)
35
+ else
36
+ if pool.respond_to?(:pool_config)
37
+ if pool.pool_config.respond_to?(:schema_reflection) # activerecord >= 7.1
38
+ if ActiveRecord.version >= Gem::Version.create('7.2')
39
+ pool.pool_config.schema_reflection.columns_hash(pool, table_name)[column_name]
40
+ else
41
+ pool.pool_config.schema_reflection.columns_hash(ActiveRecord::Base.connection, table_name)[column_name]
42
+ end
43
+ else # activerecord < 7.1
44
+ pool.pool_config.schema_cache.columns_hash(table_name)[column_name]
45
+ end
46
+ elsif pool.respond_to?(:schema_cache) # activerecord < 6.1
47
+ pool.schema_cache.columns_hash(table_name)[column_name]
48
+ else # activerecord < 5.0
49
+ column_of_via_arel_table(table_name, column_name)
50
+ end
51
+ end
52
+ rescue ActiveRecord::ConnectionNotEstablished
53
+ column_of_via_arel_table(table_name, column_name)
54
+ rescue ActiveRecord::StatementInvalid
55
+ nil
56
+ rescue => e
57
+ warn("Warning: Unexpected exception caught while fetching column name for #{table_name}.#{column_name} in `column_of`")
58
+ warn(e)
59
+ warn(e.backtrace)
60
+ nil
61
+ end
62
+ end
@@ -3,23 +3,25 @@ require 'arel'
3
3
  module ArelExtensions
4
4
  module InsertManager
5
5
  def bulk_insert(cols, data)
6
- res_columns = []
7
- case cols.first
8
- when String, Symbol
9
- cols.each { |c|
10
- res_columns << @ast.relation[c]
11
- }
12
- when Array
13
- if String === cols.first.first
14
- res_columns = cols.map {|c| [@ast.relation[c.first]] }
15
- elsif Arel::Attributes::Attribute == cols.first.first
16
- res_columns = cols
17
- end
18
- when NilClass
19
- res_columns = @ast.relation.columns
20
- end
21
- self.values = BulkValues.new(res_columns, data)
22
- @ast.columns = res_columns
6
+ raise ArgumentError, 'cols must be present' if cols.blank?
7
+ columns =
8
+ case cols.first
9
+ 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}"
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
23
25
  end
24
26
 
25
27
  class BulkValues < Arel::Nodes::Node