activerecord-jdbc-adapter 52.8-java → 60.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.travis.yml +58 -37
  4. data/Gemfile +9 -2
  5. data/README.md +25 -9
  6. data/Rakefile +1 -1
  7. data/Rakefile.jdbc +8 -1
  8. data/activerecord-jdbc-adapter.gemspec +5 -8
  9. data/lib/arjdbc/abstract/connection_management.rb +7 -0
  10. data/lib/arjdbc/abstract/core.rb +16 -23
  11. data/lib/arjdbc/abstract/database_statements.rb +26 -2
  12. data/lib/arjdbc/abstract/statement_cache.rb +2 -5
  13. data/lib/arjdbc/abstract/transaction_support.rb +5 -3
  14. data/lib/arjdbc/db2/column.rb +0 -39
  15. data/lib/arjdbc/derby/adapter.rb +1 -20
  16. data/lib/arjdbc/firebird/adapter.rb +0 -21
  17. data/lib/arjdbc/h2/adapter.rb +0 -15
  18. data/lib/arjdbc/hsqldb/adapter.rb +0 -14
  19. data/lib/arjdbc/informix/adapter.rb +0 -23
  20. data/lib/arjdbc/jdbc/adapter.rb +3 -1
  21. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  22. data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
  23. data/lib/arjdbc/jdbc/base_ext.rb +3 -1
  24. data/lib/arjdbc/jdbc/callbacks.rb +2 -0
  25. data/lib/arjdbc/jdbc/column.rb +2 -0
  26. data/lib/arjdbc/jdbc/connection.rb +2 -0
  27. data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
  28. data/lib/arjdbc/jdbc/error.rb +2 -0
  29. data/lib/arjdbc/jdbc/extension.rb +2 -0
  30. data/lib/arjdbc/jdbc/java.rb +3 -1
  31. data/lib/arjdbc/jdbc/railtie.rb +3 -1
  32. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
  33. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
  34. data/lib/arjdbc/jdbc/type_cast.rb +2 -0
  35. data/lib/arjdbc/jdbc/type_converter.rb +2 -0
  36. data/lib/arjdbc/mysql/adapter.rb +47 -18
  37. data/lib/arjdbc/mysql/connection_methods.rb +0 -1
  38. data/lib/arjdbc/postgresql/adapter.rb +220 -213
  39. data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
  40. data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
  41. data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
  42. data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
  43. data/lib/arjdbc/postgresql/column.rb +6 -4
  44. data/lib/arjdbc/postgresql/connection_methods.rb +0 -1
  45. data/lib/arjdbc/postgresql/name.rb +2 -0
  46. data/lib/arjdbc/postgresql/oid_types.rb +2 -0
  47. data/lib/arjdbc/sqlite3/adapter.rb +175 -180
  48. data/lib/arjdbc/sqlite3/connection_methods.rb +15 -5
  49. data/lib/arjdbc/tasks/databases.rake +13 -10
  50. data/lib/arjdbc/util/quoted_cache.rb +3 -1
  51. data/lib/arjdbc/util/serialized_attributes.rb +3 -1
  52. data/lib/arjdbc/util/table_copier.rb +3 -1
  53. data/lib/arjdbc/version.rb +1 -1
  54. data/pom.xml +4 -4
  55. data/rakelib/01-tomcat.rake +2 -2
  56. data/rakelib/rails.rake +1 -1
  57. data/src/java/arjdbc/ArJdbcModule.java +5 -5
  58. data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
  59. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +434 -701
  60. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +0 -51
  61. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
  62. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +31 -24
  63. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +94 -99
  64. metadata +7 -9
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # based on active_record/connection_adapters/postgresql/array_parser.rb
2
4
  # until it's some day shareable with Rails ... this is not public API !
3
5
  module ActiveRecord
@@ -33,7 +35,7 @@ module ActiveRecord
33
35
  is_escaping = false
34
36
  is_quoted = false
35
37
  was_quoted = false
36
- current_item = ''
38
+ current_item = ''.dup
37
39
 
38
40
  local_index = index
39
41
  while local_index
