activerecord-jdbc-adapter 72.0-java → 80.0.pre1-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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +129 -24
  3. data/.mise.toml +3 -0
  4. data/Gemfile +42 -47
  5. data/README.md +3 -2
  6. data/Rakefile +62 -14
  7. data/activerecord-jdbc-adapter.gemspec +2 -2
  8. data/lib/arjdbc/abstract/core.rb +1 -1
  9. data/lib/arjdbc/abstract/database_statements.rb +11 -7
  10. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  11. data/lib/arjdbc/postgresql/adapter.rb +4 -1
  12. data/lib/arjdbc/sqlite3/adapter.rb +48 -7
  13. data/lib/arjdbc/version.rb +1 -1
  14. data/pom.xml +3 -3
  15. data/rakelib/db.rake +5 -3
  16. data/rakelib/rails.rake +0 -1
  17. data/src/java/arjdbc/ArJdbcModule.java +13 -10
  18. data/src/java/arjdbc/db2/DB2Module.java +4 -4
  19. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +8 -9
  20. data/src/java/arjdbc/h2/H2Module.java +2 -1
  21. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +8 -7
  22. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +5 -6
  23. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +4 -3
  24. data/src/java/arjdbc/jdbc/DriverWrapper.java +13 -8
  25. data/src/java/arjdbc/jdbc/JdbcResult.java +10 -7
  26. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +168 -154
  27. data/src/java/arjdbc/mssql/MSSQLModule.java +3 -3
  28. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +13 -9
  29. data/src/java/arjdbc/mysql/MySQLModule.java +3 -3
  30. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +30 -24
  31. data/src/java/arjdbc/oracle/OracleModule.java +2 -3
  32. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +22 -18
  33. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +2 -3
  34. data/src/java/arjdbc/postgresql/PostgreSQLResult.java +24 -12
  35. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +16 -12
  36. data/src/java/arjdbc/sqlite3/SQLite3Module.java +2 -3
  37. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +78 -29
  38. data/src/java/arjdbc/util/DateTimeUtils.java +7 -5
  39. data/src/java/arjdbc/util/ObjectSupport.java +2 -2
  40. data/src/java/arjdbc/util/StringHelper.java +1 -1
  41. metadata +6 -6
  42. data/.travis.yml +0 -128
@@ -223,17 +223,29 @@ module ArJdbc
223
223
 
224
224
  # REFERENTIAL INTEGRITY ====================================
225
225
 
226
+ def execute_batch(statements, name = nil, **kwargs)
227
+ if statements.is_a?(Array)
228
+ # SQLite JDBC doesn't support multiple statements in one execute
229
+ # Execute each statement separately
230
+ statements.each do |sql|
231
+ raw_execute(sql, name, **kwargs.merge(batch: true))
232
+ end
233
+ else
234
+ raw_execute(statements, name, batch: true, **kwargs)
235
+ end
236
+ end
237
+
226
238
  def disable_referential_integrity # :nodoc:
227
239
  old_foreign_keys = query_value("PRAGMA foreign_keys")
228
240
  old_defer_foreign_keys = query_value("PRAGMA defer_foreign_keys")
229
241
 
230
242
  begin
231
- execute("PRAGMA defer_foreign_keys = ON")
232
- execute("PRAGMA foreign_keys = OFF")
243
+ raw_execute("PRAGMA defer_foreign_keys = ON", "SCHEMA", allow_retry: false, materialize_transactions: false)
244
+ raw_execute("PRAGMA foreign_keys = OFF", "SCHEMA", allow_retry: false, materialize_transactions: false)
233
245
  yield
234
246
  ensure
235
- execute("PRAGMA defer_foreign_keys = #{old_defer_foreign_keys}")
236
- execute("PRAGMA foreign_keys = #{old_foreign_keys}")
247
+ raw_execute("PRAGMA defer_foreign_keys = #{old_defer_foreign_keys}", "SCHEMA", allow_retry: false, materialize_transactions: false)
248
+ raw_execute("PRAGMA foreign_keys = #{old_foreign_keys}", "SCHEMA", allow_retry: false, materialize_transactions: false)
237
249
  end
238
250
  end
239
251
 
@@ -388,6 +400,24 @@ module ArJdbc
388
400
  end
389
401
  end
390
402
 
