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

Sign up to get free protection for your applications and to get access to all the features.
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