@@ -58,7 +60,7 @@ module ActiveRecord
58
60
  is_escaping = true
59
61
  when COMMA
60
62
  add_item_to_array(array, current_item, was_quoted)
61
- current_item = ''
63
+ current_item = ''.dup
62
64
  was_quoted = false
63
65
  when DOUBLE_QUOTE
64
66
  is_quoted = true
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord::ConnectionAdapters::PostgreSQL::OID
2
4
  class Bytea < ActiveModel::Type::Binary
3
5
  module PG
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArJdbc
2
4
  module PostgreSQL
3
5
 
@@ -20,13 +22,13 @@ module ArJdbc
20
22
  # Quoted types
21
23
  when /\A[\(B]?'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m
22
24
  # The default 'now'::date is CURRENT_DATE
23
- if $1 == "now".freeze && $2 == "date".freeze
25
+ if $1 == "now" && $2 == "date"
24
26
  nil
25
27
  else
26
- $1.gsub("''".freeze, "'".freeze)
28
+ $1.gsub("''", "'")
27
29
  end
28
30
  # Boolean types
29
- when 'true'.freeze, 'false'.freeze
31
+ when 'true', 'false'
30
32
  default
31
33
  # Numeric types
32
34
  when /\A\(?(-?\d+(\.\d*)?)\)?(::bigint)?\z/
@@ -46,7 +48,7 @@ module ArJdbc
46
48
  end
47
49
 
48
50
  def has_default_function?(default_value, default)
49
- !default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP} === default
51
+ !default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
50
52
  end
51
53
  end
52
54
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  ArJdbc::ConnectionMethods.module_eval do
3
3
  def postgresql_connection(config)
4
- config = config.deep_dup
5
4
  # NOTE: this isn't "really" necessary but Rails (in tests) assumes being able to :
6
5
  # ActiveRecord::Base.postgresql_connection ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false)
7
6
  # ... while using symbols by default but than configurations returning string keys ;(
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This patches the Name class so that it doesn't use pg gem specific quoting
2
4
  module ActiveRecord
3
5
  module ConnectionAdapters
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thread'
2
4
 
3
5
  module ArJdbc
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ArJdbc.load_java_part :SQLite3
2
4
 
3
5
  require "arjdbc/abstract/core"
@@ -30,7 +32,7 @@ module ArJdbc
30
32
  SchemaCreation = ConnectionAdapters::SQLite3::SchemaCreation
31
33
  SQLite3Adapter = ConnectionAdapters::AbstractAdapter
32
34
 
33
- ADAPTER_NAME = 'SQLite'.freeze
35
+ ADAPTER_NAME = 'SQLite'
34
36
 
35
37
  # DIFFERENCE: FQN
36
38
  include ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
@@ -54,20 +56,8 @@ module ArJdbc
54
56
  # DIFFERENCE: class_attribute in original adapter is moved down to our section which is a class
55
57
  # since we cannot define it here in the module (original source this is a class).
56
58
 
57
- class StatementPool < ConnectionAdapters::StatementPool
58
- private
59
-
60
- def dealloc(stmt)
61
- stmt[:stmt].close unless stmt[:stmt].closed?
62
- end
63
- end
64
-
65
59
  def initialize(connection, logger, connection_options, config)
66
60
  super(connection, logger, config)
67
-
68
- @active = true
69
- @statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
70
-
71
61
  configure_connection
72
62
  end
73
63
 
@@ -80,15 +70,19 @@ module ArJdbc
80
70
  end
81
71
 
82
72
  def supports_partial_index?
83
- sqlite_version >= "3.8.0"
73
+ database_version >= "3.9.0"
74
+ end
75
+
76
+ def supports_expression_index?
77
+ database_version >= "3.9.0"
84
78
  end
85
79
 
86
80
  def requires_reloading?
87
81
  true
88
82
  end
89
83
 
90
- def supports_foreign_keys_in_create?
91
- sqlite_version >= "3.6.19"
84
+ def supports_foreign_keys?
85
+ true
92
86
  end
93
87
 
