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
@@ -1,16 +1,25 @@
1
1
  ArJdbc.load_java_part :SQLite3
2
2
 
3
- require "arjdbc/common_jdbc_methods"
3
+ require "arjdbc/abstract/core"
4
+ require "arjdbc/abstract/database_statements"
5
+ require 'arjdbc/abstract/statement_cache'
6
+ require "arjdbc/abstract/transaction_support"
7
+ require "active_record/connection_adapters/abstract_adapter"
4
8
  require "active_record/connection_adapters/statement_pool"
5
- require "active_record/connection_adapters/abstract/database_statements"
6
9
  require "active_record/connection_adapters/sqlite3/explain_pretty_printer"
7
10
  require "active_record/connection_adapters/sqlite3/quoting"
8
11
  require "active_record/connection_adapters/sqlite3/schema_creation"
12
+ require "active_record/connection_adapters/sqlite3/schema_definitions"
13
+ require "active_record/connection_adapters/sqlite3/schema_dumper"
14
+ require "active_record/connection_adapters/sqlite3/schema_statements"
9
15
 
10
16
  module ArJdbc
11
17
  # All the code in this module is a copy of ConnectionAdapters::SQLite3Adapter from active_record 5.
12
18
  # The constants at the front of this file are to allow the rest of the file to remain with no modifications
13
- # from its original source.
19
+ # from its original source. If you hack on this file try not to modify this module and instead try and
20
+ # put those overrides in SQL3Adapter below. We try and keep a copy of the Rails this adapter supports
21
+ # with the current goal of being able to diff changes easily over time and to also eventually remove
22
+ # this module from ARJDBC altogether.
14
23
  module SQLite3
15
24
  # DIFFERENCE: Some common constant names to reduce differences in rest of this module from AR5 version
16
25
  ConnectionAdapters = ::ActiveRecord::ConnectionAdapters
@@ -22,7 +31,10 @@ module ArJdbc
22
31
 
23
32
  ADAPTER_NAME = 'SQLite'.freeze
24
33
 
25
- include Quoting
34
+ # DIFFERENCE: FQN
35
+ include ::ActiveRecord::ConnectionAdapters::SQLite3::Quoting
36
+ include ::ActiveRecord::ConnectionAdapters::SQLite3::ColumnDumper
37
+ include ::ActiveRecord::ConnectionAdapters::SQLite3::SchemaStatements
26
38
 
