Skip to content

Commit 25c0875

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 8b72cf2 commit 25c0875

File tree

3 files changed

+234
-50
lines changed

3 files changed

+234
-50
lines changed

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

+122-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.sql.Array;
1919
import java.sql.Blob;
2020
import java.sql.CallableStatement;
21+
import java.sql.ClientInfoStatus;
2122
import java.sql.Clob;
2223
import java.sql.Connection;
2324
import java.sql.DatabaseMetaData;
@@ -35,12 +36,14 @@
3536
import java.sql.Statement;
3637
import java.sql.Struct;
3738
import java.util.Arrays;
39+
import java.util.Collection;
40+
import java.util.Collections;
41+
import java.util.HashMap;
3842
import java.util.List;
3943
import java.util.Map;
4044
import java.util.Properties;
4145
import java.util.concurrent.Executor;
4246

43-
@SuppressWarnings("Since15")
4447
public class SQLConnection implements Connection {
4548

4649
private static final int UNSET_HOLDABILITY = 0;
@@ -212,12 +215,12 @@ public PreparedStatement prepareStatement(String sql, String[] columnNames) thro
212215

213216
@Override
214217
public CallableStatement prepareCall(String sql) throws SQLException {
215-
throw new SQLFeatureNotSupportedException();
218+
return prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
216219
}
217220

218221
@Override
219222
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
220-
throw new SQLFeatureNotSupportedException();
223+
return prepareCall(sql, resultSetType, resultSetConcurrency, getHoldability());
221224
}
222225

223226
@Override
@@ -236,28 +239,51 @@ public String nativeSQL(String sql) throws SQLException {
236239

237240
@Override
238241
public void setAutoCommit(boolean autoCommit) throws SQLException {
242+
checkNotClosed();
239243
if (autoCommit == false) {
240244
throw new SQLFeatureNotSupportedException();
241245
}
242246
}
243247

244248
@Override
245249
public boolean getAutoCommit() throws SQLException {
250+
checkNotClosed();
246251
return true;
247252
}
248253

249254
@Override
250255
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+
}
251263
throw new SQLFeatureNotSupportedException();
252264
}
253265

254266
@Override
255267
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+
}
256275
throw new SQLFeatureNotSupportedException();
257276
}
258277

259278
@Override
260279
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+
}
261287
throw new SQLFeatureNotSupportedException();
262288
}
263289

@@ -282,52 +308,61 @@ public DatabaseMetaData getMetaData() throws SQLException {
282308

283309
@Override
284310
public void setReadOnly(boolean readOnly) throws SQLException {
285-
311+
checkNotClosed();
312+
throw new SQLFeatureNotSupportedException();
286313
}
287314

288315
@Override
289316
public boolean isReadOnly() throws SQLException {
317+
checkNotClosed();
290318
return false;
291319
}
292320

293321
@Override
294322
public void setCatalog(String catalog) throws SQLException {
323+
checkNotClosed();
295324
}
296325

297326
@Override
298327
public String getCatalog() throws SQLException {
328+
checkNotClosed();
299329
return null;
300330
}
301331

302332
@Override
303333
public void setTransactionIsolation(int level) throws SQLException {
334+
checkNotClosed();
304335
if (level != Connection.TRANSACTION_NONE) {
305336
throw new SQLFeatureNotSupportedException();
306337
}
307338
}
308339

309340
@Override
310341
public int getTransactionIsolation() throws SQLException {
342+
checkNotClosed();
311343
return Connection.TRANSACTION_NONE;
312344
}
313345

314346
@Override
315347
public SQLWarning getWarnings() throws SQLException {
348+
checkNotClosed();
316349
return null;
317350
}
318351

319352
@Override
320353
public void clearWarnings() throws SQLException {
321-
354+
checkNotClosed();
322355
}
323356

324357
@Override
325358
public Map<String, Class<?>> getTypeMap() throws SQLException {
359+
checkNotClosed();
326360
throw new SQLFeatureNotSupportedException();
327361
}
328362

329363
@Override
330364
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
365+
checkNotClosed();
331366
throw new SQLFeatureNotSupportedException();
332367
}
333368

@@ -349,85 +384,165 @@ public int getHoldability() throws SQLException {
349384

350385
@Override
351386
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+
}
352394
throw new SQLFeatureNotSupportedException();
353395
}
354396

355397
@Override
356398
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+
}
357406
throw new SQLFeatureNotSupportedException();
358407
}
359408

360409
@Override
361410
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
411+
checkNotClosed();
362412
throw new SQLFeatureNotSupportedException();
363413
}
364414

365415
@Override
366416
public Clob createClob() throws SQLException {
417+
checkNotClosed();
367418
throw new SQLFeatureNotSupportedException();
368419
}
369420

370421
@Override
371422
public Blob createBlob() throws SQLException {
423+
checkNotClosed();
372424
throw new SQLFeatureNotSupportedException();
373425
}
374426

375427
@Override
376428
public NClob createNClob() throws SQLException {
429+
checkNotClosed();
377430
throw new SQLFeatureNotSupportedException();
378431
}
379432

380433
@Override
381434
public SQLXML createSQLXML() throws SQLException {
435+
checkNotClosed();
382436
throw new SQLFeatureNotSupportedException();
383437
}
384438

439+
/**
440+
* {@inheritDoc}
441+
*
442+
* @param timeout temporally ignored param
443+
*
444+
* @return connection activity status
445+
*/
385446
@Override
386447
public boolean isValid(int timeout) throws SQLException {
387448
return true;
388449
}
389450

390451
@Override
391452
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+
}
393459
}
394460

395461
@Override
396462
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);
398504
}
399505

400506
@Override
401507
public String getClientInfo(String name) throws SQLException {
508+
checkNotClosed();
402509
throw new SQLFeatureNotSupportedException();
403510
}
404511

405512
@Override
406513
public Properties getClientInfo() throws SQLException {
514+
checkNotClosed();
407515
throw new SQLFeatureNotSupportedException();
408516
}
409517

410518
@Override
411519
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
520+
checkNotClosed();
412521
throw new SQLFeatureNotSupportedException();
413522
}
414523

415524
@Override
416525
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
526+
checkNotClosed();
417527
throw new SQLFeatureNotSupportedException();
418528
}
419529

420530
@Override
421531
public void setSchema(String schema) throws SQLException {
532+
checkNotClosed();
422533
}
423534

424535
@Override
425536
public String getSchema() throws SQLException {
537+
checkNotClosed();
426538
return null;
427539
}
428540

429541
@Override
430542
public void abort(Executor executor) throws SQLException {
543+
if (isClosed()) {
544+
return;
545+
}
431546
throw new SQLFeatureNotSupportedException();
432547
}
433548

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
public enum SQLStates {
44

5+
CONNECTION_DOES_NOT_EXIST("08003"),
56
INVALID_PARAMETER_VALUE("22023"),
6-
CONNECTION_DOES_NOT_EXIST("08003");
7+
INVALID_TRANSACTION_STATE("25000");
78

89
private final String sqlState;
910

0 commit comments

Comments
 (0)