activerecord-jdbc-adapter 61.0-java → 70.0.pre-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0f6e1df31960b2169ea7d6c7d664a5d44a3302e0382957842124a0ed1090488
4
- data.tar.gz: 63a7540994c1ef969cb67702fdf0860ab17f47632b985b9d52f690a5e247ea51
3
+ metadata.gz: 0552eaeb2b86ff8a8a2e24e86c56315c059dff050596c329cb5a082ad9d0c460
4
+ data.tar.gz: 12c7b5068269990ed27e15e7ef0d97ba0928a7bbcfbc6ca2cc6aa3e854d780ba
5
5
  SHA512:
6
- metadata.gz: e367ae078f402928bb460a0677e506282deb20c802ccb6d4fafe27fea61717ea64048b6ef4b77b1143da97b56efbe71373b80e2ea870f007a6bcbf394a7be637
7
- data.tar.gz: fb746f2b1260275e7cb4a7fe6f20c7720f5f23525e5a9ea5ecc852dac7f2141f01d177419ef701b43960ea36c42cb476536f229e575551200d2a5c8cc532c6ab
6
+ metadata.gz: 90f35907b970e53e8c3910cf7d6e572a33d78270ab7002ad7c10170bdff4872d8784bf4d361b6ef5d1dda397387e5e2804fabee549b195e594178ba7bcfa7b97
7
+ data.tar.gz: 10be265dd0aab6905de89bb779b1aa653e004e0ed0d5a536c4a54ca876b2dc806c17da8d36b2a15c1852c97e87305b29edc99c5e05e2d946f43e44202a989288
@@ -0,0 +1,273 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ test-rails-mysql:
21
+
22
+ name: Rails Tests (MySQL)
23
+ runs-on: ubuntu-latest
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ ruby-version: ['jruby-head']
28
+ db: ['mysql2']
29
+ test_targets: ["rails:test_mysql2"]
30
+ ar_version: ["7-0-stable"]
31
+ prepared_statements: ['false', 'true']
32
+ driver: ['MySQL']
33
+
34
+ services:
35
+ mysql:
36
+ image: mysql:5.7
37
+ ports:
38
+ - 3306
39
+
40
+ env:
41
+ DB: ${{ matrix.db }}
42
+ AR_VERSION: ${{ matrix.ar_version }}
43
+ PREPARED_STATEMENTS: ${{ matrix.prepared_statements }}
44
+ DRIVER: ${{ matrix.driver }}
45
+ JRUBY_OPTS: "-J-Xms64M -J-Xmx1024M"
46
+
47
+ steps:
48
+ - uses: actions/checkout@v3
49
+ - name: Set up Ruby
50
+ uses: ruby/setup-ruby@v1
51
+ with:
52
+ ruby-version: ${{ matrix.ruby-version }}
53
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
54
+ - name: Setup database
55
+ run: |
56
+ sudo service mysql start
57
+ mysql --version || true # to see if we're using MySQL or MariaDB
58
+ mysql -u root -proot -e "CREATE USER rails@localhost;"
59
+ mysql -u root -proot -e "grant all privileges on activerecord_unittest.* to rails@localhost;"
60
+ mysql -u root -proot -e "grant all privileges on activerecord_unittest2.* to rails@localhost;"
61
+ mysql -u root -proot -e "grant all privileges on inexistent_activerecord_unittest.* to rails@localhost;"
62
+ mysql -u root -proot -e "CREATE DATABASE activerecord_unittest DEFAULT CHARACTER SET utf8mb4;"
63
+ mysql -u root -proot -e "CREATE DATABASE activerecord_unittest2 DEFAULT CHARACTER SET utf8mb4;"
64
+ - name: Build
65
+ run: |
66
+ echo "JAVA_OPTS=$JAVA_OPTS"
67
+ rake jar # compiles ext generates: lib/arjdbc/jdbc/adapter_java.jar
68
+ - name: Run tests
69
+ run: |
70
+ bundle exec rake ${{ matrix.test_targets }}
71
+
72
+ test-rails-pgsql:
73
+
74
+ name: Rails Tests (Postgres)
75
+ runs-on: ubuntu-latest
76
+ strategy:
77
+ fail-fast: false
78
+ matrix:
79
+ ruby-version: [ 'jruby-head' ]
80
+ db: [ 'postgresql' ]
81
+ test_targets: [ "rails:test_postgresql" ]
82
+ ar_version: ["7-0-stable"]
83
+ prepared_statements: [ 'false', 'true' ]
84
+
85
+ services:
86
+ postgres:
87
+ image: postgres:10
88
+ env:
89
+ POSTGRES_PASSWORD: postgres
90
+ POSTGRES_HOST_AUTH_METHOD: trust
91
+ ports:
92
+ - 5432:5432
93
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
94
+
95
+ env:
96
+ DB: ${{ matrix.db }}
97
+ AR_VERSION: ${{ matrix.ar_version }}
98
+ JRUBY_OPTS: "-J-Xms64M -J-Xmx1024M"
99
+ PREPARED_STATEMENTS: ${{ matrix.prepared_statements }}
100
+ PGHOST: localhost
101
+ PGPORT: 5432
102
+ PGUSER: postgres
103
+
104
+ steps:
105
+ - uses: actions/checkout@v3
106
+ - name: Set up Ruby
107
+ uses: ruby/setup-ruby@v1
108
+ with:
109
+ ruby-version: ${{ matrix.ruby-version }}
110
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
111
+ - name: Setup database
112
+ run: |
113
+ psql -c "create database activerecord_unittest;" -U postgres
114
+ psql -c "create database activerecord_unittest2;" -U postgres
115
+ - name: Build
116
+ run: |
117
+ rake jar # compiles ext generates: lib/arjdbc/jdbc/adapter_java.jar
118
+ - name: Run tests
119
+ run: |
120
+ bundle exec rake ${{ matrix.test_targets }}
121
+
122
+ test-rails-sqlite:
123
+
124
+ name: Rails Tests (SQLite)
125
+ runs-on: ubuntu-latest
126
+ strategy:
127
+ fail-fast: false
128
+ matrix:
129
+ ruby-version: ['jruby-head']
130
+ db: ['sqlite3']
131
+ test_targets: ["rails:test_sqlite3"]
132
+ ar_version: ["7-0-stable"]
133
+
134
+ env:
135
+ DB: ${{ matrix.db }}
136
+ AR_VERSION: ${{ matrix.ar_version }}
137
+ JRUBY_OPTS: "-J-Xms64M -J-Xmx1024M"
138
+
139
+ steps:
140
+ - uses: actions/checkout@v3
141
+ - name: Set up Ruby
142
+ uses: ruby/setup-ruby@v1
143
+ with:
144
+ ruby-version: ${{ matrix.ruby-version }}
145
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
146
+ - name: Build
147
+ run: |
148
+ echo "JAVA_OPTS=$JAVA_OPTS"
149
+ rake jar # compiles ext generates: lib/arjdbc/jdbc/adapter_java.jar
150
+ - name: Run tests
151
+ run: |
152
+ bundle exec rake ${{ matrix.test_targets }}
153
+
154
+ test-arjdbc-mysql:
155
+
156
+ name: ARJDBC Tests (MySQL)
157
+ runs-on: ubuntu-latest
158
+ strategy:
159
+ fail-fast: false
160
+ matrix:
161
+ ruby-version: ['jruby-head']
162
+ db: ['mysql2']
163
+ test_targets: ["db:mysql test_mysql2"]
164
+ prepared_statements: ['false', 'true']
165
+ driver: ['MySQL']
166
+
167
+ services:
168
+ mysql:
169
+ image: mysql:5.7
170
+ ports:
171
+ - 3306
172
+
173
+ env:
174
+ DB: ${{ matrix.db }}
175
+ DRIVER: ${{ matrix.driver }}
176
+ JRUBY_OPTS: "-J-Xms64M -J-Xmx1024M"
177
+ MY_USER: root
178
+ MY_PASSWORD: root
179
+ PREPARED_STATEMENTS: ${{ matrix.prepared_statements }}
180
+
181
+ steps:
182
+ - uses: actions/checkout@v3
183
+ - name: Set up Ruby
184
+ uses: ruby/setup-ruby@v1
185
+ with:
186
+ ruby-version: ${{ matrix.ruby-version }}
187
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
188
+ - name: Setup database
189
+ run: |
190
+ sudo service mysql start
191
+ mysql --version || true # to see if we're using MySQL or MariaDB
192
+ - name: Build
193
+ run: |
194
+ rake jar
195
+ - name: Run tests
196
+ run: |
197
+ bundle exec rake ${{ matrix.test_targets }}
198
+
199
+ test-arjdbc-pgsql:
200
+
201
+ name: ARJDBC Tests (Postgres)
202
+ runs-on: ubuntu-latest
203
+ strategy:
204
+ fail-fast: false
205
+ matrix:
206
+ ruby-version: ['jruby-head']
207
+ db: ['postgresql']
208
+ test_targets: ["db:postgresql test_postgresql"]
209
+ prepared_statements: ['false', 'true']
210
+ insert_returning: ['false', 'true']
211
+
212
+ services:
213
+ postgres:
214
+ image: postgres:10
215
+ env:
216
+ POSTGRES_PASSWORD: postgres
217
+ POSTGRES_HOST_AUTH_METHOD: trust
218
+ ports:
219
+ - 5432:5432
220
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
221
+
222
+ env:
223
+ DB: ${{ matrix.db }}
224
+ DRIVER: ${{ matrix.driver }}
225
+ JRUBY_OPTS: "-J-Xms64M -J-Xmx1024M"
226
+ PREPARED_STATEMENTS: ${{ matrix.prepared_statements }}
227
+ INSERT_RETURNING: ${{ matrix.insert_returning }}
228
+ PGHOST: localhost
229
+ PGPORT: 5432
230
+ PGUSER: postgres
231
+
232
+ steps:
233
+ - uses: actions/checkout@v3
234
+ - name: Set up Ruby
235
+ uses: ruby/setup-ruby@v1
236
+ with:
237
+ ruby-version: ${{ matrix.ruby-version }}
238
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
239
+ - name: Build
240
+ run: |
241
+ rake jar
242
+ - name: Run tests
243
+ run: |
244
+ bundle exec rake ${{ matrix.test_targets }}
245
+
246
+ test-arjdbc-sqlite:
247
+
248
+ name: ARJDBC Tests (SQLite)
249
+ runs-on: ubuntu-latest
250
+ strategy:
251
+ fail-fast: false
252
+ matrix:
253
+ ruby-version: ['jruby-head']
254
+ db: ['sqlite3']
255
+ test_targets: ['test_sqlite3']
256
+
257
+ env:
258
+ DB: ${{ matrix.db }}
259
+ JRUBY_OPTS: "-J-Xms64M -J-Xmx1024M"
260
+
261
+ steps:
262
+ - uses: actions/checkout@v3
263
+ - name: Set up Ruby
264
+ uses: ruby/setup-ruby@v1
265
+ with:
266
+ ruby-version: ${{ matrix.ruby-version }}
267
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
268
+ - name: Build
269
+ run: |
270
+ rake jar
271
+ - name: Run tests
272
+ run: |
273
+ bundle exec rake ${{ matrix.test_targets }}
data/Gemfile CHANGED
@@ -47,11 +47,11 @@ else
47
47
  gemspec name: 'activerecord-jdbc-adapter' # Use versiom from .gemspec