27
39
  NATIVE_DATABASE_TYPES = {
28
40
  primary_key: "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL",
@@ -46,15 +58,22 @@ module ArJdbc
46
58
  end
47
59
  end
48
60
 
61
+ def update_table_definition(table_name, base) # :nodoc:
62
+ # DIFFERENCE: FQN
63
+ ::ActiveRecord::ConnectionAdapters::SQLite3::Table.new(table_name, base)
64
+ end
65
+
49
66
  def schema_creation # :nodoc:
50
- SQLite3::SchemaCreation.new self
67
+ # DIFFERENCE: FQN
68
+ ::ActiveRecord::ConnectionAdapters::SQLite3::SchemaCreation.new self
51
69
  end
52
70
 
53
71
  def arel_visitor # :nodoc:
54
72
  Arel::Visitors::SQLite.new(self)
55
73
  end
56
74
 
57
- def initialize(connection, logger, connection_options, config)
75
+ # Difference we remove connection_options because we are not using it.
76
+ def initialize(connection, logger, config)
58
77
  super(connection, logger, config)
59
78
 
60
79
  @active = nil
@@ -79,17 +98,12 @@ module ArJdbc
79
98
  true
80
99
  end
81
100
 
82
- # Returns true, since this connection adapter supports migrations.
83
- def supports_migrations? #:nodoc:
84
- true
85
- end
86
-
87
- def supports_primary_key? #:nodoc:
101
+ def requires_reloading?
88
102
  true
89
103
  end
90
104
 
91
- def requires_reloading?
92
- true
105
+ def supports_foreign_keys_in_create?
106
+ sqlite_version >= "3.6.19"
93
107
  end
94
108
 
95
109
  def supports_views?
@@ -125,10 +139,6 @@ module ArJdbc
125
139
  true
126
140
  end
127
141
 
128
- def valid_type?(type)
129
- true
130
- end
131
-
132
142
  # Returns 62. SQLite supports index names up to 64
133
143
  # characters. The rest is used by Rails internally to perform
134
144
  # temporary rename operations
@@ -149,45 +159,61 @@ module ArJdbc
149
159
  true
150
160
  end
151
161
 
162
+ # REFERENTIAL INTEGRITY ====================================
163
+
164
+ def disable_referential_integrity # :nodoc:
165
+ old = query_value("PRAGMA foreign_keys")
166
+
167
+ begin
168
+ execute("PRAGMA foreign_keys = OFF")
169
+ yield
170
+ ensure
171
+ execute("PRAGMA foreign_keys = #{old}")
172
+ end
173
+ end
174
+
152
175
  #--
153
176
  # DATABASE STATEMENTS ======================================
154
177
  #++
155
178
 
156
179
  def explain(arel, binds = [])
157
180
  sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
181
+ # DIFFERENCE: FQN
158
182
  ::ActiveRecord::ConnectionAdapters::SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
159
183
  end
160
184
 
161
185
  def exec_query(sql, name = nil, binds = [], prepare: false)
162
- type_casted_binds = binds.map { |attr| type_cast(attr.value_for_database) }
163
-
164
- log(sql, name, binds) do
165
- # Don't cache statements if they are not prepared
166
- unless prepare
167
- stmt = @connection.prepare(sql)
168
- begin
169
- cols = stmt.columns
170
- unless without_prepared_statement?(binds)
171
- stmt.bind_params(type_casted_binds)
186
+ type_casted_binds = type_casted_binds(binds)
187
+
188
+ log(sql, name, binds, type_casted_binds) do
189
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
190
+ # Don't cache statements if they are not prepared
191
+ unless prepare
192
+ stmt = @connection.prepare(sql)
193
+ begin
194
+ cols = stmt.columns
195
+ unless without_prepared_statement?(binds)
196
+ stmt.bind_params(type_casted_binds)
197
+ end
198
+ records = stmt.to_a
199
+ ensure
200
+ stmt.close
172
201
  end
202
+ else
203
+ cache = @statements[sql] ||= {
204
+ stmt: @connection.prepare(sql)
205
+ }
206
+ stmt = cache[:stmt]
207
+ cols = cache[:cols] ||= stmt.columns
208
+ stmt.reset!
209
+ stmt.bind_params(type_casted_binds)
173
210
  records = stmt.to_a
174
- ensure
175
- stmt.close
176
211
  end
177
- stmt = records
178
- else
179
- cache = @statements[sql] ||= {
180
- :stmt => @connection.prepare(sql)
181
- }
182
- stmt = cache[:stmt]
183
- cols = cache[:cols] ||= stmt.columns
184
- stmt.reset!
185
- stmt.bind_params(type_casted_binds)
186
- end
187
212
 
188
- ActiveRecord::Result.new(cols, stmt.to_a)
213
+ ActiveRecord::Result.new(cols, records)
214
+ end
189
215
  end
190
- end
216
+ end
191
217
 
192
218
  def exec_delete(sql, name = 'SQL', binds = [])
193
219
  exec_query(sql, name, binds)
@@ -200,7 +226,11 @@ module ArJdbc
200
226
  end
201
227
 
202
228
  def execute(sql, name = nil) #:nodoc:
203
- log(sql, name) { @connection.execute(sql) }
229
+ log(sql, name) do
230
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
231
+ @connection.execute(sql)
232
+ end
233
+ end
204
234
  end
205
235
 
206
236
  def begin_db_transaction #:nodoc:
@@ -217,80 +247,30 @@ module ArJdbc
217
247
 
218
248
  # SCHEMA STATEMENTS ========================================
219
249
 
220
- def tables(name = nil) # :nodoc:
221
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
222
- #tables currently returns both tables and views.
223
- This behavior is deprecated and will be changed with Rails 5.1 to only return tables.
224
- Use #data_sources instead.
225
- MSG
226
-
227
- if name
228
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
229
- Passing arguments to #tables is deprecated without replacement.
230
- MSG
250
+ def new_column_from_field(table_name, field) # :nondoc:
251
+ case field["dflt_value"]
252
+ when /^null$/i
253
+ field["dflt_value"] = nil
254
+ when /^'(.*)'$/m
255
+ field["dflt_value"] = $1.gsub("''", "'")
256
+ when /^"(.*)"$/m
257
+ field["dflt_value"] = $1.gsub('""', '"')
231
258
  end
232
259
 
233
- data_sources
234
- end
235
-
236
- def data_sources
237
- select_values("SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence'", "SCHEMA")
238
- end
239
-
240
- def table_exists?(table_name)
241
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
242
- #table_exists? currently checks both tables and views.
243
- This behavior is deprecated and will be changed with Rails 5.1 to only check tables.
244
- Use #data_source_exists? instead.
245
- MSG
246
-
247
- data_source_exists?(table_name)
248
- end
249
-
250
- def data_source_exists?(table_name)
251
- return false unless table_name.present?
252
-
253
- sql = "SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence'"
254
- sql << " AND name = #{quote(table_name)}"
255
-
256
- select_values(sql, "SCHEMA").any?
257
- end
258
-
259
- def views # :nodoc:
260
- select_values("SELECT name FROM sqlite_master WHERE type = 'view' AND name <> 'sqlite_sequence'", "SCHEMA")
261
- end
262
-
263
- def view_exists?(view_name) # :nodoc:
264
- return false unless view_name.present?
265
-
266
- sql = "SELECT name FROM sqlite_master WHERE type = 'view' AND name <> 'sqlite_sequence'"
267
- sql << " AND name = #{quote(view_name)}"
268
-
269
- select_values(sql, "SCHEMA").any?
270
- end
271
-
272
- # Returns an array of +Column+ objects for the table specified by +table_name+.
273
- def columns(table_name) # :nodoc:
274
- table_name = table_name.to_s
275
- table_structure(table_name).map do |field|
276
- case field["dflt_value"]
277
- when /^null$/i
278
- field["dflt_value"] = nil
279
- when /^'(.*)'$/m
280
- field["dflt_value"] = $1.gsub("''", "'")
281
- when /^"(.*)"$/m
282
- field["dflt_value"] = $1.gsub('""', '"')
283
- end
284
-
285
- collation = field["collation"]
286
- sql_type = field["type"]
287
- type_metadata = fetch_type_metadata(sql_type)
288
- new_column(field["name"], field["dflt_value"], type_metadata, field["notnull"].to_i == 0, table_name, nil, collation)
289
- end
260
+ collation = field["collation"]
261
+ sql_type = field["type"]
262
+ type_metadata = fetch_type_metadata(sql_type)
263
+ new_column(field["name"], field["dflt_value"], type_metadata, field["notnull"].to_i == 0, table_name, nil, collation)
290
264
  end
291
265
 
292
266
  # Returns an array of indexes for the given table.
293
267
  def indexes(table_name, name = nil) #:nodoc:
268
+ if name
269
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
270
+ Passing name to #indexes is deprecated without replacement.
271
+ MSG
272
+ end
273
+
294
274
  exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
295
275
  sql = <<-SQL
296
276
  SELECT sql
@@ -300,17 +280,17 @@ module ArJdbc
300
280
  SELECT sql
301
281
  FROM sqlite_temp_master
302
282
  WHERE name=#{quote(row['name'])} AND type='index'
303
- SQL
283
+ SQL
304
284
  index_sql = exec_query(sql).first["sql"]
305
285
  match = /\sWHERE\s+(.+)$/i.match(index_sql)
306
286
  where = match[1] if match
307
287
  IndexDefinition.new(
308
- table_name,
309
- row["name"],
310
- row["unique"] != 0,
311
- exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col|
312
- col["name"]
313
- }, nil, nil, where)
288
+ table_name,
289
+ row["name"],
290
+ row["unique"] != 0,
291
+ exec_query("PRAGMA index_info('#{row['name']}')", "SCHEMA").map { |col|
292
+ col["name"]
293
+ }, nil, nil, where)
314
294
  end
