12
12
import java .sql .Array ;
13
13
import java .sql .Blob ;
14
14
import java .sql .CallableStatement ;
15
+ import java .sql .ClientInfoStatus ;
15
16
import java .sql .Clob ;
16
17
import java .sql .Connection ;
17
18
import java .sql .DatabaseMetaData ;
29
30
import java .sql .Statement ;
30
31
import java .sql .Struct ;
31
32
import java .util .Arrays ;
33
+ import java .util .Collection ;
34
+ import java .util .Collections ;
35
+ import java .util .HashMap ;
32
36
import java .util .List ;
33
37
import java .util .Map ;
34
38
import java .util .Properties ;
40
44
import static org .tarantool .jdbc .SQLDriver .PROP_SOCKET_TIMEOUT ;
41
45
import static org .tarantool .jdbc .SQLDriver .PROP_USER ;
42
46
43
- @ SuppressWarnings ("Since15" )
44
47
public class SQLConnection implements Connection {
45
48
46
49
private static final int UNSET_HOLDABILITY = 0 ;
@@ -91,6 +94,7 @@ public class SQLConnection implements Connection {
91
94
* to honor this timeout for the following read/write operations as well.
92
95
*
93
96
* @return Connected socket.
97
+ *
94
98
* @throws SQLException if failed.
95
99
*/
96
100
protected Socket getConnectedSocket () throws SQLException {
@@ -140,7 +144,9 @@ protected Socket makeSocket() {
140
144
* @param user User name.
141
145
* @param pass Password.
142
146
* @param socket Connected socket.
147
+ *
143
148
* @return Native tarantool connection.
149
+ *
144
150
* @throws IOException if failed.
145
151
*/
146
152
protected TarantoolConnection makeConnection (String user , String pass , Socket socket ) throws IOException {
@@ -161,7 +167,7 @@ public PreparedStatement prepareStatement(String sql) throws SQLException {
161
167
162
168
@ Override
163
169
public CallableStatement prepareCall (String sql ) throws SQLException {
164
- throw new SQLFeatureNotSupportedException ( );
170
+ return prepareCall ( sql , ResultSet . TYPE_FORWARD_ONLY , ResultSet . CONCUR_READ_ONLY );
165
171
}
166
172
167
173
@ Override
@@ -171,25 +177,38 @@ public String nativeSQL(String sql) throws SQLException {
171
177
172
178
@ Override
173
179
public void setAutoCommit (boolean autoCommit ) throws SQLException {
180
+ checkNotClosed ();
174
181
if (autoCommit == false ) {
175
182
throw new SQLFeatureNotSupportedException ();
176
183
}
177
184
}
178
185
179
186
@ Override
180
187
public boolean getAutoCommit () throws SQLException {
188
+ checkNotClosed ();
181
189
return true ;
182
190
}
183
191
184
192
@ Override
185
193
public void commit () throws SQLException {
186
- throw new SQLFeatureNotSupportedException ();
194
+ checkNotClosed ();
195
+ if (getAutoCommit ()) {
196
+ throw new SQLNonTransientException (
197
+ "Cannot commit when auto-commit is enabled." ,
198
+ SQLStates .IVALID_TRANSACTION_STATE .getSqlState ()
199
+ );
200
+ }
187
201
}
188
202
189
203
@ Override
190
204
public void rollback () throws SQLException {
191
- throw new SQLFeatureNotSupportedException ();
192
-
205
+ checkNotClosed ();
206
+ if (getAutoCommit ()) {
207
+ throw new SQLNonTransientException (
208
+ "Cannot rollback when auto-commit is enabled." ,
209
+ SQLStates .IVALID_TRANSACTION_STATE .getSqlState ()
210
+ );
211
+ }
193
212
}
194
213
195
214
@ Override
@@ -213,43 +232,50 @@ public DatabaseMetaData getMetaData() throws SQLException {
213
232
214
233
@ Override
215
234
public void setReadOnly (boolean readOnly ) throws SQLException {
216
-
235
+ checkNotClosed ();
236
+ throw new SQLFeatureNotSupportedException ();
217
237
}
218
238
219
239
@ Override
220
240
public boolean isReadOnly () throws SQLException {
241
+ checkNotClosed ();
221
242
return false ;
222
243
}
223
244
224
245
@ Override
225
246
public void setCatalog (String catalog ) throws SQLException {
247
+ checkNotClosed ();
226
248
}
227
249
228
250
@ Override
229
251
public String getCatalog () throws SQLException {
252
+ checkNotClosed ();
230
253
return null ;
231
254
}
232
255
233
256
@ Override
234
257
public void setTransactionIsolation (int level ) throws SQLException {
258
+ checkNotClosed ();
235
259
if (level != Connection .TRANSACTION_NONE ) {
236
260
throw new SQLFeatureNotSupportedException ();
237
261
}
238
262
}
239
263
240
264
@ Override
241
265
public int getTransactionIsolation () throws SQLException {
266
+ checkNotClosed ();
242
267
return Connection .TRANSACTION_NONE ;
243
268
}
244
269
245
270
@ Override
246
271
public SQLWarning getWarnings () throws SQLException {
272
+ checkNotClosed ();
247
273
return null ;
248
274
}
249
275
250
276
@ Override
251
277
public void clearWarnings () throws SQLException {
252
-
278
+ checkNotClosed ();
253
279
}
254
280
255
281
@ Override
@@ -265,16 +291,18 @@ public PreparedStatement prepareStatement(String sql, int resultSetType, int res
265
291
266
292
@ Override
267
293
public CallableStatement prepareCall (String sql , int resultSetType , int resultSetConcurrency ) throws SQLException {
268
- throw new SQLFeatureNotSupportedException ( );
294
+ return prepareCall ( sql , resultSetType , resultSetConcurrency , getHoldability () );
269
295
}
270
296
271
297
@ Override
272
298
public Map <String , Class <?>> getTypeMap () throws SQLException {
299
+ checkNotClosed ();
273
300
throw new SQLFeatureNotSupportedException ();
274
301
}
275
302
276
303
@ Override
277
304
public void setTypeMap (Map <String , Class <?>> map ) throws SQLException {
305
+ checkNotClosed ();
278
306
throw new SQLFeatureNotSupportedException ();
279
307
}
280
308
@@ -296,21 +324,43 @@ public int getHoldability() throws SQLException {
296
324
297
325
@ Override
298
326
public Savepoint setSavepoint () throws SQLException {
327
+ checkNotClosed ();
328
+ if (getAutoCommit ()) {
329
+ throw new SQLNonTransientException (
330
+ "Cannot set a savepoint when auto-commit is enabled." ,
331
+ SQLStates .IVALID_TRANSACTION_STATE .getSqlState ()
332
+ );
333
+ }
299
334
throw new SQLFeatureNotSupportedException ();
300
335
}
301
336
302
337
@ Override
303
338
public Savepoint setSavepoint (String name ) throws SQLException {
339
+ checkNotClosed ();
340
+ if (getAutoCommit ()) {
341
+ throw new SQLNonTransientException (
342
+ "Cannot set a savepoint when auto-commit is enabled." ,
343
+ SQLStates .IVALID_TRANSACTION_STATE .getSqlState ()
344
+ );
345
+ }
304
346
throw new SQLFeatureNotSupportedException ();
305
347
}
306
348
307
349
@ Override
308
350
public void rollback (Savepoint savepoint ) throws SQLException {
351
+ checkNotClosed ();
352
+ if (getAutoCommit ()) {
353
+ throw new SQLNonTransientException (
354
+ "Cannot roll back to a savepoint when auto-commit is enabled." ,
355
+ SQLStates .IVALID_TRANSACTION_STATE .getSqlState ()
356
+ );
357
+ }
309
358
throw new SQLFeatureNotSupportedException ();
310
359
}
311
360
312
361
@ Override
313
362
public void releaseSavepoint (Savepoint savepoint ) throws SQLException {
363
+ checkNotClosed ();
314
364
throw new SQLFeatureNotSupportedException ();
315
365
}
316
366
@@ -336,90 +386,159 @@ public PreparedStatement prepareStatement(String sql,
336
386
@ Override
337
387
public CallableStatement prepareCall (String sql , int resultSetType , int resultSetConcurrency , int resultSetHoldability )
338
388
throws SQLException {
389
+ checkNotClosed ();
339
390
throw new SQLFeatureNotSupportedException ();
340
391
}
341
392
342
393
@ Override
343
394
public PreparedStatement prepareStatement (String sql , int autoGeneratedKeys ) throws SQLException {
395
+ checkNotClosed ();
344
396
throw new SQLFeatureNotSupportedException ();
345
397
}
346
398
347
399
@ Override
348
400
public PreparedStatement prepareStatement (String sql , int [] columnIndexes ) throws SQLException {
401
+ checkNotClosed ();
349
402
throw new SQLFeatureNotSupportedException ();
350
403
}
351
404
352
405
@ Override
353
406
public PreparedStatement prepareStatement (String sql , String [] columnNames ) throws SQLException {
407
+ checkNotClosed ();
354
408
throw new SQLFeatureNotSupportedException ();
355
409
}
356
410
357
411
@ Override
358
412
public Clob createClob () throws SQLException {
413
+ checkNotClosed ();
359
414
throw new SQLFeatureNotSupportedException ();
360
415
}
361
416
362
417
@ Override
363
418
public Blob createBlob () throws SQLException {
419
+ checkNotClosed ();
364
420
throw new SQLFeatureNotSupportedException ();
365
421
}
366
422
367
423
@ Override
368
424
public NClob createNClob () throws SQLException {
425
+ checkNotClosed ();
369
426
throw new SQLFeatureNotSupportedException ();
370
427
}
371
428
372
429
@ Override
373
430
public SQLXML createSQLXML () throws SQLException {
431
+ checkNotClosed ();
374
432
throw new SQLFeatureNotSupportedException ();
375
433
}
376
434
435
+ /**
436
+ * {@inheritDoc}
437
+ *
438
+ * @param timeout temporally ignored param
439
+ *
440
+ * @return connection activity status
441
+ */
377
442
@ Override
378
443
public boolean isValid (int timeout ) throws SQLException {
379
444
return true ;
380
445
}
381
446
382
447
@ Override
383
448
public void setClientInfo (String name , String value ) throws SQLClientInfoException {
384
- throw new SQLClientInfoException ();
449
+ try {
450
+ checkNotClosed ();
451
+ throwUnknownClientProperties (Collections .singleton (name ));
452
+ } catch (SQLException cause ) {
453
+ throwUnknownReasonClientProperties ("Connection is closed" , Collections .singleton (name ), cause );
454
+ }
385
455
}
386
456
387
457
@ Override
388
458
public void setClientInfo (Properties properties ) throws SQLClientInfoException {
389
- throw new SQLClientInfoException ();
459
+ try {
460
+ checkNotClosed ();
461
+ throwUnknownClientProperties (properties .keySet ());
462
+ } catch (SQLException cause ) {
463
+ throwUnknownReasonClientProperties ("Connection is closed" , properties .keySet (), cause );
464
+ }
465
+ }
466
+
467
+ /**
468
+ * Throws an exception caused by {@code cause} and marks all properties
469
+ * as {@link ClientInfoStatus#REASON_UNKNOWN}
470
+ *
471
+ * @param reason reason mesage
472
+ * @param properties client properties
473
+ * @param cause original cause
474
+ *
475
+ * @throws SQLClientInfoException wrapped exception
476
+ */
477
+ private void throwUnknownReasonClientProperties (String reason ,
478
+ Collection <Object > properties ,
479
+ SQLException cause ) throws SQLClientInfoException {
480
+ Map <String , ClientInfoStatus > failedProperties = new HashMap <>();
481
+ properties .forEach (property -> {
482
+ failedProperties .put (property .toString (), ClientInfoStatus .REASON_UNKNOWN );
483
+ });
484
+ throw new SQLClientInfoException (reason , failedProperties , cause );
485
+ }
486
+
487
+ /**
488
+ * Throws exception for unrecognizable properties
489
+ *
490
+ * @param properties unknown property names
491
+ *
492
+ * @throws SQLClientInfoException wrapped exception
493
+ */
494
+ private void throwUnknownClientProperties (Collection <Object > properties ) throws SQLClientInfoException {
495
+ Map <String , ClientInfoStatus > failedProperties = new HashMap <>();
496
+ properties .forEach (property -> {
497
+ failedProperties .put (property .toString (), ClientInfoStatus .REASON_UNKNOWN_PROPERTY );
498
+ });
499
+ throw new SQLClientInfoException (failedProperties );
390
500
}
391
501
392
502
@ Override
393
503
public String getClientInfo (String name ) throws SQLException {
504
+ checkNotClosed ();
394
505
throw new SQLFeatureNotSupportedException ();
395
506
}
396
507
397
508
@ Override
398
509
public Properties getClientInfo () throws SQLException {
510
+ checkNotClosed ();
399
511
throw new SQLFeatureNotSupportedException ();
400
512
}
401
513
402
514
@ Override
403
515
public Array createArrayOf (String typeName , Object [] elements ) throws SQLException {
516
+ checkNotClosed ();
404
517
throw new SQLFeatureNotSupportedException ();
405
518
}
406
519
407
520
@ Override
408
521
public Struct createStruct (String typeName , Object [] attributes ) throws SQLException {
522
+ checkNotClosed ();
409
523
throw new SQLFeatureNotSupportedException ();
410
524
}
411
525
412
526
@ Override
413
527
public void setSchema (String schema ) throws SQLException {
528
+ checkNotClosed ();
414
529
}
415
530
416
531
@ Override
417
532
public String getSchema () throws SQLException {
533
+ checkNotClosed ();
418
534
return null ;
419
535
}
420
536
421
537
@ Override
422
538
public void abort (Executor executor ) throws SQLException {
539
+ if (isClosed ()) {
540
+ return ;
541
+ }
423
542
throw new SQLFeatureNotSupportedException ();
424
543
}
425
544
@@ -544,8 +663,9 @@ private void handleException(Exception e) {
544
663
* Checks whether <code>holdability</code> is supported
545
664
*
546
665
* @param holdability param to be checked
666
+ *
547
667
* @throws SQLFeatureNotSupportedException param is not supported
548
- * @throws SQLNonTransientException param has invalid value
668
+ * @throws SQLNonTransientException param has invalid value
549
669
*/
550
670
private void checkHoldabilitySupport (int holdability ) throws SQLException {
551
671
if (holdability != ResultSet .CLOSE_CURSORS_AT_COMMIT
@@ -562,6 +682,7 @@ private void checkHoldabilitySupport(int holdability) throws SQLException {
562
682
*
563
683
* @param sql SQL Text.
564
684
* @param params Parameters of the SQL statement.
685
+ *
565
686
* @return Formatted error message.
566
687
*/
567
688
private static String formatError (String sql , Object ... params ) {
0 commit comments