94
88
  def supports_views?
@@ -99,26 +93,18 @@ module ArJdbc
99
93
  true
100
94
  end
101
95
 
102
- def supports_multi_insert?
103
- sqlite_version >= "3.7.11"
104
- end
105
-
106
- def active?
107
- @active
96
+ def supports_json?
97
+ true
108
98
  end
109
99
 
110
- # Disconnects from the database if already connected. Otherwise, this
111
- # method does nothing.
112
- def disconnect!
113
- super
114
- @active = false
115
- @connection.close rescue nil
100
+ def supports_insert_on_conflict?
101
+ database_version >= "3.24.0"
116
102
  end
103
+ alias supports_insert_on_duplicate_skip? supports_insert_on_conflict?
104
+ alias supports_insert_on_duplicate_update? supports_insert_on_conflict?
105
+ alias supports_insert_conflict_target? supports_insert_on_conflict?
117
106
 
118
- # Clears the prepared statements cache.
119
- def clear_cache!
120
- @statements.clear
121
- end
107
+ # DIFFERENCE: active?, reconnect!, disconnect! handles by arjdbc core
122
108
 
123
109
  def supports_index_sort_order?
124
110
  true
@@ -144,90 +130,66 @@ module ArJdbc
144
130
  true
145
131
  end
146
132
 
133
+ def supports_lazy_transactions?
134
+ true
135
+ end
136
+
147
137
  # REFERENTIAL INTEGRITY ====================================
148
138
 
149
139
  def disable_referential_integrity # :nodoc:
150
- old = query_value("PRAGMA foreign_keys")
140
+ old_foreign_keys = query_value("PRAGMA foreign_keys")
141
+ old_defer_foreign_keys = query_value("PRAGMA defer_foreign_keys")
151
142
 
152
143
  begin
144
+ execute("PRAGMA defer_foreign_keys = ON")
153
145
  execute("PRAGMA foreign_keys = OFF")
154
146
  yield
155
147
  ensure
156
- execute("PRAGMA foreign_keys = #{old}")
148
+ execute("PRAGMA defer_foreign_keys = #{old_defer_foreign_keys}")
149
+ execute("PRAGMA foreign_keys = #{old_foreign_keys}")
157
150
  end
158
151
  end
159
-
152
+
160
153
  #--
161
154
  # DATABASE STATEMENTS ======================================
162
155
  #++
163
156
 
157
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(:begin, :commit, :explain, :select, :pragma, :release, :savepoint, :rollback) # :nodoc:
158
+ private_constant :READ_QUERY
159
+
160
+ def write_query?(sql) # :nodoc:
161
+ !READ_QUERY.match?(sql)
162
+ end
163
+
164
164
  def explain(arel, binds = [])
165
165
  sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
166
166
  # DIFFERENCE: FQN
167
167
  ::ActiveRecord::ConnectionAdapters::SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
168
168
  end
169
169
 
170
- def exec_query(sql, name = nil, binds = [], prepare: false)
171
- type_casted_binds = type_casted_binds(binds)
172
-
173
- log(sql, name, binds, type_casted_binds) do
174
- ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
175
- # Don't cache statements if they are not prepared
176
- unless prepare
177
- stmt = @connection.prepare(sql)
178
- begin
179
- cols = stmt.columns
180
- unless without_prepared_statement?(binds)
181
- stmt.bind_params(type_casted_binds)
182
- end
183
- records = stmt.to_a
184
- ensure
185
- stmt.close
186
- end
187
- else
188
- cache = @statements[sql] ||= {
189
- stmt: @connection.prepare(sql)
190
- }
191
- stmt = cache[:stmt]
192
- cols = cache[:cols] ||= stmt.columns
193
- stmt.reset!
194
- stmt.bind_params(type_casted_binds)
195
- records = stmt.to_a
196
- end
170
+ # DIFFERENCE: implemented in ArJdbc::Abstract::DatabaseStatements
171
+ #def exec_query(sql, name = nil, binds = [], prepare: false)
197
172
 