315
295
  end
316
296
 
@@ -393,14 +373,34 @@ module ArJdbc
393
373
  rename_column_indexes(table_name, column.name, new_column_name)
394
374
  end
395
375
 
396
- protected
376
+ def add_reference(table_name, ref_name, **options) # :nodoc:
377
+ super(table_name, ref_name, type: :integer, **options)
378
+ end
379
+ alias :add_belongs_to :add_reference
380
+
381
+ def foreign_keys(table_name)
382
+ fk_info = exec_query("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA")
383
+ fk_info.map do |row|
384
+ options = {
385
+ column: row["from"],
386
+ primary_key: row["to"],
387
+ on_delete: extract_foreign_key_action(row["on_delete"]),
388
+ on_update: extract_foreign_key_action(row["on_update"])
389
+ }
390
+ # DIFFERENCE: FQN
391
+ ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, row["table"], options)
392
+ end
393
+ end
394
+
395
+ private
397
396
 
398
397
  def table_structure(table_name)
399
398
  structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA")
400
399
  raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
401
400
  table_structure_with_collation(table_name, structure)
402
401
  end
403
-
402
+ alias column_definitions table_structure
403
+
404
404
  def alter_table(table_name, options = {}) #:nodoc:
405
405
  altered_table_name = "a#{table_name}"
