activerecord-jdbc-adapter 52.7-java → 60.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) 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_require.rb +3 -1
  22. data/lib/arjdbc/jdbc/base_ext.rb +3 -1
  23. data/lib/arjdbc/jdbc/callbacks.rb +2 -0
  24. data/lib/arjdbc/jdbc/column.rb +2 -0
  25. data/lib/arjdbc/jdbc/connection.rb +2 -0
  26. data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
  27. data/lib/arjdbc/jdbc/error.rb +2 -0
  28. data/lib/arjdbc/jdbc/extension.rb +2 -0
  29. data/lib/arjdbc/jdbc/java.rb +3 -1
  30. data/lib/arjdbc/jdbc/railtie.rb +3 -1
  31. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
  32. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
  33. data/lib/arjdbc/jdbc/type_cast.rb +2 -0
  34. data/lib/arjdbc/jdbc/type_converter.rb +2 -0
  35. data/lib/arjdbc/mysql/adapter.rb +47 -18
  36. data/lib/arjdbc/mysql/connection_methods.rb +0 -1
  37. data/lib/arjdbc/postgresql/adapter.rb +220 -213
  38. data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
  39. data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
  40. data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
  41. data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
  42. data/lib/arjdbc/postgresql/column.rb +6 -4
  43. data/lib/arjdbc/postgresql/connection_methods.rb +0 -1
  44. data/lib/arjdbc/postgresql/name.rb +2 -0
  45. data/lib/arjdbc/postgresql/oid_types.rb +2 -0
  46. data/lib/arjdbc/sqlite3/adapter.rb +175 -180
  47. data/lib/arjdbc/sqlite3/connection_methods.rb +15 -5
  48. data/lib/arjdbc/tasks/databases.rake +13 -10
  49. data/lib/arjdbc/util/quoted_cache.rb +3 -1
  50. data/lib/arjdbc/util/serialized_attributes.rb +3 -1
  51. data/lib/arjdbc/util/table_copier.rb +3 -1
  52. data/lib/arjdbc/version.rb +1 -1
  53. data/pom.xml +4 -4
  54. data/rakelib/01-tomcat.rake +2 -2
  55. data/rakelib/rails.rake +1 -1
  56. data/src/java/arjdbc/ArJdbcModule.java +5 -5
  57. data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
  58. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +434 -701
  59. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +0 -51
  60. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
  61. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +31 -24
  62. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +94 -99
  63. metadata +8 -10
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  ArJdbc::ConnectionMethods.module_eval do
3
3
  def sqlite3_connection(config)
4
- config = config.deep_dup
5
4
  config[:adapter_spec] ||= ::ArJdbc::SQLite3
6
5
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::SQLite3Adapter unless config.key?(:adapter_class)
7
6
 
@@ -23,17 +22,27 @@ ArJdbc::ConnectionMethods.module_eval do
23
22
  raise
24
23
  end
25
24
  end
26
-
25
+
26
+ config[:properties] ||= {}
27
+
27
28
  database = config[:database] # NOTE: "jdbc:sqlite::memory:" syntax is supported
28
29
  config[:url] ||= "jdbc:sqlite:#{database == ':memory:' ? '' : database}"
29
30
  config[:connection_alive_sql] ||= 'SELECT 1'
30
31
 
32
+ if config[:readonly]
33
+ # See
34
+ # * http://sqlite.org/c3ref/open.html
35
+ # * http://sqlite.org/c3ref/c_open_autoproxy.html
36
+ # => 0x01 = readonly, 0x40 = uri (default in JDBC)
37
+ config[:properties][:open_mode] = 0x01 | 0x40
38
+ end
39
+
31
40
  timeout = config[:timeout]
32
41
  if timeout && timeout.to_s !~ /\A\d+\Z/
33
42
  raise TypeError.new "Timeout must be nil or a number (got: #{timeout})."
34
43
  end
35
44
 
36
- options = ( config[:properties] ||= {} )
45
+ options = config[:properties]
37
46
  options['busy_timeout'] ||= timeout unless timeout.nil?
38
47
 
39
48
  jdbc_connection(config)
@@ -51,8 +60,9 @@ ArJdbc::ConnectionMethods.module_eval do
51
60
  def parse_sqlite3_config!(config)
52
61
  database = ( config[:database] ||= config[:dbfile] )
53
62
  if ':memory:' != database
54
- config[:database] = File.expand_path(database, Rails.root) if defined?(Rails.root)
55
- dirname = File.dirname(database)
63
+ # make sure to have an absolute path. Ruby and Java don't agree on working directory
64
+ config[:database] = File.expand_path(database, defined?(Rails.root) ? Rails.root : nil)
65
+ dirname = File.dirname(config[:database])
56
66
  Dir.mkdir(dirname) unless File.directory?(dirname)
57
67
  end
58
68
  end
@@ -5,25 +5,28 @@ module ActiveRecord::Tasks
5
5
  DatabaseTasks.module_eval do
6
6
 
7
7
  # @override patched to adapt jdbc configuration
8
- def each_current_configuration(environment)
8
+ def each_current_configuration(environment, spec_name = nil)
9
9
  environments = [environment]
10
10
  environments << 'test' if environment == 'development'
11
11
 
12
- configurations = ActiveRecord::Base.configurations.values_at(*environments)
13
- configurations.compact.each do |config|
14
- yield adapt_jdbc_config(config) unless config['database'].blank?
12
+ environments.each do |env|
13
+ ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
14
+ next if spec_name && spec_name != db_config.spec_name
15
+
16
+ yield adapt_jdbc_config(db_config.config), db_config.spec_name, env unless db_config.config['database'].blank?
17
+ end
15
18
  end
16
19
  end
17
20
 
18
21
  # @override patched to adapt jdbc configuration
19
22
  def each_local_configuration
20
- ActiveRecord::Base.configurations.each_value do |config|
21
- next unless config['database']
23
+ ActiveRecord::Base.configurations.configs_for.each do |db_config|
24
+ next unless db_config.config['database']
22
25
 
23
- if local_database?(config)
24
- yield adapt_jdbc_config(config)
26
+ if local_database?(db_config.config)
27
+ yield adapt_jdbc_config(db_config.config)
25
28
  else
26
- $stderr.puts "This task only modifies local databases. #{config['database']} is on a remote host."
29
+ $stderr.puts "This task only modifies local databases. #{db_config.config['database']} is on a remote host."
27
30
  end
28
31
  end
29
32
  end
@@ -45,4 +48,4 @@ module ActiveRecord::Tasks
45
48
 
46
49
  end if const_defined?(:MySQLDatabaseTasks)
47
50
 
48
- end
51
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArJdbc
2
4
  module Util
3
5
  # Caches table and column name (quoted) outcomes.
@@ -57,4 +59,4 @@ module ArJdbc
57
59
 
58
60
  end
59
61
  end
60
- end
62
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArJdbc
2
4
  module Util
3
5
  # Gets included into `ActiveRecord::Base` to support sending LOB values
@@ -95,4 +97,4 @@ module ArJdbc
95
97
  end
96
98
  # @private only due backwards compatibility
97
99
  SerializedAttributesHelper = Util::SerializedAttributes
98
- end
100
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ArJdbc
2
4
  module Util
3
5
  module TableCopier
@@ -107,4 +109,4 @@ module ArJdbc
107
109
  end
108
110
  # @private @deprecated backwards compatibility
109
111
  MissingFunctionalityHelper = Util::TableCopier
110
- end
112
+ end
@@ -1,3 +1,3 @@
1
1
  module ArJdbc
2
- VERSION = '52.7'
2
+ VERSION = '60.0'
3
3
  end
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>9.1.6.0</jruby.version>
15
+ <jruby.version>9.2.6.0</jruby.version>
16
16
  </properties>
17
17
 
18
18
  <issueManagement>
@@ -75,7 +75,7 @@
75
75
  <dependency>
76
76
  <groupId>org.postgresql</groupId>
77
77
  <artifactId>postgresql</artifactId>
78
- <version>42.1.4.jre7</version>
78
+ <version>42.1.4</version>
79
79
  </dependency>
80
80
  </dependencies>
81
81
 
@@ -103,8 +103,8 @@
103
103
  <artifactId>maven-compiler-plugin</artifactId>
104
104
  <version>2.5.1</version>
105
105
  <configuration>
106
- <source>1.7</source>
107
- <target>1.7</target>
106
+ <source>1.8</source>
107
+ <target>1.8</target>
108
108
  </configuration>
109
109
  </plugin>
110
110
  </plugins>
@@ -1,6 +1,6 @@
1
1
  namespace :'tomcat-jndi' do # contains a FS JNDI impl (for tests)
2
2
 
3
- TOMCAT_MAVEN_REPO = 'https://repo1.maven.org/maven2/org/apache/tomcat'
3
+ TOMCAT_MAVEN_REPO = 'http://repo2.maven.org/maven2/org/apache/tomcat'
4
4
  TOMCAT_VERSION = '7.0.54'
5
5
 
6
6
  DOWNLOAD_DIR = File.expand_path('../test/jars', File.dirname(__FILE__))
@@ -48,4 +48,4 @@ namespace :'tomcat-jndi' do # contains a FS JNDI impl (for tests)
48
48
  rm jar_path if File.exist?(jar_path)
49
49
  end
50
50
 
51
- end
51
+ end
@@ -51,7 +51,7 @@ namespace :rails do
51
51
  ruby_opts_string += " -C \"#{ar_path}\""
52
52
  ruby_opts_string += " -rbundler/setup"
53
53
  ruby_opts_string += " -rminitest -rminitest/excludes" unless ENV['NO_EXCLUDES'].eql?('true')
54
- file_list = ENV["TEST"] ? FileList[ ENV["TEST"].split(',') ] : test_files_finder.call
54
+ file_list = ENV["TEST"] ? FileList[ ENV["TEST"] ] : test_files_finder.call
55
55
  file_list_string = file_list.map { |fn| "\"#{fn}\"" }.join(' ')
56
56
  # test_loader_code = "-e \"ARGV.each{|f| require f}\"" # :direct
57
57
  option_list = ( ENV["TESTOPTS"] || ENV["TESTOPT"] || ENV["TEST_OPTS"] || '' )
@@ -151,7 +151,7 @@ public class ArJdbcModule {
151
151
  throw newNativeException(runtime, e);
152
152
  }
153
153
 
154
- return runtime.getTrue();
154
+ return context.tru;
155
155
  }
156
156
 