198
- ActiveRecord::Result.new(cols, records)
199
- end
200
- end
201
- end
202
-
203
- def exec_delete(sql, name = 'SQL', binds = [])
204
- exec_query(sql, name, binds)
205
- @connection.changes
206
- end
207
- alias :exec_update :exec_delete
173
+ # DIFFERENCE: implemented in ArJdbc::Abstract::DatabaseStatements
174
+ #def exec_delete(sql, name = "SQL", binds = [])
208
175
 
209
176
  def last_inserted_id(result)
210
177
  @connection.last_insert_row_id
211
178
  end
212
179
 
213
- def execute(sql, name = nil) #:nodoc:
214
- log(sql, name) do
215
- ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
216
- @connection.execute(sql)
217
- end
218
- end
219
- end
180
+ # DIFFERENCE: implemented in ArJdbc::Abstract::DatabaseStatements
181
+ #def execute(sql, name = nil) #:nodoc:
220
182
 
221
183
  def begin_db_transaction #:nodoc:
222
- log("begin transaction",nil) { @connection.transaction }
184
+ log("begin transaction", nil) { @connection.transaction }
223
185
  end
224
186
 
225
187
  def commit_db_transaction #:nodoc:
226
- log("commit transaction",nil) { @connection.commit }
188
+ log("commit transaction", nil) { @connection.commit }
227
189
  end
228
190
 
229
191
  def exec_rollback_db_transaction #:nodoc:
230
- log("rollback transaction",nil) { @connection.rollback }
192
+ log("rollback transaction", nil) { @connection.rollback }
231
193
  end
232
194
 
233
195
  # SCHEMA STATEMENTS ========================================
@@ -251,13 +213,6 @@ module ArJdbc
251
213
  rename_table_indexes(table_name, new_name)
252
214
  end
253
215
 
254
- # DIFFERENCE: deprecated causes a JRuby 9.1 bug where "super" calls itself -> do inline
255
- def valid_alter_table_type?(type, options = {})
256
- ActiveSupport::Deprecation.deprecation_warning(__method__)
257
- !invalid_alter_table_type?(type, options)
258
- end
259
- #deprecate :valid_alter_table_type?
260
-
261
216
  def add_column(table_name, column_name, type, options = {}) #:nodoc:
262
217
  if invalid_alter_table_type?(type, options)
263
218
  alter_table(table_name) do |definition|
@@ -271,6 +226,9 @@ module ArJdbc
271
226
  def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
272
227
  alter_table(table_name) do |definition|
273
228
  definition.remove_column column_name
229
+ definition.foreign_keys.delete_if do |_, fk_options|
230
+ fk_options[:column] == column_name.to_s
231
+ end
274
232
  end
275
233
  end
276
234
 
@@ -330,14 +288,6 @@ module ArJdbc
330
288
  end
331
289
  end
332
290
 
333
- def insert_fixtures(rows, table_name)
334
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
335
- `insert_fixtures` is deprecated and will be removed in the next version of Rails.
336
- Consider using `insert_fixtures_set` for performance improvement.
337
- MSG
338
- insert_fixtures_set(table_name => rows)
339
- end
340
-
341
291
  def insert_fixtures_set(fixture_set, tables_to_delete = [])
342
292
  disable_referential_integrity do
343
293
  transaction(requires_new: true) do
@@ -349,8 +299,44 @@ module ArJdbc
349
299
  end
350
300
  end
351
301
  end
352
-
302
+
303
+ def build_insert_sql(insert) # :nodoc:
304
+ sql = +"INSERT #{insert.into} #{insert.values_list}"
305
+
306
+ if insert.skip_duplicates?
307
+ sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING"
308
+ elsif insert.update_duplicates?
309
+ sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET "
310
+ sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",")
311
+ end
312
+
313
+ sql
314
+ end
315
+
316
+ def get_database_version # :nodoc:
317
+ SQLite3Adapter::Version.new(query_value("SELECT sqlite_version(*)"))
318
+ end
319
+
320
+ def build_truncate_statements(*table_names)
321
+ truncate_tables = table_names.map do |table_name|
322
+ "DELETE FROM #{quote_table_name(table_name)}"
323
+ end
324
+ combine_multi_statements(truncate_tables)
325
+ end
326
+
327
+ def check_version
328
+ if database_version < "3.8.0"
329
+ raise "Your version of SQLite (#{database_version}) is too old. Active Record supports SQLite >= 3.8."
330
+ end
331
+ end
332
+
353
333
  private