406
406
  caller = lambda { |definition| yield definition if block_given? }
@@ -490,43 +490,51 @@ module ArJdbc
490
490
  # Older versions of SQLite return:
491
491
  # column *column_name* is not unique
492
492
  when /column(s)? .* (is|are) not unique/, /UNIQUE constraint failed: .*/
493
- RecordNotUnique.new(message)
493
+ # DIFFERENCE: FQN
494
+ ::ActiveRecord::RecordNotUnique.new(message)
495
+ when /.* may not be NULL/, /NOT NULL constraint failed: .*/
496
+ # DIFFERENCE: FQN
497
+ ::ActiveRecord::NotNullViolation.new(message)
498
+ when /FOREIGN KEY constraint failed/i
499
+ # DIFFERENCE: FQN
500
+ ::ActiveRecord::InvalidForeignKey.new(message)
494
501
  else
495
502
  super
496
503
  end
497
504
  end
498
505
 
499
- private
500
506
  COLLATE_REGEX = /.*\"(\w+)\".*collate\s+\"(\w+)\".*/i.freeze
501
507
 
502
508
  def table_structure_with_collation(table_name, basic_structure)
503
509
  collation_hash = {}
504
- sql = "SELECT sql FROM
505
- (SELECT * FROM sqlite_master UNION ALL
506
- SELECT * FROM sqlite_temp_master)
507
- WHERE type='table' and name='#{ table_name }' \;"
510
+ sql = <<-SQL
511
+ SELECT sql FROM
512
+ (SELECT * FROM sqlite_master UNION ALL
513
+ SELECT * FROM sqlite_temp_master)
514
+ WHERE type = 'table' AND name = #{quote(table_name)}
515
+ SQL
508
516
 
509
517
  # Result will have following sample string
510
518
  # CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
511
519
  # "password_digest" varchar COLLATE "NOCASE");
512
- result = exec_query(sql, 'SCHEMA').first
520
+ result = exec_query(sql, "SCHEMA").first
513
521
 
514
522
  if result
515
523
  # Splitting with left parentheses and picking up last will return all
516
524
  # columns separated with comma(,).
517
- columns_string = result["sql"].split('(').last
525
+ columns_string = result["sql"].split("(").last
518
526
 
519
- columns_string.split(',').each do |column_string|
527
+ columns_string.split(",").each do |column_string|
520
528
  # This regex will match the column name and collation type and will save
