activerecord-jdbc-alt-adapter 52.6.0-java → 60.0.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -2
  3. data/.travis.yml +58 -37
  4. data/Gemfile +9 -2
  5. data/README.md +30 -14
  6. data/Rakefile +1 -1
  7. data/Rakefile.jdbc +8 -1
  8. data/activerecord-jdbc-adapter.gemspec +5 -8
  9. data/activerecord-jdbc-alt-adapter.gemspec +5 -8
  10. data/lib/arel/visitors/sqlserver.rb +33 -23
  11. data/lib/arjdbc/abstract/connection_management.rb +7 -0
  12. data/lib/arjdbc/abstract/core.rb +16 -23
  13. data/lib/arjdbc/abstract/database_statements.rb +24 -0
  14. data/lib/arjdbc/abstract/statement_cache.rb +2 -5
  15. data/lib/arjdbc/abstract/transaction_support.rb +5 -3
  16. data/lib/arjdbc/db2/column.rb +0 -39
  17. data/lib/arjdbc/derby/adapter.rb +1 -20
  18. data/lib/arjdbc/firebird/adapter.rb +0 -21
  19. data/lib/arjdbc/h2/adapter.rb +0 -15
  20. data/lib/arjdbc/hsqldb/adapter.rb +0 -14
  21. data/lib/arjdbc/informix/adapter.rb +0 -23
  22. data/lib/arjdbc/jdbc/adapter.rb +3 -1
  23. data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
  24. data/lib/arjdbc/jdbc/base_ext.rb +3 -1
  25. data/lib/arjdbc/jdbc/callbacks.rb +2 -0
  26. data/lib/arjdbc/jdbc/column.rb +2 -0
  27. data/lib/arjdbc/jdbc/connection.rb +2 -0
  28. data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
  29. data/lib/arjdbc/jdbc/error.rb +2 -0
  30. data/lib/arjdbc/jdbc/extension.rb +2 -0
  31. data/lib/arjdbc/jdbc/java.rb +3 -1
  32. data/lib/arjdbc/jdbc/railtie.rb +3 -1
  33. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
  34. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
  35. data/lib/arjdbc/jdbc/type_cast.rb +2 -0
  36. data/lib/arjdbc/jdbc/type_converter.rb +2 -0
  37. data/lib/arjdbc/mssql.rb +3 -1
  38. data/lib/arjdbc/mssql/adapter.rb +105 -36
  39. data/lib/arjdbc/mssql/column.rb +5 -1
  40. data/lib/arjdbc/mssql/connection_methods.rb +8 -2
  41. data/lib/arjdbc/mssql/database_limits.rb +2 -0
  42. data/lib/arjdbc/mssql/database_statements.rb +43 -5
  43. data/lib/arjdbc/mssql/errors.rb +2 -0
  44. data/lib/arjdbc/mssql/explain_support.rb +3 -1
  45. data/lib/arjdbc/mssql/extensions/attribute_methods.rb +5 -1
  46. data/lib/arjdbc/mssql/extensions/calculations.rb +2 -0
  47. data/lib/arjdbc/mssql/quoting.rb +38 -0
  48. data/lib/arjdbc/mssql/schema_creation.rb +24 -2
  49. data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
  50. data/lib/arjdbc/mssql/schema_dumper.rb +2 -0
  51. data/lib/arjdbc/mssql/schema_statements.rb +63 -21
  52. data/lib/arjdbc/mssql/transaction.rb +2 -0
  53. data/lib/arjdbc/mssql/types.rb +2 -0
  54. data/lib/arjdbc/mssql/types/binary_types.rb +2 -0
  55. data/lib/arjdbc/mssql/types/date_and_time_types.rb +2 -0
  56. data/lib/arjdbc/mssql/types/deprecated_types.rb +2 -0
  57. data/lib/arjdbc/mssql/types/numeric_types.rb +2 -0
  58. data/lib/arjdbc/mssql/types/string_types.rb +2 -0
  59. data/lib/arjdbc/mssql/utils.rb +2 -0
  60. data/lib/arjdbc/mysql/adapter.rb +47 -18
  61. data/lib/arjdbc/postgresql/adapter.rb +220 -213
  62. data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
  63. data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
  64. data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
  65. data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
  66. data/lib/arjdbc/postgresql/column.rb +6 -4
  67. data/lib/arjdbc/postgresql/name.rb +2 -0
  68. data/lib/arjdbc/postgresql/oid_types.rb +2 -0
  69. data/lib/arjdbc/sqlite3/adapter.rb +175 -180
  70. data/lib/arjdbc/sqlite3/connection_methods.rb +15 -4
  71. data/lib/arjdbc/tasks/databases.rake +13 -10
  72. data/lib/arjdbc/tasks/mssql_database_tasks.rb +49 -5
  73. data/lib/arjdbc/util/quoted_cache.rb +3 -1
  74. data/lib/arjdbc/util/serialized_attributes.rb +3 -1
  75. data/lib/arjdbc/util/table_copier.rb +3 -1
  76. data/lib/arjdbc/version.rb +1 -1
  77. data/pom.xml +4 -4
  78. data/rakelib/01-tomcat.rake +2 -2
  79. data/src/java/arjdbc/ArJdbcModule.java +5 -5
  80. data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
  81. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +406 -629
  82. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +37 -51
  83. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
  84. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +31 -24
  85. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +94 -99
  86. data/src/java/arjdbc/util/DateTimeUtils.java +12 -4
  87. metadata +8 -16
@@ -23,17 +23,27 @@ ArJdbc::ConnectionMethods.module_eval do
23
23
  raise
24
24
  end
25
25
  end
26
-
26
+
27
+ config[:properties] ||= {}
28
+
27
29
  database = config[:database] # NOTE: "jdbc:sqlite::memory:" syntax is supported
28
30
  config[:url] ||= "jdbc:sqlite:#{database == ':memory:' ? '' : database}"
29
31
  config[:connection_alive_sql] ||= 'SELECT 1'
30
32
 
33
+ if config[:readonly]
34
+ # See
35
+ # * http://sqlite.org/c3ref/open.html
36
+ # * http://sqlite.org/c3ref/c_open_autoproxy.html
37
+ # => 0x01 = readonly, 0x40 = uri (default in JDBC)
38
+ config[:properties][:open_mode] = 0x01 | 0x40
39
+ end
40
+
31
41
  timeout = config[:timeout]
32
42
  if timeout && timeout.to_s !~ /\A\d+\Z/
33
43
  raise TypeError.new "Timeout must be nil or a number (got: #{timeout})."
34
44
  end
35
45
 
36
- options = ( config[:properties] ||= {} )
46
+ options = config[:properties]
37
47
  options['busy_timeout'] ||= timeout unless timeout.nil?
38
48
 
39
49
  jdbc_connection(config)
@@ -51,8 +61,9 @@ ArJdbc::ConnectionMethods.module_eval do
51
61
  def parse_sqlite3_config!(config)
52
62
  database = ( config[:database] ||= config[:dbfile] )
53
63
  if ':memory:' != database
54
- config[:database] = File.expand_path(database, Rails.root) if defined?(Rails.root)
55
- dirname = File.dirname(database)
64
+ # make sure to have an absolute path. Ruby and Java don't agree on working directory
65
+ config[:database] = File.expand_path(database, defined?(Rails.root) ? Rails.root : nil)
66
+ dirname = File.dirname(config[:database])
56
67
  Dir.mkdir(dirname) unless File.directory?(dirname)
57
68
  end
58
69
  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,17 +1,37 @@
1
+ require 'active_record/tasks/database_tasks'
2
+
1
3
  require 'arjdbc/tasks/jdbc_database_tasks'
2
4
 
3
5
  module ArJdbc
4
6
  module Tasks
5
7
  class MSSQLDatabaseTasks < JdbcDatabaseTasks
8
+ delegate :clear_active_connections!, to: ActiveRecord::Base
9
+
10
+ def create
11
+ establish_master_connection
12
+ connection.create_database(configuration['database'])
13
+ establish_connection configuration
14
+ rescue ActiveRecord::StatementInvalid => error
15
+ case error.message
16
+ when /database .* already exists/i
17
+ raise ActiveRecord::Tasks::DatabaseAlreadyExists
18
+ else
19
+ raise
20
+ end
21
+ end
22
+
23
+ def drop
24
+ establish_master_connection
25
+ connection.drop_database configuration['database']
26
+ end
6
27
 
