Skip to content

Commit c185851

Browse files
committed
Extended pool test case.
1 parent a64f9d3 commit c185851

5 files changed

Lines changed: 73 additions & 30 deletions

File tree

core/src/main/java/me/zort/sqllib/SQLDatabaseConnectionImpl.java

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public class SQLDatabaseConnectionImpl extends PooledSQLDatabaseConnection {
7373
private transient ObjectMapper objectMapper;
7474
@Setter
7575
private transient Logger logger;
76+
private int errorCount = 0;
7677

7778
/**
7879
* Constructs new instance of this implementation with default
@@ -223,6 +224,7 @@ public final boolean buildEntitySchema(String tableName, Class<?> entityClass) {
223224

224225
/**
225226
* Performs new query and returns the result. This result is never null.
227+
* This method also maps the result to the specified type using {@link ObjectMapper}.
226228
* See: {@link QueryRowsResult#isSuccessful()}
227229
*
228230
* Examples:
@@ -259,7 +261,7 @@ public <T> QueryRowsResult<T> query(Query query, Class<T> typeClass) {
259261
/**
260262
* Performs new query and returns the result. This result is never null.
261263
*
262-
* @see SQLDatabaseConnection#query(Query, Class)
264+
* @param query The query to use
263265
*/
264266
@Override
265267
public QueryRowsResult<Row> query(Query query) {
@@ -348,21 +350,39 @@ private QueryResult exec(Query query, boolean isRetry) {
348350
*/
349351
@Override
350352
public QueryResult save(String table, Object obj) { // by default, it creates and upsert request.
351-
Pair<String[], UnknownValueWrapper[]> data = buildDefsVals(obj);
353+
DefsVals defsVals = buildDefsVals(obj);
352354

353-
if(data == null) {
355+
if(defsVals == null) {
354356
return new QueryResultImpl(false);
355357
}
356358

357359
return save(obj).table(table).execute();
358360
}
359361

362+
public UpsertQuery save(Object obj) {
363+
DefsVals defsVals = buildDefsVals(obj);
364+
if(defsVals == null) return null;
365+
366+
String[] defs = defsVals.getDefs();
367+
UnknownValueWrapper[] vals = defsVals.getVals();
368+
UpsertQuery upsert = upsert().into(null, defs);
369+
for(UnknownValueWrapper wrapper : vals) {
370+
upsert.appendVal(wrapper.getObject());
371+
}
372+
SetStatement<InsertQuery> setStmt = upsert.onDuplicateKey();
373+
for(int i = 0; i < defs.length; i++) {
374+
setStmt.and(defs[i], vals[i].getObject());
375+
}
376+
377+
return (UpsertQuery) setStmt.getAncestor();
378+
}
379+
360380
public QueryResult insert(String table, Object obj) {
361-
Pair<String[], UnknownValueWrapper[]> data = buildDefsVals(obj);
362-
if (data == null) return new QueryResultImpl(false);
381+
DefsVals defsVals = buildDefsVals(obj);
382+
if (defsVals == null) return new QueryResultImpl(false);
363383

364-
InsertQuery query = insert().into(table, data.getFirst());
365-
for (UnknownValueWrapper valueWrapper : data.getSecond()) {
384+
InsertQuery query = insert().into(table, defsVals.getDefs());
385+
for (UnknownValueWrapper valueWrapper : defsVals.getVals()) {
366386
query.appendVal(valueWrapper.getObject());
367387
}
368388

@@ -371,7 +391,7 @@ public QueryResult insert(String table, Object obj) {
371391

372392
@SuppressWarnings("unchecked")
373393
@Nullable
374-
protected Pair<String[], UnknownValueWrapper[]> buildDefsVals(Object obj) {
394+
protected DefsVals buildDefsVals(Object obj) {
375395
Objects.requireNonNull(obj);
376396

377397
Class<?> aClass = obj.getClass();
@@ -408,7 +428,7 @@ protected Pair<String[], UnknownValueWrapper[]> buildDefsVals(Object obj) {
408428
defs[i] = entryArray[i].getKey();
409429
vals[i] = new UnknownValueWrapper(entryArray[i].getValue());
410430
}
411-
return new Pair<>(defs, vals);
431+
return new DefsVals(defs, vals);
412432
}
413433

414434
@SuppressWarnings("all")
@@ -428,26 +448,20 @@ private boolean reconnect() {
428448
return true;
429449
}
430450

431-
public UpsertQuery save(Object obj) {
432-
Pair<String[], UnknownValueWrapper[]> data = buildDefsVals(obj);
433-
if(data == null) return null;
451+
public void debug(String message) {
452+
if(options.isDebug()) logger.info(message);
453+
}
434454

435-
String[] defs = data.getFirst();
436-
UnknownValueWrapper[] vals = data.getSecond();
437-
UpsertQuery upsert = upsert().into(null, defs);
438-
for(UnknownValueWrapper wrapper : vals) {
439-
upsert.appendVal(wrapper.getObject());
440-
}
441-
SetStatement<InsertQuery> setStmt = upsert.onDuplicateKey();
442-
for(int i = 0; i < defs.length; i++) {
443-
setStmt.and(defs[i], vals[i].getObject());
455+
@Override
456+
public void close() {
457+
if (errorCount > 0 && getAssignedPool() != null) {
458+
// If there was any error and this connection is part of a pool,
459+
// we won't return object to the pool, but disconnect.
460+
disconnect();
461+
return;
444462
}
445463

446-
return (UpsertQuery) setStmt.getAncestor();
447-
}
448-
449-
public void debug(String message) {
450-
if(options.isDebug()) logger.info(message);
464+
super.close();
451465
}
452466

453467
@Override
@@ -461,6 +475,7 @@ public final boolean isDebug() {
461475
}
462476

463477
private void notifyError(int code) {
478+
errorCount++;
464479
this.errorStateHandlers.forEach(handler -> runCatching(() -> handler.onErrorState(code)));
465480
}
466481

@@ -503,6 +518,13 @@ public static class UnknownValueWrapper {
503518
private Object object;
504519
}
505520

521+
@AllArgsConstructor
522+
@Getter
523+
public static class DefsVals {
524+
private final String[] defs;
525+
private final UnknownValueWrapper[] vals;
526+
}
527+
506528
public interface ErrorStateObserver {
507529
void onErrorState(int code);
508530
}

core/src/main/java/me/zort/sqllib/SQLiteDatabaseConnectionImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ public SQLiteDatabaseConnectionImpl(SQLConnectionFactory connectionFactory, SQLD
4848
*/
4949
@Override
5050
public QueryResult save(String table, Object obj) {
51-
Pair<String[], UnknownValueWrapper[]> defsValsPair = buildDefsVals(obj);
52-
if(defsValsPair == null) {
51+
DefsVals defsVals = buildDefsVals(obj);
52+
if(defsVals == null) {
5353
return new QueryResultImpl(false);
5454
}
55-
String[] defs = defsValsPair.getFirst();
56-
UnknownValueWrapper[] vals = defsValsPair.getSecond();
55+
String[] defs = defsVals.getDefs();
56+
UnknownValueWrapper[] vals = defsVals.getVals();
5757

5858
debug("Saving object into table " + table + " with definitions " + Arrays.toString(defs) + " and values " + Arrays.toString(vals));
5959

core/src/main/java/me/zort/sqllib/pool/PooledSQLDatabaseConnection.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
public abstract class PooledSQLDatabaseConnection extends SQLDatabaseConnection implements Closeable {
1111

12+
@Getter(onMethod_ = {@Nullable})
1213
private SQLConnectionPool assignedPool = null;
1314
@Getter(onMethod_ = {@Nullable})
1415
private long lastUsed = System.currentTimeMillis();

core/src/main/java/me/zort/sqllib/pool/SQLConnectionPool.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public static final class Options {
4040
private final long borrowObjectTimeout;
4141
private final boolean blockWhenExhausted;
4242

43+
private int errorCount = 0;
44+
4345
// --***-- Pooled connection caches --***--
4446
private final Queue<PooledSQLDatabaseConnection> freeConnections = new ConcurrentLinkedQueue<>();
4547
private final List<PooledSQLDatabaseConnection> usedConnections = new CopyOnWriteArrayList<>();
@@ -110,6 +112,7 @@ private PooledSQLDatabaseConnection establishObject() throws SQLException {
110112

111113
if (polled instanceof SQLDatabaseConnectionImpl) {
112114
((SQLDatabaseConnectionImpl) polled).addErrorHandler(code -> {
115+
errorCount++;
113116
// Remove the connection from the pool and disconnect
114117
// on fatal errors.
115118
freeConnections.remove(polled);
@@ -131,6 +134,10 @@ public int size() {
131134
return usedConnections.size() + freeConnections.size();
132135
}
133136

137+
public int errorCount() {
138+
return errorCount;
139+
}
140+
134141
/**
135142
* Closes all connections in the pool and
136143
* clears the caches.

src/test/java/me/zort/sqllib/test/TestCase1.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,19 @@ public void test6_Pool() {
166166
throw new RuntimeException(e);
167167
}
168168
assertEquals(1, pool.size());
169+
try(SQLDatabaseConnection connection = pool.getResource()) {
170+
connection.exec(() -> "xcbnxcvkjonmcvxikjno");
171+
} catch(SQLException e) {
172+
throw new RuntimeException(e);
173+
}
174+
assertEquals(1, pool.errorCount());
175+
assertEquals(0, pool.size());
176+
try {
177+
pool.getResource().close();
178+
} catch (SQLException e) {
179+
throw new RuntimeException(e);
180+
}
181+
assertEquals(1, pool.size());
169182
pool.close();
170183
assertEquals(0, pool.size());
171184
}

0 commit comments

Comments
 (0)