521
529
  # the value in $1 and $2 respectively.
522
- collation_hash[$1] = $2 if (COLLATE_REGEX =~ column_string)
530
+ collation_hash[$1] = $2 if COLLATE_REGEX =~ column_string
523
531
  end
524
532
 
525
533
  basic_structure.map! do |column|
526
- column_name = column['name']
534
+ column_name = column["name"]
527
535
 
528
536
  if collation_hash.has_key? column_name
529
- column['collation'] = collation_hash[column_name]
537
+ column["collation"] = collation_hash[column_name]
530
538
  end
531
539
 
532
540
  column
@@ -535,6 +543,23 @@ module ArJdbc
535
543
  basic_structure.to_hash
536
544
  end
537
545
  end
546
+
547
+ def create_table_definition(*args)
548
+ # DIFFERENCE: FQN
549
+ ::ActiveRecord::ConnectionAdapters::SQLite3::TableDefinition.new(*args)
550
+ end
551
+
552
+ def extract_foreign_key_action(specifier)
553
+ case specifier
554
+ when "CASCADE"; :cascade
555
+ when "SET NULL"; :nullify
556
+ when "RESTRICT"; :restrict
557
+ end
558
+ end
559
+
560
+ def configure_connection
561
+ execute("PRAGMA foreign_keys = ON", "SCHEMA")
562
+ end
538
563
  end
539
564
  end
540
565
 
@@ -639,50 +664,26 @@ module ActiveRecord::ConnectionAdapters
639
664
  # ActiveRecord::ConnectionAdapters::SQLite3Adapter. Once we can do that we can remove the
640
665
  # module SQLite3 above and remove a majority of this file.
641
666
  class SQLite3Adapter < AbstractAdapter
642
- include ArJdbc::CommonJdbcMethods
667
+ include ArJdbc::Abstract::Core
643
668
  include ArJdbc::SQLite3
669
+ include ArJdbc::Abstract::DatabaseStatements
670
+ include ArJdbc::Abstract::StatementCache
671
+ include ArJdbc::Abstract::TransactionSupport
644
672
 
645
- # FIXME: Add @connection.encoding then remove this method
646
- def encoding
647
- select_value 'PRAGMA encoding'
648
- end
649
-
650
- def exec_query(sql, name = nil, binds = [], prepare: false)
651
- use_prepared = prepare || !without_prepared_statement?(binds)
652
-
653
- if use_prepared
654
- type_casted_binds = prepare_binds_for_jdbc(binds)
655
- log(sql, name, binds) { @connection.execute_prepared(sql, type_casted_binds) }
656
- else
657
- log(sql, name) { @connection.execute(sql) }
658
- end
659
- end
660
-
661
- def exec_update(sql, name = nil, binds = [])
662
- use_prepared = !without_prepared_statement?(binds)
663
-
664
- if use_prepared
665
- type_casted_binds = prepare_binds_for_jdbc(binds)
666
- log(sql, name, binds) { @connection.execute_prepared_update(sql, type_casted_binds) }
667
- else
668
- log(sql, name) { @connection.execute_update(sql, nil) }
669
- end
673
+ def begin_isolated_db_transaction(isolation)
674
+ raise ActiveRecord::TransactionIsolationError, 'adapter does not support setting transaction isolation'
670
675
  end
671
- alias :exec_delete :exec_update
672
676
 
673
- # Sqlite3 JDBC types in prepared statements seem to report blob as varchar (12).
674
- # So to work around this we will pass attribute type in with the value so we can
675
- # then remap to appropriate type in JDBC without needing to ask JDBC what type
676
- # it should be using. No one likes a stinking liar...
677
- def prepare_binds_for_jdbc(binds)
678
- binds.map do |attribute|
679
- [attribute.type.type, type_cast(attribute.value_for_database)]
680
- end
677
+ # FIXME: 5.1 crashes without this. I think this is Arel hitting a fallback path in to_sql.rb.
678
+ # So maybe an untested code path in their source. Still means we are doing something wrong to
679
+ # even hit it.
680
+ def quote(value, comment=nil)
681
+ super(value)
681
682
  end