7
28
  def purge
8
- test = deep_dup(configuration)
9
- test_database = resolve_database(test)
10
- test['database'] = 'master'
11
- establish_connection(test)
12
- connection.recreate_database(test_database)
29
+ clear_active_connections!
30
+ drop
31
+ create
13
32
  end
14
33
 
34
+
15
35
  def structure_dump(filename)
16
36
  config = config_from_url_if_needed
17
37
  `smoscript -s #{config['host']} -d #{config['database']} -u #{config['username']} -p #{config['password']} -f #{filename} -A -U`
@@ -24,6 +44,10 @@ module ArJdbc
24
44
 
25
45
  private
26
46
 
47
+ def establish_master_connection
48
+ establish_connection configuration.merge('database' => 'master')
49
+ end
50
+
27
51
  def config_from_url_if_needed
28
52
  config = self.config
29
53
  if config['url'] && ! config.key?('database')
@@ -42,5 +66,25 @@ module ArJdbc
42
66
  end
43
67
 
44
68
  end
69
+
70
+ module DatabaseTasksMSSQL
71
+ extend ActiveSupport::Concern
72
+
73
+ module ClassMethods
74
+
75
+ def check_protected_environments!
76
+ super
77
+ rescue ActiveRecord::JDBCError => error
78
+ case error.message
79
+ when /cannot open database .* requested by the login/i
80
+ else
81
+ raise
82
+ end
83
+ end
84
+
85
+ end
86
+ end
87
+
88
+ ActiveRecord::Tasks::DatabaseTasks.send :include, DatabaseTasksMSSQL
45
89
  end
46
90
  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.6.0'
2
+ VERSION = '60.0.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
@@ -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);
322
306
  }
307
+ else {
308
+ final int level = metaData.getDefaultTransactionIsolation();
309
+ supported = level > Connection.TRANSACTION_NONE; // > 0
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;
@@ -735,33 +684,35 @@ public class RubyJdbcConnection extends RubyObject {
735
684
 
736
685
  @JRubyMethod(name = "read_only?")
737
686
  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() );
687
+ try {
688
+ final Connection connection = getConnectionInternal(false);
689
+ if (connection != null) {
690
+ return context.runtime.newBoolean(connection.isReadOnly());
742
691
  }
743
- catch (SQLException e) { return handleException(context, e); }
692
+ } catch (SQLException e) {
693
+ return handleException(context, e);
744
694
  }
745
695
  return context.nil;
746
696
  }
747
697
 
748
698
  @JRubyMethod(name = "read_only=")
749
699
  public IRubyObject set_read_only(final ThreadContext context, final IRubyObject flag) {
750
- final Connection connection = getConnection(true);
751
700
  try {
701
+ final Connection connection = getConnectionInternal(true);
752
702
  connection.setReadOnly( flag.isTrue() );
753
703
  return context.runtime.newBoolean( connection.isReadOnly() );
704
+ } catch (SQLException e) {
705
+ return handleException(context, e);
754
706
  }
755
- catch (SQLException e) { return handleException(context, e); }
756
707
  }
757
708
 
758
709
  @JRubyMethod(name = { "open?" /* "conn?" */ })
759
710
  public IRubyObject open_p(final ThreadContext context) {
760
- final Connection connection = getConnection(false);
711
+ try {
712
+ final Connection connection = getConnectionInternal(false);
761
713
 
762
- if (connection == null) return context.runtime.getFalse();
714
+ if (connection == null) return context.fals;
763
715
 
764
- try {
765
716
  // NOTE: isClosed method generally cannot be called to determine
766
717
  // whether a connection to a database is valid or invalid ...
767
718
  return context.runtime.newBoolean(!connection.isClosed());
@@ -774,10 +725,10 @@ public class RubyJdbcConnection extends RubyObject {
774
725
  public IRubyObject close(final ThreadContext context) {
775
726
  final Connection connection = getConnection(false);
776
727
 
777
- if (connection == null) return context.runtime.getFalse();
728
+ if (connection == null) return context.fals;
778
729
 
779
730
  try {
780
- if (connection.isClosed()) return context.runtime.getFalse();
731
+ if (connection.isClosed()) return context.fals;
781
732
 
782
733
  setConnection(null); // does connection.close();
783
734
  } catch (Exception e) {
@@ -787,69 +738,65 @@ public class RubyJdbcConnection extends RubyObject {
787
738
 
788
739
  // ActiveRecord expects a closed connection to not try and re-open a connection
789
740
  // whereas JNDI expects that.
790
- if (!isJndi()) disconnect(context);
741
+ if (!jndi) disconnect(context);
791
742
 
792
- return context.runtime.getTrue();
743
+ return context.tru;
793
744
  }
794
745
 
795
746
  @JRubyMethod(name = "database_name")
796
747
  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);
748
+ return withConnection(context, connection -> {
749
+ String name = connection.getCatalog();
750
+ if ( name == null ) {
751
+ name = connection.getMetaData().getUserName();
752
+ if ( name == null ) return context.nil;
805
753
  }
754
+ return context.runtime.newString(name);
806
755
  });
807
756
  }
808
757
 
809
758
  @JRubyMethod(name = "execute", required = 1)
810
759
  public IRubyObject execute(final ThreadContext context, final IRubyObject sql) {
811
760
  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();
761
+ return withConnection(context, connection -> {
762
+ Statement statement = null;
763
+ try {
764
+ statement = createStatement(context, connection);
822
765
 
823
- IRubyObject result = context.nil; // If no results, return nil
824
- ResultSet resultSet;
766
+ // For DBs that do support multiple statements, lets return the last result set
767
+ // to be consistent with AR
768
+ boolean hasResultSet = doExecute(statement, query);
769
+ int updateCount = statement.getUpdateCount();
825
770
 
826
- while (hasResultSet || updateCount != -1) {
771
+ IRubyObject result = context.nil; // If no results, return nil
772
+ ResultSet resultSet;
827
773
 
828
- if (hasResultSet) {
829
- resultSet = statement.getResultSet();
774
+ while (hasResultSet || updateCount != -1) {
830
775
 
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
- }
776
+ if (hasResultSet) {
777
+ resultSet = statement.getResultSet();
839
778
 
840
- // Check to see if there is another result set
841
- hasResultSet = statement.getMoreResults();
842
- updateCount = statement.getUpdateCount();
779
+ // Unfortunately the result set gets closed when getMoreResults()
780
+ // is called, so we have to process the result sets as we get them
781
+ // this shouldn't be an issue in most cases since we're only getting 1 result set anyways
782
+ result = mapExecuteResult(context, connection, resultSet);
783
+ resultSet.close();
784
+ } else {
785
+ result = context.runtime.newFixnum(updateCount);
843
786
  }
844
787
 
845
- return result;
846
-
847
- } catch (final SQLException e) {
848
- debugErrorSQL(context, query);
849
- throw e;
850
- } finally {
851
- close(statement);
788
+ // Check to see if there is another result set
789
+ hasResultSet = statement.getMoreResults();
790
+ updateCount = statement.getUpdateCount();
852
791
  }
792
+
793
+ return result;
794
+
795
+ } catch (final SQLException e) {
796
+ debugErrorSQL(context, query);
797
+ throw e;
798
+ } finally {
799
+ close(statement);
853
800
  }
854
801
  });
855
802
  }
@@ -928,7 +875,6 @@ public class RubyJdbcConnection extends RubyObject {
928
875
  }
929
876
 
930
877
  return mapGeneratedKeys(context, connection, statement);
931
-
932
878
  } catch (final SQLException e) {
933
879
  debugErrorSQL(context, query);
934
880
  throw e;
@@ -971,7 +917,6 @@ public class RubyJdbcConnection extends RubyObject {
971
917
  setStatementParameters(context, connection, statement, (RubyArray) binds);
972
918
  statement.executeUpdate();
973
919
  return mapGeneratedKeys(context, connection, statement);
974
-
975
920
  } catch (final SQLException e) {
976
921
  debugErrorSQL(context, query);
977
922
  throw e;
@@ -997,22 +942,20 @@ public class RubyJdbcConnection extends RubyObject {
997
942
  */
998
943
  @JRubyMethod(name = {"execute_update", "execute_delete"}, required = 1)
999
944
  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);
945
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
946
+ Statement statement = null;
947
+ final String query = sqlString(sql);
1004
948
 
1005
- try {
1006
- statement = createStatement(context, connection);
949
+ try {
950
+ statement = createStatement(context, connection);
1007
951
 
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
- }
952
+ final int rowCount = statement.executeUpdate(query);
953
+ return context.runtime.newFixnum(rowCount);
954
+ } catch (final SQLException e) {
955
+ debugErrorSQL(context, query);
956
+ throw e;
957
+ } finally {
958
+ close(statement);
1016
959
  }
1017
960
  });
1018
961
  }
@@ -1028,21 +971,19 @@ public class RubyJdbcConnection extends RubyObject {
1028
971
  */
1029
972
  @JRubyMethod(name = {"execute_prepared_update", "execute_prepared_delete"}, required = 2)
1030
973
  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
- }
974
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
975
+ PreparedStatement statement = null;
976
+ final String query = sqlString(sql);
977
+ try {
978
+ statement = connection.prepareStatement(query);
979
+ setStatementParameters(context, connection, statement, (RubyArray) binds);
980
+ final int rowCount = statement.executeUpdate();
981
+ return context.runtime.newFixnum(rowCount);
982
+ } catch (final SQLException e) {
983
+ debugErrorSQL(context, query);
984
+ throw e;
985
+ } finally {
986
+ close(statement);
1046
987
  }
1047
988
  });
1048
989
  }
