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.
Files changed (68) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -2
  3. data/.travis.yml +15 -416
  4. data/Gemfile +35 -37
  5. data/README.md +23 -118
  6. data/RUNNING_TESTS.md +31 -26
  7. data/Rakefile +2 -3
  8. data/activerecord-jdbc-adapter.gemspec +1 -2
  9. data/lib/arjdbc/abstract/connection_management.rb +21 -0
  10. data/lib/arjdbc/abstract/core.rb +62 -0
  11. data/lib/arjdbc/abstract/database_statements.rb +46 -0
  12. data/lib/arjdbc/abstract/statement_cache.rb +58 -0
  13. data/lib/arjdbc/abstract/transaction_support.rb +86 -0
  14. data/lib/arjdbc/derby/adapter.rb +6 -1
  15. data/lib/arjdbc/discover.rb +0 -7
  16. data/lib/arjdbc/firebird/adapter.rb +2 -2
  17. data/lib/arjdbc/jdbc/adapter.rb +10 -252
  18. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  19. data/lib/arjdbc/jdbc/connection.rb +6 -0
  20. data/lib/arjdbc/jdbc.rb +2 -2
  21. data/lib/arjdbc/mysql/adapter.rb +87 -944
  22. data/lib/arjdbc/mysql/connection_methods.rb +4 -2
  23. data/lib/arjdbc/postgresql/adapter.rb +288 -1023
  24. data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
  25. data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
  26. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -5
  27. data/lib/arjdbc/postgresql/column.rb +10 -599
  28. data/lib/arjdbc/postgresql/connection_methods.rb +9 -0
  29. data/lib/arjdbc/postgresql/name.rb +24 -0
  30. data/lib/arjdbc/postgresql/oid_types.rb +25 -110
  31. data/lib/arjdbc/sqlite3/adapter.rb +171 -170
  32. data/lib/arjdbc/tasks/database_tasks.rb +1 -3
  33. data/lib/arjdbc/tasks/db2_database_tasks.rb +2 -2
  34. data/lib/arjdbc/version.rb +1 -1
  35. data/pom.xml +3 -3
  36. data/rakelib/02-test.rake +0 -12
  37. data/rakelib/compile.rake +1 -1
  38. data/rakelib/db.rake +7 -5
  39. data/rakelib/rails.rake +63 -64
  40. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +1 -17
  41. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +518 -1260
  42. data/src/java/arjdbc/mysql/MySQLModule.java +3 -3
  43. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +53 -134
  44. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +214 -240
  45. data/src/java/arjdbc/sqlite3/SQLite3Module.java +0 -20
  46. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +85 -10
  47. metadata +20 -34
  48. data/Appraisals +0 -41
  49. data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
  50. data/lib/arjdbc/common_jdbc_methods.rb +0 -89
  51. data/lib/arjdbc/mysql/bulk_change_table.rb +0 -150
  52. data/lib/arjdbc/mysql/column.rb +0 -162
  53. data/lib/arjdbc/mysql/explain_support.rb +0 -82
  54. data/lib/arjdbc/mysql/schema_creation.rb +0 -58
  55. data/lib/arjdbc/oracle/adapter.rb +0 -952
  56. data/lib/arjdbc/oracle/column.rb +0 -126
  57. data/lib/arjdbc/oracle/connection_methods.rb +0 -21
  58. data/lib/arjdbc/oracle.rb +0 -4
  59. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +0 -21
  60. data/lib/arjdbc/postgresql/base/oid.rb +0 -412
  61. data/lib/arjdbc/postgresql/base/schema_definitions.rb +0 -131
  62. data/lib/arjdbc/postgresql/explain_support.rb +0 -53
  63. data/lib/arjdbc/postgresql/oid/bytea.rb +0 -2
  64. data/lib/arjdbc/postgresql/schema_creation.rb +0 -60
  65. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +0 -297
  66. data/lib/arjdbc/tasks/oracle_database_tasks.rb +0 -65
  67. data/src/java/arjdbc/oracle/OracleModule.java +0 -75
  68. 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
- [![Gem Version](https://badge.fury.io/rb/activerecord-jdbc-adapter.png)][7]
4
-
5
- ActiveRecord-JDBC-Adapter (AR-JDBC) 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
+ [![Gem Version](https://badge.fury.io/rb/activerecord-jdbc-adapter.svg)][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**, **Oracle**, *MS-SQL** (SQL Server),
24
- **DB2**, **Firebird**, **Derby**, **HSQLDB**, **H2**, and **Informix**.
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
- Other databases will require testing and likely a custom configuration module.
27
- Please join the JRuby [mailing list][1] to help us discover support for more
28
- databases.
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
- 2a. If you're generating a new Rails application, use the following command:
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: 'derby',
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', '~> 3.2.14'
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 "~> 3.2.10"
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-jdbcderby-adapter
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-jdbcderby-adapter' if defined? JRUBY_VERSION
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 default run against the "current" ActiveRecord version locked down
33
- by Bundler, however since we usually do support more versions from a single code
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 appraisal:rails31 test_mysql TEST=test/db/mysql/rake_test.rb
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 appraisal:rails40 test_postgres TESTOPTS="--name=/integer/"
40
+ rake test_postgres TESTOPTS="--name=/integer/"
42
41
 
43
- This of course also works when running the "plain" test (no appraisal:xxx) task.
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
- Since 1.3.0 we also support prepared statements, these are off by default (AR)
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
- It's very desirable to pass all unit tests from ActiveRecord's own test suite.
54
- Unfortunately it's been a while since we have accomplished that, luckily a lot
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
- To run the AR-JDBC's sources agains AR tests, use the **rails:test** task, be
63
- sure to specify a **DRIVER** and the **RAILS** sources path on the file system :
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 RAILS=path/to/rails_source_dir
69
+ jruby -S rake rails:test:all DRIVER=derby
66
70
 
67
- There's even tasks for Rails built-in adapters e.g. `rake rails:test_mysql`
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
- You will likely only be able to run the Rails suite against the latest (stable)
70
- ActiveRecord ~> version we support (check the *Gemfile.lock*) e.g. for
71
- **activerecord (3.2.13)** you want to **git checkout 3-2-stable** branch.
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
- We strive to not stub and include native (MRI) test required artefacts into
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[derby h2 hsqldb mssql mysql postgresql sqlite3].map { |a| "activerecord-jdbc#{a}-adapter" }
19
- DRIVERS = %w[derby h2 hsqldb jtds mysql postgres sqlite3].map { |a| "jdbc-#{a}" }
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
- # NOTE: 1.3.0 only supports >= 2.3 but users report it works with 2.2 :
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
@@ -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 @connection.marked_savepoint_names.include?(name)
186
+ release_savepoint(name) if existing_savepoint_name?(name)
182
187
  super(name)
183
188
  end
184
189
 
@@ -75,13 +75,6 @@ module ArJdbc
75
75
  end
76
76
  end
77
77
 
78
- extension :Oracle do |name|
79
- if name =~ /oracle/i
80
- require 'arjdbc/oracle'
81
- true
82
- end
83
- end
84
-
85
78
  # NOTE: following ones are likely getting deprecated :
86
79
 
87
80
  extension :FireBird do |name|
@@ -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 # oracle-enhanced
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