activerecord-jdbc-adapter 52.1-java → 52.2-java

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 (34) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +34 -15
  3. data/Gemfile +1 -2
  4. data/README.md +10 -3
  5. data/lib/arjdbc/abstract/core.rb +12 -2
  6. data/lib/arjdbc/abstract/database_statements.rb +1 -1
  7. data/lib/arjdbc/abstract/statement_cache.rb +4 -4
  8. data/lib/arjdbc/db2/adapter.rb +68 -60
  9. data/lib/arjdbc/db2/as400.rb +12 -0
  10. data/lib/arjdbc/db2/column.rb +3 -0
  11. data/lib/arjdbc/db2/connection_methods.rb +4 -0
  12. data/lib/arjdbc/jdbc.rb +3 -0
  13. data/lib/arjdbc/jdbc/adapter.rb +0 -6
  14. data/lib/arjdbc/jdbc/column.rb +4 -2
  15. data/lib/arjdbc/mysql/adapter.rb +8 -0
  16. data/lib/arjdbc/postgresql/adapter.rb +5 -72
  17. data/lib/arjdbc/postgresql/oid_types.rb +82 -14
  18. data/lib/arjdbc/version.rb +1 -1
  19. data/rakelib/rails.rake +4 -3
  20. data/src/java/arjdbc/ArJdbcModule.java +5 -15
  21. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +2 -2
  22. data/src/java/arjdbc/jdbc/ConnectionFactory.java +0 -87
  23. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +0 -1
  24. data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +61 -0
  25. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +46 -18
  26. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +2 -2
  27. data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +52 -0
  28. data/src/java/arjdbc/postgresql/PostgreSQLResult.java +90 -17
  29. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +68 -49
  30. data/src/java/arjdbc/util/DateTimeUtils.java +119 -0
  31. data/src/java/arjdbc/util/PG.java +8 -0
  32. data/src/java/arjdbc/util/QuotingUtils.java +6 -7
  33. metadata +6 -4
  34. data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ce3b01a3484aa192fc9a22b788e3117aa44adedd
4
- data.tar.gz: 48b8197f1de856fe9994bfdf798c078eb92b6e2d
2
+ SHA256:
3
+ metadata.gz: edf65c8d44c40981f576b4b4e771621266594633377cdb3e4372c3f6d0f21d95
4
+ data.tar.gz: 73cb6e5361a6f7bd99eb0dcb5fb0dbb1ab750e436a53143725354d34b178273f
5
5
  SHA512:
6
- metadata.gz: d1cc13e79b76c8cef827ce7af505720845f5ad7e66c8ffd4bd07dbf4da6563e3d5450c3351ba7dd95b37c096d10b417e28bc3487fba5319d70bbe9776407b0a9
7
- data.tar.gz: fab5dc5990fb886dda12232efebcdeed0701bddb4e7b605514a07a955149b34b41bde32f7b18b99aa9274e6ced874733ceddbd72c58302dad0781aeacf2f955f
6
+ metadata.gz: 856163f3d41918753ec4426904c20619fc46c12bbc1303e1332173c399566c17d8f1e652dd3d5cb3a1e97347e2b6158bab6f97a09a322ffc45483e0dd8b307a6
7
+ data.tar.gz: 443e9c168b7e9af22d5870ea63b5b084f1563ac58897d12a99893e9f8f855f4e51466376eb11ea74c920f46729c8ceb56dadfb2662aa9b7675c836a62df1cd41
@@ -1,9 +1,18 @@
1
1
  language: ruby
2
2
  sudo: false
3
+ branches:
4
+ only:
5
+ - master
6
+ - /.*-stable$/
7
+ - /^test-.*/
8
+ - /maintenance|support/
9
+ - /.*dev$/
3
10
  bundler_args: --without development
4
11
  script: bundle exec rake ${TEST_PREFIX}test_$DB
5
12
  before_install:
6
13
  - unset _JAVA_OPTIONS
14
+ - rvm @default,@global do gem uninstall bundler -a -x -I || true
15
+ - gem install bundler -v "~>1.17.3"
7
16
  before_script:
8
17
  - echo "JAVA_OPTS=$JAVA_OPTS"
9
18
  - export JRUBY_OPTS="-J-Xms64M -J-Xmx1024M"
@@ -45,19 +54,29 @@ env:
45
54
  - DB=postgresql PREPARED_STATEMENTS=true INSERT_RETURNING=true
