activerecord-jdbc-adapter 51.2-java → 51.3-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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b92cd70cfbcb8827986847b53e1d527f5fcee621
4
- data.tar.gz: 2480d4df7693895d1ca20ac406dadb26f7c432e4
2
+ SHA256:
3
+ metadata.gz: 7117b15f231051ebccb138e4f19e65780e179a751dc44fdb58dd54677af296b6
4
+ data.tar.gz: bad84fbfae38b6d2b30d6bbc09893001c0e2a60ab7137ace692462e257197807
5
5
  SHA512:
6
- metadata.gz: 42f15c16ca5d768f29993be86e43234b832be0fd580625a1d080f9827f405fe9b3a44752cf25970e11a00aeafd3e9d1b20ee715eac15404f042027e5cb8e5643
7
- data.tar.gz: ba4acdb1f07ab847ee0f560c8c9869f72456cfb812e69823b01ad4c0fb62126331401941a015ccd8058e40be7d395f14c418021a14f8f8d9d8eb42befb7ae16f
6
+ metadata.gz: 22e383cc2c136411ce1b70fcb28bb17f83aee13ecffa69bdc5768c53787fc1eb9f8ba566dcc31433a5bfca46788d905222cc4f721c0dc1b83af1fe721a494c91
7
+ data.tar.gz: '084f6078c6887cf33d8c99f9ecf1b2fb907d3e5a1c27ea04058c30773970a295701846d6869e672aff9e8e7141ce29883be763f8b829dbefb36e8ddb562cbd01'
data/.travis.yml CHANGED
@@ -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"
@@ -33,6 +42,8 @@ rvm:
33
42
  - jruby-9.1.16.0
34
43
  jdk:
35
44
  - openjdk8
45
+ addons:
46
+ postgresql: "9.4"
36
47
  env:
37
48
  - DB=mysql2 PREPARED_STATEMENTS=false
38
49
  - DB=mysql2 PREPARED_STATEMENTS=true
@@ -43,19 +54,29 @@ env:
43
54
  - DB=postgresql PREPARED_STATEMENTS=true INSERT_RETURNING=true
44
55
  - DB=sqlite3 PREPARED_STATEMENTS=false
45
56
  - DB=sqlite3 PREPARED_STATEMENTS=true
46
- #- DB=jndi PREPARED_STATEMENTS=false
47
- #- DB=jndi PREPARED_STATEMENTS=true
48
- branches:
49
- only:
50
- - master
51
- - /.*-stable$/
52
- - /^test-.*/
53
- - /maintenance|support/
54
- - /.*dev$/
57
+ - DB=jndi PREPARED_STATEMENTS=false
58
+ - DB=jndi PREPARED_STATEMENTS=true
55
59
  matrix:
56
60
  allow_failures:
57
61
  - rvm: jruby-head
58
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
59
80
  # jruby-head
60
81
  - rvm: jruby-head
61
82
  env: DB=mysql2
@@ -71,9 +92,9 @@ matrix:
71
92
  mariadb: '10.1'
72
93
  env: DB=mariadb PREPARED_STATEMENTS=true
73
94
  # Rails test-suite :
74
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.1.6" # PS off by default
75
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.1.6" PREPARED_STATEMENTS=true
76
- - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.1.6" DRIVER=MariaDB
77
- - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.1.6" # PS on by default
78
- - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.1.6" PREPARED_STATEMENTS=false
79
- - env: DB=sqlite3 TEST_PREFIX="rails:" AR_VERSION="v5.1.6"
95
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.1.7" # PS off by default
96
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.1.7" PREPARED_STATEMENTS=true
97
+ - env: DB=mysql2 TEST_PREFIX="rails:" AR_VERSION="v5.1.7" DRIVER=MariaDB
98
+ - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.1.7" # PS on by default
99
+ - env: DB=postgresql TEST_PREFIX="rails:" AR_VERSION="v5.1.7" PREPARED_STATEMENTS=false
100
+ - env: DB=sqlite3 TEST_PREFIX="rails:" AR_VERSION="v5.1.7"
@@ -26,8 +26,8 @@ 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)
30
- cached_statement = fetch_cached_statement(sql) if prepare && supports_statement_cache?
29
+ # this is different from normal AR that always caches
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
33
33
  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?