334
+ # See https://www.sqlite.org/limits.html,
335
+ # the default value is 999 when not configured.
336
+ def bind_params_length
337
+ 999
338
+ end
339
+
354
340
  def initialize_type_map(m = type_map)
355
341
  super
356
342
  register_class_with_limit m, %r(int)i, SQLite3Integer
@@ -369,14 +355,27 @@ module ArJdbc
369
355
  type.to_sym == :primary_key || options[:primary_key]
370
356
  end
371
357
 
372
- def alter_table(table_name, options = {}) #:nodoc:
358
+ def alter_table(table_name, foreign_keys = foreign_keys(table_name), **options)
373
359
  altered_table_name = "a#{table_name}"
374
- caller = lambda { |definition| yield definition if block_given? }
360
+
361
+ caller = lambda do |definition|
362
+ rename = options[:rename] || {}
363
+ foreign_keys.each do |fk|
364
+ if column = rename[fk.options[:column]]
365
+ fk.options[:column] = column
366
+ end
367
+ to_table = strip_table_name_prefix_and_suffix(fk.to_table)
368
+ definition.foreign_key(to_table, fk.options)
369
+ end
370
+
371
+ yield definition if block_given?
372
+ end
375
373
 
376
374
  transaction do
377
- move_table(table_name, altered_table_name,
378
- options.merge(temporary: true))
379
- move_table(altered_table_name, table_name, &caller)
375
+ disable_referential_integrity do
376
+ move_table(table_name, altered_table_name, options.merge(temporary: true))
377
+ move_table(altered_table_name, table_name, &caller)
378
+ end
380
379
  end
381
380
  end
382
381
 
@@ -395,23 +394,24 @@ module ArJdbc
395
394
  end
396
395
  columns(from).each do |column|
397
396
  column_name = options[:rename] ?
398
- (options[:rename][column.name] ||
399
- options[:rename][column.name.to_sym] ||
400
- column.name) : column.name
397
+ (options[:rename][column.name] ||
398
+ options[:rename][column.name.to_sym] ||
399
+ column.name) : column.name
401
400
 
402
401
  @definition.column(column_name, column.type,
403
- limit: column.limit, default: column.default,
404
- precision: column.precision, scale: column.scale,
405
- null: column.null, collation: column.collation,
406
- primary_key: column_name == from_primary_key
402
+ limit: column.limit, default: column.default,
403
+ precision: column.precision, scale: column.scale,
404
+ null: column.null, collation: column.collation,
405
+ primary_key: column_name == from_primary_key
407
406
  )
408
407
  end
408
+
409
409
  yield @definition if block_given?
410
410
  end
411
411
  copy_table_indexes(from, to, options[:rename] || {})
412
412
  copy_table_contents(from, to,
413
- @definition.columns.map(&:name),
414
- options[:rename] || {})
413
+ @definition.columns.map(&:name),
414
+ options[:rename] || {})
415
415
  end
416
416
 
417
417
  def copy_table_indexes(from, to, rename = {})
@@ -426,9 +426,12 @@ module ArJdbc
426
426
  name = name[1..-1]
427
427
  end
428
428
 
429
- to_column_names = columns(to).map(&:name)
430
- columns = index.columns.map { |c| rename[c] || c }.select do |column|
431
- to_column_names.include?(column)
429
+ columns = index.columns
430
+ if columns.is_a?(Array)
431
+ to_column_names = columns(to).map(&:name)
432
+ columns = columns.map { |c| rename[c] || c }.select do |column|
433
+ to_column_names.include?(column)
434
+ end
432
435
  end
433
436
 
434
437
  unless columns.empty?
@@ -454,27 +457,23 @@ module ArJdbc
454
457
  SELECT #{quoted_from_columns} FROM #{quote_table_name(from)}")