403
+ # Returns a list of defined virtual tables (for Rails 8 compatibility)
404
+ VIRTUAL_TABLE_REGEX = /USING\s+(\w+)(?:\s*\((.*)\))?/im
405
+ def virtual_tables
406
+ query = <<~SQL
407
+ SELECT name, sql FROM sqlite_master
408
+ WHERE type = 'table' AND sql LIKE 'CREATE VIRTUAL TABLE%';
409
+ SQL
410
+
411
+ exec_query(query, "SCHEMA").cast_values.each_with_object({}) do |(name, sql), memo|
412
+ match = sql.match(VIRTUAL_TABLE_REGEX)
413
+ next unless match
414
+
415
+ module_name = match[1]
416
+ arguments = match[2] || ""
417
+ memo[name] = [module_name, arguments.strip]
418
+ end.to_a
419
+ end
420
+
391
421
  def build_insert_sql(insert) # :nodoc:
392
422
  sql = +"INSERT #{insert.into} #{insert.values_list}"
393
423
 
@@ -791,7 +821,17 @@ module ArJdbc
791
821
  DEFAULT_PRAGMAS.merge(pragmas).each do |pragma, value|
792
822
  if ::SQLite3::Pragmas.respond_to?(pragma)
793
823
  stmt = ::SQLite3::Pragmas.public_send(pragma, value)
794
- raw_execute(stmt, "SCHEMA")
824
+ # Skip pragma execution if we're inside a transaction and it's not allowed
825
+ begin
826
+ raw_execute(stmt, "SCHEMA")
827
+ rescue => e
828
+ if e.message.include?("Safety level may not be changed inside a transaction")
829
+ # Log warning and skip this pragma
830
+ warn "Cannot set pragma '#{pragma}' inside a transaction, skipping"
831
+ else
832
+ raise
833
+ end
834
+ end
795
835
  else
796
836
  warn "Unknown SQLite pragma: #{pragma}"
797
837
  end
@@ -845,7 +885,7 @@ module ActiveRecord::ConnectionAdapters
845
885
  include ArJdbc::Abstract::ConnectionManagement
846
886
  include ArJdbc::Abstract::DatabaseStatements
847
887
  include ArJdbc::Abstract::StatementCache
848
- include ArJdbc::Abstract::TransactionSupport
888
+ # Don't include TransactionSupport - use Rails' SQLite3::DatabaseStatements instead
849
889
 
850
890
 
851
891
  ##
@@ -954,7 +994,8 @@ module ActiveRecord::ConnectionAdapters
954
994
 
955
995
  # because the JDBC driver doesn't like multiple SQL statements in one JDBC statement
956
996
  def combine_multi_statements(total_sql)
957
- total_sql
997
+ # For Rails 8 compatibility - join multiple statements with semicolon
998
+ total_sql.is_a?(Array) ? total_sql.join(";\n") : total_sql
958
999
  end
959
1000
 
960
1001
  def type_map
@@ -1,3 +1,3 @@
1
1
  module ArJdbc
2
- VERSION = '72.0'
2
+ VERSION = '80.0.pre1'
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.2.6.0</jruby.version>
15
+ <jruby.version>10.0.0.1</jruby.version>
16
16
  </properties>
17
17
 
18
18
  <issueManagement>
@@ -103,8 +103,8 @@
103
103
  <artifactId>maven-compiler-plugin</artifactId>
104
104
  <version>2.5.1</version>
105
105
  <configuration>
106
- <source>1.8</source>
107
- <target>1.8</target>
106
+ <source>21</source>
107
+ <target>21</target>
108
108
  </configuration>
109
109
  </plugin>
110
110
  </plugins>
data/rakelib/db.rake CHANGED
@@ -39,7 +39,7 @@ GRANT ALL PRIVILEGES ON `test\_%`.* TO #{MYSQL_CONFIG[:username]}@localhost;
39
39
  task :postgresql do
40
40
  require File.expand_path('../../test/shared_helper', __FILE__)
41
41
  fail 'could not create test database: psql executable not found' unless psql = which('psql')
42
- fail 'could not create test database: missing "postgres" role' unless PostgresHelper.postgres_role?
42
+ fail 'could not create test database: missing "arjdbc" role' unless PostgresHelper.postgres_role?
43
43
 
44
44
  load 'test/db/postgres_config.rb' # rescue nil
45
45
  puts POSTGRES_CONFIG.inspect if $VERBOSE