157
157
  /**
@@ -191,7 +191,7 @@ public class ArJdbcModule {
191
191
  }
192
192
 
193
193
  // NOTE: probably useless - only to be useful for the pooled runtime mode when jar at WEB-INF/lib
194
- static final Map<Ruby, Map<String, Boolean>> loadedDrivers = new WeakHashMap<Ruby, Map<String, Boolean>>(8);
194
+ static final Map<Ruby, Map<String, Boolean>> loadedDrivers = new WeakHashMap<>(8);
195
195
 
196
196
  private static IRubyObject loadDriver(final ThreadContext context, final IRubyObject self,
197
197
  final String constName) {
@@ -202,7 +202,7 @@ public class ArJdbcModule {
202
202
  synchronized (ArJdbcModule.class) {
203
203
  loadedMap = loadedDrivers.get(runtime);
204
204
  if ( loadedMap == null ) {
205
- loadedMap = new HashMap<String, Boolean>(4);
205
+ loadedMap = new HashMap<>(4);
206
206
  loadedDrivers.put(runtime, loadedMap);
207
207
  }
208
208
  }
@@ -210,8 +210,8 @@ public class ArJdbcModule {
210
210
 
211
211
  final Boolean driverLoaded = loadedMap.get(constName);
212
212
  if ( driverLoaded != null ) {
213
- if ( driverLoaded.booleanValue() ) return runtime.getFalse();
214
- return runtime.getNil();
213
+ if (driverLoaded) return context.fals;
214
+ return context.nil;
215
215
  }
216
216
 
217
217
  try { // require 'jdbc/mysql'
@@ -60,15 +60,7 @@ public class DriverWrapper {
60
60
 
61
61
  private Driver allocateDriver(final Class<? extends Driver> driverClass)
62
62
  throws InstantiationException, IllegalAccessException {
63
- try {
64
- return driverClass.newInstance();
65
- }
66
- catch (InstantiationException e) {
67
- throw e;
68
- }
69
- catch (IllegalAccessException e) {
70
- throw e;
71
- }
63
+ return driverClass.newInstance();
72
64
  }
73
65
 
74
66
  protected static Class<? extends Driver> loadDriver(final Ruby runtime, final String name)
@@ -73,7 +73,6 @@ import org.jruby.RubyBoolean;
73
73
  import org.jruby.RubyClass;
74
74
  import org.jruby.RubyException;
75
75
  import org.jruby.RubyFixnum;
76
- import org.jruby.RubyFloat;
77
76
  import org.jruby.RubyHash;
78
77
  import org.jruby.RubyIO;
79
78
  import org.jruby.RubyInteger;
@@ -86,6 +85,7 @@ import org.jruby.RubyTime;
86
85
  import org.jruby.anno.JRubyMethod;
87
86
  import org.jruby.exceptions.RaiseException;
88
87
  import org.jruby.ext.bigdecimal.RubyBigDecimal;
88
+ import org.jruby.ext.date.RubyDate;
89
89
  import org.jruby.javasupport.JavaEmbedUtils;
90
90
  import org.jruby.javasupport.JavaUtil;
91
91
  import org.jruby.runtime.Block;
@@ -147,11 +147,6 @@ public class RubyJdbcConnection extends RubyObject {
147
147
  return JdbcConnection;
148
148
  }
149
149
 
150
- @Deprecated
151
- public static RubyClass getJdbcConnectionClass(final Ruby runtime) {
152
- return getConnectionAdapters(runtime).getClass("JdbcConnection");
153
- }
154
-
155
150
  public static RubyClass getJdbcConnection(final Ruby runtime) {
156
151
  return (RubyClass) getConnectionAdapters(runtime).getConstantAt("JdbcConnection");
157
152
  }
@@ -231,34 +226,30 @@ public class RubyJdbcConnection extends RubyObject {
231
226
 
232
227
  @JRubyMethod(name = "transaction_isolation", alias = "get_transaction_isolation")
233
228
  public IRubyObject get_transaction_isolation(final ThreadContext context) {
234
- return withConnection(context, new Callable<IRubyObject>() {
235
- public IRubyObject call(final Connection connection) throws SQLException {
236
- final int level = connection.getTransactionIsolation();
237
- final String isolationSymbol = formatTransactionIsolationLevel(level);
238
- if ( isolationSymbol == null ) return context.nil;
239
- return context.runtime.newSymbol(isolationSymbol);
240
- }
229
+ return withConnection(context, connection -> {
230
+ final int level = connection.getTransactionIsolation();
231
+ final String isolationSymbol = formatTransactionIsolationLevel(level);
232
+ if ( isolationSymbol == null ) return context.nil;
233
+ return context.runtime.newSymbol(isolationSymbol);
241
234
  });
242
235
  }
243
236
 
244
237
  @JRubyMethod(name = "transaction_isolation=", alias = "set_transaction_isolation")
245
238
  public IRubyObject set_transaction_isolation(final ThreadContext context, final IRubyObject isolation) {
246
- return withConnection(context, new Callable<IRubyObject>() {
247
- public IRubyObject call(final Connection connection) throws SQLException {
248
- final int level;
249
- if ( isolation.isNil() ) {
250
- level = connection.getMetaData().getDefaultTransactionIsolation();
251
- }
252
- else {
253
- level = mapTransactionIsolationLevel(isolation);
254
- }
239
+ return withConnection(context, connection -> {
240
+ final int level;
241
+ if ( isolation.isNil() ) {
242
+ level = connection.getMetaData().getDefaultTransactionIsolation();
243
+ }
244
+ else {
245
+ level = mapTransactionIsolationLevel(isolation);
246
+ }
255
247
 
256
- connection.setTransactionIsolation(level);
248
+ connection.setTransactionIsolation(level);
257
249
 
258
- final String isolationSymbol = formatTransactionIsolationLevel(level);
259
- if ( isolationSymbol == null ) return context.nil;
260
- return context.runtime.newSymbol(isolationSymbol);
261
- }
250
+ final String isolationSymbol = formatTransactionIsolationLevel(level);
251
+ if ( isolationSymbol == null ) return context.nil;
252
+ return context.runtime.newSymbol(isolationSymbol);
262
253
  });
263
254
  }
264
255
 
@@ -306,31 +297,25 @@ public class RubyJdbcConnection extends RubyObject {
306
297
  final IRubyObject[] args) throws SQLException {
307
298
  final IRubyObject isolation = args.length > 0 ? args[0] : null;
308
299
 
309
- return withConnection(context, new Callable<IRubyObject>() {
310
- public IRubyObject call(final Connection connection) throws SQLException {
311
- final DatabaseMetaData metaData = connection.getMetaData();
312
- final boolean supported;
313
- if ( isolation != null && ! isolation.isNil() ) {
314
- final int level = mapTransactionIsolationLevel(isolation);
315
- supported = metaData.supportsTransactionIsolationLevel(level);
316
- }
317
- else {
318
- final int level = metaData.getDefaultTransactionIsolation();
319
- supported = level > Connection.TRANSACTION_NONE; // > 0
320
- }
321
- return context.runtime.newBoolean(supported);
300
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
301
+ final DatabaseMetaData metaData = connection.getMetaData();
302
+ final boolean supported;
303
+ if ( isolation != null && ! isolation.isNil() ) {
304
+ final int level = mapTransactionIsolationLevel(isolation);
305
+ supported = metaData.supportsTransactionIsolationLevel(level);
306
+ }
307
+ else {
308
+ final int level = metaData.getDefaultTransactionIsolation();
309
+ supported = level > Connection.TRANSACTION_NONE; // > 0
322
310
  }
311
+ return context.runtime.newBoolean(supported);
323
312
  });
324
313
  }
325
314
 
326
315
  @JRubyMethod(name = {"begin", "transaction"}, required = 1) // optional isolation argument for AR-4.0
327
316
  public IRubyObject begin(final ThreadContext context, final IRubyObject isolation) {
328
317
  try { // handleException == false so we can handle setTXIsolation
329
- return withConnection(context, false, new Callable<IRubyObject>() {
330
- public IRubyObject call(final Connection connection) throws SQLException {
331
- return beginTransaction(context, connection, isolation == context.nil ? null : isolation);
332
- }
333
- });
318
+ return withConnection(context, false, connection -> beginTransaction(context, connection, isolation == context.nil ? null : isolation));
334
319
  } catch (SQLException e) {
335
320
  return handleException(context, e);
336
321
  }
@@ -339,11 +324,7 @@ public class RubyJdbcConnection extends RubyObject {
339
324
  @JRubyMethod(name = {"begin", "transaction"}) // optional isolation argument for AR-4.0
340
325
  public IRubyObject begin(final ThreadContext context) {
341
326
  try { // handleException == false so we can handle setTXIsolation
342
- return withConnection(context, false, new Callable<IRubyObject>() {
343
- public IRubyObject call(final Connection connection) throws SQLException {
344
- return beginTransaction(context, connection, null);
345
- }
346
- });
327
+ return withConnection(context, false, connection -> beginTransaction(context, connection, null));
347
328
  } catch (SQLException e) {
348
329
  return handleException(context, e);
349
330
  }
@@ -373,8 +354,8 @@ public class RubyJdbcConnection extends RubyObject {
373
354
 
374
355
  @JRubyMethod(name = "commit")
375
356
  public IRubyObject commit(final ThreadContext context) {
376
- final Connection connection = getConnection(true);
377
357
  try {
358
+ final Connection connection = getConnectionInternal(true);
378
359
  if ( ! connection.getAutoCommit() ) {
379
360
  try {
380
361
  connection.commit();
@@ -394,13 +375,13 @@ public class RubyJdbcConnection extends RubyObject {
394
375
 
395
376
  @JRubyMethod(name = "rollback")
396
377
  public IRubyObject rollback(final ThreadContext context) {
397
- final Connection connection = getConnection(true);
398
378
  try {
379
+ final Connection connection = getConnectionInternal(true);
399
380
  if ( ! connection.getAutoCommit() ) {
400
381
  try {
401
382
  connection.rollback();
402
383
  resetSavepoints(context); // if any
403
- return context.runtime.getTrue();
384
+ return context.tru;
404
385
  } finally {
405
386
  connection.setAutoCommit(true);
406
387
  }
@@ -414,11 +395,9 @@ public class RubyJdbcConnection extends RubyObject {
414
395
 
415
396
  @JRubyMethod(name = "supports_savepoints?")
416
397
  public IRubyObject supports_savepoints_p(final ThreadContext context) throws SQLException {
417
- return withConnection(context, new Callable<IRubyObject>() {
418
- public IRubyObject call(final Connection connection) throws SQLException {
419
- final DatabaseMetaData metaData = connection.getMetaData();
420
- return context.runtime.newBoolean( metaData.supportsSavepoints() );
421
- }
398
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
399
+ final DatabaseMetaData metaData = connection.getMetaData();
400
+ return context.runtime.newBoolean( metaData.supportsSavepoints() );
422
401
  });
423
402
  }
424
403
 
@@ -429,8 +408,8 @@ public class RubyJdbcConnection extends RubyObject {
429
408
 
430
409
  @JRubyMethod(name = "create_savepoint", required = 1)
431
410
  public IRubyObject create_savepoint(final ThreadContext context, IRubyObject name) {
432
- final Connection connection = getConnection(true);
433
411
  try {
412
+ final Connection connection = getConnectionInternal(true);
434
413
  connection.setAutoCommit(false);
435
414
 
436
415
  final Savepoint savepoint ;
@@ -458,8 +437,8 @@ public class RubyJdbcConnection extends RubyObject {
458
437
  public IRubyObject rollback_savepoint(final ThreadContext context, final IRubyObject name) {
459
438
  if (name == context.nil) throw context.runtime.newArgumentError("nil savepoint name given");
460
439
 
461
- final Connection connection = getConnection(true);
462
440
  try {
441
+ final Connection connection = getConnectionInternal(true);
463
442
  Savepoint savepoint = getSavepoints(context).get(name);
464
443
  if ( savepoint == null ) {
465
444
  throw context.runtime.newRuntimeError("could not rollback savepoint: '" + name + "' (not set)");
@@ -476,7 +455,6 @@ public class RubyJdbcConnection extends RubyObject {
476
455
  public IRubyObject release_savepoint(final ThreadContext context, final IRubyObject name) {
477
456
  if (name == context.nil) throw context.runtime.newArgumentError("nil savepoint name given");
478
457
 
479
- final Connection connection = getConnection(true);
480
458
  try {
481
459
  Object savepoint = getSavepoints(context).remove(name);
482
460
 
@@ -487,6 +465,7 @@ public class RubyJdbcConnection extends RubyObject {
487
465
  savepoint = ((IRubyObject) savepoint).toJava(Savepoint.class);
488
466
  }
489
467
 
468
+ final Connection connection = getConnectionInternal(true);
490
469
  releaseSavepoint(connection, (Savepoint) savepoint);
491
470
  return context.nil;
492
471
  }
@@ -525,7 +504,7 @@ public class RubyJdbcConnection extends RubyObject {
525
504
  }
526
505
 
527
506
  @SuppressWarnings("unchecked")
528
- private final Map<IRubyObject, Savepoint> getSavepoints(final boolean init) {
507
+ private Map<IRubyObject, Savepoint> getSavepoints(final boolean init) {
529
508
  if ( hasInternalVariable("savepoints") ) {
530
509
  return (Map<IRubyObject, Savepoint>) getInternalVariable("savepoints");
531
510
  }
@@ -545,13 +524,6 @@ public class RubyJdbcConnection extends RubyObject {
545
524
  return false;
546
525
  }
547
526
 
548
- @Deprecated // second argument is now mandatory - only kept for compatibility
549
- @JRubyMethod(required = 1)
550
- public final IRubyObject initialize(final ThreadContext context, final IRubyObject config) {
551
- doInitialize(context, config, context.nil);
552
- return this;
553
- }
554
-
555
527
  @JRubyMethod(required = 2)
556
528
  public final IRubyObject initialize(final ThreadContext context, final IRubyObject config, final IRubyObject adapter) {
557
529
  doInitialize(context, config, adapter);
@@ -559,12 +531,17 @@ public class RubyJdbcConnection extends RubyObject {
559
531
  }
560
532
 
561
533
  protected void doInitialize(final ThreadContext context, final IRubyObject config, final IRubyObject adapter) {
562
- this.config = config; this.adapter = adapter;
534
+ this.config = config;
535
+ this.adapter = adapter;
563
536
 
564
537
  this.jndi = setupConnectionFactory(context);
565
538
  this.lazy = jndi; // JNDIs are lazy by default otherwise eager
566
539
  try {
567
- initConnection(context);
540
+ if (adapter == null || adapter == context.nil) {
541
+ warn(context, "adapter not set, please pass adapter on JdbcConnection#initialize(config, adapter)");
542
+ }
543
+
544
+ if (!lazy) setConnection(newConnection());
568
545
  }
569
546
  catch (SQLException e) {
570
547
  String message = e.getMessage();
@@ -575,7 +552,7 @@ public class RubyJdbcConnection extends RubyObject {
575
552
  IRubyObject value = getConfigValue(context, "configure_connection");
576
553
  if ( value == context.nil ) this.configureConnection = true;
577
554
  else {
578
- this.configureConnection = value != context.runtime.getFalse();
555
+ this.configureConnection = value != context.fals;
579
556
  }
580
557
 
581
558
  IRubyObject jdbcFetchSize = getConfigValue(context, "jdbc_fetch_size");
@@ -586,7 +563,6 @@ public class RubyJdbcConnection extends RubyObject {
586
563
 
587
564
  @JRubyMethod(name = "adapter")
588
565
  public IRubyObject adapter(final ThreadContext context) {
589
- final IRubyObject adapter = getAdapter();
590
566
  return adapter == null ? context.nil : adapter;
591
567
  }
592
568
 
@@ -601,43 +577,9 @@ public class RubyJdbcConnection extends RubyObject {
601
577
  return factory;
602
578
  }
603
579
 
604
- /**
605
- * Called during <code>initialize</code> after the connection factory
606
- * has been set to check if we can connect and/or perform any initialization
607
- * necessary.
608
- * <br/>
609
- * NOTE: connection has not been configured at this point,
610
- * nor should we retry - we're creating a brand new JDBC connection
611
- *
612
- * @param context
613
- * @return connection
614
- */
615
- @Deprecated
616
- @JRubyMethod(name = "init_connection")
617
- public synchronized IRubyObject init_connection(final ThreadContext context) {
618
- try {
619
- return initConnection(context);
620
- }
621
- catch (SQLException e) {
622
- return handleException(context, e); // throws
623
- }
624
- }
625
-
626
- private IRubyObject initConnection(final ThreadContext context) throws SQLException {
627
- final IRubyObject adapter = getAdapter(); // self.adapter
628
- if ( adapter == null || adapter == context.nil ) {
629
- warn(context, "adapter not set, please pass adapter on JdbcConnection#initialize(config, adapter)");
630
- }
631
-
632
- if ( ! lazy ) setConnection( newConnection() );
633
-
634
- return context.nil;
635
- }
636
-
637
580
  private void configureConnection() {
638
581
  if ( ! configureConnection ) return; // return false;
639
582
 
640
- final IRubyObject adapter = getAdapter(); // self.adapter
641
583
  if ( adapter != null && ! adapter.isNil() ) {
642
584
  if ( adapter.respondsTo("configure_connection") ) {
643
585
  final ThreadContext context = getRuntime().getCurrentContext();
@@ -659,7 +601,7 @@ public class RubyJdbcConnection extends RubyObject {
659
601
 
660
602
  @JRubyMethod(name = "jdbc_connection", alias = "connection", required = 1)
661
603
  public final IRubyObject connection(final ThreadContext context, final IRubyObject unwrap) {
662
- if ( unwrap == context.nil || unwrap == context.runtime.getFalse() ) {
604
+ if ( unwrap == context.nil || unwrap == context.fals ) {
663
605
  return connection(context);
664
606
  }
665
607
  Connection connection = connectionImpl(context);
@@ -695,18 +637,25 @@ public class RubyJdbcConnection extends RubyObject {
695
637
 
696
638
  @JRubyMethod(name = "active?", alias = "valid?")
697
639
  public RubyBoolean active_p(final ThreadContext context) {
698
- if ( ! connected ) return context.runtime.getFalse();
699
- if ( isJndi() ) {
640
+ if ( ! connected ) return context.fals;
641
+ if (jndi) {
700
642
  // for JNDI the data-source / pool is supposed to
701
643
  // manage connections for us thus no valid check!
702
644
  boolean active = getConnectionFactory() != null;
703
645
  return context.runtime.newBoolean( active );
704
646
  }
705
- final Connection connection = getConnection();
706
- if ( connection == null ) return context.runtime.getFalse(); // unlikely
647
+ final Connection connection = getConnection(false);
648
+ if ( connection == null ) return context.fals; // unlikely
707
649
  return context.runtime.newBoolean( isConnectionValid(context, connection) );
708
650
  }
709
651
 
652
+ @JRubyMethod(name = "really_valid?")
653
+ public RubyBoolean really_valid_p(final ThreadContext context) {
654
+ final Connection connection = getConnection(true);
655
+ if (connection == null) return context.fals;
656
+ return context.runtime.newBoolean(isConnectionValid(context, connection));
657
+ }
658
+
710
659
  @JRubyMethod(name = "disconnect!")
711
660
  public synchronized IRubyObject disconnect(final ThreadContext context) {
712
661
  setConnection(null); connected = false;
@@ -727,41 +676,40 @@ public class RubyJdbcConnection extends RubyObject {
727
676
 
728
677
  private void connectImpl(final boolean forceConnection) throws SQLException {
729
678
  setConnection( forceConnection ? newConnection() : null );
730
- if (forceConnection) {
731
- if (getConnectionImpl() == null) throw new SQLException("Didn't get a connection. Wrong URL?");
732
- configureConnection();
733
- }
679
+ if ( forceConnection ) configureConnection();
734
680
  }
735
681
 
736
682
  @JRubyMethod(name = "read_only?")
737
683
  public IRubyObject is_read_only(final ThreadContext context) {
738
- final Connection connection = getConnection(false);
739
- if ( connection != null ) {
740
- try {
741
- return context.runtime.newBoolean( connection.isReadOnly() );
684
+ try {
685
+ final Connection connection = getConnectionInternal(false);
686
+ if (connection != null) {
687
+ return context.runtime.newBoolean(connection.isReadOnly());
742
688
  }
743
- catch (SQLException e) { return handleException(context, e); }
689
+ } catch (SQLException e) {
690
+ return handleException(context, e);
744
691
  }
745
692
  return context.nil;
746
693
  }
747
694
 
748
695
  @JRubyMethod(name = "read_only=")
749
696
  public IRubyObject set_read_only(final ThreadContext context, final IRubyObject flag) {
750
- final Connection connection = getConnection(true);
751
697
  try {
698
+ final Connection connection = getConnectionInternal(true);
752
699
  connection.setReadOnly( flag.isTrue() );
753
700
  return context.runtime.newBoolean( connection.isReadOnly() );
701
+ } catch (SQLException e) {
702
+ return handleException(context, e);
754
703
  }
755
- catch (SQLException e) { return handleException(context, e); }
756
704
  }
757
705
 
758
706
  @JRubyMethod(name = { "open?" /* "conn?" */ })
759
707
  public IRubyObject open_p(final ThreadContext context) {
760
- final Connection connection = getConnection(false);
708
+ try {
709
+ final Connection connection = getConnectionInternal(false);
761
710
 
762
- if (connection == null) return context.runtime.getFalse();
711
+ if (connection == null) return context.fals;
763
712
 
764
- try {
765
713
  // NOTE: isClosed method generally cannot be called to determine
766
714
  // whether a connection to a database is valid or invalid ...
767
715
  return context.runtime.newBoolean(!connection.isClosed());
@@ -774,10 +722,10 @@ public class RubyJdbcConnection extends RubyObject {
774
722
  public IRubyObject close(final ThreadContext context) {
775
723
  final Connection connection = getConnection(false);
776
724
 
777
- if (connection == null) return context.runtime.getFalse();
725
+ if (connection == null) return context.fals;
778
726
 
779
727
  try {
780
- if (connection.isClosed()) return context.runtime.getFalse();
728
+ if (connection.isClosed()) return context.fals;
781
729
 
782
730
  setConnection(null); // does connection.close();
783
731
  } catch (Exception e) {
@@ -787,69 +735,65 @@ public class RubyJdbcConnection extends RubyObject {
787
735
 
788
736
  // ActiveRecord expects a closed connection to not try and re-open a connection
789
737
  // whereas JNDI expects that.
790
- if (!isJndi()) disconnect(context);
738
+ if (!jndi) disconnect(context);
791
739
 
792
- return context.runtime.getTrue();
740
+ return context.tru;
793
741
  }
794
742
 
795
743
  @JRubyMethod(name = "database_name")
796
744
  public IRubyObject database_name(final ThreadContext context) {
797
- return withConnection(context, new Callable<IRubyObject>() {
798
- public IRubyObject call(final Connection connection) throws SQLException {
799
- String name = connection.getCatalog();
800
- if ( name == null ) {
801
- name = connection.getMetaData().getUserName();
802
- if ( name == null ) return context.nil;
803
- }
804
- return context.runtime.newString(name);
745
+ return withConnection(context, connection -> {
746
+ String name = connection.getCatalog();
747
+ if ( name == null ) {
748
+ name = connection.getMetaData().getUserName();
749
+ if ( name == null ) return context.nil;
805
750
  }
751
+ return context.runtime.newString(name);
806
752
  });
807
753
  }
808
754
 
809
755
  @JRubyMethod(name = "execute", required = 1)
810
756
  public IRubyObject execute(final ThreadContext context, final IRubyObject sql) {
811
757
  final String query = sqlString(sql);
812
- return withConnection(context, new Callable<IRubyObject>() {
813
- public IRubyObject call(final Connection connection) throws SQLException {
814
- Statement statement = null;
815
- try {
816
- statement = createStatement(context, connection);
817
-
818
- // For DBs that do support multiple statements, lets return the last result set
819
- // to be consistent with AR
820
- boolean hasResultSet = doExecute(statement, query);
821
- int updateCount = statement.getUpdateCount();
758
+ return withConnection(context, connection -> {
759
+ Statement statement = null;
760
+ try {
761
+ statement = createStatement(context, connection);
822
762
 
823
- IRubyObject result = context.nil; // If no results, return nil
824
- ResultSet resultSet;
763
+ // For DBs that do support multiple statements, lets return the last result set
764
+ // to be consistent with AR
765
+ boolean hasResultSet = doExecute(statement, query);
766
+ int updateCount = statement.getUpdateCount();
825
767
 
826
- while (hasResultSet || updateCount != -1) {
768
+ IRubyObject result = context.nil; // If no results, return nil
769
+ ResultSet resultSet;
827
770
 
828
- if (hasResultSet) {
829
- resultSet = statement.getResultSet();
771
+ while (hasResultSet || updateCount != -1) {
830
772
 
831
- // Unfortunately the result set gets closed when getMoreResults()
832
- // is called, so we have to process the result sets as we get them
833
- // this shouldn't be an issue in most cases since we're only getting 1 result set anyways
834
- result = mapExecuteResult(context, connection, resultSet);
835
- resultSet.close();
836
- } else {
837
- result = context.runtime.newFixnum(updateCount);
838
- }
773
+ if (hasResultSet) {
774
+ resultSet = statement.getResultSet();
839
775
 
840
- // Check to see if there is another result set
841
- hasResultSet = statement.getMoreResults();
842
- updateCount = statement.getUpdateCount();
776
+ // Unfortunately the result set gets closed when getMoreResults()
777
+ // is called, so we have to process the result sets as we get them
778
+ // this shouldn't be an issue in most cases since we're only getting 1 result set anyways
779
+ result = mapExecuteResult(context, connection, resultSet);
780
+ resultSet.close();
781
+ } else {
782
+ result = context.runtime.newFixnum(updateCount);
843
783
  }
844
784
 
845
- return result;
846
-
847
- } catch (final SQLException e) {
848
- debugErrorSQL(context, query);
849
- throw e;
850
- } finally {
851
- close(statement);
785
+ // Check to see if there is another result set
786
+ hasResultSet = statement.getMoreResults();
787
+ updateCount = statement.getUpdateCount();
852
788
  }
789
+
790
+ return result;
791
+
792
+ } catch (final SQLException e) {
793
+ debugErrorSQL(context, query);
794
+ throw e;
795
+ } finally {
796
+ close(statement);
853
797
  }
854
798
  });
855
799
  }
@@ -888,106 +832,62 @@ public class RubyJdbcConnection extends RubyObject {
888
832
  return mapQueryResult(context, connection, resultSet);
889
833
  }
890
834
 
891
- private static String[] createStatementPk(IRubyObject pk) {
892
- String[] statementPk;
893
- if (pk instanceof RubyArray) {
894
- RubyArray ary = (RubyArray) pk;
895
- int size = ary.size();
896
- statementPk = new String[size];
897
- for (int i = 0; i < size; i++) {
898
- statementPk[i] = sqlString(ary.eltInternal(i));
899
- }
900
- } else {
901
- statementPk = new String[] { sqlString(pk) };
902
- }
903
- return statementPk;
904
- }
905
-
906
835
  /**
907
836
  * Executes an INSERT SQL statement
908
837
  * @param context
909
838
  * @param sql
910
- * @param pk Rails PK
911
839
  * @return ActiveRecord::Result
912
840
  * @throws SQLException
913
841
  */
914
- @JRubyMethod(name = "execute_insert_pk", required = 2)
915
- public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject pk) {
916
- return withConnection(context, new Callable<IRubyObject>() {
917
- public IRubyObject call(final Connection connection) throws SQLException {
918
- Statement statement = null;
919
- final String query = sqlString(sql);
920
- try {
921
-
922
- statement = createStatement(context, connection);
923
-
924
- if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
925
- statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
926
- } else {
927
- statement.executeUpdate(query, createStatementPk(pk));
928
- }
842
+ @JRubyMethod(name = "execute_insert", required = 1)
843
+ public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql) {
844
+ return withConnection(context, connection -> {
845
+ Statement statement = null;
846
+ final String query = sqlString(sql);
847
+ try {
929
848
 
930
- return mapGeneratedKeys(context, connection, statement);
849
+ statement = createStatement(context, connection);
850
+ statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
851
+ return mapGeneratedKeys(context, connection, statement);
931
852
 
932
- } catch (final SQLException e) {
933
- debugErrorSQL(context, query);
934
- throw e;
935
- } finally {
936
- close(statement);
937
- }
853
+ } catch (final SQLException e) {
854
+ debugErrorSQL(context, query);
855
+ throw e;
856
+ } finally {
857
+ close(statement);
938
858
  }
939
859
  });
940
860
  }
941
861
 
942
- @Deprecated
943
- @JRubyMethod(name = "execute_insert", required = 1)
944
- public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql) {
945
- return execute_insert_pk(context, sql, context.nil);
946
- }
947
-
948
862
  /**
949
863
  * Executes an INSERT SQL statement using a prepared statement
950
864
  * @param context
951
865
  * @param sql
952
866
  * @param binds RubyArray of values to be bound to the query
953
- * @param pk Rails PK
954
867
  * @return ActiveRecord::Result
955
868
  * @throws SQLException
956
869
  */
957
- @JRubyMethod(name = "execute_insert_pk", required = 3)
958
- public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject binds,
959
- final IRubyObject pk) {
960
- return withConnection(context, new Callable<IRubyObject>() {
961
- public IRubyObject call(final Connection connection) throws SQLException {
962
- PreparedStatement statement = null;
963
- final String query = sqlString(sql);
964
- try {
965
- if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
966
- statement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
967
- } else {
968
- statement = connection.prepareStatement(query, createStatementPk(pk));
969
- }
870
+ @JRubyMethod(name = "execute_insert", required = 2)
871
+ public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql, final IRubyObject binds) {
872
+ return withConnection(context, connection -> {
873
+ PreparedStatement statement = null;
874
+ final String query = sqlString(sql);
875
+ try {
970
876
 
971
- setStatementParameters(context, connection, statement, (RubyArray) binds);
972
- statement.executeUpdate();
973
- return mapGeneratedKeys(context, connection, statement);
877
+ statement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
878
+ setStatementParameters(context, connection, statement, (RubyArray) binds);
879
+ statement.executeUpdate();
880
+ return mapGeneratedKeys(context, connection, statement);
974
881
 
975
- } catch (final SQLException e) {
976
- debugErrorSQL(context, query);
977
- throw e;
978
- } finally {
979
- close(statement);
980
- }
882
+ } catch (final SQLException e) {
883
+ debugErrorSQL(context, query);
884
+ throw e;
885
+ } finally {
886
+ close(statement);
981
887
  }
982
888
  });
983
889
  }
984
890
 
985
- @Deprecated
986
- @JRubyMethod(name = "execute_insert", required = 2)
987
- public IRubyObject execute_insert(final ThreadContext context, final IRubyObject binds, final IRubyObject sql) {
988
- return execute_insert_pk(context, sql, binds, context.nil);
989
- }
990
-
991
891
  /**
992
892
  * Executes an UPDATE (DELETE) SQL statement
993
893
  * @param context
@@ -997,22 +897,20 @@ public class RubyJdbcConnection extends RubyObject {
997
897
  */
998
898
  @JRubyMethod(name = {"execute_update", "execute_delete"}, required = 1)
999
899
  public IRubyObject execute_update(final ThreadContext context, final IRubyObject sql) {
1000
- return withConnection(context, new Callable<IRubyObject>() {
1001
- public IRubyObject call(final Connection connection) throws SQLException {
1002
- Statement statement = null;
1003
- final String query = sqlString(sql);
900
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
901
+ Statement statement = null;
902
+ final String query = sqlString(sql);
1004
903
 
1005
- try {
1006
- statement = createStatement(context, connection);
904
+ try {
905
+ statement = createStatement(context, connection);
1007
906
 
1008
- final int rowCount = statement.executeUpdate(query);
1009
- return context.runtime.newFixnum(rowCount);
1010
- } catch (final SQLException e) {
1011
- debugErrorSQL(context, query);
1012
- throw e;
1013
- } finally {
1014
- close(statement);
1015
- }
907
+ final int rowCount = statement.executeUpdate(query);
908
+ return context.runtime.newFixnum(rowCount);
909
+ } catch (final SQLException e) {
910
+ debugErrorSQL(context, query);
911
+ throw e;
912
+ } finally {
913
+ close(statement);
1016
914
  }
1017
915
  });
1018
916
  }
@@ -1028,21 +926,19 @@ public class RubyJdbcConnection extends RubyObject {
1028
926
  */
1029
927
  @JRubyMethod(name = {"execute_prepared_update", "execute_prepared_delete"}, required = 2)
1030
928
  public IRubyObject execute_prepared_update(final ThreadContext context, final IRubyObject sql, final IRubyObject binds) {
1031
- return withConnection(context, new Callable<IRubyObject>() {
1032
- public IRubyObject call(final Connection connection) throws SQLException {
1033
- PreparedStatement statement = null;
1034
- final String query = sqlString(sql);
1035
- try {
1036
- statement = connection.prepareStatement(query);
1037
- setStatementParameters(context, connection, statement, (RubyArray) binds);
1038
- final int rowCount = statement.executeUpdate();
1039
- return context.runtime.newFixnum(rowCount);
1040
- } catch (final SQLException e) {
1041
- debugErrorSQL(context, query);
1042
- throw e;
1043
- } finally {
1044
- close(statement);
1045
- }
929
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
930
+ PreparedStatement statement = null;
931
+ final String query = sqlString(sql);
932
+ try {
933
+ statement = connection.prepareStatement(query);
934
+ setStatementParameters(context, connection, statement, (RubyArray) binds);
935
+ final int rowCount = statement.executeUpdate();
936
+ return context.runtime.newFixnum(rowCount);
937
+ } catch (final SQLException e) {
938
+ debugErrorSQL(context, query);
939
+ throw e;
940
+ } finally {
941
+ close(statement);
1046
942
  }
1047
943
  });
1048
944
  }
@@ -1089,50 +985,48 @@ public class RubyJdbcConnection extends RubyObject {
1089
985
 
1090
986
  private IRubyObject doExecuteQueryRaw(final ThreadContext context,
1091
987
  final String query, final int maxRows, final Block block, final RubyArray binds) {
1092
- return withConnection(context, new Callable<IRubyObject>() {
1093
- public IRubyObject call(final Connection connection) throws SQLException {
1094
- Statement statement = null; boolean hasResult;
1095
- try {
1096
- if ( binds == null || binds.isEmpty()) { // plain statement
1097
- statement = createStatement(context, connection);
1098
- statement.setMaxRows(maxRows); // zero means there is no limit
1099
- hasResult = statement.execute(query);
1100
- }
1101
- else {
1102
- final PreparedStatement prepStatement;
1103
- statement = prepStatement = connection.prepareStatement(query);
1104
- if (fetchSize != 0) statement.setFetchSize(fetchSize);
1105
- statement.setMaxRows(maxRows); // zero means there is no limit
1106
- setStatementParameters(context, connection, prepStatement, binds);
1107
- hasResult = prepStatement.execute();
1108
- }
988
+ return withConnection(context, connection -> {
989
+ Statement statement = null; boolean hasResult;
990
+ try {
991
+ if ( binds == null || binds.isEmpty()) { // plain statement
992
+ statement = createStatement(context, connection);
993
+ statement.setMaxRows(maxRows); // zero means there is no limit
994
+ hasResult = statement.execute(query);
995
+ }
996
+ else {
997
+ final PreparedStatement prepStatement;
998
+ statement = prepStatement = connection.prepareStatement(query);
999
+ if (fetchSize != 0) statement.setFetchSize(fetchSize);
1000
+ statement.setMaxRows(maxRows); // zero means there is no limit
1001
+ setStatementParameters(context, connection, prepStatement, binds);
1002
+ hasResult = prepStatement.execute();
1003
+ }
1109
1004
 
1110
- if (block.isGiven()) {
1111
- if (hasResult) {
1112
- // yield(id1, name1) ... row 1 result data
1113
- // yield(id2, name2) ... row 2 result data
1114
- return yieldResultRows(context, connection, statement.getResultSet(), block);
1115
- }
1116
- return context.nil;
1117
- }
1005
+ if (block.isGiven()) {
1118
1006
  if (hasResult) {
1119
- return mapToRawResult(context, connection, statement.getResultSet(), false);
1007
+ // yield(id1, name1) ... row 1 result data
1008
+ // yield(id2, name2) ... row 2 result data
1009
+ return yieldResultRows(context, connection, statement.getResultSet(), block);
1120
1010
  }
1121
- return context.runtime.newEmptyArray();
1011
+ return context.nil;
1122
1012
  }
1123
- catch (final SQLException e) {
1124
- debugErrorSQL(context, query);
1125
- throw e;
1126
- }
1127
- finally {
1128
- close(statement);
1013
+ if (hasResult) {
1014
+ return mapToRawResult(context, connection, statement.getResultSet(), false);
1129
1015
  }
1016
+ return context.runtime.newEmptyArray();
1017
+ }
1018
+ catch (final SQLException e) {
1019
+ debugErrorSQL(context, query);
1020
+ throw e;
1021
+ }
1022
+ finally {
1023
+ close(statement);
1130
1024
  }
1131
1025
  });
1132
1026
  }
1133
1027
 
1134
1028
  protected static String sqlString(final IRubyObject sql) {
1135
- return sql instanceof RubyString ? ((RubyString) sql).decodeString() : sql.convertToString().decodeString();
1029
+ return sql.convertToString().decodeString();
1136
1030
  }
1137
1031
 
1138
1032
  /**
@@ -1145,26 +1039,24 @@ public class RubyJdbcConnection extends RubyObject {
1145
1039
  */
1146
1040
  @JRubyMethod(required = 1)
1147
1041
  public IRubyObject execute_query(final ThreadContext context, final IRubyObject sql) {
1148
- return withConnection(context, new Callable<IRubyObject>() {
1149
- public IRubyObject call(final Connection connection) throws SQLException {
1150
- Statement statement = null;
1151
- final String query = sqlString(sql);
1152
- try {
1153
- statement = createStatement(context, connection);
1042
+ return withConnection(context, connection -> {
1043
+ Statement statement = null;
1044
+ final String query = sqlString(sql);
1045
+ try {
1046
+ statement = createStatement(context, connection);
1154
1047
 
1155
- // At least until AR 5.1 #exec_query still gets called for things that don't return results in some cases :(
1156
- if (statement.execute(query)) {
1157
- return mapQueryResult(context, connection, statement.getResultSet());
1158
- }
1048
+ // At least until AR 5.1 #exec_query still gets called for things that don't return results in some cases :(
1049
+ if (statement.execute(query)) {
1050
+ return mapQueryResult(context, connection, statement.getResultSet());
1051
+ }
1159
1052
 
1160
- return context.nil;
1053
+ return newEmptyResult(context);
1161
1054
 
1162
- } catch (final SQLException e) {
1163
- debugErrorSQL(context, query);
1164
- throw e;
1165
- } finally {
1166
- close(statement);
1167
- }
1055
+ } catch (final SQLException e) {
1056
+ debugErrorSQL(context, query);
1057
+ throw e;
1058
+ } finally {
1059
+ close(statement);
1168
1060
  }
1169
1061
  });
1170
1062
  }
@@ -1177,13 +1069,11 @@ public class RubyJdbcConnection extends RubyObject {
1177
1069
  */
1178
1070
  @JRubyMethod(required = 1)
1179
1071
  public IRubyObject prepare_statement(final ThreadContext context, final IRubyObject sql) {
1180
- return withConnection(context, new Callable<IRubyObject>() {
1181
- public IRubyObject call(Connection connection) throws SQLException {
1182
- final String query = sql.convertToString().getUnicodeValue();
1183
- PreparedStatement statement = connection.prepareStatement(query);
1184
- if (fetchSize != 0) statement.setFetchSize(fetchSize);
1185
- return JavaUtil.convertJavaToRuby(context.runtime, statement);
1186
- }
1072
+ return withConnection(context, connection -> {
1073
+ final String query = sql.convertToString().getUnicodeValue();
1074
+ PreparedStatement statement = connection.prepareStatement(query);
1075
+ if (fetchSize != 0) statement.setFetchSize(fetchSize);
1076
+ return JavaUtil.convertJavaToRuby(context.runtime, statement);
1187
1077
  });
1188
1078
  }
1189
1079
 
@@ -1206,40 +1096,40 @@ public class RubyJdbcConnection extends RubyObject {
1206
1096
  @JRubyMethod(required = 3)
1207
1097
  public IRubyObject execute_prepared_query(final ThreadContext context, final IRubyObject sql,
1208
1098
  final IRubyObject binds, final IRubyObject cachedStatement) {
1209
- return withConnection(context, new Callable<IRubyObject>() {
1210
- public IRubyObject call(final Connection connection) throws SQLException {
1211
- final boolean cached = !(cachedStatement == null || cachedStatement.isNil());
1212
- final String query = sql.convertToString().getUnicodeValue();
1213
- PreparedStatement statement = null;
1099
+ return withConnection(context, connection -> {
1100
+ final boolean cached = !(cachedStatement == null || cachedStatement.isNil());
1101
+ String query = null;
1102
+ PreparedStatement statement = null;
1214
1103
 
1215
- try {
1216
- if (cached) {
1217
- statement = (PreparedStatement) JavaEmbedUtils.rubyToJava(cachedStatement);
1218
- } else {
1219
- statement = connection.prepareStatement(query);
1220
- if (fetchSize != 0) statement.setFetchSize(fetchSize);
1221
- }
1104
+ try {
1105
+ if (cached) {
1106
+ statement = (PreparedStatement) JavaEmbedUtils.rubyToJava(cachedStatement);
1107
+ } else {
1108
+ query = sql.convertToString().getUnicodeValue();
1109
+ statement = connection.prepareStatement(query);
1110
+ if (fetchSize != 0) statement.setFetchSize(fetchSize);
1111
+ }
1222
1112
 
1223
- setStatementParameters(context, connection, statement, (RubyArray) binds);
1113
+ setStatementParameters(context, connection, statement, (RubyArray) binds);
1224
1114
 
1225
- if (statement.execute()) {
1226
- ResultSet resultSet = statement.getResultSet();
1227
- IRubyObject results = mapQueryResult(context, connection, resultSet);
1228
- resultSet.close();
1115
+ if (statement.execute()) {
1116
+ ResultSet resultSet = statement.getResultSet();
1117
+ IRubyObject results = mapQueryResult(context, connection, resultSet);
1118
+ resultSet.close();
1229
1119
 
1230
- return results;
1231
- } else {
1232
- return context.nil;
1233
- }
1234
- } catch (final SQLException e) {
1235
- debugErrorSQL(context, query);
1236
- throw e;
1237
- } finally {
1238
- if ( cached ) {
1239
- statement.clearParameters();
1240
- } else {
1241
- close(statement);
1242
- }
1120
+ return results;
1121
+ } else {
1122
+ return newEmptyResult(context);
1123
+ }
1124
+ } catch (final SQLException e) {
1125
+ if (query == null) query = sql.convertToString().getUnicodeValue();
1126
+ debugErrorSQL(context, query);
1127
+ throw e;
1128
+ } finally {
1129
+ if ( cached ) {
1130
+ statement.clearParameters();
1131
+ } else {
1132
+ close(statement);
1243
1133
  }
1244
1134
  }
1245
1135
  });
@@ -1251,35 +1141,6 @@ public class RubyJdbcConnection extends RubyObject {
1251
1141
  return mapToResult(context, connection, resultSet, columns);
1252
1142
  }
1253
1143
 
1254
- /**
1255
- * @deprecated please do not use this method
1256
- */
1257
- @Deprecated // only used by Oracle adapter - also it's really a bad idea
1258
- @JRubyMethod(name = "execute_id_insert", required = 2)
1259
- public IRubyObject execute_id_insert(final ThreadContext context, final IRubyObject sql, final IRubyObject id) {
1260
- final Ruby runtime = context.runtime;
1261
-
1262
- callMethod("warn", RubyString.newUnicodeString(runtime, "DEPRECATED: execute_id_insert(sql, id) will be removed"));
1263
-
1264
- return withConnection(context, new Callable<IRubyObject>() {
1265
- public IRubyObject call(final Connection connection) throws SQLException {
1266
- PreparedStatement statement = null;
1267
- final String insertSQL = sql.convertToString().getUnicodeValue();
1268
- try {
1269
- statement = connection.prepareStatement(insertSQL);
1270
- statement.setLong(1, RubyNumeric.fix2long(id));
1271
- statement.executeUpdate();
1272
- }
1273
- catch (final SQLException e) {
1274
- debugErrorSQL(context, insertSQL);
1275
- throw e;
1276
- }
1277
- finally { close(statement); }
1278
- return id;
1279
- }
1280
- });
1281
- }
1282
-
1283
1144
  @JRubyMethod(name = "supported_data_types")
1284
1145
  public IRubyObject supported_data_types(final ThreadContext context) throws SQLException {
1285
1146
  final Connection connection = getConnection(true);
@@ -1303,12 +1164,10 @@ public class RubyJdbcConnection extends RubyObject {
1303
1164
  protected static final int PRIMARY_KEYS_COLUMN_NAME = 4;
1304
1165
 
1305
1166
  private List<RubyString> primaryKeys(final ThreadContext context, final String tableName) {
1306
- return withConnection(context, new Callable<List<RubyString>>() {
1307
- public List<RubyString> call(final Connection connection) throws SQLException {
1308
- final String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1309
- final TableName table = extractTableName(connection, null, null, _tableName);
1310
- return primaryKeys(context, connection, table);
1311
- }
1167
+ return withConnection(context, connection -> {
1168
+ final String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1169
+ final TableName table = extractTableName(connection, null, null, _tableName);
1170
+ return primaryKeys(context, connection, table);
1312
1171
  });
1313
1172
  }
1314
1173
 
@@ -1316,7 +1175,7 @@ public class RubyJdbcConnection extends RubyObject {
1316
1175
  final Connection connection, final TableName table) throws SQLException {
1317
1176
  final DatabaseMetaData metaData = connection.getMetaData();
1318
1177
  ResultSet resultSet = null;
1319
- final List<RubyString> keyNames = new ArrayList<RubyString>();
1178
+ final List<RubyString> keyNames = new ArrayList<>();
1320
1179
  try {
1321
1180
  resultSet = metaData.getPrimaryKeys(table.catalog, table.schema, table.name);
1322
1181
  final Ruby runtime = context.runtime;
@@ -1330,26 +1189,6 @@ public class RubyJdbcConnection extends RubyObject {
1330
1189
  return keyNames;
1331
1190
  }
1332
1191
 
1333
- @Deprecated //@JRubyMethod(name = "tables")
1334
- public IRubyObject tables(ThreadContext context) {
1335
- return tables(context, null, null, null, TABLE_TYPE);
1336
- }
1337
-
1338
- @Deprecated //@JRubyMethod(name = "tables")
1339
- public IRubyObject tables(ThreadContext context, IRubyObject catalog) {
1340
- return tables(context, toStringOrNull(catalog), null, null, TABLE_TYPE);
1341
- }
1342
-
1343
- @Deprecated //@JRubyMethod(name = "tables")
1344
- public IRubyObject tables(ThreadContext context, IRubyObject catalog, IRubyObject schemaPattern) {
1345
- return tables(context, toStringOrNull(catalog), toStringOrNull(schemaPattern), null, TABLE_TYPE);
1346
- }
1347
-
1348
- @Deprecated //@JRubyMethod(name = "tables")
1349
- public IRubyObject tables(ThreadContext context, IRubyObject catalog, IRubyObject schemaPattern, IRubyObject tablePattern) {
1350
- return tables(context, toStringOrNull(catalog), toStringOrNull(schemaPattern), toStringOrNull(tablePattern), TABLE_TYPE);
1351
- }
1352
-
1353
1192
  @JRubyMethod(name = "tables", required = 0, optional = 4)
1354
1193
  public IRubyObject tables(final ThreadContext context, final IRubyObject[] args) {
1355
1194
  switch ( args.length ) {
@@ -1367,11 +1206,7 @@ public class RubyJdbcConnection extends RubyObject {
1367
1206
 
1368
1207
  protected IRubyObject tables(final ThreadContext context,
1369
1208
  final String catalog, final String schemaPattern, final String tablePattern, final String[] types) {
1370
- return withConnection(context, new Callable<IRubyObject>() {
1371
- public IRubyObject call(final Connection connection) throws SQLException {
1372
- return matchTables(context, connection, catalog, schemaPattern, tablePattern, types, false);
1373
- }
1374
- });
1209
+ return withConnection(context, connection -> matchTables(context, connection, catalog, schemaPattern, tablePattern, types, false));
1375
1210
  }
1376
1211
 
1377
1212
  protected String[] getTableTypes() {
@@ -1401,40 +1236,36 @@ public class RubyJdbcConnection extends RubyObject {
1401
1236
 
1402
1237
  protected IRubyObject tableExists(final ThreadContext context,
1403
1238
  final String defaultSchema, final String tableName) {
1404
- return withConnection(context, new Callable<RubyBoolean>() {
1405
- public RubyBoolean call(final Connection connection) throws SQLException {
1406
- final TableName components = extractTableName(connection, defaultSchema, tableName);
1407
- return context.runtime.newBoolean( tableExists(context, connection, components) );
1408
- }
1239
+ return withConnection(context, connection -> {
1240
+ final TableName components = extractTableName(connection, defaultSchema, tableName);
1241
+ return context.runtime.newBoolean( tableExists(context, connection, components) );
1409
1242
  });
1410
1243
  }
1411
1244
 
1412
1245
  @JRubyMethod(name = {"columns", "columns_internal"}, required = 1, optional = 2)
1413
1246
  public RubyArray columns_internal(final ThreadContext context, final IRubyObject[] args)
1414
1247
  throws SQLException {
1415
- return withConnection(context, new Callable<RubyArray>() {
1416
- public RubyArray call(final Connection connection) throws SQLException {
1417
- ResultSet columns = null;
1418
- try {
1419
- final String tableName = args[0].toString();
1420
- // optionals (NOTE: catalog argumnet was never used before 1.3.0) :
1421
- final String catalog = args.length > 1 ? toStringOrNull(args[1]) : null;
1422
- final String defaultSchema = args.length > 2 ? toStringOrNull(args[2]) : null;
1423
-
1424
- final TableName components;
1425
- components = extractTableName(connection, catalog, defaultSchema, tableName);
1248
+ return withConnection(context, connection -> {
1249
+ ResultSet columns = null;
1250
+ try {
1251
+ final String tableName = args[0].toString();
1252
+ // optionals (NOTE: catalog argumnet was never used before 1.3.0) :
1253
+ final String catalog = args.length > 1 ? toStringOrNull(args[1]) : null;
1254
+ final String defaultSchema = args.length > 2 ? toStringOrNull(args[2]) : null;
1426
1255
 
1427
- if ( ! tableExists(context, connection, components) ) {
1428
- throw new SQLException("table: " + tableName + " does not exist");
1429
- }
1256
+ final TableName components;
1257
+ components = extractTableName(connection, catalog, defaultSchema, tableName);
1430
1258
 
1431
- final DatabaseMetaData metaData = connection.getMetaData();
1432
- columns = metaData.getColumns(components.catalog, components.schema, components.name, null);
1433
- return mapColumnsResult(context, metaData, components, columns);
1434
- }
1435
- finally {
1436
- close(columns);
1259
+ if ( ! tableExists(context, connection, components) ) {
1260
+ throw new SQLException("table: " + tableName + " does not exist");
1437
1261
  }
1262
+
1263
+ final DatabaseMetaData metaData = connection.getMetaData();
1264
+ columns = metaData.getColumns(components.catalog, components.schema, components.name, null);
1265
+ return mapColumnsResult(context, metaData, components, columns);
1266
+ }
1267
+ finally {
1268
+ close(columns);
1438
1269
  }
1439
1270
  });
1440
1271
  }
@@ -1464,70 +1295,68 @@ public class RubyJdbcConnection extends RubyObject {
1464
1295
  * should filter the return from this method instead.
1465
1296
  */
1466
1297
  protected IRubyObject indexes(final ThreadContext context, final String tableName, final String name, final String schemaName) {
1467
- return withConnection(context, new Callable<IRubyObject>() {
1468
- public IRubyObject call(final Connection connection) throws SQLException {
1469
- final Ruby runtime = context.runtime;
1470
- final RubyClass IndexDefinition = getIndexDefinition(context);
1298
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1299
+ final Ruby runtime = context.runtime;
1300
+ final RubyClass IndexDefinition = getIndexDefinition(context);
1471
1301
 
1472
- String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1473
- String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1474
- final TableName table = extractTableName(connection, null, _schemaName, _tableName);
1302
+ String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1303
+ String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1304
+ final TableName table = extractTableName(connection, null, _schemaName, _tableName);
1475
1305
 
1476
- final List<RubyString> primaryKeys = primaryKeys(context, connection, table);
1306
+ final List<RubyString> primaryKeys = primaryKeys(context, connection, table);
1477
1307
 
1478
- ResultSet indexInfoSet = null;
1479
- final RubyArray indexes = RubyArray.newArray(runtime, 8);
1480
- try {
1481
- final DatabaseMetaData metaData = connection.getMetaData();
1482
- indexInfoSet = metaData.getIndexInfo(table.catalog, table.schema, table.name, false, true);
1483
- String currentIndex = null;
1484
-
1485
- while ( indexInfoSet.next() ) {
1486
- String indexName = indexInfoSet.getString(INDEX_INFO_NAME);
1487
- if ( indexName == null ) continue;
1488
- RubyArray currentColumns = null;
1308
+ ResultSet indexInfoSet = null;
1309
+ final RubyArray indexes = RubyArray.newArray(runtime, 8);
1310
+ try {
1311
+ final DatabaseMetaData metaData = connection.getMetaData();
1312
+ indexInfoSet = metaData.getIndexInfo(table.catalog, table.schema, table.name, false, true);
1313
+ String currentIndex = null;
1489
1314
 
1490
- indexName = caseConvertIdentifierForRails(metaData, indexName);
1315
+ while ( indexInfoSet.next() ) {
1316
+ String indexName = indexInfoSet.getString(INDEX_INFO_NAME);
1317
+ if ( indexName == null ) continue;
1318
+ RubyArray currentColumns = null;
1491
1319
 
1492
- final String columnName = indexInfoSet.getString(INDEX_INFO_COLUMN_NAME);
1493
- final RubyString rubyColumnName = cachedString(
1494
- context, caseConvertIdentifierForRails(metaData, columnName)
1495
- );
1496
- if ( primaryKeys.contains(rubyColumnName) ) continue;
1320
+ indexName = caseConvertIdentifierForRails(metaData, indexName);
1497
1321
 
1498
- // We are working on a new index
1499
- if ( ! indexName.equals(currentIndex) ) {
1500
- currentIndex = indexName;
1322
+ final String columnName = indexInfoSet.getString(INDEX_INFO_COLUMN_NAME);
1323
+ final RubyString rubyColumnName = cachedString(
1324
+ context, caseConvertIdentifierForRails(metaData, columnName)
1325
+ );
1326
+ if ( primaryKeys.contains(rubyColumnName) ) continue;
1501
1327
 
1502
- String indexTableName = indexInfoSet.getString(INDEX_INFO_TABLE_NAME);
1503
- indexTableName = caseConvertIdentifierForRails(metaData, indexTableName);
1328
+ // We are working on a new index
1329
+ if ( ! indexName.equals(currentIndex) ) {
1330
+ currentIndex = indexName;
1504
1331
 
1505
- final boolean nonUnique = indexInfoSet.getBoolean(INDEX_INFO_NON_UNIQUE);
1332
+ String indexTableName = indexInfoSet.getString(INDEX_INFO_TABLE_NAME);
1333
+ indexTableName = caseConvertIdentifierForRails(metaData, indexTableName);
1506
1334
 
1507
- IRubyObject[] args = new IRubyObject[] {
1508
- cachedString(context, indexTableName), // table_name
1509
- cachedString(context, indexName), // index_name
1510
- nonUnique ? runtime.getFalse() : runtime.getTrue(), // unique
1511
- currentColumns = RubyArray.newArray(runtime, 4) // [] column names
1512
- // orders, (since AR 3.2) where, type, using (AR 4.0)
1513
- };
1335
+ final boolean nonUnique = indexInfoSet.getBoolean(INDEX_INFO_NON_UNIQUE);
1514
1336
 
1515
- indexes.append( IndexDefinition.newInstance(context, args, Block.NULL_BLOCK) ); // IndexDefinition.new
1516
- }
1337
+ IRubyObject[] args = new IRubyObject[] {
1338
+ cachedString(context, indexTableName), // table_name
1339
+ cachedString(context, indexName), // index_name
1340
+ nonUnique ? context.fals : context.tru, // unique
1341
+ currentColumns = RubyArray.newArray(runtime, 4) // [] column names
1342
+ // orders, (since AR 3.2) where, type, using (AR 4.0)
1343
+ };
1517
1344
 
1518
- // one or more columns can be associated with an index
1519
- if ( currentColumns != null ) currentColumns.append(rubyColumnName);
1345
+ indexes.append( IndexDefinition.newInstance(context, args, Block.NULL_BLOCK) ); // IndexDefinition.new
1520
1346
  }
1521
1347
 
1522
- return indexes;
1348
+ // one or more columns can be associated with an index
1349
+ if ( currentColumns != null ) currentColumns.append(rubyColumnName);
1350
+ }
1351
+
1352
+ return indexes;
1523
1353
 
1524
- } finally { close(indexInfoSet); }
1525
- }
1354
+ } finally { close(indexInfoSet); }
1526
1355
  });
1527
1356
  }
1528
1357
 
1529
1358
  protected RubyClass getIndexDefinition(final ThreadContext context) {
1530
- final RubyClass adapterClass = getAdapter().getMetaClass();
1359
+ final RubyClass adapterClass = adapter.getMetaClass();
1531
1360
  IRubyObject IDef = adapterClass.getConstantAt("IndexDefinition");
1532
1361
  return IDef != null ? (RubyClass) IDef : getIndexDefinition(context.runtime);
1533
1362
  }
@@ -1538,57 +1367,55 @@ public class RubyJdbcConnection extends RubyObject {
1538
1367
  }
1539
1368
 
1540
1369
  protected IRubyObject foreignKeys(final ThreadContext context, final String tableName, final String schemaName, final String catalog) {
1541
- return withConnection(context, new Callable<IRubyObject>() {
1542
- public IRubyObject call(final Connection connection) throws SQLException {
1543
- final Ruby runtime = context.runtime;
1544
- final RubyClass FKDefinition = getForeignKeyDefinition(context);
1370
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1371
+ final Ruby runtime = context.runtime;
1372
+ final RubyClass FKDefinition = getForeignKeyDefinition(context);
1545
1373
 
1546
- String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1547
- String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1548
- final TableName table = extractTableName(connection, catalog, _schemaName, _tableName);
1374
+ String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1375
+ String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1376
+ final TableName table = extractTableName(connection, catalog, _schemaName, _tableName);
1549
1377
 
1550
- ResultSet fkInfoSet = null;
1551
- final List<IRubyObject> fKeys = new ArrayList<IRubyObject>(8);
1552
- try {
1553
- final DatabaseMetaData metaData = connection.getMetaData();
1554
- fkInfoSet = metaData.getImportedKeys(table.catalog, table.schema, table.name);
1378
+ ResultSet fkInfoSet = null;
1379
+ final List<IRubyObject> fKeys = new ArrayList<>(8);
1380
+ try {
1381
+ final DatabaseMetaData metaData = connection.getMetaData();
1382
+ fkInfoSet = metaData.getImportedKeys(table.catalog, table.schema, table.name);
1555
1383
 
1556
- while ( fkInfoSet.next() ) {
1557
- final RubyHash options = RubyHash.newHash(runtime);
1384
+ while ( fkInfoSet.next() ) {
1385
+ final RubyHash options = RubyHash.newHash(runtime);
1558
1386
 
1559
- String fkName = fkInfoSet.getString("FK_NAME");
1560
- if (fkName != null) {
1561
- fkName = caseConvertIdentifierForRails(metaData, fkName);
1562
- options.put(runtime.newSymbol("name"), fkName);
1563
- }
1387
+ String fkName = fkInfoSet.getString("FK_NAME");
1388
+ if (fkName != null) {
1389
+ fkName = caseConvertIdentifierForRails(metaData, fkName);
1390
+ options.put(runtime.newSymbol("name"), fkName);
1391
+ }
1564
1392
 
1565
- String columnName = fkInfoSet.getString("FKCOLUMN_NAME");
1566
- options.put(runtime.newSymbol("column"), caseConvertIdentifierForRails(metaData, columnName));
1393
+ String columnName = fkInfoSet.getString("FKCOLUMN_NAME");
1394
+ options.put(runtime.newSymbol("column"), caseConvertIdentifierForRails(metaData, columnName));
1567
1395
 
1568
- columnName = fkInfoSet.getString("PKCOLUMN_NAME");
1569
- options.put(runtime.newSymbol("primary_key"), caseConvertIdentifierForRails(metaData, columnName));
1396
+ columnName = fkInfoSet.getString("PKCOLUMN_NAME");
1397
+ options.put(runtime.newSymbol("primary_key"), caseConvertIdentifierForRails(metaData, columnName));
1570
1398
 
1571
- String fkTableName = fkInfoSet.getString("FKTABLE_NAME");
1572
- fkTableName = caseConvertIdentifierForRails(metaData, fkTableName);
1399
+ String fkTableName = fkInfoSet.getString("FKTABLE_NAME");
1400
+ fkTableName = caseConvertIdentifierForRails(metaData, fkTableName);
1573
1401
 
1574
- String pkTableName = fkInfoSet.getString("PKTABLE_NAME");
1575
- pkTableName = caseConvertIdentifierForRails(metaData, pkTableName);
1402
+ String pkTableName = fkInfoSet.getString("PKTABLE_NAME");
1403
+ pkTableName = caseConvertIdentifierForRails(metaData, pkTableName);
1576
1404
 
1577
- final String onDelete = extractForeignKeyRule( fkInfoSet.getInt("DELETE_RULE") );
1578
- if ( onDelete != null ) options.op_aset(context, runtime.newSymbol("on_delete"), runtime.newSymbol(onDelete));
1405
+ final String onDelete = extractForeignKeyRule( fkInfoSet.getInt("DELETE_RULE") );
1406
+ if ( onDelete != null ) options.op_aset(context, runtime.newSymbol("on_delete"), runtime.newSymbol(onDelete));
1579
1407
 
1580
- final String onUpdate = extractForeignKeyRule( fkInfoSet.getInt("UPDATE_RULE") );
1581
- if ( onUpdate != null ) options.op_aset(context, runtime.newSymbol("on_update"), runtime.newSymbol(onUpdate));
1408
+ final String onUpdate = extractForeignKeyRule( fkInfoSet.getInt("UPDATE_RULE") );
1409
+ if ( onUpdate != null ) options.op_aset(context, runtime.newSymbol("on_update"), runtime.newSymbol(onUpdate));
1582
1410
 
1583
- IRubyObject from_table = cachedString(context, fkTableName);
1584
- IRubyObject to_table = cachedString(context, pkTableName);
1585
- fKeys.add( FKDefinition.newInstance(context, from_table, to_table, options, Block.NULL_BLOCK) ); // ForeignKeyDefinition.new
1586
- }
1411
+ IRubyObject from_table = cachedString(context, fkTableName);
1412
+ IRubyObject to_table = cachedString(context, pkTableName);
1413
+ fKeys.add( FKDefinition.newInstance(context, from_table, to_table, options, Block.NULL_BLOCK) ); // ForeignKeyDefinition.new
1414
+ }
1587
1415
 
1588
- return runtime.newArray(fKeys);
1416
+ return runtime.newArray(fKeys);
1589
1417
 
1590
- } finally { close(fkInfoSet); }
1591
- }
1418
+ } finally { close(fkInfoSet); }
1592
1419
  });
1593
1420
  }
1594
1421
 
@@ -1603,7 +1430,7 @@ public class RubyJdbcConnection extends RubyObject {
1603
1430
  }
1604
1431
 
1605
1432
  protected RubyClass getForeignKeyDefinition(final ThreadContext context) {
1606
- final RubyClass adapterClass = getAdapter().getMetaClass();
1433
+ final RubyClass adapterClass = adapter.getMetaClass();
1607
1434
  IRubyObject FKDef = adapterClass.getConstantAt("ForeignKeyDefinition");
1608
1435
  return FKDef != null ? (RubyClass) FKDef : getForeignKeyDefinition(context.runtime);
1609
1436
  }
@@ -1611,42 +1438,34 @@ public class RubyJdbcConnection extends RubyObject {
1611
1438
 
1612
1439
  @JRubyMethod(name = "supports_foreign_keys?")
1613
1440
  public IRubyObject supports_foreign_keys_p(final ThreadContext context) throws SQLException {
1614
- return withConnection(context, new Callable<IRubyObject>() {
1615
- public IRubyObject call(final Connection connection) throws SQLException {
1616
- final DatabaseMetaData metaData = connection.getMetaData();
1617
- return context.runtime.newBoolean( metaData.supportsIntegrityEnhancementFacility() );
1618
- }
1441
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1442
+ final DatabaseMetaData metaData = connection.getMetaData();
1443
+ return context.runtime.newBoolean( metaData.supportsIntegrityEnhancementFacility() );
1619
1444
  });
1620
1445
  }
1621
1446
 
1622
1447
  @JRubyMethod(name = "supports_views?")
1623
1448
  public IRubyObject supports_views_p(final ThreadContext context) throws SQLException {
1624
- return withConnection(context, new Callable<IRubyObject>() {
1625
- public IRubyObject call(final Connection connection) throws SQLException {
1626
- final DatabaseMetaData metaData = connection.getMetaData();
1627
- final ResultSet tableTypes = metaData.getTableTypes();
1628
- try {
1629
- while ( tableTypes.next() ) {
1630
- if ( "VIEW".equalsIgnoreCase( tableTypes.getString(1) ) ) {
1631
- return context.runtime.newBoolean( true );
1632
- }
1449
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1450
+ final DatabaseMetaData metaData = connection.getMetaData();
1451
+ final ResultSet tableTypes = metaData.getTableTypes();
1452
+ try {
1453
+ while ( tableTypes.next() ) {
1454
+ if ( "VIEW".equalsIgnoreCase( tableTypes.getString(1) ) ) {
1455
+ return context.runtime.newBoolean( true );
1633
1456
  }
1634
1457
  }
1635
- finally {
1636
- close(tableTypes);
1637
- }
1638
- return context.runtime.newBoolean( false );
1639
1458
  }
1459
+ finally {
1460
+ close(tableTypes);
1461
+ }
1462
+ return context.runtime.newBoolean( false );
1640
1463
  });
1641
1464
  }
1642
1465
 
1643
1466
  @JRubyMethod(name = "with_jdbc_connection", alias = "with_connection_retry_guard", frame = true)
1644
1467
  public IRubyObject with_jdbc_connection(final ThreadContext context, final Block block) {
1645
- return withConnection(context, new Callable<IRubyObject>() {
1646
- public IRubyObject call(final Connection connection) throws SQLException {
1647
- return block.call(context, convertJavaToRuby(connection));
1648
- }
1649
- });
1468
+ return withConnection(context, connection -> block.call(context, convertJavaToRuby(connection)));
1650
1469
  }
1651
1470
 
1652
1471
  /*
@@ -1707,24 +1526,22 @@ public class RubyJdbcConnection extends RubyObject {
1707
1526
  // TODO: Fix this, the columns don't have the info needed to handle this anymore
1708
1527
  // currently commented out so that it will compile
1709
1528
 
1710
- return withConnection(context, new Callable<Integer>() {
1711
- public Integer call(final Connection connection) throws SQLException {
1712
- PreparedStatement statement = null;
1713
- try {
1714
- statement = connection.prepareStatement(sql);
1715
- /*
1716
- if ( binary ) { // blob
1717
- setBlobParameter(context, connection, statement, 1, value, column, Types.BLOB);
1718
- }
1719
- else { // clob
1720
- setClobParameter(context, connection, statement, 1, value, column, Types.CLOB);
1721
- }
1722
- setStatementParameter(context, context.runtime, connection, statement, 2, idValue, idColumn);
1723
- */
1724
- return statement.executeUpdate();
1529
+ return withConnection(context, connection -> {
1530
+ PreparedStatement statement = null;
1531
+ try {
1532
+ statement = connection.prepareStatement(sql);
1533
+ /*
1534
+ if ( binary ) { // blob
1535
+ setBlobParameter(context, connection, statement, 1, value, column, Types.BLOB);
1725
1536
  }
1726
- finally { close(statement); }
1537
+ else { // clob
1538
+ setClobParameter(context, connection, statement, 1, value, column, Types.CLOB);
1539
+ }
1540
+ setStatementParameter(context, context.runtime, connection, statement, 2, idValue, idColumn);
1541
+ */
1542
+ return statement.executeUpdate();
1727
1543
  }
1544
+ finally { close(statement); }
1728
1545
  });
1729
1546
  }
1730
1547
 
@@ -1780,7 +1597,7 @@ public class RubyJdbcConnection extends RubyObject {
1780
1597
  final IRubyObject self, final IRubyObject config, final Block block) {
1781
1598
  final IRubyObject ds_or_name = rawDataSourceOrName(context, config);
1782
1599
 
1783
- if ( ds_or_name == null ) return context.runtime.getFalse();
1600
+ if ( ds_or_name == null ) return context.fals;
1784
1601
 
1785
1602
  final javax.sql.DataSource dataSource;
1786
1603
  final Object dsOrName = ds_or_name.toJava(Object.class);
@@ -1836,7 +1653,7 @@ public class RubyJdbcConnection extends RubyObject {
1836
1653
  }
1837
1654
  }
1838
1655
 
1839
- if ( configValue == null || configValue == context.nil || configValue == runtime.getFalse() ) {
1656
+ if ( configValue == null || configValue == context.nil || configValue == context.fals ) {
1840
1657
  return null;
1841
1658
  }
1842
1659
  return configValue;
@@ -1859,13 +1676,6 @@ public class RubyJdbcConnection extends RubyObject {
1859
1676
  }
1860
1677
  }
1861
1678
 
1862
- @Deprecated
1863
- @JRubyMethod(name = "setup_jdbc_factory", visibility = Visibility.PROTECTED)
1864
- public IRubyObject set_driver_factory(final ThreadContext context) {
1865
- setDriverFactory(context);
1866
- return get_connection_factory(context.runtime);
1867
- }
1868
-
1869
1679
  private ConnectionFactory setDriverFactory(final ThreadContext context) {
1870
1680
 
1871
1681
  final IRubyObject url = getConfigValue(context, "url");
@@ -1965,12 +1775,6 @@ public class RubyJdbcConnection extends RubyObject {
1965
1775
  return props;
1966
1776
  }
1967
1777
 
1968
- @JRubyMethod(name = "setup_jndi_factory", visibility = Visibility.PROTECTED)
1969
- public IRubyObject set_data_source_factory(final ThreadContext context) {
1970
- setDataSourceFactory(context);
1971
- return get_connection_factory(context.runtime);
1972
- }
1973
-
1974
1778
  private ConnectionFactory setDataSourceFactory(final ThreadContext context) {
1975
1779
  final javax.sql.DataSource dataSource; final String lookupName;
1976
1780
  IRubyObject value = getConfigValue(context, "data_source");
@@ -1992,28 +1796,10 @@ public class RubyJdbcConnection extends RubyObject {
1992
1796
  private static volatile boolean defaultConfigJndi;
1993
1797
  private static transient ConnectionFactory defaultConnectionFactory;
1994
1798
 
1995
- /**
1996
- * Sets the connection factory from the available configuration.
1997
- * @param context
1998
- * @see #initialize
1999
- */
2000
- @Deprecated
2001
- @JRubyMethod(name = "setup_connection_factory", visibility = Visibility.PROTECTED)
2002
- public IRubyObject setup_connection_factory(final ThreadContext context) {
2003
- setupConnectionFactory(context);
2004
- return get_connection_factory(context.runtime);
2005
- }
2006
-
2007
- private IRubyObject get_connection_factory(final Ruby runtime) {
2008
- return JavaUtil.convertJavaToRuby(runtime, connectionFactory);
2009
- }
2010
-
2011
1799
  /**
2012
1800
  * @return whether the connection factory is JNDI based
2013
1801
  */
2014
1802
  private boolean setupConnectionFactory(final ThreadContext context) {
2015
- final IRubyObject config = getConfig();
2016
-
2017
1803
  if ( defaultConfig == null ) {
2018
1804
  synchronized(RubyJdbcConnection.class) {
2019
1805
  if ( defaultConfig == null ) {
@@ -2045,18 +1831,17 @@ public class RubyJdbcConnection extends RubyObject {
2045
1831
 
2046
1832
  @JRubyMethod(name = "jndi?", alias = "jndi_connection?")
2047
1833
  public RubyBoolean jndi_p(final ThreadContext context) {
2048
- return context.runtime.newBoolean( isJndi() );
1834
+ return context.runtime.newBoolean(jndi);
2049
1835
  }
2050
1836
 
2051
1837
  protected boolean isJndi() { return this.jndi; }
2052
1838
 
2053
1839
  @JRubyMethod(name = "config")
2054
- public IRubyObject config() { return getConfig(); }
1840
+ public IRubyObject config() { return config; }
2055
1841
 
2056
1842
  public IRubyObject getConfig() { return this.config; }
2057
1843
 
2058
1844
  protected final IRubyObject getConfigValue(final ThreadContext context, final String key) {
2059
- final IRubyObject config = getConfig();
2060
1845
  final RubySymbol keySym = context.runtime.newSymbol(key);
2061
1846
  if ( config instanceof RubyHash ) {
2062
1847
  final IRubyObject value = ((RubyHash) config).fastARef(keySym);
@@ -2067,7 +1852,6 @@ public class RubyJdbcConnection extends RubyObject {
2067
1852
 
2068
1853
  protected final IRubyObject setConfigValue(final ThreadContext context,
2069
1854
  final String key, final IRubyObject value) {
2070
- final IRubyObject config = getConfig();
2071
1855
  final RubySymbol keySym = context.runtime.newSymbol(key);
2072
1856
  if ( config instanceof RubyHash ) {
2073
1857
  return ((RubyHash) config).op_aset(context, keySym, value);
@@ -2077,7 +1861,6 @@ public class RubyJdbcConnection extends RubyObject {
2077
1861
 
2078
1862
  protected final IRubyObject setConfigValueIfNotSet(final ThreadContext context,
2079
1863
  final String key, final IRubyObject value) {
2080
- final IRubyObject config = getConfig();
2081
1864
  final RubySymbol keySym = context.runtime.newSymbol(key);
2082
1865
  if ( config instanceof RubyHash ) {
2083
1866
  final IRubyObject setValue = ((RubyHash) config).fastARef(keySym);
@@ -2097,7 +1880,7 @@ public class RubyJdbcConnection extends RubyObject {
2097
1880
  protected final IRubyObject getAdapter() { return this.adapter; }
2098
1881
 
2099
1882
  protected RubyClass getJdbcColumnClass(final ThreadContext context) {
2100
- return (RubyClass) getAdapter().callMethod(context, "jdbc_column_class");
1883
+ return (RubyClass) adapter.callMethod(context, "jdbc_column_class");
2101
1884
  }
2102
1885
 
2103
1886
  protected ConnectionFactory getConnectionFactory() throws RaiseException {
@@ -2309,7 +2092,7 @@ public class RubyJdbcConnection extends RubyObject {
2309
2092
  @JRubyMethod(name = "raw_date_time?", meta = true)
2310
2093
  public static IRubyObject useRawDateTime(final ThreadContext context, final IRubyObject self) {
2311
2094
  if ( rawDateTime == null ) return context.nil;
2312
- return context.runtime.newBoolean( rawDateTime.booleanValue() );
2095
+ return context.runtime.newBoolean(rawDateTime);
2313
2096
  }
2314
2097
 
2315
2098
  @JRubyMethod(name = "raw_date_time=", meta = true)
@@ -2323,17 +2106,6 @@ public class RubyJdbcConnection extends RubyObject {
2323
2106
  return value;
2324
2107
  }
2325
2108
 
2326
- /**
2327
- * @return AR::Type-casted value
2328
- * @since 1.3.18
2329
- */
2330
- @Deprecated
2331
- protected static IRubyObject typeCastFromDatabase(final ThreadContext context,
2332
- final IRubyObject adapter, final RubySymbol typeName, final RubyString value) {
2333
- final IRubyObject type = adapter.callMethod(context, "lookup_cast_type", typeName);
2334
- return type.callMethod(context, "deserialize", value);
2335
- }
2336
-
2337
2109
  protected IRubyObject dateToRuby(final ThreadContext context,
2338
2110
  final Ruby runtime, final ResultSet resultSet, final int column)
2339
2111
  throws SQLException {
@@ -2344,11 +2116,11 @@ public class RubyJdbcConnection extends RubyObject {
2344
2116
  return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
2345
2117
  }
2346
2118
 
2347
- if ( rawDateTime != null && rawDateTime.booleanValue() ) {
2119
+ if ( rawDateTime != null && rawDateTime) {
2348
2120
  return RubyString.newString(runtime, DateTimeUtils.dateToString(value));
2349
2121
  }
2350
2122
 
2351
- return DateTimeUtils.newDateAsTime(context, value, DateTimeZone.UTC).callMethod(context, "to_date");
2123
+ return DateTimeUtils.newDateAsTime(context, value, null).callMethod(context, "to_date");
2352
2124
  }
2353
2125
 
2354
2126
  protected IRubyObject timeToRuby(final ThreadContext context,
@@ -2360,7 +2132,7 @@ public class RubyJdbcConnection extends RubyObject {
2360
2132
  return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
2361
2133
  }
2362
2134
 
2363
- if ( rawDateTime != null && rawDateTime.booleanValue() ) {
2135
+ if ( rawDateTime != null && rawDateTime) {
2364
2136
  return RubyString.newString(runtime, DateTimeUtils.timeToString(value));
2365
2137
  }
2366
2138
 
@@ -2376,7 +2148,7 @@ public class RubyJdbcConnection extends RubyObject {
2376
2148
  return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
2377
2149
  }
2378
2150
 
2379
- if ( rawDateTime != null && rawDateTime.booleanValue() ) {
2151
+ if ( rawDateTime != null && rawDateTime) {
2380
2152
  return RubyString.newString(runtime, DateTimeUtils.timestampToString(value));
2381
2153
  }
2382
2154
 
@@ -2388,19 +2160,6 @@ public class RubyJdbcConnection extends RubyObject {
2388
2160
  return DateTimeUtils.newTime(context, value, getDefaultTimeZone(context));
2389
2161
  }
2390
2162
 
2391
- @Deprecated
2392
- protected static RubyString timestampToRubyString(final Ruby runtime, String value) {
2393
- // Timestamp's format: yyyy-mm-dd hh:mm:ss.fffffffff
2394
- String suffix; // assumes java.sql.Timestamp internals :
2395
- if ( value.endsWith( suffix = " 00:00:00.0" ) ) {
2396
- value = value.substring( 0, value.length() - suffix.length() );
2397
- }
2398
- else if ( value.endsWith( suffix = ".0" ) ) {
2399
- value = value.substring( 0, value.length() - suffix.length() );
2400
- }
2401
- return RubyString.newUnicodeString(runtime, value);
2402
- }
2403
-
2404
2163
  protected static Boolean rawBoolean;
2405
2164
  static {
2406
2165
  final String booleanRaw = SafePropertyAccessor.getProperty("arjdbc.boolean.raw");
@@ -2412,7 +2171,7 @@ public class RubyJdbcConnection extends RubyObject {
2412
2171
  @JRubyMethod(name = "raw_boolean?", meta = true)
2413
2172
  public static IRubyObject useRawBoolean(final ThreadContext context, final IRubyObject self) {
2414
2173
  if ( rawBoolean == null ) return context.nil;
2415
- return context.runtime.newBoolean( rawBoolean.booleanValue() );
2174
+ return context.runtime.newBoolean(rawBoolean);
2416
2175
  }
2417
2176
 
2418
2177
  @JRubyMethod(name = "raw_boolean=", meta = true)
@@ -2444,13 +2203,13 @@ public class RubyJdbcConnection extends RubyObject {
2444
2203
  protected IRubyObject booleanToRuby(final ThreadContext context,
2445
2204
  final Ruby runtime, final ResultSet resultSet, final int column)
2446
2205
  throws SQLException {
2447
- if ( rawBoolean != null && rawBoolean.booleanValue() ) {
2206
+ if ( rawBoolean != null && rawBoolean) {
2448
2207
  final String value = resultSet.getString(column);
2449
2208
  if ( value == null /* && resultSet.wasNull() */ ) return context.nil;
2450
2209
  return RubyString.newUnicodeString(runtime, value);
2451
2210
  }
2452
2211
  final boolean value = resultSet.getBoolean(column);
2453
- if ( value == false && resultSet.wasNull() ) return context.nil;
2212
+ if (!value && resultSet.wasNull()) return context.nil;
2454
2213
  return runtime.newBoolean(value);
2455
2214
  }
2456
2215
 
@@ -2668,7 +2427,7 @@ public class RubyJdbcConnection extends RubyObject {
2668
2427
  }
2669
2428
  }
2670
2429
 
2671
- protected static final Map<String, Integer> JDBC_TYPE_FOR = new HashMap<String, Integer>(32, 1);
2430
+ protected static final Map<String, Integer> JDBC_TYPE_FOR = new HashMap<>(32, 1);
2672
2431
  static {
2673
2432
  JDBC_TYPE_FOR.put("string", Types.VARCHAR);
2674
2433
  JDBC_TYPE_FOR.put("text", Types.CLOB);
@@ -2710,7 +2469,7 @@ public class RubyJdbcConnection extends RubyObject {
2710
2469
  final String internedType = internedTypeFor(context, attribute);
2711
2470
  final Integer sqlType = jdbcTypeFor(internedType);
2712
2471
  if ( sqlType != null ) {
2713
- return sqlType.intValue();
2472
+ return sqlType;
2714
2473
  }
2715
2474
 
2716
2475
  return Types.OTHER; // -1 as well as 0 are used in Types
@@ -2888,11 +2647,6 @@ public class RubyJdbcConnection extends RubyObject {
2888
2647
  statement.setTimestamp(index, timestamp, getCalendar(dateTime.getZone()));
2889
2648
  }
2890
2649
 
2891
- @Deprecated
2892
- protected static Timestamp convertToTimestamp(final RubyFloat value) {
2893
- return DateTimeUtils.convertToTimestamp(value);
2894
- }
2895
-
2896
2650
  protected static Calendar getCalendar(final DateTimeZone zone) { // final java.util.Date hint
2897
2651
  if (DateTimeZone.UTC == zone) return getCalendarUTC();
2898
2652
  if (DateTimeZone.getDefault() == zone) return new GregorianCalendar();
@@ -2938,6 +2692,12 @@ public class RubyJdbcConnection extends RubyObject {
2938
2692
  value = value.callMethod(context, "to_date");
2939
2693
  }
2940
2694
 
2695
+ if (value instanceof RubyDate) {
2696
+ RubyDate rubyDate = (RubyDate) value;
2697
+ statement.setDate(index, rubyDate.toJava(Date.class));
2698
+ return;
2699
+ }
2700
+
2941
2701
  // NOTE: assuming Date#to_s does right ...
2942
2702
  statement.setDate(index, Date.valueOf(value.toString()));
2943
2703
  }
@@ -2976,7 +2736,7 @@ public class RubyJdbcConnection extends RubyObject {
2976
2736
  // For some reason the driver doesn't like "character varying" as a type
2977
2737
  if ( type.eql(context.runtime.newSymbol("string")) ) return "varchar";
2978
2738
 
2979
- final RubyHash nativeTypes = (RubyHash) getAdapter().callMethod(context, "native_database_types");
2739
+ final RubyHash nativeTypes = (RubyHash) adapter.callMethod(context, "native_database_types");
2980
2740
  // e.g. `integer: { name: 'integer' }`
2981
2741
  final RubyHash typeInfo = (RubyHash) nativeTypes.op_aref(context, type);
2982
2742
 
@@ -3037,16 +2797,7 @@ public class RubyJdbcConnection extends RubyObject {
3037
2797
  }
3038
2798
 
3039
2799
  /**
3040
- * Always returns a connection (might cause a reconnect if there's none).
3041
- * @return connection
3042
- * @throws <code>ActiveRecord::ConnectionNotEstablished</code>, <code>ActiveRecord::JDBCError</code>
3043
- */
3044
- protected Connection getConnection() throws RaiseException {
3045
- return getConnection(false);
3046
- }
3047
-
3048
- /**
3049
- * @see #getConnection()
2800
+ * Returns a connection (might cause a reconnect if there's none).
3050
2801
  * @param required set to true if a connection is required to exists (e.g. on commit)
3051
2802
  * @return connection
3052
2803
  * @throws <code>ActiveRecord::ConnectionNotEstablished</code> if disconnected
@@ -3061,17 +2812,15 @@ public class RubyJdbcConnection extends RubyObject {
3061
2812
  }
3062
2813
  }
3063
2814
 
3064
- private Connection getConnectionInternal(final boolean required) throws SQLException {
2815
+ protected Connection getConnectionInternal(final boolean required) throws SQLException {
3065
2816
  Connection connection = getConnectionImpl();
3066
- if ( connection == null ) {
3067
- if ( required ) {
3068
- if ( ! connected ) handleNotConnected(); // raise ConnectionNotEstablished
3069
- synchronized (this) {
2817
+ if (connection == null && required) {
2818
+ if (!connected) handleNotConnected(); // raise ConnectionNotEstablished
2819
+ synchronized (this) {
2820
+ connection = getConnectionImpl();
2821
+ if ( connection == null ) {
2822
+ connectImpl(true); // throws SQLException
3070
2823
  connection = getConnectionImpl();
3071
- if ( connection == null ) {
3072
- connectImpl( true ); // throws SQLException
3073
- connection = getConnectionImpl();
3074
- }
3075
2824
  }
3076
2825
  }
3077
2826
  }
@@ -3202,7 +2951,7 @@ public class RubyJdbcConnection extends RubyObject {
3202
2951
  try {
3203
2952
  tablesSet = metaData.getTables(catalog, _schemaPattern, _tablePattern, types);
3204
2953
  if ( checkExistsOnly ) { // only check if given table exists
3205
- return tablesSet.next() ? context.runtime.getTrue() : null;
2954
+ return tablesSet.next() ? context.tru : null;
3206
2955
  }
3207
2956
  else {
3208
2957
  return mapTables(context, connection, catalog, _schemaPattern, _tablePattern, tablesSet);
@@ -3211,15 +2960,6 @@ public class RubyJdbcConnection extends RubyObject {
3211
2960
  finally { close(tablesSet); }
3212
2961
  }
3213
2962
 
3214
- @Deprecated
3215
- protected IRubyObject matchTables(final Ruby runtime,
3216
- final Connection connection,
3217
- final String catalog, final String schemaPattern,
3218
- final String tablePattern, final String[] types,
3219
- final boolean checkExistsOnly) throws SQLException {
3220
- return matchTables(runtime.getCurrentContext(), connection, catalog, schemaPattern, tablePattern, types, checkExistsOnly);
3221
- }
3222
-
3223
2963
  // NOTE java.sql.DatabaseMetaData.getTables :
3224
2964
  protected final static int TABLES_TABLE_CAT = 1;
3225
2965
  protected final static int TABLES_TABLE_SCHEM = 2;
@@ -3307,7 +3047,7 @@ public class RubyJdbcConnection extends RubyObject {
3307
3047
  final String tabName = results.getString(TABLE_NAME);
3308
3048
  final RubyString tableName = cachedString(context, caseConvertIdentifierForRails(metaData, tabName));
3309
3049
 
3310
- final IRubyObject type_metadata = getAdapter().callMethod(context, "fetch_type_metadata", sqlType);
3050
+ final IRubyObject type_metadata = adapter.callMethod(context, "fetch_type_metadata", sqlType);
3311
3051
 
3312
3052
  // (name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
3313
3053
  final IRubyObject[] args = new IRubyObject[] {
@@ -3323,7 +3063,7 @@ public class RubyJdbcConnection extends RubyObject {
3323
3063
  ResultSet primaryKeys = null;
3324
3064
  try {
3325
3065
  primaryKeys = metaData.getPrimaryKeys(components.catalog, components.schema, components.name);
3326
- final List<String> primaryKeyNames = new ArrayList<String>(4);
3066
+ final List<String> primaryKeyNames = new ArrayList<>(4);
3327
3067
  while ( primaryKeys.next() ) {
3328
3068
  primaryKeyNames.add( primaryKeys.getString(COLUMN_NAME) );
3329
3069
  }
@@ -3372,7 +3112,7 @@ public class RubyJdbcConnection extends RubyObject {
3372
3112
  // not have and auto-generated ID column :
3373
3113
  boolean next = genKeys.next() && genKeys.getMetaData().getColumnCount() > 0;
3374
3114
  // singleResult == null - guess if only single key returned
3375
- if ( singleResult == null || singleResult.booleanValue() ) {
3115
+ if ( singleResult == null || singleResult) {
3376
3116
  if ( next ) {
3377
3117
  firstKey = mapGeneratedKey(runtime, genKeys);
3378
3118
  if ( singleResult != null || ! genKeys.next() ) {
@@ -3405,7 +3145,7 @@ public class RubyJdbcConnection extends RubyObject {
3405
3145
  if (supportsGeneratedKeys == null) {
3406
3146
  supportsGeneratedKeys = this.supportsGeneratedKeys = connection.getMetaData().supportsGetGeneratedKeys();
3407
3147
  }
3408
- return supportsGeneratedKeys.booleanValue();
3148
+ return supportsGeneratedKeys;
3409
3149
  }
3410
3150
 
3411
3151
  /**
@@ -3437,8 +3177,8 @@ public class RubyJdbcConnection extends RubyObject {
3437
3177
  final ColumnData[] columns = extractColumns(context, connection, resultSet, false);
3438
3178
 
3439
3179
  final Ruby runtime = context.runtime;
3440
- final IRubyObject[] blockArgs = new IRubyObject[columns.length];
3441
3180
  while ( resultSet.next() ) {
3181
+ final IRubyObject[] blockArgs = new IRubyObject[columns.length];
3442
3182
  for ( int i = 0; i < columns.length; i++ ) {
3443
3183
  final ColumnData column = columns[i];
3444
3184
  blockArgs[i] = jdbcToRuby(context, runtime, column.index, column.type, resultSet);
@@ -3464,16 +3204,6 @@ public class RubyJdbcConnection extends RubyObject {
3464
3204
  return setupColumns(context, connection, resultSet.getMetaData(), downCase);
3465
3205
  }
3466
3206
 
3467
- /**
3468
- * @deprecated use {@link #extractColumns(ThreadContext, Connection, ResultSet, boolean)}
3469
- */
3470
- @Deprecated
3471
- protected ColumnData[] extractColumns(final Ruby runtime,
3472
- final Connection connection, final ResultSet resultSet,
3473
- final boolean downCase) throws SQLException {
3474
- return extractColumns(runtime.getCurrentContext(), connection, resultSet, downCase);
3475
- }
3476
-
3477
3207
  protected <T> T withConnection(final ThreadContext context, final Callable<T> block)
3478
3208
  throws RaiseException {
3479
3209
  try {
@@ -3579,13 +3309,12 @@ public class RubyJdbcConnection extends RubyObject {
3579
3309
  }
3580
3310
 
3581
3311
  protected boolean isTransient(final Exception exception) {
3582
- if ( exception instanceof SQLTransientException ) return true;
3583
- return false;
3312
+ return exception instanceof SQLTransientException;
3584
3313
  }
3585
3314
 
3586
3315
  protected boolean isRecoverable(final Exception exception) {
3587
- if ( exception instanceof SQLRecoverableException) return true;
3588
- return false; // exception instanceof SQLException; // pre JDBC 4.0 drivers?
3316
+ return exception instanceof SQLRecoverableException;
3317
+ // exception instanceof SQLException; // pre JDBC 4.0 drivers?
3589
3318
  }
3590
3319
 
3591
3320
  private static Throwable getCause(Throwable exception) {
@@ -3743,6 +3472,11 @@ public class RubyJdbcConnection extends RubyObject {
3743
3472
  return Result.newInstance(context, columnsToArray(context, columns), rows, Block.NULL_BLOCK); // Result.new
3744
3473
  }
3745
3474
 
3475
+ protected static IRubyObject newEmptyResult(final ThreadContext context) {
3476
+ final RubyClass Result = getResult(context.runtime);
3477
+ return Result.newInstance(context, RubyArray.newEmptyArray(context.runtime), RubyArray.newEmptyArray(context.runtime), Block.NULL_BLOCK); // Result.new
3478
+ }
3479
+
3746
3480
  private static RubyArray columnsToArray(ThreadContext context, ColumnData[] columns) {
3747
3481
  final IRubyObject[] cols = new IRubyObject[columns.length];
3748
3482
 
@@ -3995,7 +3729,7 @@ public class RubyJdbcConnection extends RubyObject {
3995
3729
  public static void debugStackTrace(final ThreadContext context, final Throwable e) {
3996
3730
  if ( debug || ( context != null && context.runtime.isDebug() ) ) {
3997
3731
  final PrintStream out = context != null ? context.runtime.getOut() : System.out;
3998
- if ( debugStackTrace == null || debugStackTrace.booleanValue() ) {
3732
+ if ( debugStackTrace == null || debugStackTrace) {
3999
3733
  e.printStackTrace(out);
4000
3734
  }
4001
3735
  else {
@@ -4011,8 +3745,7 @@ public class RubyJdbcConnection extends RubyObject {
4011
3745
  private static boolean driverUsedLogged;
4012
3746
 
4013
3747
  private void logDriverUsed(final Connection connection) {
4014
- if ( isDebug() ) {
4015
- if ( driverUsedLogged ) return;
3748
+ if (debug && !driverUsedLogged) {
4016
3749
  driverUsedLogged = true;
4017
3750
  try {
4018
3751
  final DatabaseMetaData meta = connection.getMetaData();