@@ -1089,50 +1030,48 @@ public class RubyJdbcConnection extends RubyObject {
1089
1030
 
1090
1031
  private IRubyObject doExecuteQueryRaw(final ThreadContext context,
1091
1032
  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
- }
1033
+ return withConnection(context, connection -> {
1034
+ Statement statement = null; boolean hasResult;
1035
+ try {
1036
+ if ( binds == null || binds.isEmpty()) { // plain statement
1037
+ statement = createStatement(context, connection);
1038
+ statement.setMaxRows(maxRows); // zero means there is no limit
1039
+ hasResult = statement.execute(query);
1040
+ }
1041
+ else {
1042
+ final PreparedStatement prepStatement;
1043
+ statement = prepStatement = connection.prepareStatement(query);
1044
+ if (fetchSize != 0) statement.setFetchSize(fetchSize);
1045
+ statement.setMaxRows(maxRows); // zero means there is no limit
1046
+ setStatementParameters(context, connection, prepStatement, binds);
1047
+ hasResult = prepStatement.execute();
1048
+ }
1109
1049
 
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
- }
1050
+ if (block.isGiven()) {
1118
1051
  if (hasResult) {
1119
- return mapToRawResult(context, connection, statement.getResultSet(), false);
1052
+ // yield(id1, name1) ... row 1 result data
1053
+ // yield(id2, name2) ... row 2 result data
1054
+ return yieldResultRows(context, connection, statement.getResultSet(), block);
1120
1055
  }
1121
- return context.runtime.newEmptyArray();
1056
+ return context.nil;
1122
1057
  }
1123
- catch (final SQLException e) {
1124
- debugErrorSQL(context, query);
1125
- throw e;
1126
- }
1127
- finally {
1128
- close(statement);
1058
+ if (hasResult) {
1059
+ return mapToRawResult(context, connection, statement.getResultSet(), false);
1129
1060
  }
1061
+ return context.runtime.newEmptyArray();
1062
+ }
1063
+ catch (final SQLException e) {
1064
+ debugErrorSQL(context, query);
1065
+ throw e;
1066
+ }
1067
+ finally {
1068
+ close(statement);
1130
1069
  }
1131
1070
  });
1132
1071
  }
1133
1072
 
1134
1073
  protected static String sqlString(final IRubyObject sql) {
1135
- return sql instanceof RubyString ? ((RubyString) sql).decodeString() : sql.convertToString().decodeString();
1074
+ return sql.convertToString().decodeString();
1136
1075
  }
1137
1076
 
1138
1077
  /**
@@ -1145,26 +1084,24 @@ public class RubyJdbcConnection extends RubyObject {
1145
1084
  */
1146
1085
  @JRubyMethod(required = 1)
1147
1086
  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);
1087
+ return withConnection(context, connection -> {
1088
+ Statement statement = null;
1089
+ final String query = sqlString(sql);
1090
+ try {
1091
+ statement = createStatement(context, connection);
1154
1092
 
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
- }
1093
+ // At least until AR 5.1 #exec_query still gets called for things that don't return results in some cases :(
1094
+ if (statement.execute(query)) {
1095
+ return mapQueryResult(context, connection, statement.getResultSet());
1096
+ }
1159
1097
 
1160
- return context.nil;
1098
+ return newEmptyResult(context);
1161
1099
 
1162
- } catch (final SQLException e) {
1163
- debugErrorSQL(context, query);
1164
- throw e;
1165
- } finally {
1166
- close(statement);
1167
- }
1100
+ } catch (final SQLException e) {
1101
+ debugErrorSQL(context, query);
1102
+ throw e;
1103
+ } finally {
1104
+ close(statement);
1168
1105
  }
1169
1106
  });
1170
1107
  }
@@ -1177,13 +1114,11 @@ public class RubyJdbcConnection extends RubyObject {
1177
1114
  */
1178
1115
  @JRubyMethod(required = 1)
1179
1116
  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
- }
1117
+ return withConnection(context, connection -> {
1118
+ final String query = sql.convertToString().getUnicodeValue();
1119
+ PreparedStatement statement = connection.prepareStatement(query);
1120
+ if (fetchSize != 0) statement.setFetchSize(fetchSize);
1121
+ return JavaUtil.convertJavaToRuby(context.runtime, statement);
1187
1122
  });
1188
1123
  }
1189
1124
 
