Skip to content

Commit aaa404a

Browse files
committed
Raise SQLException on methods of a closed Connection
Add missed checks on methods of the closed connection. Closes: #72 Affects: #119, #74
1 parent 9e26d8a commit aaa404a

File tree

4 files changed

+282
-12
lines changed

4 files changed

+282
-12
lines changed

Diff for: src/main/java/org/tarantool/jdbc/SQLConnection.java

+119-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.sql.Array;
2020
import java.sql.Blob;
2121
import java.sql.CallableStatement;
22+
import java.sql.ClientInfoStatus;
2223
import java.sql.Clob;
2324
import java.sql.Connection;
2425
import java.sql.DatabaseMetaData;
@@ -36,6 +37,9 @@
3637
import java.sql.Statement;
3738
import java.sql.Struct;
3839
import java.util.Arrays;
40+
import java.util.Collection;
41+
import java.util.Collections;
42+
import java.util.HashMap;
3943
import java.util.List;
4044
import java.util.Map;
4145
import java.util.Properties;
@@ -213,22 +217,24 @@ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) thr
213217

214218
@Override
215219
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
220+
checkNotClosed();
216221
throw new SQLFeatureNotSupportedException();
217222
}
218223

219224
@Override
220225
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
226+
checkNotClosed();
221227
throw new SQLFeatureNotSupportedException();
222228
}
223229

224230
@Override
225231
public CallableStatement prepareCall(String sql) throws SQLException {
226-
throw new SQLFeatureNotSupportedException();
232+
return prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
227233
}
228234

229235
@Override
230236
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
231-
throw new SQLFeatureNotSupportedException();
237+
return prepareCall(sql, resultSetType, resultSetConcurrency, getHoldability());
232238
}
233239

234240
@Override
@@ -237,38 +243,63 @@ public CallableStatement prepareCall(String sql,
237243
int resultSetConcurrency,
238244
int resultSetHoldability)
239245
throws SQLException {
246+
checkNotClosed();
240247
throw new SQLFeatureNotSupportedException();
241248
}
242249

243250
@Override
244251
public String nativeSQL(String sql) throws SQLException {
252+
checkNotClosed();
245253
throw new SQLFeatureNotSupportedException();
246254
}
247255

248256
@Override
249257
public void setAutoCommit(boolean autoCommit) throws SQLException {
258+
checkNotClosed();
250259
if (!autoCommit) {
251260
throw new SQLFeatureNotSupportedException();
252261
}
253262
}
254263

255264
@Override
256265
public boolean getAutoCommit() throws SQLException {
266+
checkNotClosed();
257267
return true;
258268
}
259269

260270
@Override
261271
public void commit() throws SQLException {
272+
checkNotClosed();
273+
if (getAutoCommit()) {
274+
throw new SQLNonTransientException(
275+
"Cannot commit when auto-commit is enabled.",
276+
SQLStates.INVALID_TRANSACTION_STATE.getSqlState()
277+
);
278+
}
262279
throw new SQLFeatureNotSupportedException();
263280
}
264281

265282
@Override
266283
public void rollback() throws SQLException {
284+
checkNotClosed();
285+
if (getAutoCommit()) {
286+
throw new SQLNonTransientException(
287+
"Cannot rollback when auto-commit is enabled.",
288+
SQLStates.INVALID_TRANSACTION_STATE.getSqlState()
289+
);
290+
}
267291
throw new SQLFeatureNotSupportedException();
268292
}
269293

270294
@Override
271295
public void rollback(Savepoint savepoint) throws SQLException {
296+
checkNotClosed();
297+
if (getAutoCommit()) {
298+
throw new SQLNonTransientException(
299+
"Cannot roll back to a savepoint when auto-commit is enabled.",
300+
SQLStates.INVALID_TRANSACTION_STATE.getSqlState()
301+
);
302+
}
272303
throw new SQLFeatureNotSupportedException();
273304
}
274305

@@ -293,52 +324,61 @@ public DatabaseMetaData getMetaData() throws SQLException {
293324

294325
@Override
295326
public void setReadOnly(boolean readOnly) throws SQLException {
296-
327+
checkNotClosed();
328+
throw new SQLFeatureNotSupportedException();
297329
}
298330

299331
@Override
300332
public boolean isReadOnly() throws SQLException {
333+
checkNotClosed();
301334
return false;
302335
}
303336

304337
@Override
305338
public void setCatalog(String catalog) throws SQLException {
339+
checkNotClosed();
306340
}
307341

308342
@Override
309343
public String getCatalog() throws SQLException {
344+
checkNotClosed();
310345
return null;
311346
}
312347

313348
@Override
314349
public void setTransactionIsolation(int level) throws SQLException {
350+
checkNotClosed();
315351
if (level != Connection.TRANSACTION_NONE) {
316352
throw new SQLFeatureNotSupportedException();
317353
}
318354
}
319355

320356
@Override
321357
public int getTransactionIsolation() throws SQLException {
358+
checkNotClosed();
322359
return Connection.TRANSACTION_NONE;
323360
}
324361

325362
@Override
326363
public SQLWarning getWarnings() throws SQLException {
364+
checkNotClosed();
327365
return null;
328366
}
329367

330368
@Override
331369
public void clearWarnings() throws SQLException {
332-
370+
checkNotClosed();
333371
}
334372

335373
@Override
336374
public Map<String, Class<?>> getTypeMap() throws SQLException {
375+
checkNotClosed();
337376
throw new SQLFeatureNotSupportedException();
338377
}
339378

340379
@Override
341380
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
381+
checkNotClosed();
342382
throw new SQLFeatureNotSupportedException();
343383
}
344384

