activerecord-jdbc-alt-adapter 52.4.0-java → 61.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.nvimlog +0 -0
- data/.travis.yml +63 -39
- data/Gemfile +11 -4
- data/README.md +55 -35
- data/Rakefile +1 -1
- data/Rakefile.jdbc +8 -1
- data/activerecord-jdbc-adapter.gemspec +6 -9
- data/activerecord-jdbc-alt-adapter.gemspec +9 -12
- data/lib/arel/visitors/postgresql_jdbc.rb +1 -1
- data/lib/arel/visitors/sqlserver.rb +49 -23
- data/lib/arjdbc/abstract/connection_management.rb +7 -0
- data/lib/arjdbc/abstract/core.rb +17 -23
- data/lib/arjdbc/abstract/database_statements.rb +30 -2
- data/lib/arjdbc/abstract/statement_cache.rb +2 -5
- data/lib/arjdbc/abstract/transaction_support.rb +22 -7
- data/lib/arjdbc/db2/column.rb +0 -39
- data/lib/arjdbc/derby/adapter.rb +1 -20
- data/lib/arjdbc/firebird/adapter.rb +0 -21
- data/lib/arjdbc/h2/adapter.rb +0 -15
- data/lib/arjdbc/hsqldb/adapter.rb +0 -14
- data/lib/arjdbc/informix/adapter.rb +0 -23
- data/lib/arjdbc/jdbc/adapter.rb +3 -1
- data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
- data/lib/arjdbc/jdbc/base_ext.rb +3 -1
- data/lib/arjdbc/jdbc/callbacks.rb +2 -0
- data/lib/arjdbc/jdbc/column.rb +2 -0
- data/lib/arjdbc/jdbc/connection.rb +2 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
- data/lib/arjdbc/jdbc/error.rb +2 -0
- data/lib/arjdbc/jdbc/extension.rb +2 -0
- data/lib/arjdbc/jdbc/java.rb +3 -1
- data/lib/arjdbc/jdbc/railtie.rb +3 -1
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
- data/lib/arjdbc/jdbc/type_cast.rb +2 -0
- data/lib/arjdbc/jdbc/type_converter.rb +2 -0
- data/lib/arjdbc/mssql.rb +3 -1
- data/lib/arjdbc/mssql/adapter.rb +114 -36
- data/lib/arjdbc/mssql/column.rb +19 -1
- data/lib/arjdbc/mssql/connection_methods.rb +10 -2
- data/lib/arjdbc/mssql/database_limits.rb +9 -0
- data/lib/arjdbc/mssql/database_statements.rb +44 -6
- data/lib/arjdbc/mssql/errors.rb +2 -0
- data/lib/arjdbc/mssql/explain_support.rb +3 -1
- data/lib/arjdbc/mssql/extensions/attribute_methods.rb +6 -2
- data/lib/arjdbc/mssql/extensions/calculations.rb +2 -0
- data/lib/arjdbc/mssql/quoting.rb +38 -0
- data/lib/arjdbc/mssql/schema_creation.rb +25 -3
- data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
- data/lib/arjdbc/mssql/schema_dumper.rb +2 -0
- data/lib/arjdbc/mssql/schema_statements.rb +92 -22
- data/lib/arjdbc/mssql/transaction.rb +2 -0
- data/lib/arjdbc/mssql/types.rb +2 -0
- data/lib/arjdbc/mssql/types/binary_types.rb +2 -0
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +2 -0
- data/lib/arjdbc/mssql/types/deprecated_types.rb +2 -0
- data/lib/arjdbc/mssql/types/numeric_types.rb +2 -0
- data/lib/arjdbc/mssql/types/string_types.rb +2 -0
- data/lib/arjdbc/mssql/utils.rb +2 -0
- data/lib/arjdbc/mysql/adapter.rb +59 -21
- data/lib/arjdbc/mysql/connection_methods.rb +6 -1
- data/lib/arjdbc/postgresql/adapter.rb +257 -219
- data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
- data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
- data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
- data/lib/arjdbc/postgresql/column.rb +6 -4
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -0
- data/lib/arjdbc/postgresql/name.rb +2 -0
- data/lib/arjdbc/postgresql/oid_types.rb +7 -4
- data/lib/arjdbc/sqlite3/adapter.rb +266 -221
- data/lib/arjdbc/sqlite3/connection_methods.rb +26 -4
- data/lib/arjdbc/tasks/databases.rake +21 -13
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +126 -25
- data/lib/arjdbc/util/quoted_cache.rb +3 -1
- data/lib/arjdbc/util/serialized_attributes.rb +3 -1
- data/lib/arjdbc/util/table_copier.rb +3 -1
- data/lib/arjdbc/version.rb +3 -1
- data/pom.xml +4 -4
- data/rakelib/01-tomcat.rake +2 -2
- data/rakelib/rails.rake +1 -1
- data/src/java/arjdbc/ArJdbcModule.java +5 -5
- data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +549 -691
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +88 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +125 -53
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +97 -103
- data/src/java/arjdbc/util/DateTimeUtils.java +12 -4
- metadata +10 -18
|
@@ -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,8 @@ 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
|
+
import org.jruby.ext.date.RubyDateTime;
|
|
89
90
|
import org.jruby.javasupport.JavaEmbedUtils;
|
|
90
91
|
import org.jruby.javasupport.JavaUtil;
|
|
91
92
|
import org.jruby.runtime.Block;
|
|
@@ -124,6 +125,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
124
125
|
private IRubyObject config;
|
|
125
126
|
private IRubyObject adapter; // the AbstractAdapter instance we belong to
|
|
126
127
|
private volatile boolean connected = true;
|
|
128
|
+
private RubyClass attributeClass;
|
|
127
129
|
|
|
128
130
|
private boolean lazy = false; // final once set on initialize
|
|
129
131
|
private boolean jndi; // final once set on initialize
|
|
@@ -132,6 +134,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
132
134
|
|
|
133
135
|
protected RubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
|
|
134
136
|
super(runtime, metaClass);
|
|
137
|
+
attributeClass = runtime.getModule("ActiveModel").getClass("Attribute");
|
|
135
138
|
}
|
|
136
139
|
|
|
137
140
|
private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
|
@@ -147,11 +150,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
147
150
|
return JdbcConnection;
|
|
148
151
|
}
|
|
149
152
|
|
|
150
|
-
@Deprecated
|
|
151
|
-
public static RubyClass getJdbcConnectionClass(final Ruby runtime) {
|
|
152
|
-
return getConnectionAdapters(runtime).getClass("JdbcConnection");
|
|
153
|
-
}
|
|
154
|
-
|
|
155
153
|
public static RubyClass getJdbcConnection(final Ruby runtime) {
|
|
156
154
|
return (RubyClass) getConnectionAdapters(runtime).getConstantAt("JdbcConnection");
|
|
157
155
|
}
|
|
@@ -231,34 +229,30 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
231
229
|
|
|
232
230
|
@JRubyMethod(name = "transaction_isolation", alias = "get_transaction_isolation")
|
|
233
231
|
public IRubyObject get_transaction_isolation(final ThreadContext context) {
|
|
234
|
-
return withConnection(context,
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return context.runtime.newSymbol(isolationSymbol);
|
|
240
|
-
}
|
|
232
|
+
return withConnection(context, connection -> {
|
|
233
|
+
final int level = connection.getTransactionIsolation();
|
|
234
|
+
final String isolationSymbol = formatTransactionIsolationLevel(level);
|
|
235
|
+
if ( isolationSymbol == null ) return context.nil;
|
|
236
|
+
return context.runtime.newSymbol(isolationSymbol);
|
|
241
237
|
});
|
|
242
238
|
}
|
|
243
239
|
|
|
244
240
|
@JRubyMethod(name = "transaction_isolation=", alias = "set_transaction_isolation")
|
|
245
241
|
public IRubyObject set_transaction_isolation(final ThreadContext context, final IRubyObject isolation) {
|
|
246
|
-
return withConnection(context,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
242
|
+
return withConnection(context, connection -> {
|
|
243
|
+
final int level;
|
|
244
|
+
if ( isolation.isNil() ) {
|
|
245
|
+
level = connection.getMetaData().getDefaultTransactionIsolation();
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
level = mapTransactionIsolationLevel(isolation);
|
|
249
|
+
}
|
|
255
250
|
|
|
256
|
-
|
|
251
|
+
connection.setTransactionIsolation(level);
|
|
257
252
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
253
|
+
final String isolationSymbol = formatTransactionIsolationLevel(level);
|
|
254
|
+
if ( isolationSymbol == null ) return context.nil;
|
|
255
|
+
return context.runtime.newSymbol(isolationSymbol);
|
|
262
256
|
});
|
|
263
257
|
}
|
|
264
258
|
|
|
@@ -306,31 +300,25 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
306
300
|
final IRubyObject[] args) throws SQLException {
|
|
307
301
|
final IRubyObject isolation = args.length > 0 ? args[0] : null;
|
|
308
302
|
|
|
309
|
-
return withConnection(context,
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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);
|
|
303
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
304
|
+
final DatabaseMetaData metaData = connection.getMetaData();
|
|
305
|
+
final boolean supported;
|
|
306
|
+
if ( isolation != null && ! isolation.isNil() ) {
|
|
307
|
+
final int level = mapTransactionIsolationLevel(isolation);
|
|
308
|
+
supported = metaData.supportsTransactionIsolationLevel(level);
|
|
322
309
|
}
|
|
310
|
+
else {
|
|
311
|
+
final int level = metaData.getDefaultTransactionIsolation();
|
|
312
|
+
supported = level > Connection.TRANSACTION_NONE; // > 0
|
|
313
|
+
}
|
|
314
|
+
return context.runtime.newBoolean(supported);
|
|
323
315
|
});
|
|
324
316
|
}
|
|
325
317
|
|
|
326
318
|
@JRubyMethod(name = {"begin", "transaction"}, required = 1) // optional isolation argument for AR-4.0
|
|
327
319
|
public IRubyObject begin(final ThreadContext context, final IRubyObject isolation) {
|
|
328
320
|
try { // handleException == false so we can handle setTXIsolation
|
|
329
|
-
return withConnection(context, false,
|
|
330
|
-
public IRubyObject call(final Connection connection) throws SQLException {
|
|
331
|
-
return beginTransaction(context, connection, isolation == context.nil ? null : isolation);
|
|
332
|
-
}
|
|
333
|
-
});
|
|
321
|
+
return withConnection(context, false, connection -> beginTransaction(context, connection, isolation == context.nil ? null : isolation));
|
|
334
322
|
} catch (SQLException e) {
|
|
335
323
|
return handleException(context, e);
|
|
336
324
|
}
|
|
@@ -339,11 +327,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
339
327
|
@JRubyMethod(name = {"begin", "transaction"}) // optional isolation argument for AR-4.0
|
|
340
328
|
public IRubyObject begin(final ThreadContext context) {
|
|
341
329
|
try { // handleException == false so we can handle setTXIsolation
|
|
342
|
-
return withConnection(context, false,
|
|
343
|
-
public IRubyObject call(final Connection connection) throws SQLException {
|
|
344
|
-
return beginTransaction(context, connection, null);
|
|
345
|
-
}
|
|
346
|
-
});
|
|
330
|
+
return withConnection(context, false, connection -> beginTransaction(context, connection, null));
|
|
347
331
|
} catch (SQLException e) {
|
|
348
332
|
return handleException(context, e);
|
|
349
333
|
}
|
|
@@ -373,12 +357,12 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
373
357
|
|
|
374
358
|
@JRubyMethod(name = "commit")
|
|
375
359
|
public IRubyObject commit(final ThreadContext context) {
|
|
376
|
-
final Connection connection = getConnection(true);
|
|
377
360
|
try {
|
|
361
|
+
final Connection connection = getConnectionInternal(true);
|
|
378
362
|
if ( ! connection.getAutoCommit() ) {
|
|
379
363
|
try {
|
|
380
364
|
connection.commit();
|
|
381
|
-
resetSavepoints(context); // if any
|
|
365
|
+
resetSavepoints(context, connection); // if any
|
|
382
366
|
return context.runtime.newBoolean(true);
|
|
383
367
|
}
|
|
384
368
|
finally {
|
|
@@ -394,13 +378,13 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
394
378
|
|
|
395
379
|
@JRubyMethod(name = "rollback")
|
|
396
380
|
public IRubyObject rollback(final ThreadContext context) {
|
|
397
|
-
final Connection connection = getConnection(true);
|
|
398
381
|
try {
|
|
382
|
+
final Connection connection = getConnectionInternal(true);
|
|
399
383
|
if ( ! connection.getAutoCommit() ) {
|
|
400
384
|
try {
|
|
401
385
|
connection.rollback();
|
|
402
|
-
resetSavepoints(context); // if any
|
|
403
|
-
return context.
|
|
386
|
+
resetSavepoints(context, connection); // if any
|
|
387
|
+
return context.tru;
|
|
404
388
|
} finally {
|
|
405
389
|
connection.setAutoCommit(true);
|
|
406
390
|
}
|
|
@@ -414,11 +398,9 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
414
398
|
|
|
415
399
|
@JRubyMethod(name = "supports_savepoints?")
|
|
416
400
|
public IRubyObject supports_savepoints_p(final ThreadContext context) throws SQLException {
|
|
417
|
-
return withConnection(context,
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
return context.runtime.newBoolean( metaData.supportsSavepoints() );
|
|
421
|
-
}
|
|
401
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
402
|
+
final DatabaseMetaData metaData = connection.getMetaData();
|
|
403
|
+
return context.runtime.newBoolean( metaData.supportsSavepoints() );
|
|
422
404
|
});
|
|
423
405
|
}
|
|
424
406
|
|
|
@@ -429,8 +411,8 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
429
411
|
|
|
430
412
|
@JRubyMethod(name = "create_savepoint", required = 1)
|
|
431
413
|
public IRubyObject create_savepoint(final ThreadContext context, IRubyObject name) {
|
|
432
|
-
final Connection connection = getConnection(true);
|
|
433
414
|
try {
|
|
415
|
+
final Connection connection = getConnectionInternal(true);
|
|
434
416
|
connection.setAutoCommit(false);
|
|
435
417
|
|
|
436
418
|
final Savepoint savepoint ;
|
|
@@ -458,8 +440,8 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
458
440
|
public IRubyObject rollback_savepoint(final ThreadContext context, final IRubyObject name) {
|
|
459
441
|
if (name == context.nil) throw context.runtime.newArgumentError("nil savepoint name given");
|
|
460
442
|
|
|
461
|
-
final Connection connection = getConnection(true);
|
|
462
443
|
try {
|
|
444
|
+
final Connection connection = getConnectionInternal(true);
|
|
463
445
|
Savepoint savepoint = getSavepoints(context).get(name);
|
|
464
446
|
if ( savepoint == null ) {
|
|
465
447
|
throw context.runtime.newRuntimeError("could not rollback savepoint: '" + name + "' (not set)");
|
|
@@ -476,7 +458,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
476
458
|
public IRubyObject release_savepoint(final ThreadContext context, final IRubyObject name) {
|
|
477
459
|
if (name == context.nil) throw context.runtime.newArgumentError("nil savepoint name given");
|
|
478
460
|
|
|
479
|
-
final Connection connection = getConnection(true);
|
|
480
461
|
try {
|
|
481
462
|
Object savepoint = getSavepoints(context).remove(name);
|
|
482
463
|
|
|
@@ -487,6 +468,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
487
468
|
savepoint = ((IRubyObject) savepoint).toJava(Savepoint.class);
|
|
488
469
|
}
|
|
489
470
|
|
|
471
|
+
final Connection connection = getConnectionInternal(true);
|
|
490
472
|
releaseSavepoint(connection, (Savepoint) savepoint);
|
|
491
473
|
return context.nil;
|
|
492
474
|
}
|
|
@@ -525,7 +507,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
525
507
|
}
|
|
526
508
|
|
|
527
509
|
@SuppressWarnings("unchecked")
|
|
528
|
-
private
|
|
510
|
+
private Map<IRubyObject, Savepoint> getSavepoints(final boolean init) {
|
|
529
511
|
if ( hasInternalVariable("savepoints") ) {
|
|
530
512
|
return (Map<IRubyObject, Savepoint>) getInternalVariable("savepoints");
|
|
531
513
|
}
|
|
@@ -537,7 +519,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
537
519
|
return null;
|
|
538
520
|
}
|
|
539
521
|
|
|
540
|
-
protected boolean resetSavepoints(final ThreadContext context) {
|
|
522
|
+
protected boolean resetSavepoints(final ThreadContext context, final Connection connection) throws SQLException {
|
|
541
523
|
if ( hasInternalVariable("savepoints") ) {
|
|
542
524
|
removeInternalVariable("savepoints");
|
|
543
525
|
return true;
|
|
@@ -545,13 +527,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
545
527
|
return false;
|
|
546
528
|
}
|
|
547
529
|
|
|
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
530
|
@JRubyMethod(required = 2)
|
|
556
531
|
public final IRubyObject initialize(final ThreadContext context, final IRubyObject config, final IRubyObject adapter) {
|
|
557
532
|
doInitialize(context, config, adapter);
|
|
@@ -559,12 +534,17 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
559
534
|
}
|
|
560
535
|
|
|
561
536
|
protected void doInitialize(final ThreadContext context, final IRubyObject config, final IRubyObject adapter) {
|
|
562
|
-
this.config = config;
|
|
537
|
+
this.config = config;
|
|
538
|
+
this.adapter = adapter;
|
|
563
539
|
|
|
564
540
|
this.jndi = setupConnectionFactory(context);
|
|
565
541
|
this.lazy = jndi; // JNDIs are lazy by default otherwise eager
|
|
566
542
|
try {
|
|
567
|
-
|
|
543
|
+
if (adapter == null || adapter == context.nil) {
|
|
544
|
+
warn(context, "adapter not set, please pass adapter on JdbcConnection#initialize(config, adapter)");
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (!lazy) setConnection(newConnection());
|
|
568
548
|
}
|
|
569
549
|
catch (SQLException e) {
|
|
570
550
|
String message = e.getMessage();
|
|
@@ -575,7 +555,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
575
555
|
IRubyObject value = getConfigValue(context, "configure_connection");
|
|
576
556
|
if ( value == context.nil ) this.configureConnection = true;
|
|
577
557
|
else {
|
|
578
|
-
this.configureConnection = value != context.
|
|
558
|
+
this.configureConnection = value != context.fals;
|
|
579
559
|
}
|
|
580
560
|
|
|
581
561
|
IRubyObject jdbcFetchSize = getConfigValue(context, "jdbc_fetch_size");
|
|
@@ -586,7 +566,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
586
566
|
|
|
587
567
|
@JRubyMethod(name = "adapter")
|
|
588
568
|
public IRubyObject adapter(final ThreadContext context) {
|
|
589
|
-
final IRubyObject adapter = getAdapter();
|
|
590
569
|
return adapter == null ? context.nil : adapter;
|
|
591
570
|
}
|
|
592
571
|
|
|
@@ -601,43 +580,9 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
601
580
|
return factory;
|
|
602
581
|
}
|
|
603
582
|
|
|
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
583
|
private void configureConnection() {
|
|
638
584
|
if ( ! configureConnection ) return; // return false;
|
|
639
585
|
|
|
640
|
-
final IRubyObject adapter = getAdapter(); // self.adapter
|
|
641
586
|
if ( adapter != null && ! adapter.isNil() ) {
|
|
642
587
|
if ( adapter.respondsTo("configure_connection") ) {
|
|
643
588
|
final ThreadContext context = getRuntime().getCurrentContext();
|
|
@@ -659,7 +604,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
659
604
|
|
|
660
605
|
@JRubyMethod(name = "jdbc_connection", alias = "connection", required = 1)
|
|
661
606
|
public final IRubyObject connection(final ThreadContext context, final IRubyObject unwrap) {
|
|
662
|
-
if ( unwrap == context.nil || unwrap == context.
|
|
607
|
+
if ( unwrap == context.nil || unwrap == context.fals ) {
|
|
663
608
|
return connection(context);
|
|
664
609
|
}
|
|
665
610
|
Connection connection = connectionImpl(context);
|
|
@@ -668,11 +613,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
668
613
|
return convertJavaToRuby( connection.unwrap(Connection.class) );
|
|
669
614
|
}
|
|
670
615
|
}
|
|
671
|
-
catch (AbstractMethodError e) {
|
|
672
|
-
debugStackTrace(context, e);
|
|
673
|
-
warn(context, "driver/pool connection does not support unwrapping: " + e);
|
|
674
|
-
}
|
|
675
|
-
catch (SQLException e) {
|
|
616
|
+
catch (AbstractMethodError | SQLException e) {
|
|
676
617
|
debugStackTrace(context, e);
|
|
677
618
|
warn(context, "driver/pool connection does not support unwrapping: " + e);
|
|
678
619
|
}
|
|
@@ -695,18 +636,25 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
695
636
|
|
|
696
637
|
@JRubyMethod(name = "active?", alias = "valid?")
|
|
697
638
|
public RubyBoolean active_p(final ThreadContext context) {
|
|
698
|
-
if ( ! connected ) return context.
|
|
699
|
-
if (
|
|
639
|
+
if ( ! connected ) return context.fals;
|
|
640
|
+
if (jndi) {
|
|
700
641
|
// for JNDI the data-source / pool is supposed to
|
|
701
642
|
// manage connections for us thus no valid check!
|
|
702
643
|
boolean active = getConnectionFactory() != null;
|
|
703
644
|
return context.runtime.newBoolean( active );
|
|
704
645
|
}
|
|
705
|
-
final Connection connection = getConnection();
|
|
706
|
-
if ( connection == null ) return context.
|
|
646
|
+
final Connection connection = getConnection(false);
|
|
647
|
+
if ( connection == null ) return context.fals; // unlikely
|
|
707
648
|
return context.runtime.newBoolean( isConnectionValid(context, connection) );
|
|
708
649
|
}
|
|
709
650
|
|
|
651
|
+
@JRubyMethod(name = "really_valid?")
|
|
652
|
+
public RubyBoolean really_valid_p(final ThreadContext context) {
|
|
653
|
+
final Connection connection = getConnection(true);
|
|
654
|
+
if (connection == null) return context.fals;
|
|
655
|
+
return context.runtime.newBoolean(isConnectionValid(context, connection));
|
|
656
|
+
}
|
|
657
|
+
|
|
710
658
|
@JRubyMethod(name = "disconnect!")
|
|
711
659
|
public synchronized IRubyObject disconnect(final ThreadContext context) {
|
|
712
660
|
setConnection(null); connected = false;
|
|
@@ -727,38 +675,43 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
727
675
|
|
|
728
676
|
private void connectImpl(final boolean forceConnection) throws SQLException {
|
|
729
677
|
setConnection( forceConnection ? newConnection() : null );
|
|
730
|
-
if (
|
|
678
|
+
if (forceConnection) {
|
|
679
|
+
if (getConnectionImpl() == null) throw new SQLException("Didn't get a connection. Wrong URL?");
|
|
680
|
+
configureConnection();
|
|
681
|
+
}
|
|
731
682
|
}
|
|
732
683
|
|
|
733
684
|
@JRubyMethod(name = "read_only?")
|
|
734
685
|
public IRubyObject is_read_only(final ThreadContext context) {
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
return context.runtime.newBoolean(
|
|
686
|
+
try {
|
|
687
|
+
final Connection connection = getConnectionInternal(false);
|
|
688
|
+
if (connection != null) {
|
|
689
|
+
return context.runtime.newBoolean(connection.isReadOnly());
|
|
739
690
|
}
|
|
740
|
-
|
|
691
|
+
} catch (SQLException e) {
|
|
692
|
+
return handleException(context, e);
|
|
741
693
|
}
|
|
742
694
|
return context.nil;
|
|
743
695
|
}
|
|
744
696
|
|
|
745
697
|
@JRubyMethod(name = "read_only=")
|
|
746
698
|
public IRubyObject set_read_only(final ThreadContext context, final IRubyObject flag) {
|
|
747
|
-
final Connection connection = getConnection(true);
|
|
748
699
|
try {
|
|
700
|
+
final Connection connection = getConnectionInternal(true);
|
|
749
701
|
connection.setReadOnly( flag.isTrue() );
|
|
750
702
|
return context.runtime.newBoolean( connection.isReadOnly() );
|
|
703
|
+
} catch (SQLException e) {
|
|
704
|
+
return handleException(context, e);
|
|
751
705
|
}
|
|
752
|
-
catch (SQLException e) { return handleException(context, e); }
|
|
753
706
|
}
|
|
754
707
|
|
|
755
708
|
@JRubyMethod(name = { "open?" /* "conn?" */ })
|
|
756
709
|
public IRubyObject open_p(final ThreadContext context) {
|
|
757
|
-
|
|
710
|
+
try {
|
|
711
|
+
final Connection connection = getConnectionInternal(false);
|
|
758
712
|
|
|
759
|
-
|
|
713
|
+
if (connection == null) return context.fals;
|
|
760
714
|
|
|
761
|
-
try {
|
|
762
715
|
// NOTE: isClosed method generally cannot be called to determine
|
|
763
716
|
// whether a connection to a database is valid or invalid ...
|
|
764
717
|
return context.runtime.newBoolean(!connection.isClosed());
|
|
@@ -771,10 +724,10 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
771
724
|
public IRubyObject close(final ThreadContext context) {
|
|
772
725
|
final Connection connection = getConnection(false);
|
|
773
726
|
|
|
774
|
-
if (connection == null) return context.
|
|
727
|
+
if (connection == null) return context.fals;
|
|
775
728
|
|
|
776
729
|
try {
|
|
777
|
-
if (connection.isClosed()) return context.
|
|
730
|
+
if (connection.isClosed()) return context.fals;
|
|
778
731
|
|
|
779
732
|
setConnection(null); // does connection.close();
|
|
780
733
|
} catch (Exception e) {
|
|
@@ -784,69 +737,65 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
784
737
|
|
|
785
738
|
// ActiveRecord expects a closed connection to not try and re-open a connection
|
|
786
739
|
// whereas JNDI expects that.
|
|
787
|
-
if (!
|
|
740
|
+
if (!jndi) disconnect(context);
|
|
788
741
|
|
|
789
|
-
return context.
|
|
742
|
+
return context.tru;
|
|
790
743
|
}
|
|
791
744
|
|
|
792
745
|
@JRubyMethod(name = "database_name")
|
|
793
746
|
public IRubyObject database_name(final ThreadContext context) {
|
|
794
|
-
return withConnection(context,
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
if ( name == null ) return context.nil;
|
|
800
|
-
}
|
|
801
|
-
return context.runtime.newString(name);
|
|
747
|
+
return withConnection(context, connection -> {
|
|
748
|
+
String name = connection.getCatalog();
|
|
749
|
+
if ( name == null ) {
|
|
750
|
+
name = connection.getMetaData().getUserName();
|
|
751
|
+
if ( name == null ) return context.nil;
|
|
802
752
|
}
|
|
753
|
+
return context.runtime.newString(name);
|
|
803
754
|
});
|
|
804
755
|
}
|
|
805
756
|
|
|
806
757
|
@JRubyMethod(name = "execute", required = 1)
|
|
807
758
|
public IRubyObject execute(final ThreadContext context, final IRubyObject sql) {
|
|
808
759
|
final String query = sqlString(sql);
|
|
809
|
-
return withConnection(context,
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
statement = createStatement(context, connection);
|
|
814
|
-
|
|
815
|
-
// For DBs that do support multiple statements, lets return the last result set
|
|
816
|
-
// to be consistent with AR
|
|
817
|
-
boolean hasResultSet = doExecute(statement, query);
|
|
818
|
-
int updateCount = statement.getUpdateCount();
|
|
760
|
+
return withConnection(context, connection -> {
|
|
761
|
+
Statement statement = null;
|
|
762
|
+
try {
|
|
763
|
+
statement = createStatement(context, connection);
|
|
819
764
|
|
|
820
|
-
|
|
821
|
-
|
|
765
|
+
// For DBs that do support multiple statements, lets return the last result set
|
|
766
|
+
// to be consistent with AR
|
|
767
|
+
boolean hasResultSet = doExecute(statement, query);
|
|
768
|
+
int updateCount = statement.getUpdateCount();
|
|
822
769
|
|
|
823
|
-
|
|
770
|
+
IRubyObject result = context.nil; // If no results, return nil
|
|
771
|
+
ResultSet resultSet;
|
|
824
772
|
|
|
825
|
-
|
|
826
|
-
resultSet = statement.getResultSet();
|
|
773
|
+
while (hasResultSet || updateCount != -1) {
|
|
827
774
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
// this shouldn't be an issue in most cases since we're only getting 1 result set anyways
|
|
831
|
-
result = mapExecuteResult(context, connection, resultSet);
|
|
832
|
-
resultSet.close();
|
|
833
|
-
} else {
|
|
834
|
-
result = context.runtime.newFixnum(updateCount);
|
|
835
|
-
}
|
|
775
|
+
if (hasResultSet) {
|
|
776
|
+
resultSet = statement.getResultSet();
|
|
836
777
|
|
|
837
|
-
//
|
|
838
|
-
|
|
839
|
-
|
|
778
|
+
// Unfortunately the result set gets closed when getMoreResults()
|
|
779
|
+
// is called, so we have to process the result sets as we get them
|
|
780
|
+
// this shouldn't be an issue in most cases since we're only getting 1 result set anyways
|
|
781
|
+
result = mapExecuteResult(context, connection, resultSet);
|
|
782
|
+
resultSet.close();
|
|
783
|
+
} else {
|
|
784
|
+
result = context.runtime.newFixnum(updateCount);
|
|
840
785
|
}
|
|
841
786
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
debugErrorSQL(context, query);
|
|
846
|
-
throw e;
|
|
847
|
-
} finally {
|
|
848
|
-
close(statement);
|
|
787
|
+
// Check to see if there is another result set
|
|
788
|
+
hasResultSet = statement.getMoreResults();
|
|
789
|
+
updateCount = statement.getUpdateCount();
|
|
849
790
|
}
|
|
791
|
+
|
|
792
|
+
return result;
|
|
793
|
+
|
|
794
|
+
} catch (final SQLException e) {
|
|
795
|
+
debugErrorSQL(context, query);
|
|
796
|
+
throw e;
|
|
797
|
+
} finally {
|
|
798
|
+
close(statement);
|
|
850
799
|
}
|
|
851
800
|
});
|
|
852
801
|
}
|
|
@@ -885,66 +834,100 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
885
834
|
return mapQueryResult(context, connection, resultSet);
|
|
886
835
|
}
|
|
887
836
|
|
|
837
|
+
private static String[] createStatementPk(IRubyObject pk) {
|
|
838
|
+
String[] statementPk;
|
|
839
|
+
if (pk instanceof RubyArray) {
|
|
840
|
+
RubyArray ary = (RubyArray) pk;
|
|
841
|
+
int size = ary.size();
|
|
842
|
+
statementPk = new String[size];
|
|
843
|
+
for (int i = 0; i < size; i++) {
|
|
844
|
+
statementPk[i] = sqlString(ary.eltInternal(i));
|
|
845
|
+
}
|
|
846
|
+
} else {
|
|
847
|
+
statementPk = new String[] { sqlString(pk) };
|
|
848
|
+
}
|
|
849
|
+
return statementPk;
|
|
850
|
+
}
|
|
851
|
+
|
|
888
852
|
/**
|
|
889
853
|
* Executes an INSERT SQL statement
|
|
890
854
|
* @param context
|
|
891
855
|
* @param sql
|
|
856
|
+
* @param pk Rails PK
|
|
892
857
|
* @return ActiveRecord::Result
|
|
893
858
|
* @throws SQLException
|
|
894
859
|
*/
|
|
895
|
-
@JRubyMethod(name = "
|
|
896
|
-
public IRubyObject
|
|
897
|
-
return withConnection(context,
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
try {
|
|
860
|
+
@JRubyMethod(name = "execute_insert_pk", required = 2)
|
|
861
|
+
public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject pk) {
|
|
862
|
+
return withConnection(context, connection -> {
|
|
863
|
+
Statement statement = null;
|
|
864
|
+
final String query = sqlString(sql);
|
|
865
|
+
try {
|
|
902
866
|
|
|
903
|
-
|
|
904
|
-
statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
|
|
905
|
-
return mapGeneratedKeys(context, connection, statement);
|
|
867
|
+
statement = createStatement(context, connection);
|
|
906
868
|
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
close(statement);
|
|
869
|
+
if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
|
|
870
|
+
statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
|
|
871
|
+
} else {
|
|
872
|
+
statement.executeUpdate(query, createStatementPk(pk));
|
|
912
873
|
}
|
|
874
|
+
|
|
875
|
+
return mapGeneratedKeys(context, connection, statement);
|
|
876
|
+
} catch (final SQLException e) {
|
|
877
|
+
debugErrorSQL(context, query);
|
|
878
|
+
throw e;
|
|
879
|
+
} finally {
|
|
880
|
+
close(statement);
|
|
913
881
|
}
|
|
914
882
|
});
|
|
915
883
|
}
|
|
916
884
|
|
|
885
|
+
@Deprecated
|
|
886
|
+
@JRubyMethod(name = "execute_insert", required = 1)
|
|
887
|
+
public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql) {
|
|
888
|
+
return execute_insert_pk(context, sql, context.nil);
|
|
889
|
+
}
|
|
890
|
+
|
|
917
891
|
/**
|
|
918
892
|
* Executes an INSERT SQL statement using a prepared statement
|
|
919
893
|
* @param context
|
|
920
894
|
* @param sql
|
|
921
895
|
* @param binds RubyArray of values to be bound to the query
|
|
896
|
+
* @param pk Rails PK
|
|
922
897
|
* @return ActiveRecord::Result
|
|
923
898
|
* @throws SQLException
|
|
924
899
|
*/
|
|
925
|
-
@JRubyMethod(name = "
|
|
926
|
-
public IRubyObject
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
900
|
+
@JRubyMethod(name = "execute_insert_pk", required = 3)
|
|
901
|
+
public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject binds,
|
|
902
|
+
final IRubyObject pk) {
|
|
903
|
+
return withConnection(context, connection -> {
|
|
904
|
+
PreparedStatement statement = null;
|
|
905
|
+
final String query = sqlString(sql);
|
|
906
|
+
try {
|
|
907
|
+
if (pk == context.nil || pk == context.fals || !supportsGeneratedKeys(connection)) {
|
|
933
908
|
statement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
|
|
934
|
-
|
|
935
|
-
statement.
|
|
936
|
-
return mapGeneratedKeys(context, connection, statement);
|
|
937
|
-
|
|
938
|
-
} catch (final SQLException e) {
|
|
939
|
-
debugErrorSQL(context, query);
|
|
940
|
-
throw e;
|
|
941
|
-
} finally {
|
|
942
|
-
close(statement);
|
|
909
|
+
} else {
|
|
910
|
+
statement = connection.prepareStatement(query, createStatementPk(pk));
|
|
943
911
|
}
|
|
912
|
+
|
|
913
|
+
setStatementParameters(context, connection, statement, (RubyArray) binds);
|
|
914
|
+
statement.executeUpdate();
|
|
915
|
+
return mapGeneratedKeys(context, connection, statement);
|
|
916
|
+
} catch (final SQLException e) {
|
|
917
|
+
debugErrorSQL(context, query);
|
|
918
|
+
throw e;
|
|
919
|
+
} finally {
|
|
920
|
+
close(statement);
|
|
944
921
|
}
|
|
945
922
|
});
|
|
946
923
|
}
|
|
947
924
|
|
|
925
|
+
@Deprecated
|
|
926
|
+
@JRubyMethod(name = "execute_insert", required = 2)
|
|
927
|
+
public IRubyObject execute_insert(final ThreadContext context, final IRubyObject binds, final IRubyObject sql) {
|
|
928
|
+
return execute_insert_pk(context, sql, binds, context.nil);
|
|
929
|
+
}
|
|
930
|
+
|
|
948
931
|
/**
|
|
949
932
|
* Executes an UPDATE (DELETE) SQL statement
|
|
950
933
|
* @param context
|
|
@@ -954,22 +937,20 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
954
937
|
*/
|
|
955
938
|
@JRubyMethod(name = {"execute_update", "execute_delete"}, required = 1)
|
|
956
939
|
public IRubyObject execute_update(final ThreadContext context, final IRubyObject sql) {
|
|
957
|
-
return withConnection(context,
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
final String query = sqlString(sql);
|
|
940
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
941
|
+
Statement statement = null;
|
|
942
|
+
final String query = sqlString(sql);
|
|
961
943
|
|
|
962
|
-
|
|
963
|
-
|
|
944
|
+
try {
|
|
945
|
+
statement = createStatement(context, connection);
|
|
964
946
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
}
|
|
947
|
+
final int rowCount = statement.executeUpdate(query);
|
|
948
|
+
return context.runtime.newFixnum(rowCount);
|
|
949
|
+
} catch (final SQLException e) {
|
|
950
|
+
debugErrorSQL(context, query);
|
|
951
|
+
throw e;
|
|
952
|
+
} finally {
|
|
953
|
+
close(statement);
|
|
973
954
|
}
|
|
974
955
|
});
|
|
975
956
|
}
|
|
@@ -985,21 +966,19 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
985
966
|
*/
|
|
986
967
|
@JRubyMethod(name = {"execute_prepared_update", "execute_prepared_delete"}, required = 2)
|
|
987
968
|
public IRubyObject execute_prepared_update(final ThreadContext context, final IRubyObject sql, final IRubyObject binds) {
|
|
988
|
-
return withConnection(context,
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
close(statement);
|
|
1002
|
-
}
|
|
969
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
970
|
+
PreparedStatement statement = null;
|
|
971
|
+
final String query = sqlString(sql);
|
|
972
|
+
try {
|
|
973
|
+
statement = connection.prepareStatement(query);
|
|
974
|
+
setStatementParameters(context, connection, statement, (RubyArray) binds);
|
|
975
|
+
final int rowCount = statement.executeUpdate();
|
|
976
|
+
return context.runtime.newFixnum(rowCount);
|
|
977
|
+
} catch (final SQLException e) {
|
|
978
|
+
debugErrorSQL(context, query);
|
|
979
|
+
throw e;
|
|
980
|
+
} finally {
|
|
981
|
+
close(statement);
|
|
1003
982
|
}
|
|
1004
983
|
});
|
|
1005
984
|
}
|
|
@@ -1028,12 +1007,12 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1028
1007
|
binds = null;
|
|
1029
1008
|
} else { // (sql, binds)
|
|
1030
1009
|
maxRows = 0;
|
|
1031
|
-
binds = (RubyArray) TypeConverter.checkArrayType(args[1]);
|
|
1010
|
+
binds = (RubyArray) TypeConverter.checkArrayType(context, args[1]);
|
|
1032
1011
|
}
|
|
1033
1012
|
break;
|
|
1034
1013
|
case 3: // (sql, max_rows, binds)
|
|
1035
1014
|
maxRows = RubyNumeric.fix2int(args[1]);
|
|
1036
|
-
binds = (RubyArray) TypeConverter.checkArrayType(args[2]);
|
|
1015
|
+
binds = (RubyArray) TypeConverter.checkArrayType(context, args[2]);
|
|
1037
1016
|
break;
|
|
1038
1017
|
default: // (sql) 1-arg
|
|
1039
1018
|
maxRows = 0;
|
|
@@ -1046,50 +1025,48 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1046
1025
|
|
|
1047
1026
|
private IRubyObject doExecuteQueryRaw(final ThreadContext context,
|
|
1048
1027
|
final String query, final int maxRows, final Block block, final RubyArray binds) {
|
|
1049
|
-
return withConnection(context,
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
}
|
|
1028
|
+
return withConnection(context, connection -> {
|
|
1029
|
+
Statement statement = null; boolean hasResult;
|
|
1030
|
+
try {
|
|
1031
|
+
if ( binds == null || binds.isEmpty()) { // plain statement
|
|
1032
|
+
statement = createStatement(context, connection);
|
|
1033
|
+
statement.setMaxRows(maxRows); // zero means there is no limit
|
|
1034
|
+
hasResult = statement.execute(query);
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
final PreparedStatement prepStatement;
|
|
1038
|
+
statement = prepStatement = connection.prepareStatement(query);
|
|
1039
|
+
if (fetchSize != 0) statement.setFetchSize(fetchSize);
|
|
1040
|
+
statement.setMaxRows(maxRows); // zero means there is no limit
|
|
1041
|
+
setStatementParameters(context, connection, prepStatement, binds);
|
|
1042
|
+
hasResult = prepStatement.execute();
|
|
1043
|
+
}
|
|
1066
1044
|
|
|
1067
|
-
|
|
1068
|
-
if (hasResult) {
|
|
1069
|
-
// yield(id1, name1) ... row 1 result data
|
|
1070
|
-
// yield(id2, name2) ... row 2 result data
|
|
1071
|
-
return yieldResultRows(context, connection, statement.getResultSet(), block);
|
|
1072
|
-
}
|
|
1073
|
-
return context.nil;
|
|
1074
|
-
}
|
|
1045
|
+
if (block.isGiven()) {
|
|
1075
1046
|
if (hasResult) {
|
|
1076
|
-
|
|
1047
|
+
// yield(id1, name1) ... row 1 result data
|
|
1048
|
+
// yield(id2, name2) ... row 2 result data
|
|
1049
|
+
return yieldResultRows(context, connection, statement.getResultSet(), block);
|
|
1077
1050
|
}
|
|
1078
|
-
return context.
|
|
1079
|
-
}
|
|
1080
|
-
catch (final SQLException e) {
|
|
1081
|
-
debugErrorSQL(context, query);
|
|
1082
|
-
throw e;
|
|
1051
|
+
return context.nil;
|
|
1083
1052
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1053
|
+
if (hasResult) {
|
|
1054
|
+
return mapToRawResult(context, connection, statement.getResultSet(), false);
|
|
1086
1055
|
}
|
|
1056
|
+
return context.runtime.newEmptyArray();
|
|
1057
|
+
}
|
|
1058
|
+
catch (final SQLException e) {
|
|
1059
|
+
debugErrorSQL(context, query);
|
|
1060
|
+
throw e;
|
|
1061
|
+
}
|
|
1062
|
+
finally {
|
|
1063
|
+
close(statement);
|
|
1087
1064
|
}
|
|
1088
1065
|
});
|
|
1089
1066
|
}
|
|
1090
1067
|
|
|
1091
1068
|
protected static String sqlString(final IRubyObject sql) {
|
|
1092
|
-
return sql
|
|
1069
|
+
return sql.convertToString().decodeString();
|
|
1093
1070
|
}
|
|
1094
1071
|
|
|
1095
1072
|
/**
|
|
@@ -1102,26 +1079,46 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1102
1079
|
*/
|
|
1103
1080
|
@JRubyMethod(required = 1)
|
|
1104
1081
|
public IRubyObject execute_query(final ThreadContext context, final IRubyObject sql) {
|
|
1105
|
-
return withConnection(context,
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
statement = createStatement(context, connection);
|
|
1082
|
+
return withConnection(context, connection -> {
|
|
1083
|
+
Statement statement = null;
|
|
1084
|
+
final String query = sqlString(sql);
|
|
1085
|
+
try {
|
|
1086
|
+
statement = createStatement(context, connection);
|
|
1111
1087
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1088
|
+
// At least until AR 5.1 #exec_query still gets called for things that don't return results in some cases :(
|
|
1089
|
+
if (statement.execute(query)) {
|
|
1090
|
+
return mapQueryResult(context, connection, statement.getResultSet());
|
|
1091
|
+
}
|
|
1116
1092
|
|
|
1117
|
-
|
|
1093
|
+
return newEmptyResult(context);
|
|
1118
1094
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1095
|
+
} catch (final SQLException e) {
|
|
1096
|
+
debugErrorSQL(context, query);
|
|
1097
|
+
throw e;
|
|
1098
|
+
} finally {
|
|
1099
|
+
close(statement);
|
|
1100
|
+
}
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
@JRubyMethod(required = 1)
|
|
1105
|
+
public IRubyObject get_first_value(final ThreadContext context, final IRubyObject sql) {
|
|
1106
|
+
return withConnection(context, connection -> {
|
|
1107
|
+
Statement statement = null;
|
|
1108
|
+
final String query = sqlString(sql);
|
|
1109
|
+
try {
|
|
1110
|
+
statement = createStatement(context, connection);
|
|
1111
|
+
statement.execute(query);
|
|
1112
|
+
ResultSet rs = statement.getResultSet();
|
|
1113
|
+
if (rs == null || !rs.next()) return context.nil;
|
|
1114
|
+
|
|
1115
|
+
return jdbcToRuby(context, context.getRuntime(), 1, rs.getMetaData().getColumnType(1), rs);
|
|
1116
|
+
|
|
1117
|
+
} catch (final SQLException e) {
|
|
1118
|
+
debugErrorSQL(context, query);
|
|
1119
|
+
throw e;
|
|
1120
|
+
} finally {
|
|
1121
|
+
close(statement);
|
|
1125
1122
|
}
|
|
1126
1123
|
});
|
|
1127
1124
|
}
|
|
@@ -1134,13 +1131,11 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1134
1131
|
*/
|
|
1135
1132
|
@JRubyMethod(required = 1)
|
|
1136
1133
|
public IRubyObject prepare_statement(final ThreadContext context, final IRubyObject sql) {
|
|
1137
|
-
return withConnection(context,
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
return JavaUtil.convertJavaToRuby(context.runtime, statement);
|
|
1143
|
-
}
|
|
1134
|
+
return withConnection(context, connection -> {
|
|
1135
|
+
final String query = sql.convertToString().getUnicodeValue();
|
|
1136
|
+
PreparedStatement statement = connection.prepareStatement(query);
|
|
1137
|
+
if (fetchSize != 0) statement.setFetchSize(fetchSize);
|
|
1138
|
+
return JavaUtil.convertJavaToRuby(context.runtime, statement);
|
|
1144
1139
|
});
|
|
1145
1140
|
}
|
|
1146
1141
|
|
|
@@ -1163,40 +1158,40 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1163
1158
|
@JRubyMethod(required = 3)
|
|
1164
1159
|
public IRubyObject execute_prepared_query(final ThreadContext context, final IRubyObject sql,
|
|
1165
1160
|
final IRubyObject binds, final IRubyObject cachedStatement) {
|
|
1166
|
-
return withConnection(context,
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
PreparedStatement statement = null;
|
|
1161
|
+
return withConnection(context, connection -> {
|
|
1162
|
+
final boolean cached = !(cachedStatement == null || cachedStatement.isNil());
|
|
1163
|
+
String query = null;
|
|
1164
|
+
PreparedStatement statement = null;
|
|
1171
1165
|
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1166
|
+
try {
|
|
1167
|
+
if (cached) {
|
|
1168
|
+
statement = (PreparedStatement) JavaEmbedUtils.rubyToJava(cachedStatement);
|
|
1169
|
+
} else {
|
|
1170
|
+
query = sql.convertToString().getUnicodeValue();
|
|
1171
|
+
statement = connection.prepareStatement(query);
|
|
1172
|
+
if (fetchSize != 0) statement.setFetchSize(fetchSize);
|
|
1173
|
+
}
|
|
1179
1174
|
|
|
1180
|
-
|
|
1175
|
+
setStatementParameters(context, connection, statement, (RubyArray) binds);
|
|
1181
1176
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1177
|
+
if (statement.execute()) {
|
|
1178
|
+
ResultSet resultSet = statement.getResultSet();
|
|
1179
|
+
IRubyObject results = mapQueryResult(context, connection, resultSet);
|
|
1180
|
+
resultSet.close();
|
|
1186
1181
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1182
|
+
return results;
|
|
1183
|
+
} else {
|
|
1184
|
+
return newEmptyResult(context);
|
|
1185
|
+
}
|
|
1186
|
+
} catch (final SQLException e) {
|
|
1187
|
+
if (query == null) query = sql.convertToString().getUnicodeValue();
|
|
1188
|
+
debugErrorSQL(context, query);
|
|
1189
|
+
throw e;
|
|
1190
|
+
} finally {
|
|
1191
|
+
if ( cached ) {
|
|
1192
|
+
statement.clearParameters();
|
|
1193
|
+
} else {
|
|
1194
|
+
close(statement);
|
|
1200
1195
|
}
|
|
1201
1196
|
}
|
|
1202
1197
|
});
|
|
@@ -1208,35 +1203,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1208
1203
|
return mapToResult(context, connection, resultSet, columns);
|
|
1209
1204
|
}
|
|
1210
1205
|
|
|
1211
|
-
/**
|
|
1212
|
-
* @deprecated please do not use this method
|
|
1213
|
-
*/
|
|
1214
|
-
@Deprecated // only used by Oracle adapter - also it's really a bad idea
|
|
1215
|
-
@JRubyMethod(name = "execute_id_insert", required = 2)
|
|
1216
|
-
public IRubyObject execute_id_insert(final ThreadContext context, final IRubyObject sql, final IRubyObject id) {
|
|
1217
|
-
final Ruby runtime = context.runtime;
|
|
1218
|
-
|
|
1219
|
-
callMethod("warn", RubyString.newUnicodeString(runtime, "DEPRECATED: execute_id_insert(sql, id) will be removed"));
|
|
1220
|
-
|
|
1221
|
-
return withConnection(context, new Callable<IRubyObject>() {
|
|
1222
|
-
public IRubyObject call(final Connection connection) throws SQLException {
|
|
1223
|
-
PreparedStatement statement = null;
|
|
1224
|
-
final String insertSQL = sql.convertToString().getUnicodeValue();
|
|
1225
|
-
try {
|
|
1226
|
-
statement = connection.prepareStatement(insertSQL);
|
|
1227
|
-
statement.setLong(1, RubyNumeric.fix2long(id));
|
|
1228
|
-
statement.executeUpdate();
|
|
1229
|
-
}
|
|
1230
|
-
catch (final SQLException e) {
|
|
1231
|
-
debugErrorSQL(context, insertSQL);
|
|
1232
|
-
throw e;
|
|
1233
|
-
}
|
|
1234
|
-
finally { close(statement); }
|
|
1235
|
-
return id;
|
|
1236
|
-
}
|
|
1237
|
-
});
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
1206
|
@JRubyMethod(name = "supported_data_types")
|
|
1241
1207
|
public IRubyObject supported_data_types(final ThreadContext context) throws SQLException {
|
|
1242
1208
|
final Connection connection = getConnection(true);
|
|
@@ -1260,12 +1226,10 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1260
1226
|
protected static final int PRIMARY_KEYS_COLUMN_NAME = 4;
|
|
1261
1227
|
|
|
1262
1228
|
private List<RubyString> primaryKeys(final ThreadContext context, final String tableName) {
|
|
1263
|
-
return withConnection(context,
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
return primaryKeys(context, connection, table);
|
|
1268
|
-
}
|
|
1229
|
+
return withConnection(context, connection -> {
|
|
1230
|
+
final String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
|
|
1231
|
+
final TableName table = extractTableName(connection, null, null, _tableName);
|
|
1232
|
+
return primaryKeys(context, connection, table);
|
|
1269
1233
|
});
|
|
1270
1234
|
}
|
|
1271
1235
|
|
|
@@ -1273,7 +1237,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1273
1237
|
final Connection connection, final TableName table) throws SQLException {
|
|
1274
1238
|
final DatabaseMetaData metaData = connection.getMetaData();
|
|
1275
1239
|
ResultSet resultSet = null;
|
|
1276
|
-
final List<RubyString> keyNames = new ArrayList
|
|
1240
|
+
final List<RubyString> keyNames = new ArrayList<>();
|
|
1277
1241
|
try {
|
|
1278
1242
|
resultSet = metaData.getPrimaryKeys(table.catalog, table.schema, table.name);
|
|
1279
1243
|
final Ruby runtime = context.runtime;
|
|
@@ -1287,26 +1251,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1287
1251
|
return keyNames;
|
|
1288
1252
|
}
|
|
1289
1253
|
|
|
1290
|
-
@Deprecated //@JRubyMethod(name = "tables")
|
|
1291
|
-
public IRubyObject tables(ThreadContext context) {
|
|
1292
|
-
return tables(context, null, null, null, TABLE_TYPE);
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
@Deprecated //@JRubyMethod(name = "tables")
|
|
1296
|
-
public IRubyObject tables(ThreadContext context, IRubyObject catalog) {
|
|
1297
|
-
return tables(context, toStringOrNull(catalog), null, null, TABLE_TYPE);
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
@Deprecated //@JRubyMethod(name = "tables")
|
|
1301
|
-
public IRubyObject tables(ThreadContext context, IRubyObject catalog, IRubyObject schemaPattern) {
|
|
1302
|
-
return tables(context, toStringOrNull(catalog), toStringOrNull(schemaPattern), null, TABLE_TYPE);
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
@Deprecated //@JRubyMethod(name = "tables")
|
|
1306
|
-
public IRubyObject tables(ThreadContext context, IRubyObject catalog, IRubyObject schemaPattern, IRubyObject tablePattern) {
|
|
1307
|
-
return tables(context, toStringOrNull(catalog), toStringOrNull(schemaPattern), toStringOrNull(tablePattern), TABLE_TYPE);
|
|
1308
|
-
}
|
|
1309
|
-
|
|
1310
1254
|
@JRubyMethod(name = "tables", required = 0, optional = 4)
|
|
1311
1255
|
public IRubyObject tables(final ThreadContext context, final IRubyObject[] args) {
|
|
1312
1256
|
switch ( args.length ) {
|
|
@@ -1324,11 +1268,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1324
1268
|
|
|
1325
1269
|
protected IRubyObject tables(final ThreadContext context,
|
|
1326
1270
|
final String catalog, final String schemaPattern, final String tablePattern, final String[] types) {
|
|
1327
|
-
return withConnection(context,
|
|
1328
|
-
public IRubyObject call(final Connection connection) throws SQLException {
|
|
1329
|
-
return matchTables(context, connection, catalog, schemaPattern, tablePattern, types, false);
|
|
1330
|
-
}
|
|
1331
|
-
});
|
|
1271
|
+
return withConnection(context, connection -> matchTables(context, connection, catalog, schemaPattern, tablePattern, types, false));
|
|
1332
1272
|
}
|
|
1333
1273
|
|
|
1334
1274
|
protected String[] getTableTypes() {
|
|
@@ -1358,40 +1298,36 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1358
1298
|
|
|
1359
1299
|
protected IRubyObject tableExists(final ThreadContext context,
|
|
1360
1300
|
final String defaultSchema, final String tableName) {
|
|
1361
|
-
return withConnection(context,
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
return context.runtime.newBoolean( tableExists(context, connection, components) );
|
|
1365
|
-
}
|
|
1301
|
+
return withConnection(context, connection -> {
|
|
1302
|
+
final TableName components = extractTableName(connection, defaultSchema, tableName);
|
|
1303
|
+
return context.runtime.newBoolean( tableExists(context, connection, components) );
|
|
1366
1304
|
});
|
|
1367
1305
|
}
|
|
1368
1306
|
|
|
1369
1307
|
@JRubyMethod(name = {"columns", "columns_internal"}, required = 1, optional = 2)
|
|
1370
1308
|
public RubyArray columns_internal(final ThreadContext context, final IRubyObject[] args)
|
|
1371
1309
|
throws SQLException {
|
|
1372
|
-
return withConnection(context,
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
final String defaultSchema = args.length > 2 ? toStringOrNull(args[2]) : null;
|
|
1380
|
-
|
|
1381
|
-
final TableName components;
|
|
1382
|
-
components = extractTableName(connection, catalog, defaultSchema, tableName);
|
|
1310
|
+
return withConnection(context, connection -> {
|
|
1311
|
+
ResultSet columns = null;
|
|
1312
|
+
try {
|
|
1313
|
+
final String tableName = args[0].toString();
|
|
1314
|
+
// optionals (NOTE: catalog argumnet was never used before 1.3.0) :
|
|
1315
|
+
final String catalog = args.length > 1 ? toStringOrNull(args[1]) : null;
|
|
1316
|
+
final String defaultSchema = args.length > 2 ? toStringOrNull(args[2]) : null;
|
|
1383
1317
|
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
}
|
|
1318
|
+
final TableName components;
|
|
1319
|
+
components = extractTableName(connection, catalog, defaultSchema, tableName);
|
|
1387
1320
|
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
return mapColumnsResult(context, metaData, components, columns);
|
|
1391
|
-
}
|
|
1392
|
-
finally {
|
|
1393
|
-
close(columns);
|
|
1321
|
+
if ( ! tableExists(context, connection, components) ) {
|
|
1322
|
+
throw new SQLException("table: " + tableName + " does not exist");
|
|
1394
1323
|
}
|
|
1324
|
+
|
|
1325
|
+
final DatabaseMetaData metaData = connection.getMetaData();
|
|
1326
|
+
columns = metaData.getColumns(components.catalog, components.schema, components.name, null);
|
|
1327
|
+
return mapColumnsResult(context, metaData, components, columns);
|
|
1328
|
+
}
|
|
1329
|
+
finally {
|
|
1330
|
+
close(columns);
|
|
1395
1331
|
}
|
|
1396
1332
|
});
|
|
1397
1333
|
}
|
|
@@ -1421,70 +1357,68 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1421
1357
|
* should filter the return from this method instead.
|
|
1422
1358
|
*/
|
|
1423
1359
|
protected IRubyObject indexes(final ThreadContext context, final String tableName, final String name, final String schemaName) {
|
|
1424
|
-
return withConnection(context,
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
final RubyClass IndexDefinition = getIndexDefinition(context);
|
|
1428
|
-
|
|
1429
|
-
String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
|
|
1430
|
-
String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
|
|
1431
|
-
final TableName table = extractTableName(connection, null, _schemaName, _tableName);
|
|
1360
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
1361
|
+
final Ruby runtime = context.runtime;
|
|
1362
|
+
final RubyClass IndexDefinition = getIndexDefinition(context);
|
|
1432
1363
|
|
|
1433
|
-
|
|
1364
|
+
String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
|
|
1365
|
+
String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
|
|
1366
|
+
final TableName table = extractTableName(connection, null, _schemaName, _tableName);
|
|
1434
1367
|
|
|
1435
|
-
|
|
1436
|
-
final RubyArray indexes = RubyArray.newArray(runtime, 8);
|
|
1437
|
-
try {
|
|
1438
|
-
final DatabaseMetaData metaData = connection.getMetaData();
|
|
1439
|
-
indexInfoSet = metaData.getIndexInfo(table.catalog, table.schema, table.name, false, true);
|
|
1440
|
-
String currentIndex = null;
|
|
1441
|
-
RubyArray currentColumns = null;
|
|
1368
|
+
final List<RubyString> primaryKeys = primaryKeys(context, connection, table);
|
|
1442
1369
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1370
|
+
ResultSet indexInfoSet = null;
|
|
1371
|
+
final RubyArray indexes = RubyArray.newArray(runtime, 8);
|
|
1372
|
+
try {
|
|
1373
|
+
final DatabaseMetaData metaData = connection.getMetaData();
|
|
1374
|
+
indexInfoSet = metaData.getIndexInfo(table.catalog, table.schema, table.name, false, true);
|
|
1375
|
+
String currentIndex = null;
|
|
1446
1376
|
|
|
1447
|
-
|
|
1377
|
+
while ( indexInfoSet.next() ) {
|
|
1378
|
+
String indexName = indexInfoSet.getString(INDEX_INFO_NAME);
|
|
1379
|
+
if ( indexName == null ) continue;
|
|
1380
|
+
RubyArray currentColumns = null;
|
|
1448
1381
|
|
|
1449
|
-
|
|
1450
|
-
final RubyString rubyColumnName = cachedString(
|
|
1451
|
-
context, caseConvertIdentifierForRails(metaData, columnName)
|
|
1452
|
-
);
|
|
1453
|
-
if ( primaryKeys.contains(rubyColumnName) ) continue;
|
|
1382
|
+
indexName = caseConvertIdentifierForRails(metaData, indexName);
|
|
1454
1383
|
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1384
|
+
final String columnName = indexInfoSet.getString(INDEX_INFO_COLUMN_NAME);
|
|
1385
|
+
final RubyString rubyColumnName = cachedString(
|
|
1386
|
+
context, caseConvertIdentifierForRails(metaData, columnName)
|
|
1387
|
+
);
|
|
1388
|
+
if ( primaryKeys.contains(rubyColumnName) ) continue;
|
|
1458
1389
|
|
|
1459
|
-
|
|
1460
|
-
|
|
1390
|
+
// We are working on a new index
|
|
1391
|
+
if ( ! indexName.equals(currentIndex) ) {
|
|
1392
|
+
currentIndex = indexName;
|
|
1461
1393
|
|
|
1462
|
-
|
|
1394
|
+
String indexTableName = indexInfoSet.getString(INDEX_INFO_TABLE_NAME);
|
|
1395
|
+
indexTableName = caseConvertIdentifierForRails(metaData, indexTableName);
|
|
1463
1396
|
|
|
1464
|
-
|
|
1465
|
-
cachedString(context, indexTableName), // table_name
|
|
1466
|
-
cachedString(context, indexName), // index_name
|
|
1467
|
-
nonUnique ? runtime.getFalse() : runtime.getTrue(), // unique
|
|
1468
|
-
currentColumns = RubyArray.newArray(runtime, 4) // [] column names
|
|
1469
|
-
// orders, (since AR 3.2) where, type, using (AR 4.0)
|
|
1470
|
-
};
|
|
1397
|
+
final boolean nonUnique = indexInfoSet.getBoolean(INDEX_INFO_NON_UNIQUE);
|
|
1471
1398
|
|
|
1472
|
-
|
|
1473
|
-
|
|
1399
|
+
IRubyObject[] args = new IRubyObject[] {
|
|
1400
|
+
cachedString(context, indexTableName), // table_name
|
|
1401
|
+
cachedString(context, indexName), // index_name
|
|
1402
|
+
nonUnique ? context.fals : context.tru, // unique
|
|
1403
|
+
currentColumns = RubyArray.newArray(runtime, 4) // [] column names
|
|
1404
|
+
// orders, (since AR 3.2) where, type, using (AR 4.0)
|
|
1405
|
+
};
|
|
1474
1406
|
|
|
1475
|
-
|
|
1476
|
-
if ( currentColumns != null ) currentColumns.append(rubyColumnName);
|
|
1407
|
+
indexes.append( IndexDefinition.newInstance(context, args, Block.NULL_BLOCK) ); // IndexDefinition.new
|
|
1477
1408
|
}
|
|
1478
1409
|
|
|
1479
|
-
|
|
1410
|
+
// one or more columns can be associated with an index
|
|
1411
|
+
if ( currentColumns != null ) currentColumns.append(rubyColumnName);
|
|
1412
|
+
}
|
|
1480
1413
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1414
|
+
return indexes;
|
|
1415
|
+
|
|
1416
|
+
} finally { close(indexInfoSet); }
|
|
1483
1417
|
});
|
|
1484
1418
|
}
|
|
1485
1419
|
|
|
1486
1420
|
protected RubyClass getIndexDefinition(final ThreadContext context) {
|
|
1487
|
-
final RubyClass adapterClass =
|
|
1421
|
+
final RubyClass adapterClass = adapter.getMetaClass();
|
|
1488
1422
|
IRubyObject IDef = adapterClass.getConstantAt("IndexDefinition");
|
|
1489
1423
|
return IDef != null ? (RubyClass) IDef : getIndexDefinition(context.runtime);
|
|
1490
1424
|
}
|
|
@@ -1495,57 +1429,55 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1495
1429
|
}
|
|
1496
1430
|
|
|
1497
1431
|
protected IRubyObject foreignKeys(final ThreadContext context, final String tableName, final String schemaName, final String catalog) {
|
|
1498
|
-
return withConnection(context,
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
final RubyClass FKDefinition = getForeignKeyDefinition(context);
|
|
1432
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
1433
|
+
final Ruby runtime = context.runtime;
|
|
1434
|
+
final RubyClass FKDefinition = getForeignKeyDefinition(context);
|
|
1502
1435
|
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1436
|
+
String _tableName = caseConvertIdentifierForJdbc(connection, tableName);
|
|
1437
|
+
String _schemaName = caseConvertIdentifierForJdbc(connection, schemaName);
|
|
1438
|
+
final TableName table = extractTableName(connection, catalog, _schemaName, _tableName);
|
|
1506
1439
|
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1440
|
+
ResultSet fkInfoSet = null;
|
|
1441
|
+
final List<IRubyObject> fKeys = new ArrayList<>(8);
|
|
1442
|
+
try {
|
|
1443
|
+
final DatabaseMetaData metaData = connection.getMetaData();
|
|
1444
|
+
fkInfoSet = metaData.getImportedKeys(table.catalog, table.schema, table.name);
|
|
1512
1445
|
|
|
1513
|
-
|
|
1514
|
-
|
|
1446
|
+
while ( fkInfoSet.next() ) {
|
|
1447
|
+
final RubyHash options = RubyHash.newHash(runtime);
|
|
1515
1448
|
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1449
|
+
String fkName = fkInfoSet.getString("FK_NAME");
|
|
1450
|
+
if (fkName != null) {
|
|
1451
|
+
fkName = caseConvertIdentifierForRails(metaData, fkName);
|
|
1452
|
+
options.put(runtime.newSymbol("name"), fkName);
|
|
1453
|
+
}
|
|
1521
1454
|
|
|
1522
|
-
|
|
1523
|
-
|
|
1455
|
+
String columnName = fkInfoSet.getString("FKCOLUMN_NAME");
|
|
1456
|
+
options.put(runtime.newSymbol("column"), caseConvertIdentifierForRails(metaData, columnName));
|
|
1524
1457
|
|
|
1525
|
-
|
|
1526
|
-
|
|
1458
|
+
columnName = fkInfoSet.getString("PKCOLUMN_NAME");
|
|
1459
|
+
options.put(runtime.newSymbol("primary_key"), caseConvertIdentifierForRails(metaData, columnName));
|
|
1527
1460
|
|
|
1528
|
-
|
|
1529
|
-
|
|
1461
|
+
String fkTableName = fkInfoSet.getString("FKTABLE_NAME");
|
|
1462
|
+
fkTableName = caseConvertIdentifierForRails(metaData, fkTableName);
|
|
1530
1463
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1464
|
+
String pkTableName = fkInfoSet.getString("PKTABLE_NAME");
|
|
1465
|
+
pkTableName = caseConvertIdentifierForRails(metaData, pkTableName);
|
|
1533
1466
|
|
|
1534
|
-
|
|
1535
|
-
|
|
1467
|
+
final String onDelete = extractForeignKeyRule( fkInfoSet.getInt("DELETE_RULE") );
|
|
1468
|
+
if ( onDelete != null ) options.op_aset(context, runtime.newSymbol("on_delete"), runtime.newSymbol(onDelete));
|
|
1536
1469
|
|
|
1537
|
-
|
|
1538
|
-
|
|
1470
|
+
final String onUpdate = extractForeignKeyRule( fkInfoSet.getInt("UPDATE_RULE") );
|
|
1471
|
+
if ( onUpdate != null ) options.op_aset(context, runtime.newSymbol("on_update"), runtime.newSymbol(onUpdate));
|
|
1539
1472
|
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1473
|
+
IRubyObject from_table = cachedString(context, fkTableName);
|
|
1474
|
+
IRubyObject to_table = cachedString(context, pkTableName);
|
|
1475
|
+
fKeys.add( FKDefinition.newInstance(context, from_table, to_table, options, Block.NULL_BLOCK) ); // ForeignKeyDefinition.new
|
|
1476
|
+
}
|
|
1544
1477
|
|
|
1545
|
-
|
|
1478
|
+
return runtime.newArray(fKeys);
|
|
1546
1479
|
|
|
1547
|
-
|
|
1548
|
-
}
|
|
1480
|
+
} finally { close(fkInfoSet); }
|
|
1549
1481
|
});
|
|
1550
1482
|
}
|
|
1551
1483
|
|
|
@@ -1560,7 +1492,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1560
1492
|
}
|
|
1561
1493
|
|
|
1562
1494
|
protected RubyClass getForeignKeyDefinition(final ThreadContext context) {
|
|
1563
|
-
final RubyClass adapterClass =
|
|
1495
|
+
final RubyClass adapterClass = adapter.getMetaClass();
|
|
1564
1496
|
IRubyObject FKDef = adapterClass.getConstantAt("ForeignKeyDefinition");
|
|
1565
1497
|
return FKDef != null ? (RubyClass) FKDef : getForeignKeyDefinition(context.runtime);
|
|
1566
1498
|
}
|
|
@@ -1568,42 +1500,34 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1568
1500
|
|
|
1569
1501
|
@JRubyMethod(name = "supports_foreign_keys?")
|
|
1570
1502
|
public IRubyObject supports_foreign_keys_p(final ThreadContext context) throws SQLException {
|
|
1571
|
-
return withConnection(context,
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
return context.runtime.newBoolean( metaData.supportsIntegrityEnhancementFacility() );
|
|
1575
|
-
}
|
|
1503
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
1504
|
+
final DatabaseMetaData metaData = connection.getMetaData();
|
|
1505
|
+
return context.runtime.newBoolean( metaData.supportsIntegrityEnhancementFacility() );
|
|
1576
1506
|
});
|
|
1577
1507
|
}
|
|
1578
1508
|
|
|
1579
1509
|
@JRubyMethod(name = "supports_views?")
|
|
1580
1510
|
public IRubyObject supports_views_p(final ThreadContext context) throws SQLException {
|
|
1581
|
-
return withConnection(context,
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
return context.runtime.newBoolean( true );
|
|
1589
|
-
}
|
|
1511
|
+
return withConnection(context, (Callable<IRubyObject>) connection -> {
|
|
1512
|
+
final DatabaseMetaData metaData = connection.getMetaData();
|
|
1513
|
+
final ResultSet tableTypes = metaData.getTableTypes();
|
|
1514
|
+
try {
|
|
1515
|
+
while ( tableTypes.next() ) {
|
|
1516
|
+
if ( "VIEW".equalsIgnoreCase( tableTypes.getString(1) ) ) {
|
|
1517
|
+
return context.runtime.newBoolean( true );
|
|
1590
1518
|
}
|
|
1591
1519
|
}
|
|
1592
|
-
finally {
|
|
1593
|
-
close(tableTypes);
|
|
1594
|
-
}
|
|
1595
|
-
return context.runtime.newBoolean( false );
|
|
1596
1520
|
}
|
|
1521
|
+
finally {
|
|
1522
|
+
close(tableTypes);
|
|
1523
|
+
}
|
|
1524
|
+
return context.runtime.newBoolean( false );
|
|
1597
1525
|
});
|
|
1598
1526
|
}
|
|
1599
1527
|
|
|
1600
1528
|
@JRubyMethod(name = "with_jdbc_connection", alias = "with_connection_retry_guard", frame = true)
|
|
1601
1529
|
public IRubyObject with_jdbc_connection(final ThreadContext context, final Block block) {
|
|
1602
|
-
return withConnection(context,
|
|
1603
|
-
public IRubyObject call(final Connection connection) throws SQLException {
|
|
1604
|
-
return block.call(context, convertJavaToRuby(connection));
|
|
1605
|
-
}
|
|
1606
|
-
});
|
|
1530
|
+
return withConnection(context, connection -> block.call(context, convertJavaToRuby(connection)));
|
|
1607
1531
|
}
|
|
1608
1532
|
|
|
1609
1533
|
/*
|
|
@@ -1664,24 +1588,22 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1664
1588
|
// TODO: Fix this, the columns don't have the info needed to handle this anymore
|
|
1665
1589
|
// currently commented out so that it will compile
|
|
1666
1590
|
|
|
1667
|
-
return withConnection(context,
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
setClobParameter(context, connection, statement, 1, value, column, Types.CLOB);
|
|
1678
|
-
}
|
|
1679
|
-
setStatementParameter(context, context.runtime, connection, statement, 2, idValue, idColumn);
|
|
1680
|
-
*/
|
|
1681
|
-
return statement.executeUpdate();
|
|
1591
|
+
return withConnection(context, connection -> {
|
|
1592
|
+
PreparedStatement statement = null;
|
|
1593
|
+
try {
|
|
1594
|
+
statement = connection.prepareStatement(sql);
|
|
1595
|
+
/*
|
|
1596
|
+
if ( binary ) { // blob
|
|
1597
|
+
setBlobParameter(context, connection, statement, 1, value, column, Types.BLOB);
|
|
1598
|
+
}
|
|
1599
|
+
else { // clob
|
|
1600
|
+
setClobParameter(context, connection, statement, 1, value, column, Types.CLOB);
|
|
1682
1601
|
}
|
|
1683
|
-
|
|
1602
|
+
setStatementParameter(context, context.runtime, connection, statement, 2, idValue, idColumn);
|
|
1603
|
+
*/
|
|
1604
|
+
return statement.executeUpdate();
|
|
1684
1605
|
}
|
|
1606
|
+
finally { close(statement); }
|
|
1685
1607
|
});
|
|
1686
1608
|
}
|
|
1687
1609
|
|
|
@@ -1737,7 +1659,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1737
1659
|
final IRubyObject self, final IRubyObject config, final Block block) {
|
|
1738
1660
|
final IRubyObject ds_or_name = rawDataSourceOrName(context, config);
|
|
1739
1661
|
|
|
1740
|
-
if ( ds_or_name == null ) return context.
|
|
1662
|
+
if ( ds_or_name == null ) return context.fals;
|
|
1741
1663
|
|
|
1742
1664
|
final javax.sql.DataSource dataSource;
|
|
1743
1665
|
final Object dsOrName = ds_or_name.toJava(Object.class);
|
|
@@ -1793,7 +1715,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1793
1715
|
}
|
|
1794
1716
|
}
|
|
1795
1717
|
|
|
1796
|
-
if ( configValue == null || configValue == context.nil || configValue ==
|
|
1718
|
+
if ( configValue == null || configValue == context.nil || configValue == context.fals ) {
|
|
1797
1719
|
return null;
|
|
1798
1720
|
}
|
|
1799
1721
|
return configValue;
|
|
@@ -1816,13 +1738,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1816
1738
|
}
|
|
1817
1739
|
}
|
|
1818
1740
|
|
|
1819
|
-
@Deprecated
|
|
1820
|
-
@JRubyMethod(name = "setup_jdbc_factory", visibility = Visibility.PROTECTED)
|
|
1821
|
-
public IRubyObject set_driver_factory(final ThreadContext context) {
|
|
1822
|
-
setDriverFactory(context);
|
|
1823
|
-
return get_connection_factory(context.runtime);
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
1741
|
private ConnectionFactory setDriverFactory(final ThreadContext context) {
|
|
1827
1742
|
|
|
1828
1743
|
final IRubyObject url = getConfigValue(context, "url");
|
|
@@ -1922,12 +1837,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1922
1837
|
return props;
|
|
1923
1838
|
}
|
|
1924
1839
|
|
|
1925
|
-
@JRubyMethod(name = "setup_jndi_factory", visibility = Visibility.PROTECTED)
|
|
1926
|
-
public IRubyObject set_data_source_factory(final ThreadContext context) {
|
|
1927
|
-
setDataSourceFactory(context);
|
|
1928
|
-
return get_connection_factory(context.runtime);
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
1840
|
private ConnectionFactory setDataSourceFactory(final ThreadContext context) {
|
|
1932
1841
|
final javax.sql.DataSource dataSource; final String lookupName;
|
|
1933
1842
|
IRubyObject value = getConfigValue(context, "data_source");
|
|
@@ -1949,28 +1858,10 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
1949
1858
|
private static volatile boolean defaultConfigJndi;
|
|
1950
1859
|
private static transient ConnectionFactory defaultConnectionFactory;
|
|
1951
1860
|
|
|
1952
|
-
/**
|
|
1953
|
-
* Sets the connection factory from the available configuration.
|
|
1954
|
-
* @param context
|
|
1955
|
-
* @see #initialize
|
|
1956
|
-
*/
|
|
1957
|
-
@Deprecated
|
|
1958
|
-
@JRubyMethod(name = "setup_connection_factory", visibility = Visibility.PROTECTED)
|
|
1959
|
-
public IRubyObject setup_connection_factory(final ThreadContext context) {
|
|
1960
|
-
setupConnectionFactory(context);
|
|
1961
|
-
return get_connection_factory(context.runtime);
|
|
1962
|
-
}
|
|
1963
|
-
|
|
1964
|
-
private IRubyObject get_connection_factory(final Ruby runtime) {
|
|
1965
|
-
return JavaUtil.convertJavaToRuby(runtime, connectionFactory);
|
|
1966
|
-
}
|
|
1967
|
-
|
|
1968
1861
|
/**
|
|
1969
1862
|
* @return whether the connection factory is JNDI based
|
|
1970
1863
|
*/
|
|
1971
1864
|
private boolean setupConnectionFactory(final ThreadContext context) {
|
|
1972
|
-
final IRubyObject config = getConfig();
|
|
1973
|
-
|
|
1974
1865
|
if ( defaultConfig == null ) {
|
|
1975
1866
|
synchronized(RubyJdbcConnection.class) {
|
|
1976
1867
|
if ( defaultConfig == null ) {
|
|
@@ -2002,18 +1893,17 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2002
1893
|
|
|
2003
1894
|
@JRubyMethod(name = "jndi?", alias = "jndi_connection?")
|
|
2004
1895
|
public RubyBoolean jndi_p(final ThreadContext context) {
|
|
2005
|
-
return context.runtime.newBoolean(
|
|
1896
|
+
return context.runtime.newBoolean(jndi);
|
|
2006
1897
|
}
|
|
2007
1898
|
|
|
2008
1899
|
protected boolean isJndi() { return this.jndi; }
|
|
2009
1900
|
|
|
2010
1901
|
@JRubyMethod(name = "config")
|
|
2011
|
-
public IRubyObject config() { return
|
|
1902
|
+
public IRubyObject config() { return config; }
|
|
2012
1903
|
|
|
2013
1904
|
public IRubyObject getConfig() { return this.config; }
|
|
2014
1905
|
|
|
2015
1906
|
protected final IRubyObject getConfigValue(final ThreadContext context, final String key) {
|
|
2016
|
-
final IRubyObject config = getConfig();
|
|
2017
1907
|
final RubySymbol keySym = context.runtime.newSymbol(key);
|
|
2018
1908
|
if ( config instanceof RubyHash ) {
|
|
2019
1909
|
final IRubyObject value = ((RubyHash) config).fastARef(keySym);
|
|
@@ -2024,7 +1914,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2024
1914
|
|
|
2025
1915
|
protected final IRubyObject setConfigValue(final ThreadContext context,
|
|
2026
1916
|
final String key, final IRubyObject value) {
|
|
2027
|
-
final IRubyObject config = getConfig();
|
|
2028
1917
|
final RubySymbol keySym = context.runtime.newSymbol(key);
|
|
2029
1918
|
if ( config instanceof RubyHash ) {
|
|
2030
1919
|
return ((RubyHash) config).op_aset(context, keySym, value);
|
|
@@ -2034,7 +1923,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2034
1923
|
|
|
2035
1924
|
protected final IRubyObject setConfigValueIfNotSet(final ThreadContext context,
|
|
2036
1925
|
final String key, final IRubyObject value) {
|
|
2037
|
-
final IRubyObject config = getConfig();
|
|
2038
1926
|
final RubySymbol keySym = context.runtime.newSymbol(key);
|
|
2039
1927
|
if ( config instanceof RubyHash ) {
|
|
2040
1928
|
final IRubyObject setValue = ((RubyHash) config).fastARef(keySym);
|
|
@@ -2054,7 +1942,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2054
1942
|
protected final IRubyObject getAdapter() { return this.adapter; }
|
|
2055
1943
|
|
|
2056
1944
|
protected RubyClass getJdbcColumnClass(final ThreadContext context) {
|
|
2057
|
-
return (RubyClass)
|
|
1945
|
+
return (RubyClass) adapter.callMethod(context, "jdbc_column_class");
|
|
2058
1946
|
}
|
|
2059
1947
|
|
|
2060
1948
|
protected ConnectionFactory getConnectionFactory() throws RaiseException {
|
|
@@ -2266,7 +2154,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2266
2154
|
@JRubyMethod(name = "raw_date_time?", meta = true)
|
|
2267
2155
|
public static IRubyObject useRawDateTime(final ThreadContext context, final IRubyObject self) {
|
|
2268
2156
|
if ( rawDateTime == null ) return context.nil;
|
|
2269
|
-
return context.runtime.newBoolean(
|
|
2157
|
+
return context.runtime.newBoolean(rawDateTime);
|
|
2270
2158
|
}
|
|
2271
2159
|
|
|
2272
2160
|
@JRubyMethod(name = "raw_date_time=", meta = true)
|
|
@@ -2280,17 +2168,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2280
2168
|
return value;
|
|
2281
2169
|
}
|
|
2282
2170
|
|
|
2283
|
-
/**
|
|
2284
|
-
* @return AR::Type-casted value
|
|
2285
|
-
* @since 1.3.18
|
|
2286
|
-
*/
|
|
2287
|
-
@Deprecated
|
|
2288
|
-
protected static IRubyObject typeCastFromDatabase(final ThreadContext context,
|
|
2289
|
-
final IRubyObject adapter, final RubySymbol typeName, final RubyString value) {
|
|
2290
|
-
final IRubyObject type = adapter.callMethod(context, "lookup_cast_type", typeName);
|
|
2291
|
-
return type.callMethod(context, "deserialize", value);
|
|
2292
|
-
}
|
|
2293
|
-
|
|
2294
2171
|
protected IRubyObject dateToRuby(final ThreadContext context,
|
|
2295
2172
|
final Ruby runtime, final ResultSet resultSet, final int column)
|
|
2296
2173
|
throws SQLException {
|
|
@@ -2301,11 +2178,11 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2301
2178
|
return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
|
|
2302
2179
|
}
|
|
2303
2180
|
|
|
2304
|
-
if ( rawDateTime != null && rawDateTime
|
|
2181
|
+
if ( rawDateTime != null && rawDateTime) {
|
|
2305
2182
|
return RubyString.newString(runtime, DateTimeUtils.dateToString(value));
|
|
2306
2183
|
}
|
|
2307
2184
|
|
|
2308
|
-
return DateTimeUtils.newDateAsTime(context, value,
|
|
2185
|
+
return DateTimeUtils.newDateAsTime(context, value, DateTimeZone.UTC).callMethod(context, "to_date");
|
|
2309
2186
|
}
|
|
2310
2187
|
|
|
2311
2188
|
protected IRubyObject timeToRuby(final ThreadContext context,
|
|
@@ -2317,7 +2194,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2317
2194
|
return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
|
|
2318
2195
|
}
|
|
2319
2196
|
|
|
2320
|
-
if ( rawDateTime != null && rawDateTime
|
|
2197
|
+
if ( rawDateTime != null && rawDateTime) {
|
|
2321
2198
|
return RubyString.newString(runtime, DateTimeUtils.timeToString(value));
|
|
2322
2199
|
}
|
|
2323
2200
|
|
|
@@ -2333,7 +2210,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2333
2210
|
return resultSet.wasNull() ? context.nil : RubyString.newEmptyString(runtime);
|
|
2334
2211
|
}
|
|
2335
2212
|
|
|
2336
|
-
if ( rawDateTime != null && rawDateTime
|
|
2213
|
+
if ( rawDateTime != null && rawDateTime) {
|
|
2337
2214
|
return RubyString.newString(runtime, DateTimeUtils.timestampToString(value));
|
|
2338
2215
|
}
|
|
2339
2216
|
|
|
@@ -2345,19 +2222,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2345
2222
|
return DateTimeUtils.newTime(context, value, getDefaultTimeZone(context));
|
|
2346
2223
|
}
|
|
2347
2224
|
|
|
2348
|
-
@Deprecated
|
|
2349
|
-
protected static RubyString timestampToRubyString(final Ruby runtime, String value) {
|
|
2350
|
-
// Timestamp's format: yyyy-mm-dd hh:mm:ss.fffffffff
|
|
2351
|
-
String suffix; // assumes java.sql.Timestamp internals :
|
|
2352
|
-
if ( value.endsWith( suffix = " 00:00:00.0" ) ) {
|
|
2353
|
-
value = value.substring( 0, value.length() - suffix.length() );
|
|
2354
|
-
}
|
|
2355
|
-
else if ( value.endsWith( suffix = ".0" ) ) {
|
|
2356
|
-
value = value.substring( 0, value.length() - suffix.length() );
|
|
2357
|
-
}
|
|
2358
|
-
return RubyString.newUnicodeString(runtime, value);
|
|
2359
|
-
}
|
|
2360
|
-
|
|
2361
2225
|
protected static Boolean rawBoolean;
|
|
2362
2226
|
static {
|
|
2363
2227
|
final String booleanRaw = SafePropertyAccessor.getProperty("arjdbc.boolean.raw");
|
|
@@ -2369,7 +2233,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2369
2233
|
@JRubyMethod(name = "raw_boolean?", meta = true)
|
|
2370
2234
|
public static IRubyObject useRawBoolean(final ThreadContext context, final IRubyObject self) {
|
|
2371
2235
|
if ( rawBoolean == null ) return context.nil;
|
|
2372
|
-
return context.runtime.newBoolean(
|
|
2236
|
+
return context.runtime.newBoolean(rawBoolean);
|
|
2373
2237
|
}
|
|
2374
2238
|
|
|
2375
2239
|
@JRubyMethod(name = "raw_boolean=", meta = true)
|
|
@@ -2401,13 +2265,13 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2401
2265
|
protected IRubyObject booleanToRuby(final ThreadContext context,
|
|
2402
2266
|
final Ruby runtime, final ResultSet resultSet, final int column)
|
|
2403
2267
|
throws SQLException {
|
|
2404
|
-
if ( rawBoolean != null && rawBoolean
|
|
2268
|
+
if ( rawBoolean != null && rawBoolean) {
|
|
2405
2269
|
final String value = resultSet.getString(column);
|
|
2406
2270
|
if ( value == null /* && resultSet.wasNull() */ ) return context.nil;
|
|
2407
2271
|
return RubyString.newUnicodeString(runtime, value);
|
|
2408
2272
|
}
|
|
2409
2273
|
final boolean value = resultSet.getBoolean(column);
|
|
2410
|
-
if (
|
|
2274
|
+
if (!value && resultSet.wasNull()) return context.nil;
|
|
2411
2275
|
return runtime.newBoolean(value);
|
|
2412
2276
|
}
|
|
2413
2277
|
|
|
@@ -2555,9 +2419,16 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2555
2419
|
final Connection connection, final PreparedStatement statement,
|
|
2556
2420
|
final int index, IRubyObject attribute) throws SQLException {
|
|
2557
2421
|
|
|
2558
|
-
|
|
2559
|
-
final int type
|
|
2560
|
-
|
|
2422
|
+
final IRubyObject value;
|
|
2423
|
+
final int type;
|
|
2424
|
+
|
|
2425
|
+
if (attributeClass.isInstance(attribute)) {
|
|
2426
|
+
type = jdbcTypeForAttribute(context, attribute);
|
|
2427
|
+
value = valueForDatabase(context, attribute);
|
|
2428
|
+
} else {
|
|
2429
|
+
type = jdbcTypeForPrimitiveAttribute(context, attribute);
|
|
2430
|
+
value = attribute;
|
|
2431
|
+
}
|
|
2561
2432
|
|
|
2562
2433
|
// All the set methods were calling this first so save a method call in the nil case
|
|
2563
2434
|
if ( value == context.nil ) {
|
|
@@ -2625,7 +2496,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2625
2496
|
}
|
|
2626
2497
|
}
|
|
2627
2498
|
|
|
2628
|
-
protected static final Map<String, Integer> JDBC_TYPE_FOR = new HashMap
|
|
2499
|
+
protected static final Map<String, Integer> JDBC_TYPE_FOR = new HashMap<>(32, 1);
|
|
2629
2500
|
static {
|
|
2630
2501
|
JDBC_TYPE_FOR.put("string", Types.VARCHAR);
|
|
2631
2502
|
JDBC_TYPE_FOR.put("text", Types.CLOB);
|
|
@@ -2667,12 +2538,40 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2667
2538
|
final String internedType = internedTypeFor(context, attribute);
|
|
2668
2539
|
final Integer sqlType = jdbcTypeFor(internedType);
|
|
2669
2540
|
if ( sqlType != null ) {
|
|
2670
|
-
return sqlType
|
|
2541
|
+
return sqlType;
|
|
2671
2542
|
}
|
|
2672
2543
|
|
|
2673
2544
|
return Types.OTHER; // -1 as well as 0 are used in Types
|
|
2674
2545
|
}
|
|
2675
2546
|
|
|
2547
|
+
protected String internedTypeForPrimitive(final ThreadContext context, final IRubyObject value) throws SQLException {
|
|
2548
|
+
if (value instanceof RubyString) {
|
|
2549
|
+
return "string";
|
|
2550
|
+
}
|
|
2551
|
+
if (value instanceof RubyInteger) {
|
|
2552
|
+
return "integer";
|
|
2553
|
+
}
|
|
2554
|
+
if (value instanceof RubyNumeric) {
|
|
2555
|
+
return "float";
|
|
2556
|
+
}
|
|
2557
|
+
if (value instanceof RubyTime || value instanceof RubyDateTime) {
|
|
2558
|
+
return "timestamp";
|
|
2559
|
+
}
|
|
2560
|
+
if (value instanceof RubyDate) {
|
|
2561
|
+
return "date";
|
|
2562
|
+
}
|
|
2563
|
+
if (value instanceof RubyBoolean) {
|
|
2564
|
+
return "boolean";
|
|
2565
|
+
}
|
|
2566
|
+
return "string";
|
|
2567
|
+
}
|
|
2568
|
+
|
|
2569
|
+
protected Integer jdbcTypeForPrimitiveAttribute(final ThreadContext context,
|
|
2570
|
+
final IRubyObject attribute) throws SQLException {
|
|
2571
|
+
final String internedType = internedTypeForPrimitive(context, attribute);
|
|
2572
|
+
return jdbcTypeFor(internedType);
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2676
2575
|
protected Integer jdbcTypeFor(final String type) {
|
|
2677
2576
|
return JDBC_TYPE_FOR.get(type);
|
|
2678
2577
|
}
|
|
@@ -2684,7 +2583,9 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2684
2583
|
}
|
|
2685
2584
|
|
|
2686
2585
|
protected static IRubyObject attributeSQLType(final ThreadContext context, final IRubyObject attribute) {
|
|
2687
|
-
|
|
2586
|
+
final IRubyObject type = attributeType(context, attribute);
|
|
2587
|
+
if (type != null) return type.callMethod(context, "type");
|
|
2588
|
+
return context.nil;
|
|
2688
2589
|
}
|
|
2689
2590
|
|
|
2690
2591
|
private final CachingCallSite value_site = new FunctionalCachingCallSite("value"); // AR::Attribute#value
|
|
@@ -2699,23 +2600,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2699
2600
|
|
|
2700
2601
|
final IRubyObject value = value_site.call(context, attribute, attribute);
|
|
2701
2602
|
|
|
2702
|
-
|
|
2703
|
-
return "integer";
|
|
2704
|
-
}
|
|
2705
|
-
|
|
2706
|
-
if (value instanceof RubyNumeric) {
|
|
2707
|
-
return "float";
|
|
2708
|
-
}
|
|
2709
|
-
|
|
2710
|
-
if (value instanceof RubyTime) {
|
|
2711
|
-
return "timestamp";
|
|
2712
|
-
}
|
|
2713
|
-
|
|
2714
|
-
if (value instanceof RubyBoolean) {
|
|
2715
|
-
return "boolean";
|
|
2716
|
-
}
|
|
2717
|
-
|
|
2718
|
-
return "string";
|
|
2603
|
+
return internedTypeForPrimitive(context, value);
|
|
2719
2604
|
}
|
|
2720
2605
|
|
|
2721
2606
|
// to be overriden in child class for database specific types
|
|
@@ -2854,11 +2739,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2854
2739
|
statement.setTimestamp(index, timestamp, getCalendar(dateTime.getZone()));
|
|
2855
2740
|
}
|
|
2856
2741
|
|
|
2857
|
-
@Deprecated
|
|
2858
|
-
protected static Timestamp convertToTimestamp(final RubyFloat value) {
|
|
2859
|
-
return DateTimeUtils.convertToTimestamp(value);
|
|
2860
|
-
}
|
|
2861
|
-
|
|
2862
2742
|
protected static Calendar getCalendar(final DateTimeZone zone) { // final java.util.Date hint
|
|
2863
2743
|
if (DateTimeZone.UTC == zone) return getCalendarUTC();
|
|
2864
2744
|
if (DateTimeZone.getDefault() == zone) return new GregorianCalendar();
|
|
@@ -2904,9 +2784,14 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2904
2784
|
value = value.callMethod(context, "to_date");
|
|
2905
2785
|
}
|
|
2906
2786
|
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2787
|
+
if (value instanceof RubyDate) {
|
|
2788
|
+
RubyDate rubyDate = (RubyDate) value;
|
|
2789
|
+
statement.setDate(index, rubyDate.toJava(Date.class));
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
// NOTE: assuming Date#to_s does right ...
|
|
2794
|
+
statement.setDate(index, Date.valueOf(value.toString()));
|
|
2910
2795
|
}
|
|
2911
2796
|
|
|
2912
2797
|
protected void setBooleanParameter(final ThreadContext context,
|
|
@@ -2943,7 +2828,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
2943
2828
|
// For some reason the driver doesn't like "character varying" as a type
|
|
2944
2829
|
if ( type.eql(context.runtime.newSymbol("string")) ) return "varchar";
|
|
2945
2830
|
|
|
2946
|
-
final RubyHash nativeTypes = (RubyHash)
|
|
2831
|
+
final RubyHash nativeTypes = (RubyHash) adapter.callMethod(context, "native_database_types");
|
|
2947
2832
|
// e.g. `integer: { name: 'integer' }`
|
|
2948
2833
|
final RubyHash typeInfo = (RubyHash) nativeTypes.op_aref(context, type);
|
|
2949
2834
|
|
|
@@ -3004,16 +2889,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3004
2889
|
}
|
|
3005
2890
|
|
|
3006
2891
|
/**
|
|
3007
|
-
*
|
|
3008
|
-
* @return connection
|
|
3009
|
-
* @throws <code>ActiveRecord::ConnectionNotEstablished</code>, <code>ActiveRecord::JDBCError</code>
|
|
3010
|
-
*/
|
|
3011
|
-
protected Connection getConnection() throws RaiseException {
|
|
3012
|
-
return getConnection(false);
|
|
3013
|
-
}
|
|
3014
|
-
|
|
3015
|
-
/**
|
|
3016
|
-
* @see #getConnection()
|
|
2892
|
+
* Returns a connection (might cause a reconnect if there's none).
|
|
3017
2893
|
* @param required set to true if a connection is required to exists (e.g. on commit)
|
|
3018
2894
|
* @return connection
|
|
3019
2895
|
* @throws <code>ActiveRecord::ConnectionNotEstablished</code> if disconnected
|
|
@@ -3028,17 +2904,15 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3028
2904
|
}
|
|
3029
2905
|
}
|
|
3030
2906
|
|
|
3031
|
-
|
|
2907
|
+
protected Connection getConnectionInternal(final boolean required) throws SQLException {
|
|
3032
2908
|
Connection connection = getConnectionImpl();
|
|
3033
|
-
if (
|
|
3034
|
-
if (
|
|
3035
|
-
|
|
3036
|
-
|
|
2909
|
+
if (connection == null && required) {
|
|
2910
|
+
if (!connected) handleNotConnected(); // raise ConnectionNotEstablished
|
|
2911
|
+
synchronized (this) {
|
|
2912
|
+
connection = getConnectionImpl();
|
|
2913
|
+
if ( connection == null ) {
|
|
2914
|
+
connectImpl(true); // throws SQLException
|
|
3037
2915
|
connection = getConnectionImpl();
|
|
3038
|
-
if ( connection == null ) {
|
|
3039
|
-
connectImpl( true ); // throws SQLException
|
|
3040
|
-
connection = getConnectionImpl();
|
|
3041
|
-
}
|
|
3042
2916
|
}
|
|
3043
2917
|
}
|
|
3044
2918
|
}
|
|
@@ -3169,7 +3043,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3169
3043
|
try {
|
|
3170
3044
|
tablesSet = metaData.getTables(catalog, _schemaPattern, _tablePattern, types);
|
|
3171
3045
|
if ( checkExistsOnly ) { // only check if given table exists
|
|
3172
|
-
return tablesSet.next() ? context.
|
|
3046
|
+
return tablesSet.next() ? context.tru : null;
|
|
3173
3047
|
}
|
|
3174
3048
|
else {
|
|
3175
3049
|
return mapTables(context, connection, catalog, _schemaPattern, _tablePattern, tablesSet);
|
|
@@ -3178,15 +3052,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3178
3052
|
finally { close(tablesSet); }
|
|
3179
3053
|
}
|
|
3180
3054
|
|
|
3181
|
-
@Deprecated
|
|
3182
|
-
protected IRubyObject matchTables(final Ruby runtime,
|
|
3183
|
-
final Connection connection,
|
|
3184
|
-
final String catalog, final String schemaPattern,
|
|
3185
|
-
final String tablePattern, final String[] types,
|
|
3186
|
-
final boolean checkExistsOnly) throws SQLException {
|
|
3187
|
-
return matchTables(runtime.getCurrentContext(), connection, catalog, schemaPattern, tablePattern, types, checkExistsOnly);
|
|
3188
|
-
}
|
|
3189
|
-
|
|
3190
3055
|
// NOTE java.sql.DatabaseMetaData.getTables :
|
|
3191
3056
|
protected final static int TABLES_TABLE_CAT = 1;
|
|
3192
3057
|
protected final static int TABLES_TABLE_SCHEM = 2;
|
|
@@ -3275,7 +3140,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3275
3140
|
final String tabName = results.getString(TABLE_NAME);
|
|
3276
3141
|
final RubyString tableName = cachedString(context, caseConvertIdentifierForRails(metaData, tabName));
|
|
3277
3142
|
|
|
3278
|
-
final IRubyObject type_metadata =
|
|
3143
|
+
final IRubyObject type_metadata = adapter.callMethod(context, "fetch_type_metadata", sqlType);
|
|
3279
3144
|
|
|
3280
3145
|
// (name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
|
|
3281
3146
|
final IRubyObject[] args = new IRubyObject[] {
|
|
@@ -3291,7 +3156,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3291
3156
|
ResultSet primaryKeys = null;
|
|
3292
3157
|
try {
|
|
3293
3158
|
primaryKeys = metaData.getPrimaryKeys(components.catalog, components.schema, components.name);
|
|
3294
|
-
final List<String> primaryKeyNames = new ArrayList
|
|
3159
|
+
final List<String> primaryKeyNames = new ArrayList<>(4);
|
|
3295
3160
|
while ( primaryKeys.next() ) {
|
|
3296
3161
|
primaryKeyNames.add( primaryKeys.getString(COLUMN_NAME) );
|
|
3297
3162
|
}
|
|
@@ -3340,7 +3205,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3340
3205
|
// not have and auto-generated ID column :
|
|
3341
3206
|
boolean next = genKeys.next() && genKeys.getMetaData().getColumnCount() > 0;
|
|
3342
3207
|
// singleResult == null - guess if only single key returned
|
|
3343
|
-
if ( singleResult == null || singleResult
|
|
3208
|
+
if ( singleResult == null || singleResult) {
|
|
3344
3209
|
if ( next ) {
|
|
3345
3210
|
firstKey = mapGeneratedKey(runtime, genKeys);
|
|
3346
3211
|
if ( singleResult != null || ! genKeys.next() ) {
|
|
@@ -3373,7 +3238,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3373
3238
|
if (supportsGeneratedKeys == null) {
|
|
3374
3239
|
supportsGeneratedKeys = this.supportsGeneratedKeys = connection.getMetaData().supportsGetGeneratedKeys();
|
|
3375
3240
|
}
|
|
3376
|
-
return supportsGeneratedKeys
|
|
3241
|
+
return supportsGeneratedKeys;
|
|
3377
3242
|
}
|
|
3378
3243
|
|
|
3379
3244
|
/**
|
|
@@ -3405,8 +3270,8 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3405
3270
|
final ColumnData[] columns = extractColumns(context, connection, resultSet, false);
|
|
3406
3271
|
|
|
3407
3272
|
final Ruby runtime = context.runtime;
|
|
3408
|
-
final IRubyObject[] blockArgs = new IRubyObject[columns.length];
|
|
3409
3273
|
while ( resultSet.next() ) {
|
|
3274
|
+
final IRubyObject[] blockArgs = new IRubyObject[columns.length];
|
|
3410
3275
|
for ( int i = 0; i < columns.length; i++ ) {
|
|
3411
3276
|
final ColumnData column = columns[i];
|
|
3412
3277
|
blockArgs[i] = jdbcToRuby(context, runtime, column.index, column.type, resultSet);
|
|
@@ -3432,16 +3297,6 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3432
3297
|
return setupColumns(context, connection, resultSet.getMetaData(), downCase);
|
|
3433
3298
|
}
|
|
3434
3299
|
|
|
3435
|
-
/**
|
|
3436
|
-
* @deprecated use {@link #extractColumns(ThreadContext, Connection, ResultSet, boolean)}
|
|
3437
|
-
*/
|
|
3438
|
-
@Deprecated
|
|
3439
|
-
protected ColumnData[] extractColumns(final Ruby runtime,
|
|
3440
|
-
final Connection connection, final ResultSet resultSet,
|
|
3441
|
-
final boolean downCase) throws SQLException {
|
|
3442
|
-
return extractColumns(runtime.getCurrentContext(), connection, resultSet, downCase);
|
|
3443
|
-
}
|
|
3444
|
-
|
|
3445
3300
|
protected <T> T withConnection(final ThreadContext context, final Callable<T> block)
|
|
3446
3301
|
throws RaiseException {
|
|
3447
3302
|
try {
|
|
@@ -3547,13 +3402,12 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3547
3402
|
}
|
|
3548
3403
|
|
|
3549
3404
|
protected boolean isTransient(final Exception exception) {
|
|
3550
|
-
|
|
3551
|
-
return false;
|
|
3405
|
+
return exception instanceof SQLTransientException;
|
|
3552
3406
|
}
|
|
3553
3407
|
|
|
3554
3408
|
protected boolean isRecoverable(final Exception exception) {
|
|
3555
|
-
|
|
3556
|
-
|
|
3409
|
+
return exception instanceof SQLRecoverableException;
|
|
3410
|
+
// exception instanceof SQLException; // pre JDBC 4.0 drivers?
|
|
3557
3411
|
}
|
|
3558
3412
|
|
|
3559
3413
|
private static Throwable getCause(Throwable exception) {
|
|
@@ -3711,6 +3565,11 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3711
3565
|
return Result.newInstance(context, columnsToArray(context, columns), rows, Block.NULL_BLOCK); // Result.new
|
|
3712
3566
|
}
|
|
3713
3567
|
|
|
3568
|
+
protected static IRubyObject newEmptyResult(final ThreadContext context) {
|
|
3569
|
+
final RubyClass Result = getResult(context.runtime);
|
|
3570
|
+
return Result.newInstance(context, RubyArray.newEmptyArray(context.runtime), RubyArray.newEmptyArray(context.runtime), Block.NULL_BLOCK); // Result.new
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3714
3573
|
private static RubyArray columnsToArray(ThreadContext context, ColumnData[] columns) {
|
|
3715
3574
|
final IRubyObject[] cols = new IRubyObject[columns.length];
|
|
3716
3575
|
|
|
@@ -3963,7 +3822,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3963
3822
|
public static void debugStackTrace(final ThreadContext context, final Throwable e) {
|
|
3964
3823
|
if ( debug || ( context != null && context.runtime.isDebug() ) ) {
|
|
3965
3824
|
final PrintStream out = context != null ? context.runtime.getOut() : System.out;
|
|
3966
|
-
if ( debugStackTrace == null || debugStackTrace
|
|
3825
|
+
if ( debugStackTrace == null || debugStackTrace) {
|
|
3967
3826
|
e.printStackTrace(out);
|
|
3968
3827
|
}
|
|
3969
3828
|
else {
|
|
@@ -3979,8 +3838,7 @@ public class RubyJdbcConnection extends RubyObject {
|
|
|
3979
3838
|
private static boolean driverUsedLogged;
|
|
3980
3839
|
|
|
3981
3840
|
private void logDriverUsed(final Connection connection) {
|
|
3982
|
-
if (
|
|
3983
|
-
if ( driverUsedLogged ) return;
|
|
3841
|
+
if (debug && !driverUsedLogged) {
|
|
3984
3842
|
driverUsedLogged = true;
|
|
3985
3843
|
try {
|
|
3986
3844
|
final DatabaseMetaData meta = connection.getMetaData();
|