@@ -1206,40 +1141,40 @@ public class RubyJdbcConnection extends RubyObject {
1206
1141
  @JRubyMethod(required = 3)
1207
1142
  public IRubyObject execute_prepared_query(final ThreadContext context, final IRubyObject sql,
1208
1143
  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;
1144
+ return withConnection(context, connection -> {
1145
+ final boolean cached = !(cachedStatement == null || cachedStatement.isNil());
1146
+ String query = null;
1147
+ PreparedStatement statement = null;
1214
1148
 
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
- }
1149
+ try {
1150
+ if (cached) {
1151
+ statement = (PreparedStatement) JavaEmbedUtils.rubyToJava(cachedStatement);
1152
+ } else {
1153
+ query = sql.convertToString().getUnicodeValue();
1154
+ statement = connection.prepareStatement(query);
1155
+ if (fetchSize != 0) statement.setFetchSize(fetchSize);
1156
+ }
1222
1157
 
1223
- setStatementParameters(context, connection, statement, (RubyArray) binds);
1158
+ setStatementParameters(context, connection, statement, (RubyArray) binds);
1224
1159
 
1225
- if (statement.execute()) {
1226
- ResultSet resultSet = statement.getResultSet();
1227
- IRubyObject results = mapQueryResult(context, connection, resultSet);
1228
- resultSet.close();
1160
+ if (statement.execute()) {
1161
+ ResultSet resultSet = statement.getResultSet();
1162
+ IRubyObject results = mapQueryResult(context, connection, resultSet);
1163
+ resultSet.close();
1229
1164
 
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
- }
1165
+ return results;
1166
+ } else {
1167
+ return newEmptyResult(context);
1168
+ }
1169
+ } catch (final SQLException e) {
1170
+ if (query == null) query = sql.convertToString().getUnicodeValue();
1171
+ debugErrorSQL(context, query);
1172
+ throw e;
1173
+ } finally {
1174
+ if ( cached ) {
1175
+ statement.clearParameters();
1176
+ } else {
1177
+ close(statement);
1243
1178
  }
1244
1179
  }
1245
1180
  });
@@ -1251,35 +1186,6 @@ public class RubyJdbcConnection extends RubyObject {
1251
1186
  return mapToResult(context, connection, resultSet, columns);
1252
1187
  }
1253
1188
 
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
1189
  @JRubyMethod(name = "supported_data_types")
1284
1190
  public IRubyObject supported_data_types(final ThreadContext context) throws SQLException {
1285
1191
  final Connection connection = getConnection(true);
@@ -1303,12 +1209,10 @@ public class RubyJdbcConnection extends RubyObject {
1303
1209
  protected static final int PRIMARY_KEYS_COLUMN_NAME = 4;
1304
1210
 
1305
1211
  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
- }
1212
+ return withConnection(context, connection -> {
1213
+ final String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1214
+ final TableName table = extractTableName(connection, null, null, _tableName);
1215
+ return primaryKeys(context, connection, table);
1312
1216
  });
1313
1217
  }
1314
1218
 
@@ -1316,7 +1220,7 @@ public class RubyJdbcConnection extends RubyObject {
1316
1220
  final Connection connection, final TableName table) throws SQLException {
1317
1221
  final DatabaseMetaData metaData = connection.getMetaData();
1318
1222
  ResultSet resultSet = null;
1319
- final List<RubyString> keyNames = new ArrayList<RubyString>();
1223
+ final List<RubyString> keyNames = new ArrayList<>();
1320
1224
  try {
1321
1225
  resultSet = metaData.getPrimaryKeys(table.catalog, table.schema, table.name);
1322
1226
  final Ruby runtime = context.runtime;
@@ -1330,26 +1234,6 @@ public class RubyJdbcConnection extends RubyObject {
1330
1234
  return keyNames;
1331
1235
  }
1332
1236
 
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
1237
  @JRubyMethod(name = "tables", required = 0, optional = 4)
1354
1238
  public IRubyObject tables(final ThreadContext context, final IRubyObject[] args) {
1355
1239
  switch ( args.length ) {
@@ -1367,11 +1251,7 @@ public class RubyJdbcConnection extends RubyObject {
1367
1251
 
1368
1252
  protected IRubyObject tables(final ThreadContext context,
1369
1253
  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
- });
1254
+ return withConnection(context, connection -> matchTables(context, connection, catalog, schemaPattern, tablePattern, types, false));
1375
1255
  }
1376
1256
 
1377
1257
  protected String[] getTableTypes() {
@@ -1401,40 +1281,36 @@ public class RubyJdbcConnection extends RubyObject {
1401
1281
 
1402
1282
  protected IRubyObject tableExists(final ThreadContext context,
1403
1283
  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
- }
1284
+ return withConnection(context, connection -> {
1285
+ final TableName components = extractTableName(connection, defaultSchema, tableName);
1286
+ return context.runtime.newBoolean( tableExists(context, connection, components) );
1409
1287
  });
1410
1288
  }
1411
1289
 
1412
1290
  @JRubyMethod(name = {"columns", "columns_internal"}, required = 1, optional = 2)
1413
1291
  public RubyArray columns_internal(final ThreadContext context, final IRubyObject[] args)
1414
1292
  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);
1293
+ return withConnection(context, connection -> {
1294
+ ResultSet columns = null;
1295
+ try {
1296
+ final String tableName = args[0].toString();
1297
+ // optionals (NOTE: catalog argumnet was never used before 1.3.0) :
1298
+ final String catalog = args.length > 1 ? toStringOrNull(args[1]) : null;
1299
+ final String defaultSchema = args.length > 2 ? toStringOrNull(args[2]) : null;
1426
1300
 
1427
- if ( ! tableExists(context, connection, components) ) {
1428
- throw new SQLException("table: " + tableName + " does not exist");
1429
- }
1301
+ final TableName components;
1302
+ components = extractTableName(connection, catalog, defaultSchema, tableName);
1430
1303
 
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);
1304
+ if ( ! tableExists(context, connection, components) ) {
1305
+ throw new SQLException("table: " + tableName + " does not exist");
1437
1306
  }
1307
+
1308
+ final DatabaseMetaData metaData = connection.getMetaData();
1309
+ columns = metaData.getColumns(components.catalog, components.schema, components.name, null);
1310
+ return mapColumnsResult(context, metaData, components, columns);
1311
+ }
1312
+ finally {
1313
+ close(columns);
1438
1314
  }
1439
1315
  });
1440
1316
  }
@@ -1464,70 +1340,68 @@ public class RubyJdbcConnection extends RubyObject {
1464
1340
  * should filter the return from this method instead.
1465
1341
  */
1466
1342
  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);
1471
-
1472
- String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1473
- String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1474
- final TableName table = extractTableName(connection, null, _schemaName, _tableName);
1343
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1344
+ final Ruby runtime = context.runtime;
1345
+ final RubyClass IndexDefinition = getIndexDefinition(context);
1475
1346
 
1476
- final List<RubyString> primaryKeys = primaryKeys(context, connection, table);
1347
+ String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1348
+ String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1349
+ final TableName table = extractTableName(connection, null, _schemaName, _tableName);
1477
1350
 
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
- RubyArray currentColumns = null;
1351
+ final List<RubyString> primaryKeys = primaryKeys(context, connection, table);
1485
1352
 
1486
- while ( indexInfoSet.next() ) {
1487
- String indexName = indexInfoSet.getString(INDEX_INFO_NAME);
1488
- if ( indexName == null ) continue;
1353
+ ResultSet indexInfoSet = null;
1354
+ final RubyArray indexes = RubyArray.newArray(runtime, 8);
1355
+ try {
1356
+ final DatabaseMetaData metaData = connection.getMetaData();
1357
+ indexInfoSet = metaData.getIndexInfo(table.catalog, table.schema, table.name, false, true);
1358
+ String currentIndex = null;
1489
1359
 
1490
- indexName = caseConvertIdentifierForRails(metaData, indexName);
1360
+ while ( indexInfoSet.next() ) {
1361
+ String indexName = indexInfoSet.getString(INDEX_INFO_NAME);
1362
+ if ( indexName == null ) continue;
1363
+ RubyArray currentColumns = null;
1491
1364
 
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;
1365
+ indexName = caseConvertIdentifierForRails(metaData, indexName);
1497
1366
 
1498
- // We are working on a new index
1499
- if ( ! indexName.equals(currentIndex) ) {
1500
- currentIndex = indexName;
1367
+ final String columnName = indexInfoSet.getString(INDEX_INFO_COLUMN_NAME);
1368
+ final RubyString rubyColumnName = cachedString(
1369
+ context, caseConvertIdentifierForRails(metaData, columnName)
1370
+ );
1371
+ if ( primaryKeys.contains(rubyColumnName) ) continue;
1501
1372
 
1502
- String indexTableName = indexInfoSet.getString(INDEX_INFO_TABLE_NAME);
1503
- indexTableName = caseConvertIdentifierForRails(metaData, indexTableName);
1373
+ // We are working on a new index
1374
+ if ( ! indexName.equals(currentIndex) ) {
1375
+ currentIndex = indexName;
1504
1376
 
1505
- final boolean nonUnique = indexInfoSet.getBoolean(INDEX_INFO_NON_UNIQUE);
1377
+ String indexTableName = indexInfoSet.getString(INDEX_INFO_TABLE_NAME);
1378
+ indexTableName = caseConvertIdentifierForRails(metaData, indexTableName);
1506
1379
 
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
- };
1380
+ final boolean nonUnique = indexInfoSet.getBoolean(INDEX_INFO_NON_UNIQUE);
1514
1381
 
1515
- indexes.append( IndexDefinition.newInstance(context, args, Block.NULL_BLOCK) ); // IndexDefinition.new
1516
- }
1382
+ IRubyObject[] args = new IRubyObject[] {
1383
+ cachedString(context, indexTableName), // table_name
1384
+ cachedString(context, indexName), // index_name
1385
+ nonUnique ? context.fals : context.tru, // unique
1386
+ currentColumns = RubyArray.newArray(runtime, 4) // [] column names
1387
+ // orders, (since AR 3.2) where, type, using (AR 4.0)
1388
+ };
1517
1389
 
1518
- // one or more columns can be associated with an index
1519
- if ( currentColumns != null ) currentColumns.append(rubyColumnName);
1390
+ indexes.append( IndexDefinition.newInstance(context, args, Block.NULL_BLOCK) ); // IndexDefinition.new
1520
1391
  }
1521
1392
 
1522
- return indexes;
1393
+ // one or more columns can be associated with an index
1394
+ if ( currentColumns != null ) currentColumns.append(rubyColumnName);
1395
+ }
1523
1396
 
1524
- } finally { close(indexInfoSet); }
1525
- }
1397
+ return indexes;
1398
+
1399
+ } finally { close(indexInfoSet); }
1526
1400
  });