46
55
  - DB=sqlite3 PREPARED_STATEMENTS=false
47
56
  - DB=sqlite3 PREPARED_STATEMENTS=true
48
- #- DB=jndi PREPARED_STATEMENTS=false
49
- #- DB=jndi PREPARED_STATEMENTS=true
50
- branches:
51
- only:
52
- - master
53
- - /.*-stable$/
54
- - /^test-.*/
55
- - /maintenance|support/
56
- - /.*dev$/
57
+ - DB=jndi PREPARED_STATEMENTS=false
58
+ - DB=jndi PREPARED_STATEMENTS=true
57
59
  matrix:
58
60
  allow_failures:
59
61
  - rvm: jruby-head
60
62
  include:
63
+ # jruby-9.2
64
+ - rvm: jruby-9.2.6.0
65
+ env: DB=mysql2
66
+ - rvm: jruby-9.2.6.0
67
+ env: DB=postgresql
68
+ - rvm: jruby-9.2.6.0
69
+ env: DB=sqlite3
70
+ # jruby-9.2 + Java 11
71
+ - rvm: jruby-9.2.6.0
72
+ env: DB=mysql2
73
+ jdk: openjdk11
74
+ - rvm: jruby-9.2.6.0
75
+ env: DB=postgresql
76
+ jdk: openjdk11
77
+ - rvm: jruby-9.2.6.0
78
+ env: DB=sqlite3
79
+ jdk: openjdk11
61
80
  # jruby-head
62
81
  - rvm: jruby-head
63
82
  env: DB=mysql2
@@ -73,9 +92,9 @@ matrix:
73
92
  mariadb: '10.1'
74
93
  env: DB=mariadb PREPARED_STATEMENTS=true
75
94
  # Rails test-suite :
76
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.2.0" # PS off by default
77
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.2.0" PREPARED_STATEMENTS=true
78
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.2.0" DRIVER=MariaDB
79
- - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.2.0" # PS on by default
80
- - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.2.0" PREPARED_STATEMENTS=false
81
- - env: DB=sqlite3 TEST_PREFIX="rails:" AR_VERSION="v5.2.0"
95
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.2.3" # PS off by default
96
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.2.3" PREPARED_STATEMENTS=true
97
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.2.3" DRIVER=MariaDB
98
+ - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.2.3" # PS on by default
99
+ - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.2.3" PREPARED_STATEMENTS=false
100
+ - env: DB=sqlite3 TEST_PREFIX="rails:" AR_VERSION="v5.2.3"
data/Gemfile CHANGED
@@ -52,8 +52,7 @@ end
52
52
 
53
53
  group :rails do
54
54
  group :test do
55
- # FIX: Our test suite isn't ready to run in random order yet.
56
- gem 'minitest', '< 5.3.4', require: nil
55
+ gem 'minitest', '~> 5.11.3', require: nil
57
56
  gem 'minitest-excludes', '~> 2.0.1', require: nil
58
57
  gem 'minitest-rg', require: nil
59
58
 
data/README.md CHANGED
@@ -15,9 +15,16 @@ we currently have.
15
15
  For Oracle database users you are encouraged to use
16
16
  https://github.com/rsim/oracle-enhanced.
17
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
18
+ Versions are targeted at certain versions of Rails and live on their own branches.
19
+
20
+ | Gem Version | Rails Version | Branch |
21
+ | ----------- | ------------- | ------ |
22
+ | 50.x | 5.0.x | 50-stable |
23
+ | 51.x | 5.1.x | 51-stable |
24
+ | 52.x | 5.2.x | 52-stable |
25
+ | future | latest | master |
26
+
27
+ The minimum version of JRuby for 50+ is JRuby **9.1.x** and
21
28
  JRuby 9.1+ requires Java 7 or newer (we recommend Java 8 at minimum).
22
29
 
23
30
  ## Using ActiveRecord JDBC
@@ -22,7 +22,7 @@ module ArJdbc
22
22
 
23
23
  connection.configure_connection # will call us (maybe)
24
24
  end
25
-
25
+
26
26
  # Retrieve the raw `java.sql.Connection` object.
27
27
  # The unwrap parameter is useful if an attempt to unwrap a pooled (JNDI)
28
28
  # connection should be made - to really return the 'native' JDBC object.