455
458
  end
456
459
 
457
- def sqlite_version
458
- @sqlite_version ||= SQLite3Adapter::Version.new(select_value("select sqlite_version(*)"))
459
- end
460
-
461
- def translate_exception(exception, message)
460
+ def translate_exception(exception, message:, sql:, binds:)
462
461
  case exception.message
463
- # SQLite 3.8.2 returns a newly formatted error message:
464
- # UNIQUE constraint failed: *table_name*.*column_name*
465
- # Older versions of SQLite return:
466
- # column *column_name* is not unique
467
- when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/
468
- # DIFFERENCE: FQN
469
- ::ActiveRecord::RecordNotUnique.new(message)
470
- when /.* may not be NULL/, /NOT NULL constraint failed: .*/
471
- # DIFFERENCE: FQN
472
- ::ActiveRecord::NotNullViolation.new(message)
473
- when /FOREIGN KEY constraint failed/i
474
- # DIFFERENCE: FQN
475
- ::ActiveRecord::InvalidForeignKey.new(message)
476
- else
477
- super
462
+ # SQLite 3.8.2 returns a newly formatted error message:
463
+ # UNIQUE constraint failed: *table_name*.*column_name*
464
+ # Older versions of SQLite return:
465
+ # column *column_name* is not unique
466
+ when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/
467
+ # DIFFERENCE: FQN
468
+ ::ActiveRecord::RecordNotUnique.new(message, sql: sql, binds: binds)
469
+ when /.* may not be NULL/, /NOT NULL constraint failed: .*/
470
+ # DIFFERENCE: FQN
471
+ ::ActiveRecord::NotNullViolation.new(message, sql: sql, binds: binds)
472
+ when /FOREIGN KEY constraint failed/i
473
+ # DIFFERENCE: FQN
474
+ ::ActiveRecord::InvalidForeignKey.new(message, sql: sql, binds: binds)
475
+ else
476
+ super
478
477
  end
479
478
  end
480
479
 
@@ -482,11 +481,11 @@ module ArJdbc
482
481
 
483
482
  def table_structure_with_collation(table_name, basic_structure)
484
483
  collation_hash = {}
485
- sql = <<-SQL
486
- SELECT sql FROM
487
- (SELECT * FROM sqlite_master UNION ALL
488
- SELECT * FROM sqlite_temp_master)
489
- WHERE type = 'table' AND name = #{quote(table_name)}
484
+ sql = <<~SQL
485
+ SELECT sql FROM
486
+ (SELECT * FROM sqlite_master UNION ALL
487
+ SELECT * FROM sqlite_temp_master)
488
+ WHERE type = 'table' AND name = #{quote(table_name)}
490
489
  SQL
491
490
 
492
491
  # Result will have following sample string
@@ -495,9 +494,9 @@ module ArJdbc
495
494
  result = exec_query(sql, "SCHEMA").first
496
495
 
497
496
  if result
498
- # Splitting with left parentheses and picking up last will return all
497
+ # Splitting with left parentheses and discarding the first part will return all
499
498
  # columns separated with comma(,).
500
- columns_string = result["sql"].split("(").last
499
+ columns_string = result["sql"].split("(", 2).last
501
500
 
502
501
  columns_string.split(",").each do |column_string|
503
502
  # This regex will match the column name and collation type and will save
@@ -515,7 +514,7 @@ module ArJdbc
515
514
  column
516
515
  end
517
516
  else
518
- basic_structure.to_hash
517
+ basic_structure.to_a
519
518
  end
520
519
  end
521
520
 
@@ -597,24 +596,6 @@ module ActiveRecord::ConnectionAdapters
597
596
 
598
597
  private
599
598
 