1527
1401
  }
1528
1402
 
1529
1403
  protected RubyClass getIndexDefinition(final ThreadContext context) {
1530
- final RubyClass adapterClass = getAdapter().getMetaClass();
1404
+ final RubyClass adapterClass = adapter.getMetaClass();
1531
1405
  IRubyObject IDef = adapterClass.getConstantAt("IndexDefinition");
1532
1406
  return IDef != null ? (RubyClass) IDef : getIndexDefinition(context.runtime);
1533
1407
  }
@@ -1538,57 +1412,55 @@ public class RubyJdbcConnection extends RubyObject {
1538
1412
  }
1539
1413
 
1540
1414
  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);
1415
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1416
+ final Ruby runtime = context.runtime;
1417
+ final RubyClass FKDefinition = getForeignKeyDefinition(context);
1545
1418
 
1546
- String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1547
- String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1548
- final TableName table = extractTableName(connection, catalog, _schemaName, _tableName);
1419
+ String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
1420
+ String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
1421
+ final TableName table = extractTableName(connection, catalog, _schemaName, _tableName);
1549
1422
 
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);
1423
+ ResultSet fkInfoSet = null;
1424
+ final List<IRubyObject> fKeys = new ArrayList<>(8);
1425
+ try {
1426
+ final DatabaseMetaData metaData = connection.getMetaData();
1427
+ fkInfoSet = metaData.getImportedKeys(table.catalog, table.schema, table.name);
1555
1428
 
1556
- while ( fkInfoSet.next() ) {
1557
- final RubyHash options = RubyHash.newHash(runtime);
1429
+ while ( fkInfoSet.next() ) {
1430
+ final RubyHash options = RubyHash.newHash(runtime);
1558
1431
 
1559
- String fkName = fkInfoSet.getString("FK_NAME");
1560
- if (fkName != null) {
1561
- fkName = caseConvertIdentifierForRails(metaData, fkName);
1562
- options.put(runtime.newSymbol("name"), fkName);
1563
- }
1432
+ String fkName = fkInfoSet.getString("FK_NAME");
1433
+ if (fkName != null) {
1434
+ fkName = caseConvertIdentifierForRails(metaData, fkName);
1435
+ options.put(runtime.newSymbol("name"), fkName);
1436
+ }
1564
1437
 
1565
- String columnName = fkInfoSet.getString("FKCOLUMN_NAME");
1566
- options.put(runtime.newSymbol("column"), caseConvertIdentifierForRails(metaData, columnName));
1438
+ String columnName = fkInfoSet.getString("FKCOLUMN_NAME");
1439
+ options.put(runtime.newSymbol("column"), caseConvertIdentifierForRails(metaData, columnName));
1567
1440
 
1568
- columnName = fkInfoSet.getString("PKCOLUMN_NAME");
1569
- options.put(runtime.newSymbol("primary_key"), caseConvertIdentifierForRails(metaData, columnName));
1441
+ columnName = fkInfoSet.getString("PKCOLUMN_NAME");
1442
+ options.put(runtime.newSymbol("primary_key"), caseConvertIdentifierForRails(metaData, columnName));
1570
1443
 
1571
- String fkTableName = fkInfoSet.getString("FKTABLE_NAME");
1572
- fkTableName = caseConvertIdentifierForRails(metaData, fkTableName);
1444
+ String fkTableName = fkInfoSet.getString("FKTABLE_NAME");
1445
+ fkTableName = caseConvertIdentifierForRails(metaData, fkTableName);
1573
1446
 
1574
- String pkTableName = fkInfoSet.getString("PKTABLE_NAME");
1575
- pkTableName = caseConvertIdentifierForRails(metaData, pkTableName);
1447
+ String pkTableName = fkInfoSet.getString("PKTABLE_NAME");
1448
+ pkTableName = caseConvertIdentifierForRails(metaData, pkTableName);
1576
1449
 
1577
- final String onDelete = extractForeignKeyRule( fkInfoSet.getInt("DELETE_RULE") );
1578
- if ( onDelete != null ) options.op_aset(context, runtime.newSymbol("on_delete"), runtime.newSymbol(onDelete));
1450
+ final String onDelete = extractForeignKeyRule( fkInfoSet.getInt("DELETE_RULE") );
1451
+ if ( onDelete != null ) options.op_aset(context, runtime.newSymbol("on_delete"), runtime.newSymbol(onDelete));
1579
1452
 
1580
- final String onUpdate = extractForeignKeyRule( fkInfoSet.getInt("UPDATE_RULE") );
1581
- if ( onUpdate != null ) options.op_aset(context, runtime.newSymbol("on_update"), runtime.newSymbol(onUpdate));
1453
+ final String onUpdate = extractForeignKeyRule( fkInfoSet.getInt("UPDATE_RULE") );
1454
+ if ( onUpdate != null ) options.op_aset(context, runtime.newSymbol("on_update"), runtime.newSymbol(onUpdate));
1582
1455
 
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
- }
1456
+ IRubyObject from_table = cachedString(context, fkTableName);
1457
+ IRubyObject to_table = cachedString(context, pkTableName);
1458
+ fKeys.add( FKDefinition.newInstance(context, from_table, to_table, options, Block.NULL_BLOCK) ); // ForeignKeyDefinition.new
1459
+ }
1587
1460
 
1588
- return runtime.newArray(fKeys);
1461
+ return runtime.newArray(fKeys);
1589
1462
 
1590
- } finally { close(fkInfoSet); }
1591
- }
1463
+ } finally { close(fkInfoSet); }
1592
1464
  });
1593
1465
  }
1594
1466
 
@@ -1603,7 +1475,7 @@ public class RubyJdbcConnection extends RubyObject {
1603
1475
  }
1604
1476
 
1605
1477
  protected RubyClass getForeignKeyDefinition(final ThreadContext context) {
1606
- final RubyClass adapterClass = getAdapter().getMetaClass();
1478
+ final RubyClass adapterClass = adapter.getMetaClass();
1607
1479
  IRubyObject FKDef = adapterClass.getConstantAt("ForeignKeyDefinition");
1608
1480
  return FKDef != null ? (RubyClass) FKDef : getForeignKeyDefinition(context.runtime);
1609
1481
  }
@@ -1611,42 +1483,34 @@ public class RubyJdbcConnection extends RubyObject {
1611
1483
 
1612
1484
  @JRubyMethod(name = "supports_foreign_keys?")
1613
1485
  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
- }
1486
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1487
+ final DatabaseMetaData metaData = connection.getMetaData();
1488
+ return context.runtime.newBoolean( metaData.supportsIntegrityEnhancementFacility() );
1619
1489
  });
1620
1490
  }
1621
1491
 
1622
1492
  @JRubyMethod(name = "supports_views?")
1623
1493
  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
- }
1494
+ return withConnection(context, (Callable<IRubyObject>) connection -> {
1495
+ final DatabaseMetaData metaData = connection.getMetaData();
1496
+ final ResultSet tableTypes = metaData.getTableTypes();
1497
+ try {
1498
+ while ( tableTypes.next() ) {
1499
+ if ( "VIEW".equalsIgnoreCase( tableTypes.getString(1) ) ) {
1500
+ return context.runtime.newBoolean( true );
1633
1501
  }
1634
1502
  }
1635
- finally {
1636
- close(tableTypes);
1637
- }
1638
- return context.runtime.newBoolean( false );
1639
1503
  }
1504
+ finally {
1505
+ close(tableTypes);
1506
+ }
1507
+ return context.runtime.newBoolean( false );
1640
1508
  });
1641
1509
  }
1642
1510
 
1643
1511
  @JRubyMethod(name = "with_jdbc_connection", alias = "with_connection_retry_guard", frame = true)
1644
1512
  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
- });
1513
+ return withConnection(context, connection -> block.call(context, convertJavaToRuby(connection)));
1650
1514
  }
1651
1515
 