@@ -73,4 +73,14 @@ module ArJdbc
73
73
  end
74
74
  end
75
75
  end
76
- end
76
+
77
+ module LogSubscriber
78
+ JDBC_GEM_ROOT = File.expand_path("../../../..", __FILE__) + "/"
79
+
80
+ # Remove this gem from log trace so that query shows where it was called in application
81
+ def ignored_callstack(path)
82
+ super || path.start_with?(JDBC_GEM_ROOT)
83
+ end
84
+ end
85
+ ActiveRecord::LogSubscriber.prepend(ArJdbc::LogSubscriber)
86
+ end
@@ -26,7 +26,7 @@ module ArJdbc
26
26
  log(sql, name) { @connection.execute_query(sql) }
27
27
  else
28
28
  log(sql, name, binds) do
29
- # It seems that #supports_statement_cache? is defined but isn't checked before setting "prepare" (AR 5.0)
29
+ # this is different from normal AR that always caches
30
30
  cached_statement = fetch_cached_statement(sql) if prepare && @jdbc_statement_cache_enabled
31
31
  @connection.execute_prepared_query(sql, binds, cached_statement)
32
32
  end
@@ -23,7 +23,7 @@ module ArJdbc
23
23
  # Only say we support the statement cache if we are using prepared statements
24
24
  # and have a max number of statements defined
25
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)
26
+ @jdbc_statement_cache_enabled = prepared_statements && (statement_limit.nil? || statement_limit > 0)
27
27
 
28
28
  @statements = StatementPool.new(statement_limit) # AR (5.0) expects this to be stored as @statements
29
29
  end
@@ -34,11 +34,11 @@ module ArJdbc
34
34
  end
35
35
 
36
36
  def delete_cached_statement(sql)
37
- @statements.delete(cached_statement_key(sql))
37
+ @statements.delete(sql_key(sql))
38
38
  end
39
39
 
40
40
  def fetch_cached_statement(sql)
41
- @statements[cached_statement_key(sql)] ||= @connection.connection.prepare_statement(sql)
41
+ @statements[sql_key(sql)] ||= @connection.prepare_statement(sql)
42
42
  end
43
43
 
44
44
  def supports_statement_cache?
@@ -50,7 +50,7 @@ module ArJdbc
50
50
 
51
51
  # This should be overridden by the adapter if the sql itself
52
52
  # is not enough to make the key unique
53
- def cached_statement_key(sql)
53
+ def sql_key(sql)
54
54
  sql
55
55
  end
56
56
 
@@ -30,6 +30,65 @@ module ArJdbc
30
30
  # @note This adapter doesn't support explain `config.active_record.auto_explain_threshold_in_seconds` should be commented (Rails < 4.0)
31
31
  module DB2
32
32
 
33
+
34
+ module ActiveRecord::ConnectionAdapters
35
+
36
+ remove_const(:DB2Adapter) if const_defined?(:DB2Adapter)
37
+
38
+ class DB2Adapter < JdbcAdapter
39
+
40
+ include ArJdbc::DB2
41
+ include ArJdbc::DB2::Column
42
+
43
+ # AR 5.2 Fix
44
+ def initialize(connection, logger = nil, connection_parameters = nil, config = {})
45
+ super(connection, logger, config) # configure_connection happens in super
46
+ end
47
+
48
+ def jdbc_connection_class(spec)
49
+ ArJdbc::DB2.jdbc_connection_class
50
+ end
51
+
52
+ def data_source_sql(name = nil, type: nil)
53
+ scope = quoted_scope(name, type: type)
54
+
55
+ sql = if scope[:type] == "'T'"
56
+ "select table_name from sysibm.tables".dup
57
+ else
58
+ "select table_name from sysibm.views".dup
59
+ end
60
+
61
+ wheres = []
62
+
63
+ wheres << " table_type = #{scope[:type]}" if scope[:type]
64
+ wheres << " table_schema = #{scope[:schema]}" if scope[:schema]
65
+ wheres << " UPPER(table_name) = UPPER(#{scope[:name]})" if scope[:name]
66
+
67
+ if wheres.present?
68
+ sql << ' WHERE '
69
+ sql << wheres.join(' AND ')
70
+ end
71
+ sql
72
+ end
73
+
74
+ def quoted_scope(name = nil, type: nil)
75
+ type = \
76
+ case type
77
+ when "BASE TABLE"
78
+ "'T'"
79
+ when "VIEW"
80
+ "'V'"
81
+ end
82
+ scope = {}
83
+ scope[:name] = quote(name) if name
84
+ scope[:type] = type if type
85
+ scope[:schema] = quote(scope[:schema] || schema)
86
+ scope
87
+ end
88
+
89
+ end
90
+ end
91
+
33
92
  # @private