48
48
  end
49
49
 
50
- gem 'rake', '>= 11.1', require: nil
50
+ gem 'rake', require: nil
51
51
 
52
52
  group :test do
53
- gem 'test-unit', '~> 2.5.4', require: nil
54
- gem 'test-unit-context', '>= 0.4.0', require: nil
53
+ gem 'test-unit', require: nil
54
+ gem 'test-unit-context', require: nil
55
55
  gem 'mocha', '~> 1.2', require: false # Rails has '~> 0.14'
56
56
 
57
57
  gem 'bcrypt', '~> 3.1.11', require: false
@@ -59,8 +59,8 @@ end
59
59
 
60
60
  group :rails do
61
61
  group :test do
62
- gem 'minitest', '~> 5.12.2', require: nil
63
- gem 'minitest-excludes', '~> 2.0.1', require: nil
62
+ gem 'minitest', require: nil
63
+ gem 'minitest-excludes', require: nil
64
64
  gem 'minitest-rg', require: nil
65
65
 
66
66
  gem 'benchmark-ips', require: nil
@@ -72,6 +72,8 @@ group :rails do
72
72
  gem 'erubis', require: nil # "~> 2.7.0"
73
73
  # NOTE: due rails/activerecord/test/cases/connection_management_test.rb
74
74
  gem 'rack', require: nil
