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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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();