1652
1516
  /*
@@ -1707,24 +1571,22 @@ public class RubyJdbcConnection extends RubyObject {
1707
1571
  // TODO: Fix this, the columns don't have the info needed to handle this anymore
1708
1572
  // currently commented out so that it will compile
1709
1573
 
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();
1574
+ return withConnection(context, connection -> {
1575
+ PreparedStatement statement = null;
1576
+ try {
1577
+ statement = connection.prepareStatement(sql);
1578
+ /*
1579
+ if ( binary ) { // blob
1580
+ setBlobParameter(context, connection, statement, 1, value, column, Types.BLOB);
1581
+ }
1582
+ else { // clob
1583
+ setClobParameter(context, connection, statement, 1, value, column, Types.CLOB);
1725
1584
  }
1726
- finally { close(statement); }
1585
+ setStatementParameter(context, context.runtime, connection, statement, 2, idValue, idColumn);
1586
+ */
1587
+ return statement.executeUpdate();
1727
1588
  }
1589
+ finally { close(statement); }
1728
1590
  });
1729
1591
  }
1730
1592
 
@@ -1780,7 +1642,7 @@ public class RubyJdbcConnection extends RubyObject {
1780
1642
  final IRubyObject self, final IRubyObject config, final Block block) {
1781
1643
  final IRubyObject ds_or_name = rawDataSourceOrName(context, config);
1782
1644
 
1783
- if ( ds_or_name == null ) return context.runtime.getFalse();
1645
+ if ( ds_or_name == null ) return context.fals;
1784
1646
 
1785
1647
  final javax.sql.DataSource dataSource;
1786
1648
  final Object dsOrName = ds_or_name.toJava(Object.class);
@@ -1836,7 +1698,7 @@ public class RubyJdbcConnection extends RubyObject {
1836
1698
  }
1837
1699
  }
1838
1700
 
1839
- if ( configValue == null || configValue == context.nil || configValue == runtime.getFalse() ) {
1701
+ if ( configValue == null || configValue == context.nil || configValue == context.fals ) {
1840
1702
  return null;
1841
1703
  }
1842
1704
  return configValue;
@@ -1859,13 +1721,6 @@ public class RubyJdbcConnection extends RubyObject {
1859
1721
  }
1860
1722
  }
