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

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 (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