activerecord-jdbc-alt-adapter 60.3.0-java → 61.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +11 -11
  3. data/Gemfile +1 -1
  4. data/README.md +16 -12
  5. data/activerecord-jdbc-adapter.gemspec +2 -2
  6. data/activerecord-jdbc-alt-adapter.gemspec +5 -5
  7. data/lib/arel/visitors/postgresql_jdbc.rb +1 -1
  8. data/lib/arel/visitors/sqlserver.rb +16 -0
  9. data/lib/arjdbc/abstract/core.rb +1 -0
  10. data/lib/arjdbc/abstract/database_statements.rb +4 -0
  11. data/lib/arjdbc/abstract/transaction_support.rb +20 -7
  12. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  13. data/lib/arjdbc/mssql/adapter.rb +3 -1
  14. data/lib/arjdbc/mssql/column.rb +14 -0
  15. data/lib/arjdbc/mssql/connection_methods.rb +0 -3
  16. data/lib/arjdbc/mssql/database_limits.rb +7 -0
  17. data/lib/arjdbc/mssql/extensions/attribute_methods.rb +1 -1
  18. data/lib/arjdbc/mssql/schema_creation.rb +2 -2
  19. data/lib/arjdbc/mssql/schema_statements.rb +29 -1
  20. data/lib/arjdbc/mssql.rb +1 -1
  21. data/lib/arjdbc/mysql/adapter.rb +14 -5
  22. data/lib/arjdbc/mysql/connection_methods.rb +5 -1
  23. data/lib/arjdbc/postgresql/adapter.rb +85 -73
  24. data/lib/arjdbc/postgresql/column.rb +1 -1
  25. data/lib/arjdbc/postgresql/oid_types.rb +4 -3
  26. data/lib/arjdbc/sqlite3/adapter.rb +95 -58
  27. data/lib/arjdbc/sqlite3/connection_methods.rb +11 -1
  28. data/lib/arjdbc/tasks/databases.rake +15 -10
  29. data/lib/arjdbc/tasks/mssql_database_tasks.rb +88 -31
  30. data/lib/arjdbc/version.rb +3 -1
  31. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +106 -68
  32. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +82 -36
  33. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +3 -4
  34. metadata +8 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fef06d854287aa90265b3470d9e126f556afee76bcf75d6efd887c0390b3570e
4
- data.tar.gz: 45a22fd5240546ac6ae2de94bff4ced69c6155d0e78bce20feeabe65c51735e2
3
+ metadata.gz: dd61f85687802bf7bad5e3013413ccbda73395044d46775e8fa5f6d57e8410ca
4
+ data.tar.gz: 245c8e59a5bbf3e87e7f9f0759070dda617801ce650bdb089cb1c16daa4119eb
5
5
  SHA512:
6
- metadata.gz: 6b8742114ade9460ca8f7bb5fe13db0f2d1ee5195e0d93aebcc68dd6a940c3601a8a7a641c02165adb37a2e458034eb438a0ccd6f7110b51a6427f4c37f3d5ce
7
- data.tar.gz: 7f73c8c6bc76ff739af784a0d01faa0918c54e2cfa99e4394699ce9cd845ca6519561a4f59ef5002ec0c3a6cc6e17c21617ee975fce031ec4b1fb450019210f6
6
+ metadata.gz: f11b067072016b63fa265435c90d45672463cc80e5ac1e8199bc96d209704affdc30a75d89a6ac5fb67ea5fad06c91c7ef59af87651e387beb360e64dc027e32
7
+ data.tar.gz: b1e71248871946ccaa981bb0a74f08fdeba605637b020f704ae0197dad96c00947cfe0f87752f010499d6ddad9a6a97ffe7791cb6f7a0dd69e4f57f2d7643014
data/.travis.yml CHANGED
@@ -15,7 +15,7 @@ install:
15
15
 
16
16
  language: ruby
17
17
  rvm:
18
- - jruby-9.2.7.0
18
+ - jruby-9.2.14.0
19
19
  jdk:
20
20
  - openjdk8
21
21
 
@@ -37,8 +37,8 @@ before_script:
37
37
  mysql -e "grant all privileges on activerecord_unittest.* to rails@localhost;" && \
38
38
  mysql -e "grant all privileges on activerecord_unittest2.* to rails@localhost;" && \