@@ -360,36 +400,55 @@ public int getHoldability() throws SQLException {
360400

361401
@Override
362402
public Savepoint setSavepoint() throws SQLException {
403+
checkNotClosed();
404+
if (getAutoCommit()) {
405+
throw new SQLNonTransientException(
406+
"Cannot set a savepoint when auto-commit is enabled.",
407+
SQLStates.INVALID_TRANSACTION_STATE.getSqlState()
408+
);
409+
}
363410
throw new SQLFeatureNotSupportedException();
364411
}
365412

366413
@Override
367414
public Savepoint setSavepoint(String name) throws SQLException {
415+
checkNotClosed();
416+
if (getAutoCommit()) {
417+
throw new SQLNonTransientException(
418+
"Cannot set a savepoint when auto-commit is enabled.",
419+
SQLStates.INVALID_TRANSACTION_STATE.getSqlState()
420+
);
421+
}
368422
throw new SQLFeatureNotSupportedException();
369423
}
370424

371425
@Override
372426
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
427+
checkNotClosed();
373428
throw new SQLFeatureNotSupportedException();
374429
}
375430

376431
@Override
377432
public Clob createClob() throws SQLException {
433+
checkNotClosed();
378434
throw new SQLFeatureNotSupportedException();
379435
}
380436

381437
@Override
382438
public Blob createBlob() throws SQLException {
439+
checkNotClosed();
383440
throw new SQLFeatureNotSupportedException();
384441
}
385442

386443
@Override
387444
public NClob createNClob() throws SQLException {
445+
checkNotClosed();
388446
throw new SQLFeatureNotSupportedException();
389447
}
390448

391449
@Override
392450
public SQLXML createSQLXML() throws SQLException {
451+
checkNotClosed();
393452
throw new SQLFeatureNotSupportedException();
394453
}
395454

@@ -431,45 +490,99 @@ private boolean checkConnection(int timeout) {
431490

432491
@Override
433492
public void setClientInfo(String name, String value) throws SQLClientInfoException {
434-
throw new SQLClientInfoException();
493+
try {
494+
checkNotClosed();
495+
} catch (SQLException cause) {
496+
throwUnknownReasonClientProperties("Connection is closed", Collections.singleton(name), cause);
497+
}
498+
throwUnknownClientProperties(Collections.singleton(name));
435499
}
436500

437501
@Override
438502
public void setClientInfo(Properties properties) throws SQLClientInfoException {
439-
throw new SQLClientInfoException();
503+
try {
504+
checkNotClosed();
505+
} catch (SQLException cause) {
506+
throwUnknownReasonClientProperties("Connection is closed", properties.keySet(), cause);
507+
}
508+
throwUnknownClientProperties(properties.keySet());
509+
}
510+
511+
/**
512+
* Throws an exception caused by {@code cause} and marks all properties
513+
* as {@link ClientInfoStatus#REASON_UNKNOWN}.
514+
*
515+
* @param reason reason mesage
516+
* @param properties client properties
517+
* @param cause original cause
518+
*
519+
* @throws SQLClientInfoException wrapped exception
520+
*/
521+
private void throwUnknownReasonClientProperties(String reason,
522+
Collection<Object> properties,
523+
SQLException cause) throws SQLClientInfoException {
524+
Map<String, ClientInfoStatus> failedProperties = new HashMap<>();
525+
properties.forEach(property -> {
526+
failedProperties.put(property.toString(), ClientInfoStatus.REASON_UNKNOWN);
527+
});
528+
throw new SQLClientInfoException(reason, cause.getSQLState(), failedProperties, cause);
529+
}
530+
531+
/**
532+
* Throws exception for unrecognizable properties.
533+
*
534+
* @param properties unknown property names.
535+
*
536+
* @throws SQLClientInfoException wrapped exception
537+
*/
538+
private void throwUnknownClientProperties(Collection<Object> properties) throws SQLClientInfoException {
539+
Map<String, ClientInfoStatus> failedProperties = new HashMap<>();
540+
properties.forEach(property -> {
541+
failedProperties.put(property.toString(), ClientInfoStatus.REASON_UNKNOWN_PROPERTY);
542+
});
543+
throw new SQLClientInfoException(failedProperties);
440544
}
441545

442546
@Override
443547
public String getClientInfo(String name) throws SQLException {
548+
checkNotClosed();
444549
throw new SQLFeatureNotSupportedException();
445550
}
446551

447552
@Override
448553
public Properties getClientInfo() throws SQLException {
554+
checkNotClosed();
449555
throw new SQLFeatureNotSupportedException();
450556
}
451557

452558
@Override
453559
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
560+
checkNotClosed();
454561
throw new SQLFeatureNotSupportedException();
455562
}
456563

457564
@Override
458565
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
566+
checkNotClosed();
459567
throw new SQLFeatureNotSupportedException();
460568
}
461569

462570
@Override
463571
public void setSchema(String schema) throws SQLException {
572+
checkNotClosed();
464573
}
465574

466575
@Override
467576
public String getSchema() throws SQLException {
577+
checkNotClosed();
468578
return null;
469579
}
470580

471581
@Override
472582
public void abort(Executor executor) throws SQLException {
583+
if (isClosed()) {
584+
return;
585+
}
473586
throw new SQLFeatureNotSupportedException();
474587
}
475588

Diff for: src/main/java/org/tarantool/util/SQLStates.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ public enum SQLStates {
66
NO_DATA("02000"),
77
CONNECTION_DOES_NOT_EXIST("08003"),
88
INVALID_PARAMETER_VALUE("22023"),
9-
INVALID_CURSOR_STATE("24000");
9+
INVALID_CURSOR_STATE("24000"),
10+
INVALID_TRANSACTION_STATE("25000");
1011

1112
private final String sqlState;
1213

0 commit comments

Comments
 (0)