activerecord-jdbc-adapter 5.0.pre1 → 51.0
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.
- checksums.yaml +5 -5
- data/.gitignore +1 -2
- data/.travis.yml +15 -416
- data/Gemfile +35 -37
- data/README.md +23 -118
- data/RUNNING_TESTS.md +31 -26
- data/Rakefile +2 -3
- data/activerecord-jdbc-adapter.gemspec +1 -2
- data/lib/arjdbc/abstract/connection_management.rb +21 -0
- data/lib/arjdbc/abstract/core.rb +62 -0
- data/lib/arjdbc/abstract/database_statements.rb +46 -0
- data/lib/arjdbc/abstract/statement_cache.rb +58 -0
- data/lib/arjdbc/abstract/transaction_support.rb +86 -0
- data/lib/arjdbc/derby/adapter.rb +6 -1
- data/lib/arjdbc/discover.rb +0 -7
- data/lib/arjdbc/firebird/adapter.rb +2 -2
- data/lib/arjdbc/jdbc/adapter.rb +10 -252
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/connection.rb +6 -0
- data/lib/arjdbc/jdbc.rb +2 -2
- data/lib/arjdbc/mysql/adapter.rb +87 -944
- data/lib/arjdbc/mysql/connection_methods.rb +4 -2
- data/lib/arjdbc/postgresql/adapter.rb +288 -1023
- data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +8 -5
- data/lib/arjdbc/postgresql/column.rb +10 -599
- data/lib/arjdbc/postgresql/connection_methods.rb +9 -0
- data/lib/arjdbc/postgresql/name.rb +24 -0
- data/lib/arjdbc/postgresql/oid_types.rb +25 -110
- data/lib/arjdbc/sqlite3/adapter.rb +171 -170
- data/lib/arjdbc/tasks/database_tasks.rb +1 -3
- data/lib/arjdbc/tasks/db2_database_tasks.rb +2 -2
- data/lib/arjdbc/version.rb +1 -1
- data/pom.xml +3 -3
- data/rakelib/02-test.rake +0 -12
- data/rakelib/compile.rake +1 -1
- data/rakelib/db.rake +7 -5
- data/rakelib/rails.rake +63 -64
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +1 -17
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +518 -1260
- data/src/java/arjdbc/mysql/MySQLModule.java +3 -3
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +53 -134
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +214 -240
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +0 -20
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +85 -10
- metadata +20 -34
- data/Appraisals +0 -41
- data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
- data/lib/arjdbc/common_jdbc_methods.rb +0 -89
- data/lib/arjdbc/mysql/bulk_change_table.rb +0 -150
- data/lib/arjdbc/mysql/column.rb +0 -162
- data/lib/arjdbc/mysql/explain_support.rb +0 -82
- data/lib/arjdbc/mysql/schema_creation.rb +0 -58
- data/lib/arjdbc/oracle/adapter.rb +0 -952
- data/lib/arjdbc/oracle/column.rb +0 -126
- data/lib/arjdbc/oracle/connection_methods.rb +0 -21
- data/lib/arjdbc/oracle.rb +0 -4
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +0 -21
- data/lib/arjdbc/postgresql/base/oid.rb +0 -412
- data/lib/arjdbc/postgresql/base/schema_definitions.rb +0 -131
- data/lib/arjdbc/postgresql/explain_support.rb +0 -53
- data/lib/arjdbc/postgresql/oid/bytea.rb +0 -2
- data/lib/arjdbc/postgresql/schema_creation.rb +0 -60
- data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +0 -297
- data/lib/arjdbc/tasks/oracle_database_tasks.rb +0 -65
- data/src/java/arjdbc/oracle/OracleModule.java +0 -75
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +0 -465
data/README.md
CHANGED
@@ -1,31 +1,24 @@
|
|
1
1
|
# ActiveRecord JDBC Adapter
|
2
2
|
|
3
|
-
[ is a database adapter for Rails'
|
6
|
-
*ActiveRecord* component that can be used with [JRuby][0]. It allows use of
|
7
|
-
virtually any JDBC-compliant database with your JRuby on Rails application.
|
8
|
-
|
9
|
-
We supports *ActiveRecord* **2.3**, **3.x** and **4.x** from a single code base.
|
10
|
-
You'll need JRuby >= **1.6.8** (we recommend using the latest and greatest of
|
11
|
-
JRubies) thus Java >= **1.6** is mandatory.
|
12
|
-
|
13
|
-
#### AR-JDBC **1.3.x** is a recommended update for all **1.2.x** users.
|
14
|
-
|
15
|
-
Our latest major version **1.3.x** represents a few months of refactoring and
|
16
|
-
updates covering (not just) new/old *ActiveRecord* features. It tries to stay
|
17
|
-
compatible with 1.2.9 as much as possible but please be aware that it's not always
|
18
|
-
possible(mostly for the best), please read our [migration guide][8] for details.
|
19
|
-
|
20
|
-
## Databases
|
3
|
+
[][7]
|
21
4
|
|
5
|
+
ActiveRecord-JDBC-Adapter (AR-JDBC) is the main database adapter for Rails'
|
6
|
+
*ActiveRecord* component that can be used with [JRuby][0].
|
22
7
|
ActiveRecord-JDBC-Adapter provides full or nearly full support for:
|
23
|
-
**MySQL**, **PostgreSQL**, **SQLite3
|
24
|
-
|
8
|
+
**MySQL**, **PostgreSQL**, **SQLite3**. In the near future there are plans to
|
9
|
+
add support **MSSQL**. Unless we get more contributions we will not be going
|
10
|
+
beyond these four adapters. Note that the amount of work needed to get
|
11
|
+
another adapter is not huge but the amount of testing required to make sure
|
12
|
+
that adapter continues to work is not something we can do with the resources
|
13
|
+
we currently have.
|
25
14
|
|
26
|
-
|
27
|
-
|
28
|
-
|
15
|
+
For Oracle database users you are encouraged to use
|
16
|
+
https://github.com/rsim/oracle-enhanced.
|
17
|
+
|
18
|
+
Version 50.x supports Rails version 5.0.x and it lives on branch 50-stable.
|
19
|
+
Version 51.x supports Rails version 5.1.x and is currently on master until
|
20
|
+
its first release. The minimum version of JRuby for 50+ is JRuby 9.1.x and
|
21
|
+
JRuby 9.1+ requires Java 7 or newer.
|
29
22
|
|
30
23
|
## Using ActiveRecord JDBC
|
31
24
|
|
@@ -36,39 +29,14 @@ To use AR-JDBC with JRuby on Rails:
|
|
36
29
|
1. Choose the adapter you wish to gem install. The following pre-packaged
|
37
30
|
adapters are available:
|
38
31
|
|
39
|
-
- Base JDBC (`activerecord-jdbc-adapter`) - supports all available databases
|
40
|
-
via JDBC, but requires you to download and manually setup a JDBC driver for
|
41
|
-
the database you're using
|
42
32
|
- MySQL (`activerecord-jdbcmysql-adapter`)
|
43
33
|
- PostgreSQL (`activerecord-jdbcpostgresql-adapter`)
|
44
34
|
- SQLite3 (`activerecord-jdbcsqlite3-adapter`)
|
45
|
-
- Derby (`activerecord-jdbcderby-adapter`)
|
46
|
-
- HSQLDB (`activerecord-jdbchsqldb-adapter`)
|
47
|
-
- H2 (`activerecord-jdbch2-adapter`)
|
48
|
-
- MSSQL (`activerecord-jdbcmssql-adapter`) - uses the OSS jTDS driver by default
|
49
|
-
which might have issues with the latest SQLServer (but should work using the
|
50
|
-
Microsoft JDBC Driver for SQL Server - we recommend using 4.0)
|
51
35
|
|
52
|
-
|
36
|
+
2. If you're generating a new Rails application, use the following command:
|
53
37
|
|
54
38
|
jruby -S rails new sweetapp
|
55
39
|
|
56
|
-
2b. Otherwise, you might need to perform some extra configuration steps
|
57
|
-
to prepare your Rails application for JDBC.
|
58
|
-
|
59
|
-
You'll need to modify your *Gemfile* to use the *activerecord-jdbc-adapter* gem
|
60
|
-
(or one of the helper gems) under JRuby. Change your *Gemfile* to look something
|
61
|
-
like the following:
|
62
|
-
|
63
|
-
```ruby
|
64
|
-
gem 'mysql2', platform: :ruby
|
65
|
-
gem 'activerecord-jdbcmysql-adapter', platform: :jruby
|
66
|
-
```
|
67
|
-
|
68
|
-
If you're (stuck) using Rails 2.3, you might need to:
|
69
|
-
|
70
|
-
jruby script/generate jdbc
|
71
|
-
|
72
40
|
3. Configure your *database.yml* in the normal Rails style:
|
73
41
|
|
74
42
|
```yml
|
@@ -79,22 +47,6 @@ development:
|
|
79
47
|
password: 1234
|
80
48
|
```
|
81
49
|
|
82
|
-
**Legacy Configuration:** If you use one of the *activerecord-jdbcxxx-adapter*
|
83
|
-
gems, you can still put a 'jdbc' prefix in front of the database adapter name,
|
84
|
-
e.g. `adapter: jdbcmysql`.
|
85
|
-
|
86
|
-
For plain JDBC database configurations, you'll need to know the database driver
|
87
|
-
class and URL (do not forget to put the driver .jar(s) on the class-path) e.g.:
|
88
|
-
|
89
|
-
```yml
|
90
|
-
development:
|
91
|
-
adapter: jdbc
|
92
|
-
username: blog
|
93
|
-
password: 1234
|
94
|
-
driver: com.mysql.jdbc.Driver
|
95
|
-
url: jdbc:mysql://localhost:3306/blog_development
|
96
|
-
```
|
97
|
-
|
98
50
|
For JNDI data sources, you may simply specify the JNDI location as follows, it's
|
99
51
|
recommended to use the same adapter: setting as one would configure when using
|
100
52
|
"bare" (JDBC) connections e.g. :
|
@@ -122,27 +74,6 @@ production:
|
|
122
74
|
connectTimeout: 60000
|
123
75
|
```
|
124
76
|
|
125
|
-
If you're really old school you might want to use AR-JDBC with a DB2 on z/OS:
|
126
|
-
|
127
|
-
```yml
|
128
|
-
development:
|
129
|
-
adapter: jdbc
|
130
|
-
url: jdbc:db2j:net://mightyzoshost:446/RAILS_DBT1
|
131
|
-
driver: com.ibm.db2.jcc.DB2Driver
|
132
|
-
schema: DB2XB12
|
133
|
-
database: RAILS_DB1
|
134
|
-
tablespace: TSDE911
|
135
|
-
lob_tablespaces:
|
136
|
-
first_table: TSDE912
|
137
|
-
username: business
|
138
|
-
password: machines
|
139
|
-
encoding: unicode
|
140
|
-
# you can force a (DB2) dialect using:
|
141
|
-
#dialect: as400
|
142
|
-
```
|
143
|
-
|
144
|
-
More information on (configuring) AR-JDBC might be found on our [wiki][5].
|
145
|
-
|
146
77
|
### Standalone with ActiveRecord
|
147
78
|
|
148
79
|
Once the setup is made (see below) you can establish a JDBC connection like this
|
@@ -150,53 +81,34 @@ Once the setup is made (see below) you can establish a JDBC connection like this
|
|
150
81
|
|
151
82
|
```ruby
|
152
83
|
ActiveRecord::Base.establish_connection(
|
153
|
-
adapter: '
|
84
|
+
adapter: 'sqlite3',
|
154
85
|
database: 'db/my-database'
|
155
86
|
)
|
156
87
|
```
|
157
88
|
|
158
|
-
or using (requires that you manually put the driver jar on the class-path):
|
159
|
-
|
160
|
-
```ruby
|
161
|
-
ActiveRecord::Base.establish_connection(
|
162
|
-
:adapter => 'jdbc',
|
163
|
-
:driver => 'org.apache.derby.jdbc.EmbeddedDriver',
|
164
|
-
:url => 'jdbc:derby:sample_db;create=true'
|
165
|
-
)
|
166
|
-
```
|
167
|
-
|
168
89
|
#### Using Bundler
|
169
90
|
|
170
91
|
Proceed as with Rails; specify `ActiveRecord` in your Bundle along with the
|
171
92
|
chosen JDBC adapter(s), this time sample *Gemfile* for MySQL:
|
172
93
|
|
173
94
|
```ruby
|
174
|
-
gem 'activerecord', '~>
|
95
|
+
gem 'activerecord', '~> 5.0.6'
|
175
96
|
gem 'activerecord-jdbcmysql-adapter', :platform => :jruby
|
176
97
|
```
|
177
98
|
|
178
99
|
When you `require 'bundler/setup'` everything will be set up for you as expected.
|
179
100
|
|
180
|
-
You do not need to use the 'helper' *activerecord-jdbcxxx-adapter* gem we provide
|
181
|
-
but than should make sure an appropriate JDBC driver is available at runtime, in
|
182
|
-
that case simply setup your *Gemfile* as:
|
183
|
-
|
184
|
-
```ruby
|
185
|
-
gem 'activerecord', '~> 4.0.0'
|
186
|
-
gem 'activerecord-jdbc-adapter', '~> 1.3.2', platform: :jruby
|
187
|
-
```
|
188
|
-
|
189
101
|
#### Without Bundler
|
190
102
|
|
191
103
|
Install the needed gems with JRuby, for example:
|
192
104
|
|
193
|
-
gem install activerecord -v "~>
|
105
|
+
gem install activerecord -v "~> 5.0.6"
|
194
106
|
gem install activerecord-jdbc-adapter --ignore-dependencies
|
195
107
|
|
196
108
|
If you wish to use the adapter for a specific database, you can install it
|
197
109
|
directly and the (jdbc-) driver gem (dependency) will be installed as well:
|
198
110
|
|
199
|
-
jruby -S gem install activerecord-
|
111
|
+
jruby -S gem install activerecord-jdbcmysql-adapter
|
200
112
|
|
201
113
|
Your program should include:
|
202
114
|
|
@@ -204,16 +116,9 @@ Your program should include:
|
|
204
116
|
require 'active_record'
|
205
117
|
require 'activerecord-jdbc-adapter' if defined? JRUBY_VERSION
|
206
118
|
# or in case you're using the pre-packaged adapter gem :
|
207
|
-
require 'activerecord-
|
119
|
+
require 'activerecord-jdbcmysql-adapter' if defined? JRUBY_VERSION
|
208
120
|
```
|
209
121
|
|
210
|
-
## Extending AR-JDBC
|
211
|
-
|
212
|
-
You can create your own extension to AR-JDBC for a JDBC-based database that core
|
213
|
-
AR-JDBC does not support. We've created an example project for the Intersystems
|
214
|
-
Cache database that you can examine as a template.
|
215
|
-
See the [cachedb-adapter project][4] for more information.
|
216
|
-
|
217
122
|
## Source
|
218
123
|
|
219
124
|
The source for activerecord-jdbc-adapter is available using git:
|
@@ -263,4 +168,4 @@ license the database's drivers are licensed. See each driver gem's LICENSE.txt.
|
|
263
168
|
[5]: https://github.com/jruby/activerecord-jdbc-adapter/wiki
|
264
169
|
[6]: https://webchat.freenode.net/?channels=#jruby
|
265
170
|
[7]: http://badge.fury.io/rb/activerecord-jdbc-adapter
|
266
|
-
[8]: https://github.com/jruby/activerecord-jdbc-adapter/wiki/Migrating-from-1.2.x-to-1.3.0
|
171
|
+
[8]: https://github.com/jruby/activerecord-jdbc-adapter/wiki/Migrating-from-1.2.x-to-1.3.0
|
data/RUNNING_TESTS.md
CHANGED
@@ -29,52 +29,57 @@ export ORACLE_PASS=sample
|
|
29
29
|
export ORACLE_SID=MAIN
|
30
30
|
```
|
31
31
|
|
32
|
-
Tests are by
|
33
|
-
|
34
|
-
base run those with the (appraisal) provided task e.g. for MySQL :
|
32
|
+
Tests are run by calling the rake task corresponding the database adapter being
|
33
|
+
tested, e.g. for MySQL :
|
35
34
|
|
36
|
-
rake
|
35
|
+
rake test_mysql TEST=test/db/mysql/rake_test.rb
|
37
36
|
|
38
37
|
Observe the **TEST** variable used to specify a single file to be used to resolve
|
39
38
|
test cases, you pick tests by matching their names as well using **TESTOPTS** :
|
40
39
|
|
41
|
-
rake
|
40
|
+
rake test_postgres TESTOPTS="--name=/integer/"
|
42
41
|
|
43
|
-
|
42
|
+
Since 1.3.0 we also support prepared statements, these are enabled by default (AR)
|
43
|
+
but one can easily run tests with prepared statements disabled using env vars :
|
44
44
|
|
45
|
-
|
46
|
-
but one can easily run tests with prepared statements enabled using env vars :
|
47
|
-
|
48
|
-
rake test_derby PS=true # or PREPARED_STATEMENTS=true
|
45
|
+
rake test_derby PREPARED_STATEMENTS=false
|
49
46
|
|
50
47
|
|
51
48
|
### ActiveRecord (Rails) Tests
|
52
49
|
|
53
|
-
|
54
|
-
|
55
|
-
of failures are artificial (and would require tweaks at the Rails repo itself),
|
56
|
-
others simply need quality time spent to get them in shape and address issues.
|
57
|
-
|
58
|
-
First make sure you have the ActiveRecord (Rails) sources cloned locally :
|
50
|
+
We also have the ability to run our adapters against Rails ActiveRecord
|
51
|
+
tests as well. First, make sure you have the Rails repository cloned locally:
|
59
52
|
|
60
53
|
git clone git://github.com/rails/rails.git
|
61
54
|
|
62
|
-
|
63
|
-
|
55
|
+
If you clone Rails to the same parent directory this project is cloned to
|
56
|
+
then you may do either:
|
57
|
+
|
58
|
+
jruby -S rake rails:test:sqlite
|
59
|
+
jruby -S rake rails:test:postgres
|
60
|
+
jruby -S rake rails:test:mysql
|
61
|
+
|
62
|
+
If you have your rails source in another directory then you can pass
|
63
|
+
in **RAILS**:
|
64
|
+
|
65
|
+
jruby -S rake rails:test:sqlite RAILS=../../somewhere/rails
|
66
|
+
|
67
|
+
If you are working on a more exotic adapter you can also pass in **DRIVER**:
|
64
68
|
|
65
|
-
jruby -S rake rails:test DRIVER=derby
|
69
|
+
jruby -S rake rails:test:all DRIVER=derby
|
66
70
|
|
67
|
-
|
71
|
+
Note, that if you want to test against particular version of Rails you need
|
72
|
+
to check out the proper branch in Rails source (e.g. v5.0.2). If you are
|
73
|
+
just starting to debug an adapter then running:
|
68
74
|
|
69
|
-
|
70
|
-
|
71
|
-
|
75
|
+
jruby -S rake rails:test:sqlite:basic_test
|
76
|
+
jruby -S rake rails:test:postgres:basic_test
|
77
|
+
jruby -S rake rails:test:mysql:basic_test
|
72
78
|
|
73
|
-
|
74
|
-
(non-test) code e.g. the `Mysql` module, instead put that into **test/rails**.
|
79
|
+
is helpful since basic_test in active-record hits that 80% sweet spot.
|
75
80
|
|
76
81
|
[![Build Status][0]](http://travis-ci.org/#!/jruby/activerecord-jdbc-adapter)
|
77
82
|
|
78
83
|
Happy Testing!
|
79
84
|
|
80
|
-
[0]: https://secure.travis-ci.org/jruby/activerecord-jdbc-adapter.png
|
85
|
+
[0]: https://secure.travis-ci.org/jruby/activerecord-jdbc-adapter.png
|
data/Rakefile
CHANGED
@@ -8,15 +8,14 @@ require 'bundler/gem_helper'
|
|
8
8
|
Bundler::GemHelper.install_tasks
|
9
9
|
|
10
10
|
require 'bundler/setup'
|
11
|
-
require 'appraisal'
|
12
11
|
|
13
12
|
task :default => [:jar, :test]
|
14
13
|
|
15
14
|
task :build => :jar
|
16
15
|
task :install => :jar
|
17
16
|
|
18
|
-
ADAPTERS = %w[
|
19
|
-
DRIVERS = %w[
|
17
|
+
ADAPTERS = %w[mysql postgresql sqlite3].map { |a| "activerecord-jdbc#{a}-adapter" }
|
18
|
+
DRIVERS = %w[mysql postgres sqlite3].map { |a| "jdbc-#{a}" }
|
20
19
|
TARGETS = ( ADAPTERS + DRIVERS )
|
21
20
|
|
22
21
|
rake = lambda { |task| ruby "-S", "rake", task }
|
@@ -29,8 +29,7 @@ Gem::Specification.new do |gem|
|
|
29
29
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
30
30
|
gem.test_files = gem.files.grep(%r{^test/})
|
31
31
|
|
32
|
-
|
33
|
-
gem.add_dependency 'activerecord', '>= 2.2'
|
32
|
+
gem.add_dependency 'activerecord', '~> 5.1.0'
|
34
33
|
|
35
34
|
#gem.add_development_dependency 'test-unit', '2.5.4'
|
36
35
|
#gem.add_development_dependency 'test-unit-context', '>= 0.3.0'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ArJdbc
|
2
|
+
module Abstract
|
3
|
+
module ConnectionManagement
|
4
|
+
|
5
|
+
def active?
|
6
|
+
@connection.active?
|
7
|
+
end
|
8
|
+
|
9
|
+
def disconnect!
|
10
|
+
super
|
11
|
+
@connection.disconnect!
|
12
|
+
end
|
13
|
+
|
14
|
+
def reconnect!
|
15
|
+
super
|
16
|
+
@connection.reconnect! # handles adapter.configure_connection
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ArJdbc
|
2
|
+
module Abstract
|
3
|
+
|
4
|
+
# This is minimum amount of code needed from base JDBC Adapter class to make common adapters
|
5
|
+
# work. This replaces using jdbc/adapter as a base class for all adapters.
|
6
|
+
module Core
|
7
|
+
|
8
|
+
attr_reader :config
|
9
|
+
|
10
|
+
def initialize(connection, logger = nil, config = {})
|
11
|
+
@config = config
|
12
|
+
|
13
|
+
connection ||= jdbc_connection_class(config[:adapter_spec]).new(config, self)
|
14
|
+
|
15
|
+
super(connection, logger, config)
|
16
|
+
|
17
|
+
# NOTE: should not be necessary for JNDI due reconnect! on checkout :
|
18
|
+
configure_connection if respond_to?(:configure_connection)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Retrieve the raw `java.sql.Connection` object.
|
22
|
+
# The unwrap parameter is useful if an attempt to unwrap a pooled (JNDI)
|
23
|
+
# connection should be made - to really return the 'native' JDBC object.
|
24
|
+
# @param unwrap [true, false] whether to unwrap the connection object
|
25
|
+
# @return [Java::JavaSql::Connection] the JDBC connection
|
26
|
+
def jdbc_connection(unwrap = false)
|
27
|
+
java_connection = raw_connection.connection
|
28
|
+
return java_connection unless unwrap
|
29
|
+
|
30
|
+
connection_class = java.sql.Connection.java_class
|
31
|
+
begin
|
32
|
+
if java_connection.wrapper_for?(connection_class)
|
33
|
+
return java_connection.unwrap(connection_class) # java.sql.Wrapper.unwrap
|
34
|
+
end
|
35
|
+
rescue Java::JavaLang::AbstractMethodError => e
|
36
|
+
ArJdbc.warn("driver/pool connection impl does not support unwrapping (#{e})")
|
37
|
+
end
|
38
|
+
|
39
|
+
if java_connection.respond_to?(:connection)
|
40
|
+
# e.g. org.apache.tomcat.jdbc.pool.PooledConnection
|
41
|
+
java_connection.connection # getConnection
|
42
|
+
else
|
43
|
+
java_connection
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def translate_exception(e, message)
|
49
|
+
# we shall not translate native "Java" exceptions as they might
|
50
|
+
# swallow an ArJdbc / driver bug into a AR::StatementInvalid ...
|
51
|
+
return e if e.is_a?(Java::JavaLang::Throwable)
|
52
|
+
|
53
|
+
case e
|
54
|
+
when ActiveModel::RangeError, TypeError, SystemExit, SignalException, NoMemoryError then e
|
55
|
+
# NOTE: wraps AR::JDBCError into AR::StatementInvalid, desired ?!
|
56
|
+
else super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module ArJdbc
|
2
|
+
module Abstract
|
3
|
+
|
4
|
+
# This provides the basic interface for interacting with the
|
5
|
+
# database for JDBC based adapters
|
6
|
+
module DatabaseStatements
|
7
|
+
|
8
|
+
# It appears that at this point (AR 5.0) "prepare" should only ever be true
|
9
|
+
# if prepared statements are enabled
|
10
|
+
def exec_query(sql, name = nil, binds = [], prepare: false)
|
11
|
+
if without_prepared_statement?(binds)
|
12
|
+
execute(sql, name)
|
13
|
+
else
|
14
|
+
binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
|
15
|
+
log(sql, name, binds) do
|
16
|
+
# It seems that #supports_statement_cache? is defined but isn't checked before setting "prepare" (AR 5.0)
|
17
|
+
cached_statement = fetch_cached_statement(sql) if prepare && supports_statement_cache?
|
18
|
+
@connection.execute_prepared(sql, binds, cached_statement)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def exec_update(sql, name = nil, binds = [])
|
24
|
+
if without_prepared_statement?(binds)
|
25
|
+
log(sql, name) { @connection.execute_update(sql, nil) }
|
26
|
+
else
|
27
|
+
log(sql, name, binds) { @connection.execute_prepared_update(sql, binds) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
alias :exec_delete :exec_update
|
31
|
+
|
32
|
+
def execute(sql, name = nil)
|
33
|
+
log(sql, name) { @connection.execute(sql) }
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def convert_legacy_binds_to_attributes(binds)
|
39
|
+
binds.map do |column, value|
|
40
|
+
ActiveRecord::Relation::QueryAttribute.new(nil, type_cast(value, column), ActiveModel::Type::Value.new)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'active_record/connection_adapters/statement_pool'
|
2
|
+
|
3
|
+
module ArJdbc
|
4
|
+
module Abstract
|
5
|
+
module StatementCache
|
6
|
+
|
7
|
+
# This works a little differently than the AR implementation in that
|
8
|
+
# we are storing an actual PreparedStatement object instead of just
|
9
|
+
# the name of the prepared statement
|
10
|
+
class StatementPool < ActiveRecord::ConnectionAdapters::StatementPool
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def dealloc(statement)
|
15
|
+
statement.close
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(connection, logger, config)
|
21
|
+
super
|
22
|
+
|
23
|
+
# Only say we support the statement cache if we are using prepared statements
|
24
|
+
# and have a max number of statements defined
|
25
|
+
statement_limit = self.class.type_cast_config_to_integer(config[:statement_limit])
|
26
|
+
@jdbc_statement_cache_enabled = config[:prepared_statements] && (statement_limit.nil? || statement_limit > 0)
|
27
|
+
|
28
|
+
@statements = StatementPool.new(statement_limit) # AR (5.0) expects this to be stored as @statements
|
29
|
+
end
|
30
|
+
|
31
|
+
# Clears the prepared statements cache.
|
32
|
+
def clear_cache!
|
33
|
+
@statements.clear
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_cached_statement(sql)
|
37
|
+
@statements.delete(cached_statement_key(sql))
|
38
|
+
end
|
39
|
+
|
40
|
+
def fetch_cached_statement(sql)
|
41
|
+
@statements[cached_statement_key(sql)] ||= @connection.connection.prepare_statement(sql)
|
42
|
+
end
|
43
|
+
|
44
|
+
def supports_statement_cache?
|
45
|
+
@jdbc_statement_cache_enabled
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# This should be overridden by the adapter if the sql itself
|
51
|
+
# is not enough to make the key unique
|
52
|
+
def cached_statement_key(sql)
|
53
|
+
sql
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module ArJdbc
|
2
|
+
module Abstract
|
3
|
+
|
4
|
+
# Provides the basic interface needed to support transactions for JDBC based adapters
|
5
|
+
module TransactionSupport
|
6
|
+
|
7
|
+
########################## Support Checks #################################
|
8
|
+
|
9
|
+
# Does our database (+ its JDBC driver) support save-points?
|
10
|
+
# @since 1.3.0
|
11
|
+
# @override
|
12
|
+
def supports_savepoints?
|
13
|
+
@connection.supports_savepoints?
|
14
|
+
end
|
15
|
+
|
16
|
+
# Does this adapter support setting the isolation level for a transaction?
|
17
|
+
# Unlike 'plain' `ActiveRecord` we allow checking for concrete transaction
|
18
|
+
# isolation level support by the database.
|
19
|
+
# @param level optional to check if we support a specific isolation level
|
20
|
+
# @since 1.3.0
|
21
|
+
# @extension added optional level parameter
|
22
|
+
def supports_transaction_isolation?(level = nil)
|
23
|
+
return false unless level
|
24
|
+
@connection.supports_transaction_isolation?(level)
|
25
|
+
end
|
26
|
+
|
27
|
+
########################## Transaction Interface ##########################
|
28
|
+
|
29
|
+
# Starts a database transaction.
|
30
|
+
# @override
|
31
|
+
def begin_db_transaction
|
32
|
+
log('BEGIN TRANSACTION'.freeze, nil) { @connection.begin }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Starts a database transaction.
|
36
|
+
# @param isolation the transaction isolation to use
|
37
|
+
def begin_isolated_db_transaction(isolation)
|
38
|
+
log("BEGIN ISOLATED TRANSACTION - #{isolation}", nil) { @connection.begin(isolation) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Commits the current database transaction.
|
42
|
+
# @override
|
43
|
+
def commit_db_transaction
|
44
|
+
log('COMMIT TRANSACTION'.freeze, nil) { @connection.commit }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Rolls back the current database transaction.
|
48
|
+
# Called from 'rollback_db_transaction' in the AbstractAdapter
|
49
|
+
# @override
|
50
|
+
def exec_rollback_db_transaction
|
51
|
+
log('ROLLBACK TRANSACTION'.freeze, nil) { @connection.rollback }
|
52
|
+
end
|
53
|
+
|
54
|
+
########################## Savepoint Interface ############################
|
55
|
+
|
56
|
+
# Creates a (transactional) save-point one can rollback to.
|
57
|
+
# Unlike 'plain' `ActiveRecord` it is allowed to pass a save-point name.
|
58
|
+
# @param name the save-point name
|
59
|
+
# @return save-point name (even if nil passed will be generated)
|
60
|
+
# @since 1.3.0
|
61
|
+
# @extension added optional name parameter
|
62
|
+
def create_savepoint(name = current_savepoint_name)
|
63
|
+
log("SAVEPOINT #{name}", 'Savepoint') { @connection.create_savepoint(name) }
|
64
|
+
end
|
65
|
+
|
66
|
+
# Transaction rollback to a given (previously created) save-point.
|
67
|
+
# If no save-point name given rollback to the last created one.
|
68
|
+
# Called from 'rollback_to_savepoint' in AbstractAdapter
|
69
|
+
# @param name the save-point name
|
70
|
+
# @extension added optional name parameter
|
71
|
+
def exec_rollback_to_savepoint(name = current_savepoint_name)
|
72
|
+
log("ROLLBACK TO SAVEPOINT #{name}", 'Savepoint') { @connection.rollback_savepoint(name) }
|
73
|
+
end
|
74
|
+
|
75
|
+
# Release a previously created save-point.
|
76
|
+
# @note Save-points are auto-released with the transaction they're created
|
77
|
+
# in (on transaction commit or roll-back).
|
78
|
+
# @param name the save-point name
|
79
|
+
# @extension added optional name parameter
|
80
|
+
def release_savepoint(name = current_savepoint_name)
|
81
|
+
log("RELEASE SAVEPOINT #{name}", 'Savepoint') { @connection.release_savepoint(name) }
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/arjdbc/derby/adapter.rb
CHANGED
@@ -175,10 +175,15 @@ module ArJdbc
|
|
175
175
|
NATIVE_DATABASE_TYPES
|
176
176
|
end
|
177
177
|
|
178
|
+
# UNTESTED
|
179
|
+
def existing_savepoint_name?(name)
|
180
|
+
(@connection.instance_variable_get('@savepoints') || {}).key? name
|
181
|
+
end
|
182
|
+
|
178
183
|
# Ensure the savepoint name is unused before creating it.
|
179
184
|
# @override
|
180
185
|
def create_savepoint(name = current_savepoint_name(true))
|
181
|
-
release_savepoint(name) if
|
186
|
+
release_savepoint(name) if existing_savepoint_name?(name)
|
182
187
|
super(name)
|
183
188
|
end
|
184
189
|
|
data/lib/arjdbc/discover.rb
CHANGED
@@ -413,7 +413,7 @@ module ActiveRecord::ConnectionAdapters
|
|
413
413
|
# ActiveRecord::ConnectionAdapters::FirebirdAdapter.emulate_booleans = false
|
414
414
|
#
|
415
415
|
def self.emulate_booleans?; ::ArJdbc::Firebird.emulate_booleans?; end
|
416
|
-
def self.emulate_booleans; ::ArJdbc::Firebird.emulate_booleans?; end
|
416
|
+
def self.emulate_booleans; ::ArJdbc::Firebird.emulate_booleans?; end
|
417
417
|
def self.emulate_booleans=(emulate); ::ArJdbc::Firebird.emulate_booleans = emulate; end
|
418
418
|
|
419
419
|
def initialize(*args)
|
@@ -431,4 +431,4 @@ module ActiveRecord::ConnectionAdapters
|
|
431
431
|
include ::ArJdbc::Firebird::Column
|
432
432
|
end
|
433
433
|
|
434
|
-
end
|
434
|
+
end
|