18
18
import java .sql .Array ;
19
19
import java .sql .Blob ;
20
20
import java .sql .CallableStatement ;
21
+ import java .sql .ClientInfoStatus ;
21
22
import java .sql .Clob ;
22
23
import java .sql .Connection ;
23
24
import java .sql .DatabaseMetaData ;
35
36
import java .sql .Statement ;
36
37
import java .sql .Struct ;
37
38
import java .util .Arrays ;
39
+ import java .util .Collection ;
40
+ import java .util .Collections ;
41
+ import java .util .HashMap ;
38
42
import java .util .List ;
39
43
import java .util .Map ;
40
44
import java .util .Properties ;
41
45
import java .util .concurrent .Executor ;
42
46
43
- @ SuppressWarnings ("Since15" )
44
47
public class SQLConnection implements Connection {
45
48
46
49
private static final int UNSET_HOLDABILITY = 0 ;
@@ -212,12 +215,12 @@ public PreparedStatement prepareStatement(String sql, String[] columnNames) thro
212
215
213
216
@ Override
214
217
public CallableStatement prepareCall (String sql ) throws SQLException {
215
- throw new SQLFeatureNotSupportedException ( );
218
+ return prepareCall ( sql , ResultSet . TYPE_FORWARD_ONLY , ResultSet . CONCUR_READ_ONLY );
216
219
}
217
220
218
221
@ Override
219
222
public CallableStatement prepareCall (String sql , int resultSetType , int resultSetConcurrency ) throws SQLException {
220
- throw new SQLFeatureNotSupportedException ( );
223
+ return prepareCall ( sql , resultSetType , resultSetConcurrency , getHoldability () );
221
224
}
222
225
223
226
@ Override
@@ -236,28 +239,51 @@ public String nativeSQL(String sql) throws SQLException {
236
239
237
240
@ Override
238
241
public void setAutoCommit (boolean autoCommit ) throws SQLException {
242
+ checkNotClosed ();
239
243
if (autoCommit == false ) {
240
244
throw new SQLFeatureNotSupportedException ();
241
245
}
242
246
}
243
247
244
248
@ Override
245
249
public boolean getAutoCommit () throws SQLException {
250
+ checkNotClosed ();
246
251
return true ;
247
252
}
248
253
249
254
@ Override
250
255
public void commit () throws SQLException {
256
+ checkNotClosed ();
257
+ if (getAutoCommit ()) {
258
+ throw new SQLNonTransientException (
259
+ "Cannot commit when auto-commit is enabled." ,
260
+ SQLStates .INVALID_TRANSACTION_STATE .getSqlState ()
261
+ );
262
+ }
251
263
throw new SQLFeatureNotSupportedException ();
252
264
}
253
265
254
266
@ Override
255
267
public void rollback () throws SQLException {
268
+ checkNotClosed ();
269
+ if (getAutoCommit ()) {
270
+ throw new SQLNonTransientException (
271
+ "Cannot rollback when auto-commit is enabled." ,
272
+ SQLStates .INVALID_TRANSACTION_STATE .getSqlState ()
273
+ );
274
+ }
256
275
throw new SQLFeatureNotSupportedException ();
257
276
}
258
277
259
278
@ Override
260
279
public void rollback (Savepoint savepoint ) throws SQLException {
280
+ checkNotClosed ();
281
+ if (getAutoCommit ()) {
282
+ throw new SQLNonTransientException (
283
+ "Cannot roll back to a savepoint when auto-commit is enabled." ,
284
+ SQLStates .INVALID_TRANSACTION_STATE .getSqlState ()
285
+ );
286
+ }
261
287
throw new SQLFeatureNotSupportedException ();
262
288
}
263
289
@@ -282,52 +308,61 @@ public DatabaseMetaData getMetaData() throws SQLException {
282
308
283
309
@ Override
284
310
public void setReadOnly (boolean readOnly ) throws SQLException {
285
-
311
+ checkNotClosed ();
312
+ throw new SQLFeatureNotSupportedException ();
286
313
}
287
314
288
315
@ Override
289
316
public boolean isReadOnly () throws SQLException {
317
+ checkNotClosed ();
290
318
return false ;
291
319
}
292
320
293
321
@ Override
294
322
public void setCatalog (String catalog ) throws SQLException {
323
+ checkNotClosed ();
295
324
}
296
325
297
326
@ Override
298
327
public String getCatalog () throws SQLException {
328
+ checkNotClosed ();
299
329
return null ;
300
330
}
301
331
302
332
@ Override
303
333
public void setTransactionIsolation (int level ) throws SQLException {
334
+ checkNotClosed ();
304
335
if (level != Connection .TRANSACTION_NONE ) {
305
336
throw new SQLFeatureNotSupportedException ();
306
337
}
307
338
}
308
339
309
340
@ Override
310
341
public int getTransactionIsolation () throws SQLException {
342
+ checkNotClosed ();
311
343
return Connection .TRANSACTION_NONE ;
312
344
}
313
345
314
346
@ Override
315
347
public SQLWarning getWarnings () throws SQLException {
348
+ checkNotClosed ();
316
349
return null ;
317
350
}
318
351
319
352
@ Override
320
353
public void clearWarnings () throws SQLException {
321
-
354
+ checkNotClosed ();
322
355
}
323
356
324
357
@ Override
325
358
public Map <String , Class <?>> getTypeMap () throws SQLException {
359
+ checkNotClosed ();
326
360
throw new SQLFeatureNotSupportedException ();
327
361
}
328
362
329
363
@ Override
330
364
public void setTypeMap (Map <String , Class <?>> map ) throws SQLException {
365
+ checkNotClosed ();
331
366
throw new SQLFeatureNotSupportedException ();
332
367
}
333
368
@@ -349,85 +384,165 @@ public int getHoldability() throws SQLException {
349
384
350
385
@ Override
351
386
public Savepoint setSavepoint () throws SQLException {
387
+ checkNotClosed ();
388
+ if (getAutoCommit ()) {
389
+ throw new SQLNonTransientException (
390
+ "Cannot set a savepoint when auto-commit is enabled." ,
391
+ SQLStates .INVALID_TRANSACTION_STATE .getSqlState ()
392
+ );
393
+ }
352
394
throw new SQLFeatureNotSupportedException ();
353
395
}
354
396
355
397
@ Override
356
398
public Savepoint setSavepoint (String name ) throws SQLException {
399
+ checkNotClosed ();
400
+ if (getAutoCommit ()) {
401
+ throw new SQLNonTransientException (
402
+ "Cannot set a savepoint when auto-commit is enabled." ,
403
+ SQLStates .INVALID_TRANSACTION_STATE .getSqlState ()
404
+ );
405
+ }
357
406
throw new SQLFeatureNotSupportedException ();
358
407
}
359
408
360
409
@ Override
361
410
public void releaseSavepoint (Savepoint savepoint ) throws SQLException {
411
+ checkNotClosed ();
362
412
throw new SQLFeatureNotSupportedException ();
363
413
}
364
414
365
415
@ Override
366
416
public Clob createClob () throws SQLException {
417
+ checkNotClosed ();
367
418
throw new SQLFeatureNotSupportedException ();
368
419
}
369
420
370
421
@ Override
371
422
public Blob createBlob () throws SQLException {
423
+ checkNotClosed ();
372
424
throw new SQLFeatureNotSupportedException ();
373
425
}
374
426
375
427
@ Override
376
428
public NClob createNClob () throws SQLException {
429
+ checkNotClosed ();
377
430
throw new SQLFeatureNotSupportedException ();
378
431
}
379
432
380
433
@ Override
381
434
public SQLXML createSQLXML () throws SQLException {
435
+ checkNotClosed ();
382
436
throw new SQLFeatureNotSupportedException ();
383
437
}
384
438
439
+ /**
440
+ * {@inheritDoc}
441
+ *
442
+ * @param timeout temporally ignored param
443
+ *
444
+ * @return connection activity status
445
+ */
385
446
@ Override
386
447
public boolean isValid (int timeout ) throws SQLException {
387
448
return true ;
388
449
}
389
450
390
451
@ Override
391
452
public void setClientInfo (String name , String value ) throws SQLClientInfoException {
392
- throw new SQLClientInfoException ();
453
+ try {
454
+ checkNotClosed ();
455
+ throwUnknownClientProperties (Collections .singleton (name ));
456
+ } catch (SQLException cause ) {
457
+ throwUnknownReasonClientProperties ("Connection is closed" , Collections .singleton (name ), cause );
458
+ }
393
459
}
394
460
395
461
@ Override
396
462
public void setClientInfo (Properties properties ) throws SQLClientInfoException {
397
- throw new SQLClientInfoException ();
463
+ try {
464
+ checkNotClosed ();
465
+ throwUnknownClientProperties (properties .keySet ());
466
+ } catch (SQLException cause ) {
467
+ throwUnknownReasonClientProperties ("Connection is closed" , properties .keySet (), cause );
468
+ }
469
+ }
470
+
471
+ /**
472
+ * Throws an exception caused by {@code cause} and marks all properties
473
+ * as {@link ClientInfoStatus#REASON_UNKNOWN}
474
+ *
475
+ * @param reason reason mesage
476
+ * @param properties client properties
477
+ * @param cause original cause
478
+ *
479
+ * @throws SQLClientInfoException wrapped exception
480
+ */
481
+ private void throwUnknownReasonClientProperties (String reason ,
482
+ Collection <Object > properties ,
483
+ SQLException cause ) throws SQLClientInfoException {
484
+ Map <String , ClientInfoStatus > failedProperties = new HashMap <>();
485
+ properties .forEach (property -> {
486
+ failedProperties .put (property .toString (), ClientInfoStatus .REASON_UNKNOWN );
487
+ });
488
+ throw new SQLClientInfoException (reason , failedProperties , cause );
489
+ }
490
+
491
+ /**
492
+ * Throws exception for unrecognizable properties
493
+ *
494
+ * @param properties unknown property names
495
+ *
496
+ * @throws SQLClientInfoException wrapped exception
497
+ */
498
+ private void throwUnknownClientProperties (Collection <Object > properties ) throws SQLClientInfoException {
499
+ Map <String , ClientInfoStatus > failedProperties = new HashMap <>();
500
+ properties .forEach (property -> {
501
+ failedProperties .put (property .toString (), ClientInfoStatus .REASON_UNKNOWN_PROPERTY );
502
+ });
503
+ throw new SQLClientInfoException (failedProperties );
398
504
}
399
505
400
506
@ Override
401
507
public String getClientInfo (String name ) throws SQLException {
508
+ checkNotClosed ();
402
509
throw new SQLFeatureNotSupportedException ();
403
510
}
404
511
405
512
@ Override
406
513
public Properties getClientInfo () throws SQLException {
514
+ checkNotClosed ();
407
515
throw new SQLFeatureNotSupportedException ();
408
516
}
409
517
410
518
@ Override
411
519
public Array createArrayOf (String typeName , Object [] elements ) throws SQLException {
520
+ checkNotClosed ();
412
521
throw new SQLFeatureNotSupportedException ();
413
522
}
414
523
415
524
@ Override
416
525
public Struct createStruct (String typeName , Object [] attributes ) throws SQLException {
526
+ checkNotClosed ();
417
527
throw new SQLFeatureNotSupportedException ();
418
528
}
419
529
420
530
@ Override
421
531
public void setSchema (String schema ) throws SQLException {
532
+ checkNotClosed ();
422
533
}
423
534
424
535
@ Override
425
536
public String getSchema () throws SQLException {
537
+ checkNotClosed ();
426
538
return null ;
427
539
}
428
540
429
541
@ Override
430
542
public void abort (Executor executor ) throws SQLException {
543
+ if (isClosed ()) {
544
+ return ;
545
+ }
431
546
throw new SQLFeatureNotSupportedException ();
432
547
}
433
548
0 commit comments