34
93
  def self.extended(adapter); initialize!; end
35
94
 
@@ -342,60 +401,10 @@ module ArJdbc
342
401
 
343
402
  # Properly quotes the various data types.
344
403
  # @param value contains the data
345
- # @param column (optional) contains info on the field
346
404
  # @override
347
- def quote(value, column = nil)
348
- return value.quoted_id if value.respond_to?(:quoted_id)
405
+ def quote(value)
349
406
  return value if sql_literal?(value)
350
-
351
- if column
352
- if column.respond_to?(:primary) && column.primary && column.klass != String
353
- return value.to_i.to_s
354
- end
355
- if value && (column.type.to_sym == :decimal || column.type.to_sym == :integer)
356
- return value.to_s
357
- end
358
- end
359
-
360
- column_type = column && column.type.to_sym
361
-
362
- case value
363
- when nil then 'NULL'
364
- when Numeric # IBM_DB doesn't accept quotes on numeric types
365
- # if the column type is text or string, return the quote value
366
- if column_type == :text || column_type == :string
367
- "'#{value}'"
368
- else
369
- value.to_s
370
- end
371
- when String, ActiveSupport::Multibyte::Chars
372
- if column_type == :binary && column.sql_type !~ /for bit data/i
373
- if update_lob_value?(value, column)
374
- value.nil? ? 'NULL' : BLOB_VALUE_MARKER # '@@@IBMBINARY@@@'"
375
- else
376
- "BLOB('#{quote_string(value)}')"
377
- end
378
- elsif column && column.sql_type =~ /clob/ # :text
379
- if update_lob_value?(value, column)
380
- value.nil? ? 'NULL' : CLOB_VALUE_MARKER # "'@@@IBMTEXT@@@'"
381
- else
382
- "'#{quote_string(value)}'"
383
- end
384
- elsif column_type == :xml
385
- value.nil? ? 'NULL' : "'#{quote_string(value)}'" # "'<ibm>@@@IBMXML@@@</ibm>'"
386
- else
387
- "'#{quote_string(value)}'"
388
- end
389
- when Symbol then "'#{quote_string(value.to_s)}'"
390
- when Time
391
- # AS400 doesn't support date in time column
392
- if column_type == :time
393
- quote_time(value)
394
- else
395
- super
396
- end
397
- else super
398
- end
407
+ super
399
408
  end
400
409
 
401
410
  # @override
@@ -428,9 +437,9 @@ module ArJdbc
428
437
  types
429
438
  end
430
439
 
431
- def type_to_sql(type, limit = nil, precision = nil, scale = nil)
440
+ def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
432
441
  limit = nil if type.to_sym == :integer
433
- super(type, limit, precision, scale)
442
+ super
434
443
  end
435
444
 
436
445
  # @private
@@ -443,7 +452,7 @@ module ArJdbc
443
452
 
444
453
  def add_column(table_name, column_name, type, options = {})
445
454
  # The keyword COLUMN allows to use reserved names for columns (ex: date)
446
- add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
455
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options)}"
447
456
  add_column_options!(add_column_sql, options)
448
457
  execute(add_column_sql)
449
458
  end
@@ -586,7 +595,7 @@ module ArJdbc
586
595
  end
587
596
 
588
597
  def change_column(table_name, column_name, type, options = {})
589
- data_type = type_to_sql(type, options[:limit], options[:precision], options[:scale])
598
+ data_type = type_to_sql(type, options)
590
599
  sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DATA TYPE #{data_type}"
591
600
  execute_table_change(sql, table_name, 'Change Column')
592
601
 
@@ -694,11 +703,10 @@ module ArJdbc
694
703
 
695
704
  # alias_method :execute_and_auto_confirm, :execute
696
705
 
697
- # Returns the value of an identity column of the last *INSERT* statement
698
- # made over this connection.
706
+ # Returns the value of an identity column of the last *INSERT* statement made over this connection.
699
707
  # @note Check the *IDENTITY_VAL_LOCAL* function for documentation.