600
- # @override {ActiveRecord::ConnectionAdapters::Column#simplified_type}
601
- def simplified_type(field_type)
602
- case field_type
603
- when /boolean/i then :boolean
604
- when /text/i then :text
605
- when /varchar/i then :string
606
- when /int/i then :integer
607
- when /float/i then :float
608
- when /real|decimal/i then
609
- extract_scale(field_type) == 0 ? :integer : :decimal
610
- when /datetime/i then :datetime
611
- when /date/i then :date
612
- when /time/i then :time
613
- when /blob/i then :binary
614
- else super
615
- end
616
- end
617
-
618
599
  # @override {ActiveRecord::ConnectionAdapters::Column#extract_limit}
619
600
  def extract_limit(sql_type)
620
601
  return nil if sql_type =~ /^(real)\(\d+/i
@@ -646,28 +627,31 @@ module ActiveRecord::ConnectionAdapters
646
627
  class SQLite3Adapter < AbstractAdapter
647
628
  include ArJdbc::Abstract::Core
648
629
  include ArJdbc::SQLite3
630
+ include ArJdbc::Abstract::ConnectionManagement
649
631
  include ArJdbc::Abstract::DatabaseStatements
650
632
  include ArJdbc::Abstract::StatementCache
651
633
  include ArJdbc::Abstract::TransactionSupport
652
634
 
653
- # Note: This is part of original AR sqlite3_adapter.rb and not an override by us. This is to just
654
- # work around our copy of Sqlite3Adapter being a module above and not a class.
655
- ##
656
- # :singleton-method:
657
- # Indicates whether boolean values are stored in sqlite3 databases as 1
658
- # and 0 or 't' and 'f'. Leaving <tt>ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer</tt>
659
- # set to false is deprecated. SQLite databases have used 't' and 'f' to
660
- # serialize boolean values and must have old data converted to 1 and 0
661
- # (its native boolean serialization) before setting this flag to true.
662
- # Conversion can be accomplished by setting up a rake task which runs
663
- #
664
- # ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
665
- # ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
666
- # for all models and all boolean columns, after which the flag must be set
667
- # to true by adding the following to your <tt>application.rb</tt> file:
668
- #
669
- # Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
670
- class_attribute :represent_boolean_as_integer, default: false
635
+ def self.represent_boolean_as_integer=(value) # :nodoc:
636
+ if value == false
637
+ raise "`.represent_boolean_as_integer=` is now always true, so make sure your application can work with it and remove this settings."
638
+ end
639
+
640
+ ActiveSupport::Deprecation.warn(
641
+ "`.represent_boolean_as_integer=` is now always true, so setting this is deprecated and will be removed in Rails 6.1."
642
+ )
643
+ end
644
+
645
+ def self.database_exists?(config)
646
+ config = config.symbolize_keys
647
+ if config[:database] == ":memory:"
648
+ return true
649
+ else
650
+ database_file = defined?(Rails.root) ? File.expand_path(config[:database], Rails.root) : config[:database]
651
+ File.exist?(database_file)
652
+ end
653
+ end
654
+
671
655
 
672
656
  def supports_transaction_isolation?
673
657
  false
@@ -676,7 +660,7 @@ module ActiveRecord::ConnectionAdapters
676
660
  def begin_isolated_db_transaction(isolation)
677
661
  raise ActiveRecord::TransactionIsolationError, 'adapter does not support setting transaction isolation'
678
662
  end
679
-
663
+
680
664
  # SQLite driver doesn't support all types of insert statements with executeUpdate so
681
665
  # make it act like a regular query and the ids will be returned from #last_inserted_id
682
666
  # example: INSERT INTO "aircraft" DEFAULT VALUES
@@ -699,5 +683,16 @@ module ActiveRecord::ConnectionAdapters
699
683
 
700
684
  # Note: This is not an override of ours but a moved line from AR Sqlite3Adapter to register ours vs our copied module (which would be their class).
701
685
  # ActiveSupport.run_load_hooks(:active_record_sqlite3adapter, SQLite3Adapter)
686
+
687
+ private
688
+
689
+ # because the JDBC driver doesn't like multiple SQL statements in one JDBC statement
690
+ def combine_multi_statements(total_sql)
691
+ if total_sql.length == 1
692
+ total_sql.first
693
+ else
694
+ total_sql
695
+ end
696
+ end
702
697
  end
703
698
  end