39
39
  mysql -e "grant all privileges on inexistent_activerecord_unittest.* to rails@localhost;" && \
40
- mysql -e "CREATE DATABASE activerecord_unittest DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;" && \
41
- mysql -e "CREATE DATABASE activerecord_unittest2 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;" \
40
+ mysql -e "CREATE DATABASE activerecord_unittest DEFAULT CHARACTER SET utf8mb4;" && \
41
+ mysql -e "CREATE DATABASE activerecord_unittest2 DEFAULT CHARACTER SET utf8mb4;" \
42
42
  || true
43
43
  - |
44
44
  [ "$DB" == "postgresql" ] && [ "$TEST_PREFIX" == "rails:" ] && \
@@ -48,7 +48,7 @@ before_script:
48
48
 
49
49
  env:
50
50
  global:
51
- - AR_VERSION="6-0-stable"
51
+ - AR_VERSION="master"
52
52
  matrix:
53
53
  allow_failures:
54
54
  - rvm: jruby-head
@@ -111,18 +111,18 @@ matrix:
111
111
  env: DB=mariadb PREPARED_STATEMENTS=true
112
112
 
113
113
  # Rails test-suite :
114
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-0-stable" # PS off by default
115
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-0-stable" PREPARED_STATEMENTS=true
116
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-0-stable" DRIVER=MariaDB
114
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-1-stable" # PS off by default
115
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-1-stable" PREPARED_STATEMENTS=true
116
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-1-stable" DRIVER=MariaDB
117
117
 
118
118
  - addons:
119
119
  postgresql: "10"
120
- env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="6-0-stable" # PS on by default
120
+ env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="6-1-stable" # PS on by default
121
121
  - addons:
122
122
  postgresql: "10"
123
- env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="6-0-stable" PREPARED_STATEMENTS=false
123
+ env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="6-1-stable" PREPARED_STATEMENTS=false
124
124
  - addons:
125
125
  postgresql: "9.4"
126
- env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="6-0-stable" # PS on by default
126
+ env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="6-1-stable" # PS on by default
127
127
 
128
- - env: DB=sqlite3 TEST_PREFIX="rails:" AR_VERSION="6-0-stable"
128
+ - env: DB=sqlite3 TEST_PREFIX="rails:" AR_VERSION="6-1-stable"
data/Gemfile CHANGED
@@ -61,7 +61,7 @@ end
61
61
 
62
62
  group :rails do
63
63
  group :test do
64
- gem 'minitest', '~> 5.11.3', require: nil
64
+ gem 'minitest', '~> 5.12.2', require: nil
65
65
  gem 'minitest-excludes', '~> 2.0.1', require: nil
66
66
  gem 'minitest-rg', require: nil
67
67
 
data/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  This adapter is a fork of the ActiveRecord JDBC Adapter with basic support for
4
4
  **SQL Server/Azure SQL**. This adapter may work with other databases