682
683
 
683
- # last two values passed but not used so I cannot alias to exec_query
684
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
685
- exec_update(sql, name, binds)
684
+ # FIXME: Add @connection.encoding then remove this method
685
+ def encoding
686
+ select_value 'PRAGMA encoding'
686
687
  end
687
688
 
688
689
  def indexes(table_name, name = nil) #:nodoc:
@@ -32,11 +32,9 @@ module ArJdbc
32
32
  require 'arjdbc/tasks/h2_database_tasks'
33
33
  require 'arjdbc/tasks/hsqldb_database_tasks'
34
34
  require 'arjdbc/tasks/mssql_database_tasks'
35
- require 'arjdbc/tasks/oracle_database_tasks'
36
35
 
37
36
  # re-invent built-in (but deprecated on 4.0) tasks :
38
37
  register_tasks(/sqlserver/, MSSQLDatabaseTasks)
39
- register_tasks(/(oci|oracle)/, OracleDatabaseTasks)
40
38
  register_tasks(/mssql/, MSSQLDatabaseTasks) # (built-in) alias
41
39
  # tasks for custom (JDBC) adapters :
42
40
  register_tasks(/db2/, DB2DatabaseTasks)
@@ -51,4 +49,4 @@ module ArJdbc
51
49
  # - while on 2.3/3.x we keep the AR built-in task behavior
52
50
 
53
51
  end
54
- end
52
+ end
@@ -82,9 +82,9 @@ module ArJdbc
82
82
  ensure
83
83
  pk_rs.close
84
84
  end
85
- primary_keys.each do |name, cols|
85
+ primary_keys.each do |constraint_name, cols|
86
86
  dump << "ALTER TABLE #{connection.quote_table_name(table_name)}\n"
87
- dump << " ADD CONSTRAINT #{name}\n"
87
+ dump << " ADD CONSTRAINT #{constraint_name}\n"
88
88
  dump << " PRIMARY KEY (#{cols.join(', ')});\n\n"
89
89
  end
90
90
  end
@@ -1,5 +1,5 @@
1
1
  module ArJdbc
2
- VERSION = "5.0.pre1"
2
+ VERSION = "51.0"
3
3
  # @deprecated
4
4
  module Version
5
5
  # @private 1.2.x compatibility
data/pom.xml CHANGED
@@ -12,7 +12,7 @@
12
12
  <url>http://github.com/jruby/activerecord-jdbc-adapter/wiki</url>
13
13
 
14
14
  <properties>
15
- <jruby.version>1.6.8</jruby.version>
15
+ <jruby.version>9.1.6.0</jruby.version>
16
16
  </properties>
17
17
 
18
18
  <issueManagement>
@@ -103,8 +103,8 @@
103
103
  <artifactId>maven-compiler-plugin</artifactId>
104
104
  <version>2.5.1</version>
105
105
  <configuration>
106
- <source>1.6</source>
107
- <target>1.6</target>
106
+ <source>1.7</source>
107
+ <target>1.7</target>
108
108
  </configuration>
109
109
  </plugin>
110
110
  </plugins>
data/rakelib/02-test.rake CHANGED
@@ -17,15 +17,6 @@ task 'test_postgresql_with_hint' do
17
17
  end
18
18
  end
19
19
 
20
- task 'test_appraisal_hint' do
21
- next if File.exists?('.disable-appraisal-hint')
22
- unless (ENV['BUNDLE_GEMFILE'] || '') =~ /gemfiles\/.*?\.gemfile/
23
- appraisals = []; Appraisal::File.each { |file| appraisals << file.name }
24
- puts "HINT: specify AR version with `rake appraisal:{version} test_{adapter}'" +
25
- " where version=(#{appraisals.join('|')}) (`touch .disable-appraisal-hint' to disable)"
26
- end
27
- end
28
-
29
20
  Rake::TestTask.class_eval { attr_reader :test_files }
30
21
 
31
22
  def test_task_for(adapter, options = {})