700
- # @return [Fixnum]
701
- def last_insert_id
708
+ # @return [Integer, NilClass]
709
+ def last_inserted_id(result)
702
710
  @connection.identity_val_local
703
711
  end
704
712
 
@@ -4,6 +4,18 @@ module ArJdbc
4
4
  module AS400
5
5
  include DB2
6
6
 
7
+ module ActiveRecord::ConnectionAdapters
8
+ remove_const(:AS400Adapter) if const_defined?(:AS400Adapter)
9
+ class AS400Adapter < DB2Adapter
10
+
11
+ include ::ArJdbc::AS400
12
+
13
+ def jdbc_connection_class(spec)
14
+ ArJdbc::AS400.jdbc_connection_class
15
+ end
16
+ end
17
+ end
18
+
7
19
  # @private
8
20
  def self.extended(adapter); DB2.extended(adapter); end
9
21
 
@@ -47,6 +47,9 @@ module ArJdbc
47
47
 
48
48
  # @override
49
49
  def type_cast(value)
50
+ # AR5.2
51
+ return super unless respond_to?(:type)
52
+
50
53
  return nil if value.nil? || value == 'NULL' || value =~ /^\s*NULL\s*$/i
51
54
  case type
52
55
  when :string then value
@@ -15,6 +15,8 @@ ArJdbc::ConnectionMethods.module_eval do
15
15
  end
16
16
  config[:driver] ||= ::ArJdbc::DB2::DRIVER_NAME
17
17
  config[:connection_alive_sql] ||= 'SELECT 1 FROM syscat.tables FETCH FIRST 1 ROWS ONLY'
18
+ config[:adapter_class] = ActiveRecord::ConnectionAdapters::DB2Adapter unless config.key?(:adapter_class)
19
+
18
20
  jdbc_connection(config)
19
21
  end
20
22
  alias_method :jdbcdb2_connection, :db2_connection
@@ -38,6 +40,8 @@ ArJdbc::ConnectionMethods.module_eval do
38
40
  require 'arjdbc/db2/as400'
39
41
  config[:driver] ||= ::ArJdbc::AS400::DRIVER_NAME
40
42
  config[:connection_alive_sql] ||= 'SELECT 1 FROM sysibm.tables FETCH FIRST 1 ROWS ONLY'
43
+ config[:adapter_class] = ActiveRecord::ConnectionAdapters::AS400Adapter unless config.key?(:adapter_class)
44
+
41
45
  jdbc_connection(config)
42
46
  end
43
47
  alias_method :jdbcas400_connection, :as400_connection
@@ -9,6 +9,9 @@ module ArJdbc
9
9
  # @private
10
10
  AR50 = ::ActiveRecord::VERSION::MAJOR > 4
11
11
 
12
+ # @private
13
+ AR52 = ::ActiveRecord::VERSION::STRING >= '5.2'
14
+
12
15
  class << self
13
16
 
14
17
  # @private Internal API
@@ -250,12 +250,6 @@ module ActiveRecord
250
250
  end
251
251
  end
252
252
 
253
- # @private
254
- # @override
255
- def select_rows(sql, name = nil, binds = [])
256
- exec_query_raw(sql, name, binds).map!(&:values)
257
- end
258
-
259
253
  # Executes the SQL statement in the context of this connection.
260
254
  # The return value from this method depends on the SQL type (whether
261
255
  # it's a SELECT, INSERT etc.). For INSERTs a generated id might get
@@ -26,7 +26,9 @@ module ActiveRecord
26
26
  end
27
27
  end
28
28
 
29
- if ArJdbc::AR50
29
+ if ArJdbc::AR52
30
+ # undefined method `cast' for #<ActiveRecord::ConnectionAdapters::SqlTypeMetadata> on AR52
31
+ elsif ArJdbc::AR50
30
32
  default = args[0].cast(default)
31
33
 
32
34
  sql_type = args.delete_at(1)
@@ -42,7 +44,7 @@ module ActiveRecord
42
44
  # super <= 4.1: (name, default, sql_type = nil, null = true)
43
45
  # super >= 4.2: (name, default, cast_type, sql_type = nil, null = true)
44
46
  # super >= 5.0: (name, default, sql_type_metadata = nil, null = true)
45
-
47
+
46
48
  super(name, default, *args)
47
49
  init_column(name, default, *args)
48
50
  end