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.
- checksums.yaml +4 -4
- data/.travis.yml +11 -11
- data/Gemfile +1 -1
- data/README.md +16 -12
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/activerecord-jdbc-alt-adapter.gemspec +5 -5
- data/lib/arel/visitors/postgresql_jdbc.rb +1 -1
- data/lib/arel/visitors/sqlserver.rb +16 -0
- data/lib/arjdbc/abstract/core.rb +1 -0
- data/lib/arjdbc/abstract/database_statements.rb +4 -0
- data/lib/arjdbc/abstract/transaction_support.rb +20 -7
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/mssql/adapter.rb +3 -1
- data/lib/arjdbc/mssql/column.rb +14 -0
- data/lib/arjdbc/mssql/connection_methods.rb +0 -3
- data/lib/arjdbc/mssql/database_limits.rb +7 -0
- data/lib/arjdbc/mssql/extensions/attribute_methods.rb +1 -1
- data/lib/arjdbc/mssql/schema_creation.rb +2 -2
- data/lib/arjdbc/mssql/schema_statements.rb +29 -1
- data/lib/arjdbc/mssql.rb +1 -1
- data/lib/arjdbc/mysql/adapter.rb +14 -5
- data/lib/arjdbc/mysql/connection_methods.rb +5 -1
- data/lib/arjdbc/postgresql/adapter.rb +85 -73
- data/lib/arjdbc/postgresql/column.rb +1 -1
- data/lib/arjdbc/postgresql/oid_types.rb +4 -3
- data/lib/arjdbc/sqlite3/adapter.rb +95 -58
- data/lib/arjdbc/sqlite3/connection_methods.rb +11 -1
- data/lib/arjdbc/tasks/databases.rake +15 -10
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +88 -31
- data/lib/arjdbc/version.rb +3 -1
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +106 -68
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +82 -36
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +3 -4
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd61f85687802bf7bad5e3013413ccbda73395044d46775e8fa5f6d57e8410ca
|
4
|
+
data.tar.gz: 245c8e59a5bbf3e87e7f9f0759070dda617801ce650bdb089cb1c16daa4119eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
41
|
-
mysql -e "CREATE DATABASE activerecord_unittest2 DEFAULT CHARACTER SET
|
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="
|
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-
|
115
|
-
- env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-
|
116
|
-
- env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="6-
|
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-
|
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-
|
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-
|
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-
|
128
|
+
- env: DB=sqlite3 TEST_PREFIX="rails:" AR_VERSION="6-1-stable"
|
data/Gemfile
CHANGED
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
|
6
|
-
use the [original adapter](https://github.com/jruby/
|
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-
|
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', '~>
|
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
|
-
-
|
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 |
|
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', '~>
|
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 "~>
|
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', '~>
|
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.
|
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', '~>
|
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.
|
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", "-
|
52
|
+
gem.rdoc_options = ["--main", "README.md", "-HN", "-f", "darkfish"]
|
53
53
|
end
|
54
54
|
|
@@ -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
|
data/lib/arjdbc/abstract/core.rb
CHANGED
@@ -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'
|
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
|
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'
|
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'
|
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}", '
|
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}", '
|
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}", '
|
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
|
data/lib/arjdbc/mssql/adapter.rb
CHANGED
@@ -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
|
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
|
data/lib/arjdbc/mssql/column.rb
CHANGED
@@ -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 <
|
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,
|
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
|
-
|
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
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -33,10 +33,10 @@ module ActiveRecord
|
|
33
33
|
|
34
34
|
include ArJdbc::MySQL
|
35
35
|
|
36
|
-
def initialize(connection, logger,
|
37
|
-
|
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
|
-
:
|
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
|
-
|
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
|
|