@@ -34,9 +25,6 @@ def test_task_for(adapter, options = {})
34
25
  adapter = adapter.to_s.downcase
35
26
  driver = adapter if ( driver = options[:driver] ).nil?
36
27
  prereqs = options[:prereqs] || []
37
- unless prereqs.frozen?
38
- prereqs = [ prereqs ].flatten; prereqs << 'test_appraisal_hint'
39
- end
40
28
  name = options[:name] || "test_#{adapter}"
41
29
  test_task = Rake::TestTask.new(name => prereqs) do |test_task|
42
30
  files = options[:files] || begin
data/rakelib/compile.rake CHANGED
@@ -11,7 +11,7 @@ begin
11
11
  file jar_file => FileList['src/java/**/*.java', 'pkg/classes'] do
12
12
  rm_rf FileList["#{classes}/**/*"]
13
13
  ant.javac :srcdir => "src/java", :destdir => "pkg/classes",
14
- :source => "1.6", :target => "1.6", :debug => true, :deprecation => true,
14
+ :source => "7", :target => "7", :debug => true, :deprecation => true,
15
15
  :classpath => "${java.class.path}:${sun.boot.class.path}:#{driver_jars.join(':')}",
16
16
  :includeantRuntime => false
17
17
 
data/rakelib/db.rake CHANGED
@@ -6,6 +6,7 @@ namespace :db do
6
6
  task :mysql do
7
7
  fail "could not create test database: mysql executable not found" unless mysql = which('mysql')
8
8
  load 'test/db/mysql_config.rb' # rescue nil
9
+ puts MYSQL_CONFIG.inspect if $VERBOSE
9
10
  script = sql_script <<-SQL, 'mysql'
10
11
  DROP DATABASE IF EXISTS `#{MYSQL_CONFIG[:database]}`;
11
12
  CREATE USER #{MYSQL_CONFIG[:username]}@localhost;
@@ -15,13 +16,13 @@ GRANT ALL PRIVILEGES ON `test\_%`.* TO #{MYSQL_CONFIG[:username]}@localhost;
15
16
  SET PASSWORD FOR #{MYSQL_CONFIG[:username]}@localhost = PASSWORD('#{MYSQL_CONFIG[:password]}');
16
17
  SQL
17
18
  params = { '-u' => 'root' }
18
- if ENV['DATABASE_YML']
19
- require 'yaml'
20
- password = YAML.load(File.new(ENV['DATABASE_YML']))["production"]["password"]
21
- params['--password'] = password
19
+ if ENV['DATABASE_YML']; require 'yaml'
20
+ params['-p'] = YAML.load(File.new(ENV['DATABASE_YML']))["production"]["password"]
22
21
  end
22
+ params['-u'] = ENV['MY_USER'] if ENV['MY_USER']
23
+ params['-p'] = ENV['MY_PASSWORD'] if ENV['MY_PASSWORD']
23
24
  puts "Creating MySQL (test) database: #{MYSQL_CONFIG[:database]}"
24
- sh "cat #{script.path} | #{mysql} -f #{params.to_a.join(' ')}", :verbose => $VERBOSE # so password is not echoed
25
+ sh "cat #{script.path} | #{mysql} -f #{params.map {|k, v| "#{k}#{v}"}.join(' ')}", :verbose => $VERBOSE # so password is not echoed
25
26
  end
26
27
 
27
28
  desc "Creates the test database for PostgreSQL"
@@ -29,6 +30,7 @@ SQL
29
30
  fail 'could not create test database: psql executable not found' unless psql = which('psql')
30
31
  fail 'could not create test database: missing "postgres" role' unless PostgresHelper.postgres_role?
31
32
  load 'test/db/postgres_config.rb' # rescue nil
33
+ puts POSTGRES_CONFIG.inspect if $VERBOSE
32
34
  script = sql_script <<-SQL, 'psql'
33
35
  DROP DATABASE IF EXISTS #{POSTGRES_CONFIG[:database]};
34
36
  DROP USER IF EXISTS #{POSTGRES_CONFIG[:username]};