@@ -53,11 +53,13 @@ CREATE DATABASE #{POSTGRES_CONFIG[:database]} OWNER #{POSTGRES_CONFIG[:username]
53
53
  ENCODING '#{POSTGRES_CONFIG[:encoding]}' LC_COLLATE '#{POSTGRES_CONFIG[:collate]}' LC_CTYPE '#{POSTGRES_CONFIG[:collate]}';
54
54
  SQL
55
55
 
56
- params = { '-U' => ENV['PSQL_USER'] || 'postgres' }
56
+ params = { '-U' => ENV['PGUSER'] || 'arjdbc', '-d' => 'postgres' }
57
+ params['-h'] = ENV['PGHOST'] if ENV['PGHOST']
58
+ params['-p'] = ENV['PGPORT'] if ENV['PGPORT']
57
59
  params['-q'] = nil unless $VERBOSE
58
60
 
59
61
  puts "Creating PostgreSQL (test) database: #{POSTGRES_CONFIG[:database]}"
60
- sh "cat #{script.path} | #{psql} #{params.to_a.join(' ')}", verbose: $VERBOSE
62
+ sh "PGPASSWORD=#{ENV['PGPASSWORD'] || 'arjdbc'} cat #{script.path} | #{psql} #{params.to_a.join(' ')}", verbose: $VERBOSE
61
63
  end
62
64
  task postgres: :postgresql
63
65
 
data/rakelib/rails.rake CHANGED
@@ -52,7 +52,6 @@ namespace :rails do
52
52
  ruby_opts_string += " -C \"#{ar_path}\""
53
53
  ruby_opts_string += " -rbundler/setup"
54
54
  ruby_opts_string += " -rminitest -rminitest/excludes" unless ENV['NO_EXCLUDES'].eql?('true')
55
- ruby_opts_string += " -rmonkey_patches"
56
55
  file_list = ENV["TEST"] ? FileList[ ENV["TEST"].split(',') ] : test_files_finder.call
57
56
  file_list_string = file_list.map { |fn| "\"#{fn}\"" }.join(' ')
58
57
  # test_loader_code = "-e \"ARGV.each{|f| require f}\"" # :direct
@@ -43,6 +43,9 @@ import org.jruby.util.ByteList;
43
43
 
44
44
  import arjdbc.jdbc.RubyJdbcConnection;
45
45
  import static arjdbc.jdbc.RubyJdbcConnection.getJdbcConnection;
46
+ import static org.jruby.api.Access.getModule;
47
+ import static org.jruby.api.Access.objectClass;
48
+ import static org.jruby.api.Create.allocArray;
46
49
 
47
50
  /**
48
51
  * ::ArJdbc
@@ -52,9 +55,10 @@ import static arjdbc.jdbc.RubyJdbcConnection.getJdbcConnection;
52
55
  public class ArJdbcModule {
53
56
 
54
57
  public static RubyModule load(final Ruby runtime) {
55
- final RubyModule arJdbc = runtime.getOrCreateModule("ArJdbc");
56
- arJdbc.defineAnnotatedMethods( ArJdbcModule.class );
57
- return arJdbc;
58
+ var context = runtime.getCurrentContext();
59
+ return objectClass(context).
60
+ defineModuleUnder(context, "ArJdbc").
61
+ defineMethods(context, ArJdbcModule.class);
58
62
  }
59
63
 
60
64
  public static RubyModule get(final Ruby runtime) {
@@ -142,7 +146,7 @@ public class ArJdbcModule {
142
146
  catch (NoSuchMethodException e) {
143
147
  // "old" e.g. MySQLRubyJdbcConnection.createMySQLJdbcConnectionClass(runtime, jdbcConnection)
144
148
  connection.getMethod("create" + moduleName + "JdbcConnectionClass", Ruby.class, RubyClass.class).
145
- invoke(null, runtime, getJdbcConnection(runtime));
149
+ invoke(null, runtime, getJdbcConnection(context));
146
150
  }
147
151
  }
148
152
  }
@@ -162,20 +166,19 @@ public class ArJdbcModule {
162
166
  */
163
167
  @JRubyMethod(name = "modules", meta = true)