75
+
76
+ gem 'zeitwerk'
75
77
  end
76
78
 
77
79
  group :development do
@@ -1,5 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
+ path = File.expand_path('lib/arjdbc/version.rb', File.dirname(__FILE__))
4
+ puts "VERSION: #{File.read(path).match( /.*VERSION\s*=\s*['"](.*)['"]/m )[1]}"
3
5
  Gem::Specification.new do |gem|
4
6
  gem.name = 'activerecord-jdbc-adapter'
5
7
  path = File.expand_path('lib/arjdbc/version.rb', File.dirname(__FILE__))
@@ -41,7 +43,7 @@ Gem::Specification.new do |gem|
41
43
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
42
44
  gem.test_files = gem.files.grep(%r{^test/})
43
45
 
44
- gem.add_dependency 'activerecord', '~> 6.1.0'
46
+ gem.add_dependency 'activerecord', '~> 7.0'
45
47
 
46
48
  #gem.add_development_dependency 'test-unit', '2.5.4'
47
49
  #gem.add_development_dependency 'test-unit-context', '>= 0.3.0'
@@ -30,7 +30,7 @@ module ArJdbc
30
30
 
31
31
  # It appears that at this point (AR 5.0) "prepare" should only ever be true
32
32
  # if prepared statements are enabled
33
- def exec_query(sql, name = nil, binds = NO_BINDS, prepare: false)
33
+ def exec_query(sql, name = nil, binds = NO_BINDS, prepare: false, async: false)
34
34
  if preventing_writes? && write_query?(sql)
35
35
  raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
36
36
  end
@@ -69,7 +69,7 @@ module ArJdbc
69
69
  end
70
70
  alias :exec_delete :exec_update
71
71
 
72
- def execute(sql, name = nil)
72
+ def execute(sql, name = nil, async: false)
73
73
  if preventing_writes? && write_query?(sql)
74
74
  raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
75
75
  end
@@ -77,11 +77,11 @@ module ArJdbc
77
77
  materialize_transactions
78
78
  mark_transaction_written_if_write(sql)
79
79
 
80
- log(sql, name) { @connection.execute(sql) }
80
+ log(sql, name, async: async) { @connection.execute(sql) }
81
81
  end
82
82
 
83
83
  # overridden to support legacy binds
84
- def select_all(arel, name = nil, binds = NO_BINDS, preparable: nil)
84
+ def select_all(arel, name = nil, binds = NO_BINDS, preparable: nil, async: false)
85
85
  binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
86
86
  super
87
87
  end
@@ -422,7 +422,7 @@ module ArJdbc
422
422
  def quoted_date(value)
423
423
  if value.acts_like?(:time) && value.respond_to?(:usec)
424
424
  usec = sprintf("%06d", value.usec)
425
- value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
425
+ value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
426
426
  "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
427
427
  else
428
428
  super
@@ -430,7 +430,7 @@ module ArJdbc
430
430
  end if ::ActiveRecord::VERSION::MAJOR >= 3
431
431
 
432
432
  def quote_time(value)
433
- value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
433
+ value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
434
434
  # AS400 doesn't support date in time column
435
435
  "'#{value.strftime("%H:%M:%S")}'"
436
436
  end
@@ -34,7 +34,7 @@ module ArJdbc
34
34
  return nil unless time
35
35
  time_array = [time.year, time.month, time.day, time.hour, time.min, time.sec]
36
36
  time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1;
37
- Time.send(ActiveRecord::Base.default_timezone, *time_array) rescue nil
37
+ Time.send(ActiveRecord.default_timezone, *time_array) rescue nil
38
38
  end
39
39
 
40
40
  # @deprecated
@@ -197,7 +197,7 @@ module ArJdbc
197
197
  def quoted_date(value)
198
198
  if value.acts_like?(:time) && value.respond_to?(:usec)
199
199
  usec = sprintf("%06d", value.usec)
200
- value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
200
+ value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
201
201
  "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
202
202
  else
203
203
  super
@@ -339,7 +339,7 @@ module ArJdbc
339
339
  def quoted_date(value)
340
340
  if value.acts_like?(:time) && value.respond_to?(:usec)
341
341
  usec = sprintf "%04d", (value.usec / 100.0).round
342
- value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
342
+ value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
343
343
  "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
344
344
  else
345
345
  super
@@ -111,7 +111,7 @@ module ArJdbc
111
111
  if column_type == :time
112
112
  "'#{value.strftime("%H:%M:%S")}'"
113
113
  #elsif column_type == :timestamp # || column_type == :datetime
114
- #value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
114
+ #value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
115
115
  #"'#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{sprintf("%06d", value.usec)}'"
116
116
  else
117
117
  super
@@ -127,7 +127,7 @@ module ArJdbc
127
127
  def quoted_date(value)
128
128
  if value.acts_like?(:time) && value.respond_to?(:usec)
129
129
  usec = sprintf("%06d", value.usec)
130
- value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
130
+ value = ::ActiveRecord.default_timezone == :utc ? value.getutc : value.getlocal
131
131
  "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
132
132
  else
133
133
  super
@@ -434,9 +434,9 @@ module ActiveRecord
434
434
  # to be quoted, fixed since AREL 4.0.0.beta1 : http://git.io/7gyTig
435
435
  def sql_literal?(value); ::Arel::Nodes::SqlLiteral === value; end
436
436
 
437
- # Helper to get local/UTC time (based on `ActiveRecord::Base.default_timezone`).
437
+ # Helper to get local/UTC time (based on `ActiveRecord::default_timezone`).
438
438
  def get_time(value)
439
- get = ::ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
439
+ get = ::ActiveRecord.default_timezone == :utc ? :getutc : :getlocal
440
440
  value.respond_to?(get) ? value.send(get) : value
441
441
  end
442
442
 
Binary file
@@ -2,7 +2,9 @@
2
2
 
3
3
  module ActiveRecord
4
4
 
5
- if defined? ConnectionAdapters::ConnectionSpecification::Resolver # 4.0
5
+ if defined? ConnectionAdapters::ConnectionHandler # 6.1
6
+ ConnectionAdapters::ConnectionHandler
7
+ elsif defined? ConnectionAdapters::ConnectionSpecification::Resolver # 4.0, # 5.x, # 6.0
6
8
  ConnectionAdapters::ConnectionSpecification::Resolver
7
9
  elsif defined? Base::ConnectionSpecification::Resolver # 3.2
8
10
  Base::ConnectionSpecification::Resolver
@@ -130,9 +130,9 @@ module ActiveRecord::ConnectionAdapters
130
130
  return nil unless time
131
131
 
132
132
  time -= offset
133
- ActiveRecord::Base.default_timezone == :utc ? time : time.getlocal
133
+ ActiveRecord.default_timezone == :utc ? time : time.getlocal
134
134
  else
135
- timezone = ActiveRecord::Base.default_timezone
135
+ timezone = ActiveRecord.default_timezone
136
136
  Time.public_send(timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
137
137
  end
138
138
  end
@@ -81,7 +81,7 @@ module ArJdbc
81
81
  # If using Active Record's time zone support configure the connection to return
82
82
  # TIMESTAMP WITH ZONE types in UTC.
83
83
  # (SET TIME ZONE does not use an equals sign like other SET variables)
84
- if ActiveRecord::Base.default_timezone == :utc
84
+ if ActiveRecord.default_timezone == :utc
85
85
  execute("SET time zone 'UTC'", 'SCHEMA')
86
86
  elsif tz = local_tz
87
87
  execute("SET time zone '#{tz}'", 'SCHEMA')
@@ -10,6 +10,7 @@ require "active_record/connection_adapters/abstract_adapter"
10
10
  require "active_record/connection_adapters/statement_pool"
11
11
  require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
12
12
  require "active_record/connection_adapters/sqlite3/quoting"
13
+ require "active_record/connection_adapters/sqlite3/database_statements"
13
14
  require "active_record/connection_adapters/sqlite3/schema_creation"
14
15
  require "active_record/connection_adapters/sqlite3/schema_definitions"
15
16
  require "active_record/connection_adapters/sqlite3/schema_dumper"
@@ -64,6 +65,7 @@ module ArJdbc
64
65
  # DIFFERENCE: FQN
65
66
  include ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
66
67
  include ::ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
68
+ include ::ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements
67
69
 
68
70
  NATIVE_DATABASE_TYPES = {
69
71
  primary_key: "integer PRIMARY KEY AUTOINCREMENT NOT NULL",
@@ -79,15 +81,30 @@ module ArJdbc
79
81
  boolean: { name: "boolean" },
80
82
  json: { name: "json" },
81
83
  }
82
-
83
- # DIFFERENCE: class_attribute in original adapter is moved down to our section which is a class
84
- # since we cannot define it here in the module (original source this is a class).
84
+
85
+ class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
86
+ private
87
+ def dealloc(stmt)
88
+ stmt.close unless stmt.closed?
89
+ end
90
+ end
85
91
 
86
92
  def initialize(connection, logger, connection_options, config)
93
+ @memory_database = config[:database] == ":memory:"
87
94
  super(connection, logger, config)
88
95
  configure_connection
89
96
  end
90
97
 
98
+ def self.database_exists?(config)
99
+ config = config.symbolize_keys
100
+ if config[:database] == ":memory:"
101
+ true
102
+ else
103
+ database_file = defined?(Rails.root) ? File.expand_path(config[:database], Rails.root) : config[:database]
104
+ File.exist?(database_file)
105
+ end
106
+ end
107
+
91
108
  def supports_ddl_transactions?
92
109
  true
93
110
  end
@@ -101,7 +118,7 @@ module ArJdbc
101
118
  end
102
119
 
103
120
  def supports_partial_index?
104
- database_version >= "3.9.0"
121
+ true
105
122
  end
106
123
 
107
124
  def supports_expression_index?
@@ -144,6 +161,25 @@ module ArJdbc
144
161
  alias supports_insert_conflict_target? supports_insert_on_conflict?
145
162
 
146
163
  # DIFFERENCE: active?, reconnect!, disconnect! handles by arjdbc core
164
+ def supports_concurrent_connections?
165
+ !@memory_database
166
+ end
167
+
168
+ def active?
169
+ !@raw_connection.closed?
170
+ end
171
+
172
+ def reconnect!
173
+ super
174
+ connect if @connection.closed?
175
+ end
176
+
177
+ # Disconnects from the database if already connected. Otherwise, this
178
+ # method does nothing.
179
+ def disconnect!
180
+ super
181
+ @connection.close rescue nil
182
+ end
147
183
 
148
184
  def supports_index_sort_order?
149
185
  true
@@ -182,48 +218,8 @@ module ArJdbc
182
218
  end
183
219
  end
184
220
 
185
- #--
186
- # DATABASE STATEMENTS ======================================
187
- #++
188
-
189
- READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
190
- :pragma
191
- ) # :nodoc:
192
- private_constant :READ_QUERY
193
-
194
- def write_query?(sql) # :nodoc:
195
- !READ_QUERY.match?(sql)
196
- end
197
-
198
- def explain(arel, binds = [])
199
- sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
200
- # DIFFERENCE: FQN
201
- ::ActiveRecord::ConnectionAdapters::SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
202
- end
203
-
204
- # DIFFERENCE: implemented in ArJdbc::Abstract::DatabaseStatements
205
- #def exec_query(sql, name = nil, binds = [], prepare: false)
206
-
207
- # DIFFERENCE: implemented in ArJdbc::Abstract::DatabaseStatements
208
- #def exec_delete(sql, name = "SQL", binds = [])
209
-
210
- def last_inserted_id(result)
211
- @connection.last_insert_row_id
212
- end
213
-
214
- # DIFFERENCE: implemented in ArJdbc::Abstract::DatabaseStatements
215
- #def execute(sql, name = nil) #:nodoc:
216
-
217
- def begin_db_transaction #:nodoc:
218
- log("begin transaction", 'TRANSACTION') { @connection.transaction }
219
- end
220
-
221
- def commit_db_transaction #:nodoc:
222
- log("commit transaction", 'TRANSACTION') { @connection.commit }
223
- end
224
-
225
- def exec_rollback_db_transaction #:nodoc:
226
- log("rollback transaction", 'TRANSACTION') { @connection.rollback }
221
+ def all_foreign_keys_valid? # :nodoc:
222
+ execute("PRAGMA foreign_key_check").blank?
227
223
  end
228
224
 
229
225
  # SCHEMA STATEMENTS ========================================
@@ -233,14 +229,15 @@ module ArJdbc
233
229
  pks.sort_by { |f| f["pk"] }.map { |f| f["name"] }
234
230
  end
235
231
 
236
- def remove_index(table_name, column_name = nil, **options) # :nodoc:
237
- return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
232
+ def remove_index(table_name, column_name = nil, **options) # :nodoc:
233
+ return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
238
234
 
239
235
  index_name = index_name_for_remove(table_name, column_name, options)
240
236
 
241
237
  exec_query "DROP INDEX #{quote_column_name(index_name)}"
242
238
  end
243
239
 
240
+
244
241
  # Renames a table.
245
242
  #
246
243
  # Example:
@@ -271,6 +268,16 @@ module ArJdbc
271
268
  end
272
269
  end
273
270
 
271
+ def remove_columns(table_name, *column_names, type: nil, **options) # :nodoc:
272
+ alter_table(table_name) do |definition|
273
+ column_names.each do |column_name|
274
+ definition.remove_column column_name
275
+ end
276
+ column_names = column_names.map(&:to_s)
277
+ definition.foreign_keys.delete_if { |fk| column_names.include?(fk.column) }
278
+ end
279
+ end
280
+
274
281
  def change_column_default(table_name, column_name, default_or_changes) #:nodoc:
275
282
  default = extract_new_default_value(default_or_changes)
276
283
 
@@ -322,18 +329,6 @@ module ArJdbc
322
329
  end
323
330
  end
324
331
 
325
- def insert_fixtures_set(fixture_set, tables_to_delete = [])
326
- disable_referential_integrity do
327
- transaction(requires_new: true) do
328
- tables_to_delete.each { |table| delete "DELETE FROM #{quote_table_name(table)}", "Fixture Delete" }
329
-
330
- fixture_set.each do |table_name, rows|
331
- rows.each { |row| insert_fixture(row, table_name) }
332
- end
333
- end
334
- end
335
- end
336
-
337
332
  def build_insert_sql(insert) # :nodoc:
338
333
  sql = +"INSERT #{insert.into} #{insert.values_list}"
339
334
 
@@ -348,18 +343,14 @@ module ArJdbc
348
343
  sql
349
344
  end
350
345
 
351
- def shared_cache?
352
- config[:properties] && config[:properties][:shared_cache] == true
346
+ def shared_cache? # :nodoc:
347
+ @config.fetch(:flags, 0).anybits?(::SQLite3::Constants::Open::SHAREDCACHE)
353
348
  end
354
349
 
355
350
  def get_database_version # :nodoc:
356
351
  SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
357
352
  end
358
353
 
359
- def build_truncate_statement(table_name)
360
- "DELETE FROM #{quote_table_name(table_name)}"
361
- end
362
-
363
354
  def check_version
364
355
  if database_version < "3.8.0"
365
356
  raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8."
@@ -380,6 +371,34 @@ module ArJdbc
380
371
  end
381
372
  alias column_definitions table_structure
382
373
 
374
+ def extract_value_from_default(default)
375
+ case default
376
+ when /^null$/i
377
+ nil
378
+ # Quoted types
379
+ when /^'(.*)'$/m
380
+ $1.gsub("''", "'")
381
+ # Quoted types
382
+ when /^"(.*)"$/m
383
+ $1.gsub('""', '"')
384
+ # Numeric types
385
+ when /\A-?\d+(\.\d*)?\z/
386
+ $&
387
+ else
388
+ # Anything else is blank or some function
389
+ # and we can't know the value of that, so return nil.
390
+ nil
391
+ end
392
+ end
393
+
394
+ def extract_default_function(default_value, default)
395
+ default if has_default_function?(default_value, default)
396
+ end
397
+
398
+ def has_default_function?(default_value, default)
399
+ !default_value && %r{\w+\(.*\)|CURRENT_TIME|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
400
+ end
401
+
383
402
  # See: https://www.sqlite.org/lang_altertable.html
384
403
  # SQLite has an additional restriction on the ALTER TABLE statement
385
404
  def invalid_alter_table_type?(type, options)
@@ -481,6 +500,7 @@ module ArJdbc
481
500
  options = { name: name.gsub(/(^|_)(#{from})_/, "\\1#{to}_"), internal: true }
482
501
  options[:unique] = true if index.unique
483
502
  options[:where] = index.where if index.where
503
+ options[:order] = index.orders if index.orders
484
504
  add_index(to, columns, **options)
485
505
  end
486
506
  end
@@ -564,6 +584,17 @@ module ArJdbc
564
584
  Arel::Visitors::SQLite.new(self)
565
585
  end
566
586
 
587
+ def build_statement_pool
588
+ StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
589
+ end
590
+
591
+ def connect
592
+ @connection = ::SQLite3::Database.new(
593
+ @config[:database].to_s,
594
+ @config.merge(results_as_hash: true)
595
+ )
596
+ end
597
+
567
598
  def configure_connection
568
599
  execute("PRAGMA foreign_keys = ON", "SCHEMA")
569
600
  end
@@ -720,11 +751,15 @@ module ActiveRecord::ConnectionAdapters
720
751
 
721
752
  # because the JDBC driver doesn't like multiple SQL statements in one JDBC statement
722
753
  def combine_multi_statements(total_sql)
723
- if total_sql.length == 1
724
- total_sql.first
725
- else
726
- total_sql
727
- end
754
+ total_sql
755
+ end
756
+
757
+ # combine
758
+ def write_query?(sql) # :nodoc:
759
+ return sql.any? { |stmt| super(stmt) } if sql.kind_of? Array
760
+ !READ_QUERY.match?(sql)
761
+ rescue ArgumentError # Invalid encoding
762
+ !READ_QUERY.match?(sql.b)
728
763
  end
729
764
 
730
765
  def initialize_type_map(m = type_map)
@@ -1,3 +1,3 @@
1
1
  module ArJdbc
2
- VERSION = '61.0'
2
+ VERSION = '70.0.pre'
3
3
  end
@@ -720,6 +720,21 @@ public class RubyJdbcConnection extends RubyObject {
720
720
  }
721
721
  }
722
722
 
723
+ @JRubyMethod(name = "closed?")
724
+ public IRubyObject closed_p(ThreadContext context) {
725
+ try {
726
+ final Connection connection = getConnectionInternal(false);
727
+
728
+ if (connection == null) return context.fals;
729
+
730
+ // NOTE: isClosed method generally cannot be called to determine
731
+ // whether a connection to a database is valid or invalid ...
732
+ return context.runtime.newBoolean(connection.isClosed());
733
+ } catch (SQLException e) {
734
+ return handleException(context, e);
735
+ }
736
+ }
737
+
723
738
  @JRubyMethod(name = "close")
724
739
  public IRubyObject close(final ThreadContext context) {
725
740
  final Connection connection = getConnection(false);
@@ -2633,8 +2648,8 @@ public class RubyJdbcConnection extends RubyObject {
2633
2648
  }
2634
2649
 
2635
2650
  private String default_timezone(final ThreadContext context) {
2636
- final RubyClass base = getBase(context.runtime);
2637
- return default_timezone.call(context, base, base).asJavaString(); // :utc (or :local)
2651
+ final RubyModule activeRecord = ActiveRecord(context);
2652
+ return default_timezone.call(context, activeRecord, activeRecord).asJavaString(); // :utc (or :local)
2638
2653
  }
2639
2654
 
2640
2655
  // ActiveRecord::Base.default_timezone
@@ -460,6 +460,34 @@ public class SQLite3RubyJdbcConnection extends RubyJdbcConnection {
460
460
  return context.runtime.newBoolean(connection.isReadOnly());
461
461
  }
462
462
 
463
+ // note: sqlite3 cext uses this same method but we do not combine all our statements
464
+ // into a single ; delimited string but leave it as an array of statements. This is
465
+ // because the JDBC way of handling batches is to use addBatch().
466
+ @JRubyMethod(name = "execute_batch2")
467
+ public IRubyObject execute_batch2(ThreadContext context, IRubyObject statementsArg) {
468
+ // Assume we will only call this with an array.
469
+ final RubyArray statements = (RubyArray) statementsArg;
470
+ return withConnection(context, connection -> {
471
+ Statement statement = null;
472
+ try {
473
+ statement = createStatement(context, connection);
474
+
475
+ int length = statements.getLength();
476
+ for (int i = 0; i < length; i++) {
477
+ statement.addBatch(sqlString(statements.eltOk(i)));
478
+ }
479
+ statement.executeBatch();
480
+ return context.nil;
481
+ } catch (final SQLException e) {
482
+ // Generate list semicolon list of statements which should match AR error formatting more.
483
+ debugErrorSQL(context, sqlString(statements.join(context, context.runtime.newString(";\n"))));
484
+ throw e;
485
+ } finally {
486
+ close(statement);
487
+ }
488
+ });
489
+ }
490
+
463
491
  @Override
464
492
  protected void setDecimalParameter(final ThreadContext context,
465
493
  final Connection connection, final PreparedStatement statement,
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-jdbc-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: '61.0'
4
+ version: 70.0.pre
5
5
  platform: java
6
6
  authors:
7
7
  - Nick Sieger, Ola Bini, Karol Bucek and JRuby contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-17 00:00:00.000000000 Z
11
+ date: 2022-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 6.1.0
18
+ version: '7.0'
19
19
  name: activerecord
20
- type: :runtime
21
20
  prerelease: false
21
+ type: :runtime
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 6.1.0
26
+ version: '7.0'
27
27
  description: 'AR-JDBC is a database adapter for Rails'' ActiveRecord component designed
28
28
  to be used with JRuby built upon Java''s JDBC API for database access. Provides
29
29
  (ActiveRecord) built-in adapters: MySQL, PostgreSQL, SQLite3, and SQLServer.'
@@ -35,6 +35,7 @@ executables: []
35
35
  extensions: []
36
36
  extra_rdoc_files: []
37
37
  files:
38
+ - ".github/workflows/ruby.yml"
38
39
  - ".gitignore"
39
40
  - ".travis.yml"
40
41
  - ".yardopts"
@@ -226,11 +227,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
226
227
  version: '0'
227
228
  required_rubygems_version: !ruby/object:Gem::Requirement
228
229
  requirements:
229
- - - ">="
230
+ - - ">"
230
231
  - !ruby/object:Gem::Version
231
- version: '0'
232
+ version: 1.3.1
232
233
  requirements: []
233
- rubygems_version: 3.0.6
234
+ rubygems_version: 3.3.13
234
235
  signing_key:
235
236
  specification_version: 4
236
237
  summary: JDBC adapter for ActiveRecord, for use within JRuby on Rails.