@@ -49,7 +49,7 @@ module ArJdbc
49
49
 
50
50
  # This should be overridden by the adapter if the sql itself
51
51
  # is not enough to make the key unique
52
- def cached_statement_key(sql)
52
+ def sql_key(sql)
53
53
  sql
54
54
  end
55
55
 
@@ -342,60 +342,10 @@ module ArJdbc
342
342
 
343
343
  # Properly quotes the various data types.
344
344
  # @param value contains the data
345
- # @param column (optional) contains info on the field
346
345
  # @override
347
- def quote(value, column = nil)
348
- return value.quoted_id if value.respond_to?(:quoted_id)
346
+ def quote(value)
349
347
  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
348
+ super
399
349
  end
400
350
 
401
351
  # @override
@@ -32,7 +32,15 @@ module ActiveRecord
32
32
  include ArJdbc::MySQL
33
33
 
34
34
  def initialize(connection, logger, connection_parameters, config)
35
+ # workaround to skip version check on JNDI to be lazy, dummy version is high enough for Rails 5.0 - 6.0
36
+ is_jndi = ::ActiveRecord::ConnectionAdapters::JdbcConnection.jndi_config?(config)
37
+ @version = '8.1.5' if is_jndi
38
+
35
39
  super
40
+
41
+ # set to nil to have it lazy-load the real value when required
42
+ @version = nil if is_jndi
43
+
36
44
  @prepared_statements = false unless config.key?(:prepared_statements)
37
45
  # configure_connection taken care of at ArJdbc::Abstract::Core
38
46
  end
@@ -528,67 +528,6 @@ module ArJdbc
528
528
  execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
529
529
  end
530
530
 
