Skip to content

Commit f547648

Browse files
authored
Merge pull request #17 from ZorTik/development
Development
2 parents 1e485fe + c185851 commit f547648

7 files changed

Lines changed: 164 additions & 99 deletions

File tree

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import java.sql.DriverManager;
1616
import java.sql.SQLException;
1717
import java.util.Objects;
18-
import java.util.Optional;
1918

2019
public final class SQLConnectionBuilder implements Cloneable {
2120

@@ -113,7 +112,7 @@ public static class BuilderSQLConnectionFactory implements SQLConnectionFactory
113112

114113
@Nullable
115114
@Override
116-
public Connection connect() {
115+
public Connection connect() throws SQLException {
117116
try {
118117
Class.forName(driver);
119118
} catch (ClassNotFoundException e) {
@@ -122,12 +121,7 @@ public Connection connect() {
122121
String jdbc = builder.jdbc;
123122
String usr = builder.endpoint.getUsername();
124123
String pwd = builder.endpoint.getPassword();
125-
try {
126-
return DriverManager.getConnection(jdbc, usr, pwd);
127-
} catch (SQLException e) {
128-
e.printStackTrace();
129-
return null;
130-
}
124+
return DriverManager.getConnection(jdbc, usr, pwd);
131125
}
132126

133127
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.jetbrains.annotations.ApiStatus;
1212
import org.jetbrains.annotations.Nullable;
1313

14+
import java.io.Closeable;
1415
import java.sql.Connection;
1516
import java.sql.SQLException;
1617

@@ -21,7 +22,7 @@
2122
* @author ZorTik
2223
*/
2324
@SuppressWarnings("unused")
24-
public abstract class SQLDatabaseConnection implements SQLConnection {
25+
public abstract class SQLDatabaseConnection implements SQLConnection, Closeable {
2526

2627
private final SQLConnectionFactory connectionFactory;
2728
@Getter(onMethod_ = {@Nullable})
@@ -182,6 +183,11 @@ public void disconnect() {
182183
}
183184
}
184185

186+
@Override
187+
public void close() {
188+
disconnect();
189+
}
190+
185191
protected void logSqlError(Exception e) {
186192
if(isLogSqlErrors()) {
187193
e.printStackTrace();

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

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import me.zort.sqllib.internal.query.part.SetStatement;
2626
import me.zort.sqllib.mapping.DefaultResultAdapter;
2727
import me.zort.sqllib.mapping.DefaultStatementMappingFactory;
28+
import me.zort.sqllib.pool.PooledSQLDatabaseConnection;
2829
import me.zort.sqllib.util.Pair;
2930
import me.zort.sqllib.util.Validator;
3031
import org.jetbrains.annotations.ApiStatus;
@@ -50,7 +51,7 @@
5051
* @author ZorTik
5152
*/
5253
@SuppressWarnings("unused")
53-
public class SQLDatabaseConnectionImpl extends SQLDatabaseConnection {
54+
public class SQLDatabaseConnectionImpl extends PooledSQLDatabaseConnection {
5455

5556
// --***-- Default Constants --***--
5657

@@ -72,6 +73,7 @@ public class SQLDatabaseConnectionImpl extends SQLDatabaseConnection {
7273
private transient ObjectMapper objectMapper;
7374
@Setter
7475
private transient Logger logger;
76+
private int errorCount = 0;
7577

7678
/**
7779
* Constructs new instance of this implementation with default
@@ -222,6 +224,7 @@ public final boolean buildEntitySchema(String tableName, Class<?> entityClass) {
222224

223225
/**
224226
* 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}.
225228
* See: {@link QueryRowsResult#isSuccessful()}
226229
*
227230
* Examples:
@@ -258,14 +261,14 @@ public <T> QueryRowsResult<T> query(Query query, Class<T> typeClass) {
258261
/**
259262
* Performs new query and returns the result. This result is never null.
260263
*
261-
* @see SQLDatabaseConnection#query(Query, Class)
264+
* @param query The query to use
262265
*/
263266
@Override
264267
public QueryRowsResult<Row> query(Query query) {
265-
return doQuery(query, false);
268+
return query(query, false);
266269
}
267270

268-
private QueryRowsResult<Row> doQuery(Query query, boolean isRetry) {
271+
private QueryRowsResult<Row> query(Query query, boolean isRetry) {
269272
Objects.requireNonNull(query);
270273

271274
if(!handleAutoReconnect()) {
@@ -293,7 +296,7 @@ private QueryRowsResult<Row> doQuery(Query query, boolean isRetry) {
293296
} catch (SQLException e) {
294297
if (!isRetry && e.getMessage().contains("database connection closed")) {
295298
reconnect();
296-
return doQuery(query, true);
299+
return query(query, true);
297300
}
298301

299302
logSqlError(e);
@@ -313,10 +316,10 @@ private QueryRowsResult<Row> doQuery(Query query, boolean isRetry) {
313316
* about success state of the request.
314317
*/
315318
public QueryResult exec(Query query) {
316-
return doExec(query, false);
319+
return exec(query, false);
317320
}
318321

319-
private QueryResult doExec(Query query, boolean isRetry) {
322+
private QueryResult exec(Query query, boolean isRetry) {
320323
if(!handleAutoReconnect()) {
321324
return new QueryResultImpl(false, "Cannot connect to database!");
322325
}
@@ -326,7 +329,7 @@ private QueryResult doExec(Query query, boolean isRetry) {
326329
} catch (SQLException e) {
327330
if (!isRetry && e.getMessage().contains("database connection closed")) {
328331
reconnect();
329-
return doExec(query, true);
332+
return exec(query, true);
330333
}
331334

332335
logSqlError(e);
@@ -347,23 +350,39 @@ private QueryResult doExec(Query query, boolean isRetry) {
347350
*/
348351
@Override
349352
public QueryResult save(String table, Object obj) { // by default, it creates and upsert request.
350-
Pair<String[], UnknownValueWrapper[]> data = buildDefsVals(obj);
353+
DefsVals defsVals = buildDefsVals(obj);
351354

352-
if(data == null) {
355+
if(defsVals == null) {
353356
return new QueryResultImpl(false);
354357
}
355358

356359
return save(obj).table(table).execute();
357360
}
358361

359-
public QueryResult insert(String table, Object obj) {
360-
Pair<String[], UnknownValueWrapper[]> data = buildDefsVals(obj);
362+
public UpsertQuery save(Object obj) {
363+
DefsVals defsVals = buildDefsVals(obj);
364+
if(defsVals == null) return null;
361365

362-
if (data == null)
363-
return new QueryResultImpl(false);
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+
}
364376

365-
InsertQuery query = insert().into(table, data.getFirst());
366-
for (UnknownValueWrapper valueWrapper : data.getSecond()) {
377+
return (UpsertQuery) setStmt.getAncestor();
378+
}
379+
380+
public QueryResult insert(String table, Object obj) {
381+
DefsVals defsVals = buildDefsVals(obj);
382+
if (defsVals == null) return new QueryResultImpl(false);
383+
384+
InsertQuery query = insert().into(table, defsVals.getDefs());
385+
for (UnknownValueWrapper valueWrapper : defsVals.getVals()) {
367386
query.appendVal(valueWrapper.getObject());
368387
}
369388

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

373392
@SuppressWarnings("unchecked")
374393
@Nullable
375-
protected Pair<String[], UnknownValueWrapper[]> buildDefsVals(Object obj) {
394+
protected DefsVals buildDefsVals(Object obj) {
376395
Objects.requireNonNull(obj);
377396

378397
Class<?> aClass = obj.getClass();
@@ -409,7 +428,7 @@ protected Pair<String[], UnknownValueWrapper[]> buildDefsVals(Object obj) {
409428
defs[i] = entryArray[i].getKey();
410429
vals[i] = new UnknownValueWrapper(entryArray[i].getValue());
411430
}
412-
return new Pair<>(defs, vals);
431+
return new DefsVals(defs, vals);
413432
}
414433

415434
@SuppressWarnings("all")
@@ -429,31 +448,20 @@ private boolean reconnect() {
429448
return true;
430449
}
431450

432-
public UpsertQuery save(Object obj) {
433-
Pair<String[], UnknownValueWrapper[]> data = buildDefsVals(obj);
434-
435-
if(data == null) {
436-
return null;
437-
}
438-
439-
String[] defs = data.getFirst();
440-
UnknownValueWrapper[] vals = data.getSecond();
441-
442-
UpsertQuery upsert = upsert().into(null, defs);
443-
for(UnknownValueWrapper wrapper : vals) {
444-
upsert.appendVal(wrapper.getObject());
445-
}
451+
public void debug(String message) {
452+
if(options.isDebug()) logger.info(message);
453+
}
446454

447-
SetStatement<InsertQuery> setStmt = upsert.onDuplicateKey();
448-
for(int i = 0; i < defs.length; i++) {
449-
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;
450462
}
451463

452-
return (UpsertQuery) setStmt.getAncestor();
453-
}
454-
455-
public void debug(String message) {
456-
if(options.isDebug()) logger.info(message);
464+
super.close();
457465
}
458466

459467
@Override
@@ -467,6 +475,7 @@ public final boolean isDebug() {
467475
}
468476

469477
private void notifyError(int code) {
478+
errorCount++;
470479
this.errorStateHandlers.forEach(handler -> runCatching(() -> handler.onErrorState(code)));
471480
}
472481

@@ -509,6 +518,13 @@ public static class UnknownValueWrapper {
509518
private Object object;
510519
}
511520

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

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package me.zort.sqllib.pool;
2+
3+
import lombok.Getter;
4+
import me.zort.sqllib.SQLDatabaseConnection;
5+
import me.zort.sqllib.internal.factory.SQLConnectionFactory;
6+
import org.jetbrains.annotations.Nullable;
7+
8+
import java.io.Closeable;
9+
10+
public abstract class PooledSQLDatabaseConnection extends SQLDatabaseConnection implements Closeable {
11+
12+
@Getter(onMethod_ = {@Nullable})
13+
private SQLConnectionPool assignedPool = null;
14+
@Getter(onMethod_ = {@Nullable})
15+
private long lastUsed = System.currentTimeMillis();
16+
17+
public PooledSQLDatabaseConnection(SQLConnectionFactory connectionFactory) {
18+
super(connectionFactory);
19+
}
20+
21+
protected void setAssignedPool(SQLConnectionPool pool) {
22+
assignedPool = pool;
23+
}
24+
25+
protected void setLastUsed(long lastUsed) {
26+
this.lastUsed = lastUsed;
27+
}
28+
29+
@Override
30+
public void close() {
31+
lastUsed = System.currentTimeMillis();
32+
if (assignedPool != null) {
33+
assignedPool.releaseObject(this);
34+
} else {
35+
super.close();
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)