5
- supported by the original adapter such as PostgreSQL but it is advised to
6
- use the [original adapter](https://github.com/jruby/active)
5
+ supported by the original adapter such as MySQL but it is advised to
6
+ use the [original adapter](https://github.com/jruby/activerecord-jdbc-adapter)
7
7
 
8
8
  This adapter only works with JRuby and it is advised to install the latest
9
9
  stable of this adapter and Rails
@@ -14,10 +14,11 @@ stable of this adapter and Rails
14
14
  | 51.7.0 | 5.1.7 | 9.1.x |
15
15
  | 52.6.0 | 5.2.4 | 9.1.x |
16
16
  | 60.1.0 | 6.0.3 | 9.2.9 |
17
+ | 61.0.0 | 6.1.3 | 9.2.16 |
17
18
 
18
19
  This adapter passes most of the Rails tests (ActiveRecord tests) with the
19
20
  exception of some test that are not compatible with the SQL Server. To run
20
- the test use the following fork [Rails](https://github.com/JesseChavez/rails/tree/6-0-stable-dev),
21
+ the test use the following fork [Rails](https://github.com/JesseChavez/rails/tree/6-1-stable-dev),
21
22
  and the instructions in file `RUNNING_TESTS.md`. The fork has some
22
23
  schema tweaks to make it compatible with SQL Server.
23
24
 
@@ -28,16 +29,18 @@ Add the following to your `Gemfile`:
28
29
  ```ruby
29
30
  platforms :jruby do
30
31
  # Use jdbc as the database for Active Record
31
- gem 'activerecord-jdbc-alt-adapter', '~> 60.1.0'
32
+ gem 'activerecord-jdbc-alt-adapter', '~> 61.0.0'
32
33
  gem 'jdbc-mssql', '~> 0.9.0'
33
34
  end
34
35
  ```
35
36
 
36
37
  Or look at the sample rails and see how is set up:
37
38
 
39
+ - Rails 6.1 sample app [wombat61](https://github.com/JesseChavez/wombat61)
40
+
38
41
  - Rails 6.0 sample app [wombat60](https://github.com/JesseChavez/wombat60)
39
42
 
40
- - Old rails 5.0 app [wombat50](https://github.com/JesseChavez/wombat50)
43
+ - Rails 5.0 sample app [wombat50](https://github.com/JesseChavez/wombat50)
41
44
 
42
45
 
43
46
  ### Breaking changes
@@ -135,7 +138,8 @@ Versions are targeted at certain versions of Rails and live on their own branche
135
138
  | 50.x | 5.0.x | 50-stable | 9.1.x | 7 |
136
139
  | 51.x | 5.1.x | 51-stable | 9.1.x | 7 |
137
140
  | 52.x | 5.2.x | 52-stable | 9.1.x | 7 |
138
- | 60.x | 6.0.x | master | 9.2.7 | 8 |
141
+ | 60.x | 6.0.x | 60-stable | 9.2.7 | 8 |
142
+ | 61.x | 6.1.x | master | 9.2.7 | 8 |
139
143
 
140
144
  Note that JRuby 9.1.x is end-of-life. We recommend Java 8 at a minimum for all
141
145
  versions.
@@ -228,8 +232,8 @@ Proceed as with Rails; specify `ActiveRecord` in your Bundle along with the
228
232
  chosen JDBC adapter(s), this time sample *Gemfile* for MySQL:
229
233
 
230
234
  ```ruby
231
- gem 'activerecord', '~> 5.0.6'
232
- gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
235
+ gem 'activerecord', '~> 6.0.3'
236
+ gem 'activerecord-jdbcmysql-adapter', '~> 60.2', :platform => :jruby
233
237
  ```
234
238
 
235
239
  When you `require 'bundler/setup'` everything will be set up for you as expected.
@@ -238,13 +242,13 @@ When you `require 'bundler/setup'` everything will be set up for you as expected
238
242
 
239
243
  Install the needed gems with JRuby, for example:
240
244
 
241
- gem install activerecord -v "~> 5.0.6"
242
- gem install activerecord-jdbc-adapter --ignore-dependencies
245
+ gem install activerecord -v "~> 6.0.3"
246
+ gem install activerecord-jdbc-adapter -v "~> 60.2" --ignore-dependencies
243
247
 
244
248
  If you wish to use the adapter for a specific database, you can install it
245
249
  directly and the (jdbc-) driver gem (dependency) will be installed as well:
246
250
 
247
- jruby -S gem install activerecord-jdbcmysql-adapter
251
+ jruby -S gem install activerecord-jdbcmysql-adapter -v "~> 60.2"
248
252
 
249
253
  Your program should include:
250
254
 
@@ -284,7 +288,7 @@ ask on the #JRuby IRC channel on http://freenode.net/ (try [web-chat][6]).
284
288
  This project was originally written by [Nick Sieger](http://github.com/nicksieger)
285
289
  and [Ola Bini](http://github.com/olabini) with lots of help from the JRuby community.
286
290
  Polished 3.x compatibility and 4.x support (for AR-JDBC >= 1.3.0) was managed by
287
- [Karol Bucek](http://github.com/kares) among others. Support for Rails 6 was
291
+ [Karol Bucek](http://github.com/kares) among others. Support for Rails 6.0 and 6.1 was
288
292
  contributed by [shellyBits GmbH](https://shellybits.ch/)
289
293
 
290
294
  ## License
@@ -34,14 +34,14 @@ Gem::Specification.new do |gem|
34
34
  #gem.requirements << "jar org.postgresql:postgresql, 42.1.4.jre6, :scope => :compile"
35
35
 
36
36
  # compilation .jar dependencies for extension (at least until `mvn') :
37
- gem.add_development_dependency 'jdbc-mysql', '~> 5.1.44'
37
+ gem.add_development_dependency 'jdbc-mysql', '~> 8.0.0'
38
38
  gem.add_development_dependency 'jdbc-postgres', '~> 42.1'
39
39
  end
40
40
 
41
41
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
42
42
  gem.test_files = gem.files.grep(%r{^test/})
43
43
 
44
- gem.add_dependency 'activerecord', '~> 6.0.0'
44
+ gem.add_dependency 'activerecord', '~> 6.1.0'
45
45
 
46
46
  #gem.add_development_dependency 'test-unit', '2.5.4'
47
47
  #gem.add_development_dependency 'test-unit-context', '>= 0.3.0'
@@ -5,8 +5,8 @@ Gem::Specification.new do |gem|
5
5
  path = File.expand_path('lib/arjdbc/version.rb', File.dirname(__FILE__))
6
6
  gem.version = File.read(path).match( /.*VERSION\s*=\s*['"](.*)['"]/m )[1]
7
7
  gem.platform = 'java' # due jar-dependencies to resolve requirements for ext
8
- gem.authors = ['Nick Sieger, Ola Bini, Karol Bucek and JRuby contributors']
9
- gem.email = ['nick@nicksieger.com', 'ola.bini@gmail.com', 'self@kares.org']
8
+ gem.authors = ['Nick Sieger, Ola Bini, Karol Bucek, Jesse Chavez, and JRuby contributors']
9
+ gem.email = ['nick@nicksieger.com', 'ola.bini@gmail.com', 'self@kares.org', 'jesse.chavez.r@gmail.com']
10
10
  gem.homepage = 'https://github.com/JesseChavez/activerecord-jdbc-adapter'
11
11
  gem.license = 'BSD-2-Clause'
12
12
  gem.summary = 'ActiveRecord JDBC adapter, for use within JRuby on Rails and SQL Server'
@@ -36,19 +36,19 @@ Gem::Specification.new do |gem|
36
36
  #gem.requirements << "jar org.postgresql:postgresql, 42.1.4.jre6, :scope => :compile"
37
37
 
38
38
  # compilation .jar dependencies for extension (at least until `mvn') :
39
- gem.add_development_dependency 'jdbc-mysql', '~> 5.1.44'
39
+ gem.add_development_dependency 'jdbc-mysql', '~> 8.0.0'
40
40
  gem.add_development_dependency 'jdbc-postgres', '~> 42.1'
41
41
  end
42
42
 
43
43
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
44
44
  gem.test_files = gem.files.grep(%r{^test/})
45
45
 
46
- gem.add_dependency 'activerecord', '~> 6.0.0'
46
+ gem.add_dependency 'activerecord', '~> 6.1.0'
47
47
 
48
48
  #gem.add_development_dependency 'test-unit', '2.5.4'
49
49
  #gem.add_development_dependency 'test-unit-context', '>= 0.3.0'
50
50
  #gem.add_development_dependency 'mocha', '~> 0.13.1'
51
51
 
52
- gem.rdoc_options = ["--main", "README.md", "-SHN", "-f", "darkfish"]
52
+ gem.rdoc_options = ["--main", "README.md", "-HN", "-f", "darkfish"]
53
53
  end
54
54
 
@@ -2,5 +2,5 @@ require 'arel/visitors/compat'
2
2
 
3
3
  class Arel::Visitors::PostgreSQL
4
4
  # AREL converts bind argument markers "?" to "$n" for PG, but JDBC wants "?".
5
- remove_method :visit_Arel_Nodes_BindParam if ArJdbc::AR42
5
+ remove_method :bind_block
6
6
  end
@@ -51,6 +51,11 @@ module Arel
51
51
  end
52
52
  end
53
53
 
54
+ def visit_Arel_Nodes_Grouping(o, collector)
55
+ remove_invalid_ordering_from_select_statement(o.expr)
56
+ super
57
+ end
58
+
54
59
  def visit_Arel_Nodes_SelectStatement o, collector
55
60
  @select_statement = o
56
61
  distinct_One_As_One_Is_So_Not_Fetch o
@@ -183,9 +188,11 @@ module Arel
183
188
 
184
189
  def make_Fetch_Possible_And_Deterministic o
185
190
  return if o.limit.nil? && o.offset.nil?
191
+
186
192
  t = table_From_Statement o
187
193
  pk = primary_Key_From_Table t
188
194
  return unless pk
195
+
189
196
  if o.orders.empty?
190
197
  # Prefer deterministic vs a simple `(SELECT NULL)` expr.
191
198
  o.orders = [pk.asc]
@@ -221,6 +228,7 @@ module Arel
221
228
 
222
229
  def primary_Key_From_Table t
223
230
  return unless t
231
+
224
232
  # column_name = schema_cache.primary_keys(t.name) || column_cache(t.name).first.try(:second).try(:name)
225
233
  # NOTE: for table name aliases columns_hash('table_alias') requires to return an empty hash.
226
234
  column_name = @connection.schema_cache.primary_keys(t.name) ||
@@ -234,6 +242,14 @@ module Arel
234
242
  ).quoted
235
243
  end
236
244
 
245
+ # Need to remove ordering from subqueries unless TOP/OFFSET also used. Otherwise, SQLServer
246
+ # returns error "The ORDER BY clause is invalid in views, inline functions, derived tables,
247
+ # subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified."
248
+ def remove_invalid_ordering_from_select_statement(node)
249
+ return unless Arel::Nodes::SelectStatement === node
250
+
251
+ node.orders = [] unless node.offset || node.limit
252
+ end
237
253
  end
238
254
  end
239
255
  end
@@ -56,6 +56,7 @@ module ArJdbc
56
56
  case exception
57
57
  when SystemExit, SignalException, NoMemoryError then exception
58
58
  when ActiveModel::RangeError, TypeError, RuntimeError then exception
59
+ when ActiveRecord::ConnectionNotEstablished then exception
59
60
  else super
60
61
  end
61
62
  end
@@ -15,6 +15,7 @@ module ArJdbc
15
15
  end
16
16
 
17
17
  materialize_transactions
18
+ mark_transaction_written_if_write(sql)
18
19
 
19
20
  binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
20
21
 
@@ -35,6 +36,7 @@ module ArJdbc
35
36
  end
36
37
 
37
38
  materialize_transactions
39
+ mark_transaction_written_if_write(sql)
38
40
 
39
41
  binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
40
42
 
@@ -55,6 +57,7 @@ module ArJdbc
55
57
  end
56
58
 
57
59
  materialize_transactions
60
+ mark_transaction_written_if_write(sql)
58
61
 
59
62
  binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
60
63
 
@@ -72,6 +75,7 @@ module ArJdbc
72
75
  end
73
76
 
74
77
  materialize_transactions
78
+ mark_transaction_written_if_write(sql)
75
79
 
76
80
  log(sql, name) { @connection.execute(sql) }
77
81
  end
@@ -24,26 +24,26 @@ module ArJdbc
24
24
  # Starts a database transaction.
25
25
  # @override
26
26
  def begin_db_transaction
27
- log('BEGIN TRANSACTION', nil) { @connection.begin }
27
+ log('BEGIN', 'TRANSACTION') { @connection.begin }
28
28
  end
29
29
 
30
30
  # Starts a database transaction.
31
31
  # @param isolation the transaction isolation to use
32
32
  def begin_isolated_db_transaction(isolation)
33
- log("BEGIN ISOLATED TRANSACTION - #{isolation}", nil) { @connection.begin(isolation) }
33
+ log("BEGIN ISOLATED - #{isolation}", 'TRANSACTION') { @connection.begin(isolation) }
34
34
  end
35
35
 
36
36
  # Commits the current database transaction.
37
37
  # @override
38
38
  def commit_db_transaction
39
- log('COMMIT TRANSACTION', nil) { @connection.commit }
39
+ log('COMMIT', 'TRANSACTION') { @connection.commit }
40
40
  end
41
41
 
42
42
  # Rolls back the current database transaction.
43
43
  # Called from 'rollback_db_transaction' in the AbstractAdapter
44
44
  # @override
45
45
  def exec_rollback_db_transaction
46
- log('ROLLBACK TRANSACTION', nil) { @connection.rollback }
46
+ log('ROLLBACK', 'TRANSACTION') { @connection.rollback }
47
47
  end
48
48
 
49
49
  ########################## Savepoint Interface ############################
@@ -55,7 +55,7 @@ module ArJdbc
55
55
  # @since 1.3.0
56
56
  # @extension added optional name parameter
57
57
  def create_savepoint(name = current_savepoint_name)
58
- log("SAVEPOINT #{name}", 'Savepoint') { @connection.create_savepoint(name) }
58
+ log("SAVEPOINT #{name}", 'TRANSACTION') { @connection.create_savepoint(name) }
59
59
  end
60
60
 
61
61
  # Transaction rollback to a given (previously created) save-point.
@@ -64,7 +64,7 @@ module ArJdbc
64
64
  # @param name the save-point name
65
65
  # @extension added optional name parameter
66
66
  def exec_rollback_to_savepoint(name = current_savepoint_name)
67
- log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { @connection.rollback_savepoint(name) }
67
+ log("ROLLBACK TO SAVEPOINT #{name}", 'TRANSACTION') { @connection.rollback_savepoint(name) }
68
68
  end
69
69
 
70
70
  # Release a previously created save-point.
@@ -73,9 +73,22 @@ module ArJdbc
73
73
  # @param name the save-point name
74
74
  # @extension added optional name parameter
75
75
  def release_savepoint(name = current_savepoint_name)
76
- log("RELEASE SAVEPOINT #{name}", 'Savepoint') { @connection.release_savepoint(name) }
76
+ log("RELEASE SAVEPOINT #{name}", 'TRANSACTION') { @connection.release_savepoint(name) }
77
77
  end
78
78
 
79
79
  end
80
80
  end
81
81
  end
82
+
83
+ # patch to avoid the usage of WeakMap
84
+ require 'active_record/connection_adapters/abstract/transaction'
85
+ module ActiveRecord
86
+ module ConnectionAdapters
87
+ class Transaction
88
+ def add_record(record, ensure_finalize = true)
89
+ @records ||= []
90
+ @records << record
91
+ end
92
+ end
93
+ end
94
+ end
Binary file
@@ -224,7 +224,7 @@ module ActiveRecord
224
224
 
225
225
  # FIXME: This needs to be fixed when we implement the collation per
226
226
  # column basis. At the moment we only use the global database collation
227
- def default_uniqueness_comparison(attribute, value, klass) # :nodoc:
227
+ def default_uniqueness_comparison(attribute, value) # :nodoc:
228
228
  column = column_for_attribute(attribute)
229
229
 
230
230
  if [:string, :text].include?(column.type) && collation && !collation.match(/_CS/) && !value.nil?
@@ -313,6 +313,8 @@ module ActiveRecord
313
313
 
314
314
  def translate_exception(exception, message:, sql:, binds:)
315
315
  case message
316
+ when /no connection available/i
317
+ ConnectionNotEstablished.new(exception)
316
318
  when /(cannot insert duplicate key .* with unique index) | (violation of unique key constraint)/i
317
319
  RecordNotUnique.new(message, sql: sql, binds: binds)
318
320
  when /Lock request time out period exceeded/i
@@ -5,8 +5,10 @@ module ActiveRecord
5
5
  # MSSQL specific extensions to column definitions in a table.
6
6
  class MSSQLColumn < Column
7
7
  attr_reader :table_name
8
+
8
9
  def initialize(name, raw_default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
9
10
  @table_name = table_name
11
+
10
12
  default = extract_default(raw_default)
11
13
 
12
14
  super(name, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
@@ -28,6 +30,18 @@ module ActiveRecord
28
30
  sql_type.downcase.include? 'identity'
29
31
  end
30
32
 
33
+ def ==(other)
34
+ other.is_a?(MSSQLColumn) &&
35
+ super &&
36
+ table_name == other.table_name
37
+ end
38
+ alias :eql? :==
39
+
40
+ def hash
41
+ MSSQLColumn.hash ^
42
+ super.hash ^
43
+ table_name.hash
44
+ end
31
45
  end
32
46
  end
33
47
  end
@@ -78,15 +78,12 @@ ArJdbc::ConnectionMethods.module_eval do
78
78
  url << "sendTimeAsDatetime=#{config[:send_time_as_datetime] || false};"
79
79
  url << "loginTimeout=#{config[:login_timeout].to_i};" if config[:login_timeout]
80
80
  url << "lockTimeout=#{config[:lock_timeout].to_i};"
81
- url << "encrypt=#{config[:encrypt]};" if config.key?(:encrypt)
82
- url << "trustServerCertificate=#{config[:trust_server_certificate]};" if config.key?(:trust_server_certificate)
83
81
  app = config[:appname] || config[:application]
84
82
  url << "applicationName=#{app};" if app
85
83
  isc = config[:integrated_security] # Win only - needs sqljdbc_auth.dll
86
84
  url << "integratedSecurity=#{isc};" unless isc.nil?
87
85
  url
88
86
  end
89
-
90
87
  jdbc_connection(config)
91
88
  end
92
89
  alias_method :jdbcsqlserver_connection, :sqlserver_connection
@@ -8,6 +8,13 @@ module ActiveRecord
8
8
  # Returns the maximum number of elements in an IN (x,y,z) clause.
9
9
  # NOTE: Could not find a limit for IN in mssql but 10000 seems to work
10
10
  # with the active record tests
11
+ # FIXME: this method was deprecated in rails 6.1, and it seems the only
12
+ # code that used this method was the oracle visitor, the code was moved
13
+ # from rails to the adapter itself.
14
+ # https://github.com/rsim/oracle-enhanced/pull/2008/files
15
+ # related:
16
+ # https://github.com/rails/rails/pull/38946
17
+ # https://github.com/rails/rails/pull/39057
11
18
  def in_clause_length
12
19
  10_000
13
20
  end
@@ -22,7 +22,7 @@ module ActiveRecord
22
22
  attribute_names.delete_if do |name|
23
23
  # It seems is only required to check if column in identity or not.
24
24
  # This allows to update rails custom primary keys
25
- next true if readonly_attribute?(name)
25
+ next true if self.class.readonly_attribute?(name)
26
26
 
27
27
  column = self.class.columns_hash[name]
28
28
  column && column.identity?
@@ -3,7 +3,7 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module MSSQL
6
- class SchemaCreation < AbstractAdapter::SchemaCreation
6
+ class SchemaCreation < SchemaCreation
7
7
  private
8
8
 
9
9
  def visit_TableDefinition(o)
@@ -33,7 +33,7 @@ module ActiveRecord
33
33
  end
34
34
 
35
35
  create_sql << "(#{statements.join(', ')})" if statements.present?
36
- add_table_options!(create_sql, table_options(o))
36
+ add_table_options!(create_sql, o)
37
37
  create_sql
38
38
  end
39
39
  end
@@ -109,7 +109,17 @@ module ActiveRecord
109
109
  end
110
110
 
111
111
  def create_database(name, options = {})
112
- execute "CREATE DATABASE #{quote_database_name(name)}"
112
+ edition_options = create_db_edition_options(options)
113
+
114
+ if options[:collation] && edition_options.present?
115
+ execute "CREATE DATABASE #{quote_database_name(name)} COLLATE #{options[:collation]} (#{edition_options.join(', ')})"
116
+ elsif options[:collation]
117
+ execute "CREATE DATABASE #{quote_database_name(name)} COLLATE #{options[:collation]}"
118
+ elsif edition_options.present?
119
+ execute "CREATE DATABASE #{quote_database_name(name)} (#{edition_options.join(', ')})"
120
+ else
121
+ execute "CREATE DATABASE #{quote_database_name(name)}"
122
+ end
113
123
  end
114
124
 
115
125
  def recreate_database(name, options = {})
@@ -119,6 +129,9 @@ module ActiveRecord
119
129
 
120
130
  def remove_column(table_name, column_name, type = nil, options = {})
121
131
  raise ArgumentError.new('You must specify at least one column name. Example: remove_column(:people, :first_name)') if column_name.is_a? Array
132
+
133
+ return if options[:if_exists] == true && !column_exists?(table_name, column_name)
134
+
122
135
  remove_check_constraints(table_name, column_name)
123
136
  remove_default_constraint(table_name, column_name)
124
137
  remove_indexes(table_name, column_name)
@@ -340,6 +353,21 @@ module ActiveRecord
340
353
  field
341
354
  end
342
355
 
356
+ def create_db_edition_options(options = {})
357
+ edition_config = options.select { |k, _v| k.match?('azure') }
358
+
359
+ edition_config.each_with_object([]) do |(key, value), output|
360
+ output << case key
361
+ when :azure_maxsize
362
+ "MAXSIZE = #{value}"
363
+ when :azure_edition
364
+ "EDITION = #{value}"
365
+ when :service_objective
366
+ "SERVICE_OBJECTIVE = #{value}"
367
+ end
368
+ end.compact
369
+ end
370
+
343
371
  def data_source_sql(name = nil, type: nil)
344
372
  scope = quoted_scope(name, type: type)
345
373
  table_name = 'TABLE_NAME'
data/lib/arjdbc/mssql.rb CHANGED
@@ -6,4 +6,4 @@ module ArJdbc
6
6
  MsSQL = MSSQL # compatibility with 1.2
7
7
  end
8
8
 
9
- ArJdbc.warn_unsupported_adapter 'mssql', [6, 0] # warns on AR >= 4.2
9
+ ArJdbc.warn_unsupported_adapter 'mssql', [6, 1] # warns on AR >= 4.2
@@ -33,10 +33,10 @@ module ActiveRecord
33
33
 
34
34
  include ArJdbc::MySQL
35
35
 
36
- def initialize(connection, logger, connection_parameters, config)
37
- super
36
+ def initialize(connection, logger, connection_options, config)
37
+ superclass_config = config.reverse_merge(prepared_statements: false)
38
+ super(connection, logger, connection_options, superclass_config)
38
39
 
39
- @prepared_statements = false unless config.key?(:prepared_statements)
40
40
  # configure_connection taken care of at ArJdbc::Abstract::Core
41
41
  end
42
42
 
@@ -88,7 +88,7 @@ module ActiveRecord
88
88
 
89
89
  # from MySQL::DatabaseStatements
90
90
  READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
91
- :begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :describe, :desc
91
+ :desc, :describe, :set, :show, :use
92
92
  ) # :nodoc:
93
93
  private_constant :READ_QUERY
94
94
 
@@ -96,6 +96,15 @@ module ActiveRecord
96
96
  !READ_QUERY.match?(sql)
97
97
  end
98
98
 
99
+ def explain(arel, binds = [])
100
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
101
+ start = Concurrent.monotonic_time
102
+ result = exec_query(sql, "EXPLAIN", binds)
103
+ elapsed = Concurrent.monotonic_time - start
104
+
105
+ MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
106
+ end
107
+
99
108
  # Reloading the type map in abstract/statement_cache.rb blows up postgres
100
109
  def clear_cache!
101
110
  reload_type_map
@@ -179,7 +188,7 @@ module ActiveRecord
179
188
 
180
189
  # defined in MySQL::DatabaseStatements which is not included
181
190
  def default_insert_value(column)
182
- Arel.sql("DEFAULT") unless column.auto_increment?
191
+ super unless column.auto_increment?
183
192
  end
184
193
 
185
194
  # FIXME: optimize insert_fixtures_set by using JDBC Statement.addBatch()/executeBatch()
@@ -68,6 +68,7 @@ ArJdbc::ConnectionMethods.module_eval do
68
68
  # with reconnect fail-over sets connection read-only (by default)
69
69
  # properties['failOverReadOnly'] ||= 'false'
70
70
  end
71
+ properties['noDatetimeStringSync'] = true unless properties.key?('noDatetimeStringSync')
71
72
  end
72
73
  if config[:sslkey] || sslcert = config[:sslcert] # || config[:use_ssl]
73
74
  properties['useSSL'] ||= true # supported by MariaDB as well
@@ -90,11 +91,12 @@ ArJdbc::ConnectionMethods.module_eval do
90
91
  properties['localSocket'] ||= socket if mariadb_driver
91
92
  end
92
93
 
94
+ # properties['useJDBCCompliantTimezoneShift'] ||= true
93
95
  # for the Connector/J 5.1 line this is true by default - but it requires some really nasty
94
96
  # quirks to get casted Time values extracted properly according for AR's default_timezone
95
97
  # - thus we're turning it off (should be off in newer driver versions >= 6 anyway)
96
98
  # + also MariaDB driver is compilant and we would need to branch out based on driver
97
- properties['useLegacyDatetimeCode'] = false
99
+ properties['useLegacyDatetimeCode'] = false # disables the effect of 'useTimezone'
98
100
 
99
101
  jdbc_connection(config)
100
102
  end
@@ -102,6 +104,8 @@ ArJdbc::ConnectionMethods.module_eval do
102
104
  alias_method :mysql2_connection, :mysql_connection
103
105
 
104
106
  def mariadb_connection(config)
107
+ config = config.deep_dup
108
+
105
109
  config[:adapter_spec] ||= ::ArJdbc::MySQL
106
110
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::Mysql2Adapter unless config.key?(:adapter_class)
107
111