531
- # Returns an array of indexes for the given table.
532
- def indexes(table_name, name = nil)
533
- if name
534
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
535
- Passing name to #indexes is deprecated without replacement.
536
- MSG
537
- end
538
-
539
- # FIXME: AR version => table = Utils.extract_schema_qualified_name(table_name.to_s)
540
- schema, table = extract_schema_and_table(table_name.to_s)
541
-
542
- result = query(<<-SQL, 'SCHEMA')
543
- SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
544
- pg_catalog.obj_description(i.oid, 'pg_class') AS comment,
545
- (SELECT COUNT(*) FROM pg_opclass o
546
- JOIN (SELECT unnest(string_to_array(d.indclass::text, ' '))::int oid) c
547
- ON o.oid = c.oid WHERE o.opcdefault = 'f')
548
- FROM pg_class t
549
- INNER JOIN pg_index d ON t.oid = d.indrelid
550
- INNER JOIN pg_class i ON d.indexrelid = i.oid
551
- LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
552
- WHERE i.relkind = 'i'
553
- AND d.indisprimary = 'f'
554
- AND t.relname = '#{table}'
555
- AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}
556
- ORDER BY i.relname
557
- SQL
558
-
559
- result.map do |row|
560
- index_name = row[0]
561
- # FIXME: These values [1,2] are returned in a different format than AR expects, maybe we could update it on the Java side to be more accurate
562
- unique = row[1].is_a?(String) ? row[1] == 't' : row[1] # JDBC gets us a boolean
563
- indkey = row[2].is_a?(Java::OrgPostgresqlUtil::PGobject) ? row[2].value : row[2]
564
- indkey = indkey.split(" ").map(&:to_i)
565
- inddef = row[3]
566
- oid = row[4]
567
- comment = row[5]
568
- opclass = row[6]
569
-
570
- using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/m).flatten
571
-
572
- if indkey.include?(0) || opclass > 0
573
- columns = expressions
574
- else
575
- columns = Hash[query(<<-SQL.strip_heredoc, "SCHEMA")].values_at(*indkey).compact
576
- SELECT a.attnum, a.attname
577
- FROM pg_attribute a
578
- WHERE a.attrelid = #{oid}
579
- AND a.attnum IN (#{indkey.join(",")})
580
- SQL
581
-
582
- # add info on sort order for columns (only desc order is explicitly specified, asc is the default)
583
- orders = Hash[
584
- expressions.scan(/(\w+) DESC/).flatten.map { |order_column| [order_column, :desc] }
585
- ]
586
- end
587
-
588
- IndexDefinition.new(table_name, index_name, unique, columns, [], orders, where, nil, using.to_sym, comment.presence)
589
- end.compact
590
- end
591
-
592
531
  # @private
593
532
  def column_name_for_operation(operation, node)
594
533
  case operation
@@ -757,7 +696,7 @@ module ActiveRecord::ConnectionAdapters
757
696
 
758
697
  # Prepared statements aren't schema aware so we need to make sure we
759
698
  # store different PreparedStatement objects for different schemas
760
- def cached_statement_key(sql)
699
+ def sql_key(sql)
761
700
  "#{schema_search_path}-#{sql}"
762
701
  end
763
702
 
@@ -9,6 +9,61 @@ module ArJdbc
9
9
  # @private
10
10
  OID = ::ActiveRecord::ConnectionAdapters::PostgreSQL::OID
11
11
 
12
+ # this version makes sure to register the types by name as well
13
+ # we still need to version with OID since it's used from SchemaStatements as well
14
+ class ArjdbcTypeMapInitializer < OID::TypeMapInitializer
15
+ private
16
+
17
+ def name_with_ns(row)
18
+ if row['in_ns']
19
+ row['typname']
20
+ else
21
+ %Q("#{row['nspname']}"."#{row['typname']}")
22
+ end
23
+ end
24
+
25
+ def register_enum_type(row)
26
+ super
27
+ register name_with_ns(row), OID::Enum.new
28
+ end
29
+
30
+ def register_array_type(row)
31
+ super
32
+ register_with_subtype(name_with_ns(row), row['typelem'].to_i) do |subtype|
33
+ OID::Array.new(subtype, row['typdelim'])
34
+ end
35
+ end
36
+
37
+ def register_range_type(row)
38
+ super
39
+ name = name_with_ns(row)
40
+ register_with_subtype(name, row['rngsubtype'].to_i) do |subtype|
41
+ OID::Range.new(subtype, name.to_sym)
42
+ end
43
+ end
44
+
45
+ def register_domain_type(row)
46
+ if base_type = @store.lookup(row['typbasetype'].to_i)
47
+ register row['oid'], base_type
48
+ register name_with_ns(row), base_type
49
+ else
50
+ warn "unknown base type (OID: #{row['typbasetype']}) for domain #{row['typname']}."
51
+ end
52
+ end
53
+
54
+ def register_composite_type(row)
55
+ if subtype = @store.lookup(row['typelem'].to_i)
56
+ register row['oid'], OID::Vector.new(row['typdelim'], subtype)
57
+ register name_with_ns(row), OID::Vector.new(row['typdelim'], subtype)
58
+ end
59
+ end
60
+
61
+ def assert_valid_registration(oid, oid_type)
62
+ ret = super
63
+ ret == 0 ? oid : ret
64
+ end
65
+ end
66
+
12
67
  # @private
13
68
  module OIDTypes
14
69
 
@@ -41,7 +96,7 @@ module ArJdbc
41
96
 
42
97
  def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
43
98
  if !type_map.key?(oid)
44
- load_additional_types(type_map, [oid])
99
+ load_additional_types(type_map, oid)
45
100
  end
46
101
 
47
102
  type_map.fetch(oid, fmod, sql_type) {
@@ -133,26 +188,45 @@ module ArJdbc
133
188
  end
134
189
 
135
190
  load_additional_types(m)
191
+
192
+ # pgjdbc returns these if the column is auto-incrmenting
193
+ m.alias_type 'serial', 'int4'
194
+ m.alias_type 'bigserial', 'int8'
136
195
  end
137
196
 
138
- def load_additional_types(type_map, oids = nil) # :nodoc:
139
- initializer = OID::TypeMapInitializer.new(type_map)
197
+ def load_additional_types(type_map, oid = nil) # :nodoc:
198
+ initializer = ArjdbcTypeMapInitializer.new(type_map)
140
199
 
141
200
  if supports_ranges?
142
201
  query = <<-SQL
143
- SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
202
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype,
203
+ ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
144
204
  FROM pg_type as t
145
205
  LEFT JOIN pg_range as r ON oid = rngtypid
206
+ JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
146
207
  SQL
147
208
  else
148
209
  query = <<-SQL
149
- SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
210
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype,
211
+ ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
150
212
  FROM pg_type as t
213
+ JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
151
214
  SQL
152
215
  end
153
216
 
154
- if oids
155
- query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
217
+ if oid
218
+ if oid.is_a? Numeric || oid.match(/^\d+$/)
219
+ # numeric OID
220
+ query += "WHERE t.oid::integer = %s" % oid
221
+
222
+ elsif m = oid.match(/"?(\w+)"?\."?(\w+)"?/)
223
+ # namespace and type name
224
+ query += "WHERE ns.nspname = '%s' AND t.typname = '%s'" % [m[1], m[2]]
225
+
226
+ else
227
+ # only type name
228
+ query += "WHERE t.typname = '%s' AND ns.nspname = ANY(current_schemas(true))" % oid
229
+ end
156
230
  else
157
231
  query += initializer.query_conditions_for_initial_load(type_map)
158
232
  end
@@ -1,3 +1,3 @@
1
1
  module ArJdbc
2
- VERSION = '51.2'
2
+ VERSION = '51.3'
3
3
  end
data/rakelib/rails.rake CHANGED
@@ -9,14 +9,15 @@ namespace :rails do
9
9
  if ENV['RAILS']
10
10
  ar_path = File.join(ENV['RAILS'], 'activerecord')
11
11
  end
12
-
12
+
13
13
  unless ar_path && File.exist?(ar_path)
14
- ar_path = `bundle info --path activerecord`.chomp
14
+ ar_path = `bundle info --path activerecord`.lines.last.chomp
15
15
  end
16
16
 
17
17
  unless File.exist? ar_test_dir = File.join(ar_path, 'test')
18
18
  raise "can not directly load Rails tests;" +
19
- " try setting a local repository path e.g. export RAILS=`pwd`/../rails"
19
+ " try setting a local repository path e.g. export RAILS=`pwd`/../rails;" +
20
+ " failed guess: #{ar_path}"
20
21
  end
21
22
 
22
23
  driver = "jdbc-#{ENV['DRIVER'] ? ENV['DRIVER'].downcase : (adapter =~ /postgres/i ? 'postgres' : adapter)}"
@@ -29,7 +29,6 @@ import java.util.HashMap;
29
29
  import java.util.Map;
30
30
  import java.util.WeakHashMap;
31
31
 
32
- import org.jruby.NativeException;
33
32
  import org.jruby.Ruby;
34
33
  import org.jruby.RubyArray;
35
34
  import org.jruby.RubyClass;
@@ -148,13 +147,7 @@ public class ArJdbcModule {
148
147
  }
149
148
  }
150
149
  catch (ClassNotFoundException e) { /* ignored */ }
151
- catch (NoSuchMethodException e) {
152
- throw newNativeException(runtime, e);
153
- }
154
- catch (IllegalAccessException e) {
155
- throw newNativeException(runtime, e);
156
- }
157
- catch (InvocationTargetException e) {
150
+ catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
158
151
  throw newNativeException(runtime, e);
159
152
  }
160
153
 
@@ -263,18 +256,15 @@ public class ArJdbcModule {
263
256
  try {
264
257
  return klass.getMethod(name, argType).invoke(null, arg);
265
258
  }
266
- catch (IllegalAccessException e) {
267
- throw newNativeException(runtime, e);
268
- }
269
- catch (InvocationTargetException e) {
259
+ catch (IllegalAccessException | InvocationTargetException e) {
270
260
  throw newNativeException(runtime, e);
271
261
  }
272
262
  }
273
263
 
274
264
  private static RaiseException newNativeException(final Ruby runtime, final Throwable cause) {
275
- RubyClass nativeClass = runtime.getClass(NativeException.CLASS_NAME);
276
- NativeException nativeException = new NativeException(runtime, nativeClass, cause);
277
- return new RaiseException(cause, nativeException);
265
+ final RaiseException error = runtime.newRuntimeError(cause.toString());
266
+ error.initCause(cause);
267
+ return error;
278
268
  }
279
269
 
280
270
  @JRubyMethod(meta = true)