164
168
  public static IRubyObject modules(final ThreadContext context, final IRubyObject self) {
165
- final Ruby runtime = context.getRuntime();
166
169
  final RubyModule arJdbc = (RubyModule) self;
167
170
 
168
171
  final Collection<String> constants = arJdbc.getConstantNames();
169
- final RubyArray modules = runtime.newArray( constants.size() );
172
+ final RubyArray modules = allocArray(context, constants.size());
170
173
 
171
174
  for ( final String name : constants ) {
172
- final IRubyObject constant = arJdbc.getConstant(name, false);
175
+ final IRubyObject constant = arJdbc.getConstant(context, name, false);
173
176
  // isModule: return false for Ruby Classes
174
177
  if ( constant != null && constant.isModule() ) {
175
178
  if ( "Util".equals(name) ) continue;
176
179
  if ( "SerializedAttributesHelper".equals(name) ) continue; // deprecated
177
180
  if ( "Version".equals(name) ) continue; // deprecated
178
- modules.append( constant );
181
+ modules.append(context, constant);
179
182
  }
180
183
  }
181
184
  return modules;
@@ -230,9 +233,9 @@ public class ArJdbcModule {
230
233
  return null;
231
234
  }
232
235
 
233
- final RubyModule jdbc = runtime.getModule("Jdbc");
236
+ final RubyModule jdbc = getModule(context, "Jdbc");
234
237
  if ( jdbc != null ) { // Jdbc::MySQL
235
- final RubyModule constant = (RubyModule) jdbc.getConstantAt(constName);
238
+ final RubyModule constant = jdbc.getModule(context, constName);
236
239
  if ( constant != null ) { // ::Jdbc::MySQL.load_driver :
237
240
  if ( constant.respondsTo("load_driver") ) {
238
241
  IRubyObject result = constant.callMethod("load_driver");
@@ -26,6 +26,7 @@ package arjdbc.db2;
26
26
  import static arjdbc.util.QuotingUtils.BYTES_0;
27
27
  import static arjdbc.util.QuotingUtils.BYTES_1;
28
28
  import static arjdbc.util.QuotingUtils.quoteSingleQuotesWithFallback;
29
+ import static org.jruby.api.Create.newString;
29
30
 
30
31
  import org.jruby.Ruby;
31
32
  import org.jruby.RubyModule;
@@ -42,9 +43,8 @@ import org.jruby.runtime.builtin.IRubyObject;
42
43
  public class DB2Module {
43
44
 
44
45
  public static RubyModule load(final RubyModule arJdbc) {
45
- RubyModule db2 = arJdbc.defineModuleUnder("DB2");
46
- db2.defineAnnotatedMethods( DB2Module.class );
47
- return db2;
46
+ var context = arJdbc.getRuntime().getCurrentContext();
47
+ return arJdbc.defineModuleUnder(context, "DB2").defineMethods(context, DB2Module.class);
48
48
  }
49
49
 
50
50
  public static RubyModule load(final Ruby runtime) {
@@ -63,7 +63,7 @@ public class DB2Module {
63
63
  public static IRubyObject quoted_true(
64
64
  final ThreadContext context,
65
65
  final IRubyObject self) {
66
- return RubyString.newString(context.runtime, BYTES_1);
66
+ return newString(context, BYTES_1);
67
67
  }
68
68
 
69
69
  @JRubyMethod(name = "quoted_false", required = 0, frame = false)
@@ -54,17 +54,16 @@ public class DB2RubyJdbcConnection extends RubyJdbcConnection {
54
54
  super(runtime, metaClass);
55
55
  }
56
56
 
57
- public static RubyClass createDB2JdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
58
- RubyClass clazz = getConnectionAdapters(runtime).
59
- defineClassUnder("DB2JdbcConnection", jdbcConnection, ALLOCATOR);
60
- clazz.defineAnnotatedMethods(DB2RubyJdbcConnection.class);
61
-
62
- return clazz;
57
+ public static RubyClass createDB2JdbcConnectionClass(ThreadContext context, RubyClass jdbcConnection) {
58
+ return getConnectionAdapters(context).
59
+ defineClassUnder(context, "DB2JdbcConnection", jdbcConnection, ALLOCATOR).
60
+ defineMethods(context, DB2RubyJdbcConnection.class);
63
61
  }
64
62
 
65
63
  public static RubyClass load(final Ruby runtime) {
66
- RubyClass jdbcConnection = getJdbcConnection(runtime);
67
- return createDB2JdbcConnectionClass(runtime, jdbcConnection);
64
+ var context = runtime.getCurrentContext();
65
+ RubyClass jdbcConnection = getJdbcConnection(context);
66
+ return createDB2JdbcConnectionClass(context, jdbcConnection);
68
67
  }
69
68
 
70
69
  protected static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
@@ -112,7 +111,7 @@ public class DB2RubyJdbcConnection extends RubyJdbcConnection {
112
111
  try {
113
112
  statement = connection.prepareStatement("VALUES IDENTITY_VAL_LOCAL()");
114
113
  genKeys = statement.executeQuery();
115
- return doMapGeneratedKeys(context.runtime, genKeys, true);
114
+ return doMapGeneratedKeys(context, genKeys, true);
116
115
  }
117
116
  catch (final SQLException e) {
118
117
  debugMessage(context.runtime, "failed to get generated keys: ", e);
@@ -37,7 +37,8 @@ import org.jruby.RubyModule;
37
37
  public class H2Module {
38
38
 
39
39
  public static RubyModule load(final RubyModule arJdbc) {
40
- RubyModule h2 = arJdbc.defineModuleUnder("H2");
40
+ var context = arJdbc.getRuntime().getCurrentContext();
41
+ RubyModule h2 = arJdbc.defineModuleUnder(context, "H2");
41
42
  // NOTE: currently no Java implemented Ruby methods
42
43
  // h2.defineAnnotatedMethods( H2Module.class );
43
44
  return h2;
@@ -28,9 +28,11 @@ package arjdbc.h2;
28
28
  import java.sql.Connection;
29
29
  import java.sql.SQLException;
30
30
 
31
+ import arjdbc.db2.DB2RubyJdbcConnection;
31
32
  import org.jruby.Ruby;
32
33
  import org.jruby.RubyClass;
33
34
  import org.jruby.runtime.ObjectAllocator;
35
+ import org.jruby.runtime.ThreadContext;
34
36
  import org.jruby.runtime.builtin.IRubyObject;
35
37
 
36
38
  /**
@@ -45,16 +47,15 @@ public class H2RubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection {
45
47
  super(runtime, metaClass);
46
48
  }
47
49
 
48
- public static RubyClass createH2JdbcConnectionClass(Ruby runtime, RubyClass jdbcConnection) {
49
- RubyClass clazz = getConnectionAdapters(runtime).
50
- defineClassUnder("H2JdbcConnection", jdbcConnection, ALLOCATOR);
51
- clazz.defineAnnotatedMethods(H2RubyJdbcConnection.class);
52
- return clazz;
50
+ public static RubyClass createH2JdbcConnectionClass(ThreadContext context, RubyClass jdbcConnection) {
51
+ return getConnectionAdapters(context).
52
+ defineClassUnder(context, "H2JdbcConnection", jdbcConnection, ALLOCATOR).
53
+ defineMethods(context, H2RubyJdbcConnection.class);
53
54
  }
54
55
 
55
56
  public static RubyClass load(final Ruby runtime) {
56
- RubyClass jdbcConnection = getJdbcConnection(runtime);
57
- return createH2JdbcConnectionClass(runtime, jdbcConnection);
57
+ var context = runtime.getCurrentContext();
58
+ return createH2JdbcConnectionClass(context, getJdbcConnection(context));
58
59
  }
59
60
 
60
61
  protected static ObjectAllocator ALLOCATOR = new ObjectAllocator() {
@@ -28,10 +28,10 @@ package arjdbc.hsqldb;
28
28
  import static arjdbc.util.QuotingUtils.BYTES_0;
29
29
  import static arjdbc.util.QuotingUtils.BYTES_1;
30
30
  import static arjdbc.util.QuotingUtils.quoteSingleQuotesWithFallback;
31
+ import static org.jruby.api.Create.newString;
31
32
 
32
33
  import org.jruby.Ruby;
33
34
  import org.jruby.RubyModule;
34
- import org.jruby.RubyString;
35
35
  import org.jruby.anno.JRubyMethod;
36
36
  import org.jruby.runtime.ThreadContext;
37
37
  import org.jruby.runtime.builtin.IRubyObject;
@@ -39,9 +39,8 @@ import org.jruby.runtime.builtin.IRubyObject;
39
39
  public class HSQLDBModule {
40
40
 
41
41
  public static RubyModule load(final RubyModule arJdbc) {
42
- RubyModule hsqldb = arJdbc.defineModuleUnder("HSQLDB");
43
- hsqldb.defineAnnotatedMethods( HSQLDBModule.class );
44
- return hsqldb;
42
+ var context = arJdbc.getRuntime().getCurrentContext();
43
+ return arJdbc.defineModuleUnder(context, "HSQLDB").defineMethods(context, HSQLDBModule.class);
45
44
  }
46
45
 
47
46
  public static RubyModule load(final Ruby runtime) {
@@ -60,14 +59,14 @@ public class HSQLDBModule {
60
59
  public static IRubyObject quoted_true(
61
60
  final ThreadContext context,
62
61
  final IRubyObject self) {
63
- return RubyString.newString(context.getRuntime(), BYTES_1);
62
+ return newString(context, BYTES_1);
64
63
  }
65
64
 
66
65
  @JRubyMethod(name = "quoted_false", required = 0, frame = false)
67
66
  public static IRubyObject quoted_false(
68
67
  final ThreadContext context,
69
68
  final IRubyObject self) {
70
- return RubyString.newString(context.getRuntime(), BYTES_0);
69
+ return newString(context, BYTES_0);
71
70
  }
72
71
 
73
72
  }
@@ -36,6 +36,7 @@ import org.jruby.util.SafePropertyAccessor;
36
36
 
37
37
  import static arjdbc.jdbc.RubyJdbcConnection.getConnectionNotEstablished;
38
38
  import static arjdbc.jdbc.RubyJdbcConnection.wrapException;
39
+ import static org.jruby.api.Access.runtimeErrorClass;
39
40
 
40
41
  /**
41
42
  *
@@ -103,7 +104,7 @@ final class DataSourceConnectionFactory implements ConnectionFactory {
103
104
  if ( ! ( bound instanceof DataSource ) ) {
104
105
  if ( bound == null ) throw new NameNotFoundException(); // unlikely to happen
105
106
  final String msg = "bound object at '" + name + "' is not a " + DataSource.class.getName() + " but a " + bound.getClass().getName() + "\n" + bound;
106
- throw wrapException(context, getConnectionNotEstablished(context.runtime), new ClassCastException(msg), msg);
107
+ throw wrapException(context, getConnectionNotEstablished(context), new ClassCastException(msg), msg);
107
108
  }
108
109
  return (DataSource) bound;
109
110
  }
@@ -124,10 +125,10 @@ final class DataSourceConnectionFactory implements ConnectionFactory {
124
125
  else {
125
126
  message = "unable to lookup data source - name: '" + name + "' not found";
126
127
  }
127
- throw wrapException(context, getConnectionNotEstablished(context.runtime), e, message);
128
+ throw wrapException(context, getConnectionNotEstablished(context), e, message);
128
129
  }
129
130
  catch (NamingException e) {
130
- throw wrapException(context, context.runtime.getRuntimeError(), e);
131
+ throw wrapException(context, runtimeErrorClass(context), e);
131
132
  }
132
133
  }
133
134
 
@@ -23,6 +23,7 @@
23
23
  */
24
24
  package arjdbc.jdbc;
25
25
 
26
+ import java.lang.reflect.InvocationTargetException;
26
27
  import java.sql.Connection;
27
28
  import java.sql.Driver;
28
29
  import java.sql.SQLException;
@@ -45,7 +46,7 @@ public class DriverWrapper {
45
46
  private final Properties properties;
46
47
 
47
48
  DriverWrapper(final Ruby runtime, final String name, final Properties properties)
48
- throws ClassCastException, InstantiationException, IllegalAccessException {
49
+ throws ClassCastException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
49
50
  this.driver = allocateDriver( loadDriver(runtime, name) );
50
51
  this.properties = properties == null ? new Properties() : properties;
51
52
  }
@@ -59,18 +60,22 @@ public class DriverWrapper {
59
60
  }
60
61
 
61
62
  private Driver allocateDriver(final Class<? extends Driver> driverClass)
62
- throws InstantiationException, IllegalAccessException {
63
- return driverClass.newInstance();
63
+ throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
64
+ return driverClass.getDeclaredConstructor().newInstance();
64
65
  }
65
66
 
66
67
  protected static Class<? extends Driver> loadDriver(final Ruby runtime, final String name)
67
68
  throws ClassCastException {
68
- @SuppressWarnings("unchecked")
69
- Class<? extends Driver> klass = runtime.getJavaSupport().loadJavaClassVerbose(name);
70
- if ( ! Driver.class.isAssignableFrom(klass) ) {
71
- throw new ClassCastException(klass + " is not assignable from " + Driver.class);
69
+ try {
70
+ @SuppressWarnings("unchecked")
71
+ Class<? extends Driver> klass = (Class<? extends Driver>) runtime.getJavaSupport().loadJavaClass(name);
72
+ if ( ! Driver.class.isAssignableFrom(klass) ) {
73
+ throw new ClassCastException(klass + " is not assignable from " + Driver.class);
74
+ }
75
+ return klass;
76
+ } catch (ClassNotFoundException e) {
77
+ throw new RuntimeException("Cannot load driver class: " + name, e);
72
78
  }
73
- return klass;
74
79
  }
75
80
 
76
81
  public Connection connect(final String url, final String user, final String pass)
@@ -14,6 +14,10 @@ import org.jruby.runtime.Block;
14
14
  import org.jruby.runtime.ThreadContext;
15
15
  import org.jruby.runtime.builtin.IRubyObject;
16
16
 
17
+ import static org.jruby.api.Create.newArray;
18
+ import static org.jruby.api.Create.newArrayNoCopy;
19
+ import static org.jruby.api.Create.newHash;
20
+
17
21
  /**
18
22
  * This is a base Result class to be returned as the "raw" result.
19
23
  * It should be overridden for specific adapters to manage type maps
@@ -31,7 +35,7 @@ public class JdbcResult extends RubyObject {
31
35
  protected JdbcResult(ThreadContext context, RubyClass clazz, RubyJdbcConnection connection, ResultSet resultSet) throws SQLException {
32
36
  super(context.runtime, clazz);
33
37
 
34
- values = context.runtime.newArray();
38
+ values = newArray(context);
35
39
  this.connection = connection;
36
40
 
37
41
  final ResultSetMetaData resultMetaData = resultSet.getMetaData();
@@ -86,7 +90,7 @@ public class JdbcResult extends RubyObject {
86
90
 
87
91
  for (int i = 0; i < tuples.length; i++) {
88
92
  RubyArray currentRow = (RubyArray) values.eltInternal(i);
89
- RubyHash hash = RubyHash.newHash(context.runtime);
93
+ RubyHash hash = newHash(context);
90
94
  for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
91
95
  hash.fastASet(columnNames[columnIndex], currentRow.eltInternal(columnIndex));
92
96
  }
@@ -101,17 +105,16 @@ public class JdbcResult extends RubyObject {
101
105
  * @throws SQLException throws!
102
106
  */
103
107
  private void processResultSet(final ThreadContext context, final ResultSet resultSet) throws SQLException {
104
- Ruby runtime = context.runtime;
105
108
  int columnCount = columnNames.length;
106
109
 
107
110
  while (resultSet.next()) {
108
111
  final IRubyObject[] row = new IRubyObject[columnCount];
109
112
 
110
113
  for (int i = 0; i < columnCount; i++) {
111
- row[i] = connection.jdbcToRuby(context, runtime, i + 1, columnTypes[i], resultSet); // Result Set is 1 based
114
+ row[i] = connection.jdbcToRuby(context, context.runtime, i + 1, columnTypes[i], resultSet); // Result Set is 1 based
112
115
  }
113
116
 
114
- values.append(RubyArray.newArrayNoCopy(context.runtime, row));
117
+ values.append(context, newArrayNoCopy(context, row));
115
118
  }
116
119
  }
117
120
 
@@ -122,9 +125,9 @@ public class JdbcResult extends RubyObject {
122
125
  * @throws SQLException can be caused by postgres generating its type map
123
126
  */
124
127
  public IRubyObject toARResult(final ThreadContext context) throws SQLException {
125
- final RubyClass Result = RubyJdbcConnection.getResult(context.runtime);
128
+ final RubyClass Result = RubyJdbcConnection.getResult(context);
126
129
  // FIXME: Is this broken? no copy of an array AR::Result can modify? or should it be frozen?
127
- final RubyArray rubyColumnNames = RubyArray.newArrayNoCopy(context.runtime, getColumnNames());
130
+ final RubyArray rubyColumnNames = newArrayNoCopy(context, getColumnNames());
128
131
  return Result.newInstance(context, rubyColumnNames, values, columnTypeMap(context), Block.NULL_BLOCK);
129
132
  }
130
133
  }