1861
1723
 
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
1724
  private ConnectionFactory setDriverFactory(final ThreadContext context) {
1870
1725
 
1871
1726
  final IRubyObject url = getConfigValue(context, "url");
@@ -1965,12 +1820,6 @@ public class RubyJdbcConnection extends RubyObject {
1965
1820
  return props;
1966
1821
  }
1967
1822
 
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
1823
  private ConnectionFactory setDataSourceFactory(final ThreadContext context) {
1975
1824
  final javax.sql.DataSource dataSource; final String lookupName;
1976
1825
  IRubyObject value = getConfigValue(context, "data_source");
@@ -1992,28 +1841,10 @@ public class RubyJdbcConnection extends RubyObject {
1992
1841
  private static volatile boolean defaultConfigJndi;
1993
1842
  private static transient ConnectionFactory defaultConnectionFactory;
1994
1843
 
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
1844
  /**
2012
1845
  * @return whether the connection factory is JNDI based
2013
1846
  */
2014
1847
  private boolean setupConnectionFactory(final ThreadContext context) {
2015
- final IRubyObject config = getConfig();
2016
-
2017
1848
  if ( defaultConfig == null ) {
2018
1849
  synchronized(RubyJdbcConnection.class) {
2019
1850
  if ( defaultConfig == null ) {
@@ -2045,18 +1876,17 @@ public class RubyJdbcConnection extends RubyObject {
2045
1876
 
2046
1877
  @JRubyMethod(name = "jndi?", alias = "jndi_connection?")
2047
1878
  public RubyBoolean jndi_p(final ThreadContext context) {
2048
- return context.runtime.newBoolean( isJndi() );
1879
+ return context.runtime.newBoolean(jndi);
2049
1880
  }
2050
1881
 
2051
1882
  protected boolean isJndi() { return this.jndi; }
2052
1883
 
2053
1884
  @JRubyMethod(name = "config")
2054
- public IRubyObject config() { return getConfig(); }
1885
+ public IRubyObject config() { return config; }
2055
1886
 
2056
1887
  public IRubyObject getConfig() { return this.config; }
2057
1888
 
2058
1889
  protected final IRubyObject getConfigValue(final ThreadContext context, final String key) {
2059
- final IRubyObject config = getConfig();
2060
1890
  final RubySymbol keySym = context.runtime.newSymbol(key);
2061
1891
  if ( config instanceof RubyHash ) {
2062
1892
  final IRubyObject value = ((RubyHash) config).fastARef(keySym);
@@ -2067,7 +1897,6 @@ public class RubyJdbcConnection extends RubyObject {
2067
1897
 
2068
1898
  protected final IRubyObject setConfigValue(final ThreadContext context,
2069
1899
  final String key, final IRubyObject value) {
2070
- final IRubyObject config = getConfig();
2071
1900
  final RubySymbol keySym = context.runtime.newSymbol(key);
2072
1901
  if ( config instanceof RubyHash ) {
2073
1902
  return ((RubyHash) config).op_aset(context, keySym, value);
@@ -2077,7 +1906,6 @@ public class RubyJdbcConnection extends RubyObject {
2077
1906
 
2078
1907
  protected final IRubyObject setConfigValueIfNotSet(final ThreadContext context,
2079
1908
  final String key, final IRubyObject value) {
2080
- final IRubyObject config = getConfig();
2081
1909
  final RubySymbol keySym = context.runtime.newSymbol(key);
2082
1910
  if ( config instanceof RubyHash ) {
2083
1911
  final IRubyObject setValue = ((RubyHash) config).fastARef(keySym);
@@ -2097,7 +1925,7 @@ public class RubyJdbcConnection extends RubyObject {
2097
1925
  protected final IRubyObject getAdapter() { return this.adapter; }
2098
1926
 
2099
1927
  protected RubyClass getJdbcColumnClass(final ThreadContext context) {
2100
- return (RubyClass) getAdapter().callMethod(context, "jdbc_column_class");
1928
+ return (RubyClass) adapter.callMethod(context, "jdbc_column_class");
2101
1929
  }
2102
1930
 
2103
1931
  protected ConnectionFactory getConnectionFactory() throws RaiseException {
@@ -2309,7 +2137,7 @@ public class RubyJdbcConnection extends RubyObject {
2309
2137
  @JRubyMethod(name = "raw_date_time?", meta = true)
2310
2138
  public static IRubyObject useRawDateTime(final ThreadContext context, final IRubyObject self) {
2311
2139
  if ( rawDateTime == null ) return context.nil;
2312
- return context.runtime.newBoolean( rawDateTime.booleanValue() );
2140
+ return context.runtime.newBoolean(rawDateTime);
2313
2141
  }
2314
2142
 
2315
2143
  @JRubyMethod(name = "raw_date_time=", meta = true)
@@ -2323,17 +2151,6 @@ public class RubyJdbcConnection extends RubyObject {
2323
2151
  return value;
2324
2152
  }
2325
2153
 
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
2154
  protected IRubyObject dateToRuby(final ThreadContext context,
2338
2155
  final Ruby runtime, final ResultSet resultSet, final int column)
2339
2156
  throws SQLException {
@@ -2344,11 +2161,11 @@ public class RubyJdbcConnection extends RubyObject {
2344
2161
  return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
2345
2162
  }
2346
2163
 
2347
- if ( rawDateTime != null && rawDateTime.booleanValue() ) {
2164
+ if ( rawDateTime != null && rawDateTime) {
2348
2165
  return RubyString.newString(runtime, DateTimeUtils.dateToString(value));
2349
2166
  }
2350
2167
 
2351
- return DateTimeUtils.newDateAsTime(context, value, DateTimeZone.UTC).callMethod(context, "to_date");
2168
+ return DateTimeUtils.newDateAsTime(context, value, null).callMethod(context, "to_date");
2352
2169
  }
2353
2170
 
2354
2171
  protected IRubyObject timeToRuby(final ThreadContext context,
@@ -2360,7 +2177,7 @@ public class RubyJdbcConnection extends RubyObject {
2360
2177
  return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
2361
2178
  }
2362
2179
 
2363
- if ( rawDateTime != null && rawDateTime.booleanValue() ) {
2180
+ if ( rawDateTime != null && rawDateTime) {
2364
2181
  return RubyString.newString(runtime, DateTimeUtils.timeToString(value));
2365
2182
  }
2366
2183
 
@@ -2376,7 +2193,7 @@ public class RubyJdbcConnection extends RubyObject {
2376
2193
  return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
2377
2194
  }
2378
2195
 
2379
- if ( rawDateTime != null && rawDateTime.booleanValue() ) {
2196
+ if ( rawDateTime != null && rawDateTime) {
2380
2197
  return RubyString.newString(runtime, DateTimeUtils.timestampToString(value));
2381
2198
  }
2382
2199
 
@@ -2388,19 +2205,6 @@ public class RubyJdbcConnection extends RubyObject {
2388
2205
  return DateTimeUtils.newTime(context, value, getDefaultTimeZone(context));
2389
2206
  }
2390
2207
 
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
2208
  protected static Boolean rawBoolean;
2405
2209
  static {
2406
2210
  final String booleanRaw = SafePropertyAccessor.getProperty("arjdbc.boolean.raw");
@@ -2412,7 +2216,7 @@ public class RubyJdbcConnection extends RubyObject {
2412
2216
  @JRubyMethod(name = "raw_boolean?", meta = true)
2413
2217
  public static IRubyObject useRawBoolean(final ThreadContext context, final IRubyObject self) {
2414
2218
  if ( rawBoolean == null ) return context.nil;
2415
- return context.runtime.newBoolean( rawBoolean.booleanValue() );
2219
+ return context.runtime.newBoolean(rawBoolean);
2416
2220
  }
2417
2221
 
2418
2222
  @JRubyMethod(name = "raw_boolean=", meta = true)
@@ -2444,13 +2248,13 @@ public class RubyJdbcConnection extends RubyObject {
2444
2248
  protected IRubyObject booleanToRuby(final ThreadContext context,
2445
2249
  final Ruby runtime, final ResultSet resultSet, final int column)
2446
2250
  throws SQLException {
2447
- if ( rawBoolean != null && rawBoolean.booleanValue() ) {
2251
+ if ( rawBoolean != null && rawBoolean) {
2448
2252
  final String value = resultSet.getString(column);
2449
2253
  if ( value == null /* && resultSet.wasNull() */ ) return context.nil;
2450
2254
  return RubyString.newUnicodeString(runtime, value);
2451
2255
  }
2452
2256
  final boolean value = resultSet.getBoolean(column);
2453
- if ( value == false && resultSet.wasNull() ) return context.nil;
2257
+ if (!value && resultSet.wasNull()) return context.nil;
2454
2258
  return runtime.newBoolean(value);
2455
2259
  }
2456
2260
 
@@ -2668,7 +2472,7 @@ public class RubyJdbcConnection extends RubyObject {
2668
2472
  }
2669
2473
  }
2670
2474
 
2671
- protected static final Map<String, Integer> JDBC_TYPE_FOR = new HashMap<String, Integer>(32, 1);
2475
+ protected static final Map<String, Integer> JDBC_TYPE_FOR = new HashMap<>(32, 1);
2672
2476
  static {
2673
2477
  JDBC_TYPE_FOR.put("string", Types.VARCHAR);
2674
2478
  JDBC_TYPE_FOR.put("text", Types.CLOB);
@@ -2710,7 +2514,7 @@ public class RubyJdbcConnection extends RubyObject {
2710
2514
  final String internedType = internedTypeFor(context, attribute);
2711
2515
  final Integer sqlType = jdbcTypeFor(internedType);
2712
2516
  if ( sqlType != null ) {
2713
- return sqlType.intValue();
2517
+ return sqlType;
2714
2518
  }
2715
2519
 
2716
2520
  return Types.OTHER; // -1 as well as 0 are used in Types
@@ -2897,11 +2701,6 @@ public class RubyJdbcConnection extends RubyObject {
2897
2701
  statement.setTimestamp(index, timestamp, getCalendar(dateTime.getZone()));
2898
2702
  }
2899
2703
 
2900
- @Deprecated
2901
- protected static Timestamp convertToTimestamp(final RubyFloat value) {
2902
- return DateTimeUtils.convertToTimestamp(value);
2903
- }
2904
-
2905
2704
  protected static Calendar getCalendar(final DateTimeZone zone) { // final java.util.Date hint
2906
2705
  if (DateTimeZone.UTC == zone) return getCalendarUTC();
2907
2706
  if (DateTimeZone.getDefault() == zone) return new GregorianCalendar();
@@ -2947,9 +2746,14 @@ public class RubyJdbcConnection extends RubyObject {
2947
2746
  value = value.callMethod(context, "to_date");
2948
2747
  }
2949
2748
 
2950
- // NOTE: Here we rely in ActiveRecord (ActiveSupport) to get
2951
- // the date as a string in the database format.
2952
- statement.setDate(index, Date.valueOf(value.callMethod(context, "to_s", context.runtime.newSymbol("db")).toString()));
2749
+ if (value instanceof RubyDate) {
2750
+ RubyDate rubyDate = (RubyDate) value;
2751
+ statement.setDate(index, rubyDate.toJava(Date.class));
2752
+ return;
2753
+ }
2754
+
2755
+ // NOTE: assuming Date#to_s does right ...
2756
+ statement.setDate(index, Date.valueOf(value.toString()));
2953
2757
  }
2954
2758
 
2955
2759
  protected void setBooleanParameter(final ThreadContext context,
@@ -2986,7 +2790,7 @@ public class RubyJdbcConnection extends RubyObject {
2986
2790
  // For some reason the driver doesn't like "character varying" as a type
2987
2791
  if ( type.eql(context.runtime.newSymbol("string")) ) return "varchar";
2988
2792
 
2989
- final RubyHash nativeTypes = (RubyHash) getAdapter().callMethod(context, "native_database_types");
2793
+ final RubyHash nativeTypes = (RubyHash) adapter.callMethod(context, "native_database_types");
2990
2794
  // e.g. `integer: { name: 'integer' }`
2991
2795
  final RubyHash typeInfo = (RubyHash) nativeTypes.op_aref(context, type);
2992
2796
 
@@ -3047,16 +2851,7 @@ public class RubyJdbcConnection extends RubyObject {
3047
2851
  }
3048
2852
 
3049
2853
  /**
3050
- * Always returns a connection (might cause a reconnect if there's none).
3051
- * @return connection
3052
- * @throws <code>ActiveRecord::ConnectionNotEstablished</code>, <code>ActiveRecord::JDBCError</code>
3053
- */
3054
- protected Connection getConnection() throws RaiseException {
3055
- return getConnection(false);
3056
- }
3057
-
3058
- /**
3059
- * @see #getConnection()
2854
+ * Returns a connection (might cause a reconnect if there's none).
3060
2855
  * @param required set to true if a connection is required to exists (e.g. on commit)
3061
2856
  * @return connection
3062
2857
  * @throws <code>ActiveRecord::ConnectionNotEstablished</code> if disconnected
@@ -3071,17 +2866,15 @@ public class RubyJdbcConnection extends RubyObject {
3071
2866
  }
3072
2867
  }
3073
2868
 
3074
- private Connection getConnectionInternal(final boolean required) throws SQLException {
2869
+ protected Connection getConnectionInternal(final boolean required) throws SQLException {
3075
2870
  Connection connection = getConnectionImpl();
3076
- if ( connection == null ) {
3077
- if ( required ) {
3078
- if ( ! connected ) handleNotConnected(); // raise ConnectionNotEstablished
3079
- synchronized (this) {
2871
+ if (connection == null && required) {
2872
+ if (!connected) handleNotConnected(); // raise ConnectionNotEstablished
2873
+ synchronized (this) {
2874
+ connection = getConnectionImpl();
2875
+ if ( connection == null ) {
2876
+ connectImpl(true); // throws SQLException
3080
2877
  connection = getConnectionImpl();
3081
- if ( connection == null ) {
3082
- connectImpl( true ); // throws SQLException
3083
- connection = getConnectionImpl();
3084
- }
3085
2878
  }
3086
2879
  }
3087
2880
  }
@@ -3212,7 +3005,7 @@ public class RubyJdbcConnection extends RubyObject {
3212
3005
  try {
3213
3006
  tablesSet = metaData.getTables(catalog, _schemaPattern, _tablePattern, types);
3214
3007
  if ( checkExistsOnly ) { // only check if given table exists
3215
- return tablesSet.next() ? context.runtime.getTrue() : null;
3008
+ return tablesSet.next() ? context.tru : null;
3216
3009
  }
3217
3010
  else {
3218
3011
  return mapTables(context, connection, catalog, _schemaPattern, _tablePattern, tablesSet);
@@ -3221,15 +3014,6 @@ public class RubyJdbcConnection extends RubyObject {
3221
3014
  finally { close(tablesSet); }
3222
3015
  }
3223
3016
 
3224
- @Deprecated
3225
- protected IRubyObject matchTables(final Ruby runtime,
3226
- final Connection connection,
3227
- final String catalog, final String schemaPattern,
3228
- final String tablePattern, final String[] types,
3229
- final boolean checkExistsOnly) throws SQLException {
3230
- return matchTables(runtime.getCurrentContext(), connection, catalog, schemaPattern, tablePattern, types, checkExistsOnly);
3231
- }
3232
-
3233
3017
  // NOTE java.sql.DatabaseMetaData.getTables :
3234
3018
  protected final static int TABLES_TABLE_CAT = 1;
3235
3019
  protected final static int TABLES_TABLE_SCHEM = 2;
@@ -3318,7 +3102,7 @@ public class RubyJdbcConnection extends RubyObject {
3318
3102
  final String tabName = results.getString(TABLE_NAME);
3319
3103
  final RubyString tableName = cachedString(context, caseConvertIdentifierForRails(metaData, tabName));
3320
3104
 
3321
- final IRubyObject type_metadata = getAdapter().callMethod(context, "fetch_type_metadata", sqlType);
3105
+ final IRubyObject type_metadata = adapter.callMethod(context, "fetch_type_metadata", sqlType);
3322
3106
 
3323
3107
  // (name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
3324
3108
  final IRubyObject[] args = new IRubyObject[] {
@@ -3334,7 +3118,7 @@ public class RubyJdbcConnection extends RubyObject {
3334
3118
  ResultSet primaryKeys = null;
3335
3119
  try {
3336
3120
  primaryKeys = metaData.getPrimaryKeys(components.catalog, components.schema, components.name);
3337
- final List<String> primaryKeyNames = new ArrayList<String>(4);
3121
+ final List<String> primaryKeyNames = new ArrayList<>(4);
3338
3122
  while ( primaryKeys.next() ) {
3339
3123
  primaryKeyNames.add( primaryKeys.getString(COLUMN_NAME) );
3340
3124
  }
@@ -3383,7 +3167,7 @@ public class RubyJdbcConnection extends RubyObject {
3383
3167
  // not have and auto-generated ID column :
3384
3168
  boolean next = genKeys.next() && genKeys.getMetaData().getColumnCount() > 0;
3385
3169
  // singleResult == null - guess if only single key returned
3386
- if ( singleResult == null || singleResult.booleanValue() ) {
3170
+ if ( singleResult == null || singleResult) {
3387
3171
  if ( next ) {
3388
3172
  firstKey = mapGeneratedKey(runtime, genKeys);
3389
3173
  if ( singleResult != null || ! genKeys.next() ) {
@@ -3416,7 +3200,7 @@ public class RubyJdbcConnection extends RubyObject {
3416
3200
  if (supportsGeneratedKeys == null) {
3417
3201
  supportsGeneratedKeys = this.supportsGeneratedKeys = connection.getMetaData().supportsGetGeneratedKeys();
3418
3202
  }
3419
- return supportsGeneratedKeys.booleanValue();
3203
+ return supportsGeneratedKeys;
3420
3204
  }
3421
3205
 
3422
3206
  /**
@@ -3448,8 +3232,8 @@ public class RubyJdbcConnection extends RubyObject {
3448
3232
  final ColumnData[] columns = extractColumns(context, connection, resultSet, false);
3449
3233
 
3450
3234
  final Ruby runtime = context.runtime;
3451
- final IRubyObject[] blockArgs = new IRubyObject[columns.length];
3452
3235
  while ( resultSet.next() ) {
3236
+ final IRubyObject[] blockArgs = new IRubyObject[columns.length];
3453
3237
  for ( int i = 0; i < columns.length; i++ ) {
3454
3238
  final ColumnData column = columns[i];
3455
3239
  blockArgs[i] = jdbcToRuby(context, runtime, column.index, column.type, resultSet);
@@ -3475,16 +3259,6 @@ public class RubyJdbcConnection extends RubyObject {
3475
3259
  return setupColumns(context, connection, resultSet.getMetaData(), downCase);
3476
3260
  }
3477
3261
 
3478
- /**
3479
- * @deprecated use {@link #extractColumns(ThreadContext, Connection, ResultSet, boolean)}
3480
- */
3481
- @Deprecated
3482
- protected ColumnData[] extractColumns(final Ruby runtime,
3483
- final Connection connection, final ResultSet resultSet,
3484
- final boolean downCase) throws SQLException {
3485
- return extractColumns(runtime.getCurrentContext(), connection, resultSet, downCase);
3486
- }
3487
-
3488
3262
  protected <T> T withConnection(final ThreadContext context, final Callable<T> block)
3489
3263
  throws RaiseException {
3490
3264
  try {
@@ -3590,13 +3364,12 @@ public class RubyJdbcConnection extends RubyObject {
3590
3364
  }
3591
3365
 
3592
3366
  protected boolean isTransient(final Exception exception) {
3593
- if ( exception instanceof SQLTransientException ) return true;
3594
- return false;
3367
+ return exception instanceof SQLTransientException;
3595
3368
  }
3596
3369
 
3597
3370
  protected boolean isRecoverable(final Exception exception) {
3598
- if ( exception instanceof SQLRecoverableException) return true;
3599
- return false; // exception instanceof SQLException; // pre JDBC 4.0 drivers?
3371
+ return exception instanceof SQLRecoverableException;
3372
+ // exception instanceof SQLException; // pre JDBC 4.0 drivers?
3600
3373
  }
3601
3374
 
3602
3375
  private static Throwable getCause(Throwable exception) {
@@ -3754,6 +3527,11 @@ public class RubyJdbcConnection extends RubyObject {
3754
3527
  return Result.newInstance(context, columnsToArray(context, columns), rows, Block.NULL_BLOCK); // Result.new
3755
3528
  }
3756
3529
 
3530
+ protected static IRubyObject newEmptyResult(final ThreadContext context) {
3531
+ final RubyClass Result = getResult(context.runtime);
3532
+ return Result.newInstance(context, RubyArray.newEmptyArray(context.runtime), RubyArray.newEmptyArray(context.runtime), Block.NULL_BLOCK); // Result.new
3533
+ }
3534
+
3757
3535
  private static RubyArray columnsToArray(ThreadContext context, ColumnData[] columns) {
3758
3536
  final IRubyObject[] cols = new IRubyObject[columns.length];
3759
3537
 
@@ -4006,7 +3784,7 @@ public class RubyJdbcConnection extends RubyObject {
4006
3784
  public static void debugStackTrace(final ThreadContext context, final Throwable e) {
4007
3785
  if ( debug || ( context != null && context.runtime.isDebug() ) ) {
4008
3786
  final PrintStream out = context != null ? context.runtime.getOut() : System.out;
4009
- if ( debugStackTrace == null || debugStackTrace.booleanValue() ) {
3787
+ if ( debugStackTrace == null || debugStackTrace) {
4010
3788
  e.printStackTrace(out);
4011
3789
  }
4012
3790
  else {
@@ -4022,8 +3800,7 @@ public class RubyJdbcConnection extends RubyObject {
4022
3800
  private static boolean driverUsedLogged;
4023
3801
 
4024
3802
  private void logDriverUsed(final Connection connection) {
4025
- if ( isDebug() ) {
4026
- if ( driverUsedLogged ) return;
3803
+ if (debug && !driverUsedLogged) {
4027
3804
  driverUsedLogged = true;
4028
3805
  try {
4029
3806
  final DatabaseMetaData meta = connection.getMetaData();