Skip to content

Commit

Permalink
Merge pull request #26 from ZorTik/development
Browse files Browse the repository at this point in the history
Allow to use options in SQLConnectionPool.java
  • Loading branch information
ZorTik authored May 6, 2023
2 parents 3d3de25 + 3c3dac3 commit 4558302
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package me.zort.sqllib.api;

public interface ISQLConnectionBuilder<C extends SQLConnection> {

C build(ISQLDatabaseOptions options);

}
20 changes: 20 additions & 0 deletions api/src/main/java/me/zort/sqllib/api/ISQLDatabaseOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package me.zort.sqllib.api;

import com.google.gson.Gson;
import me.zort.sqllib.api.options.NamingStrategy;

public interface ISQLDatabaseOptions {

void setAutoReconnect(boolean autoReconnect);
void setDebug(boolean debug);
void setLogSqlErrors(boolean logSqlErrors);
void setNamingStrategy(NamingStrategy namingStrategy);
void setGson(Gson gson);

boolean isAutoReconnect();
boolean isDebug();
boolean isLogSqlErrors();
NamingStrategy getNamingStrategy();
Gson getGson();

}
25 changes: 25 additions & 0 deletions api/src/main/java/me/zort/sqllib/api/cache/CacheManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package me.zort.sqllib.api.cache;

import me.zort.sqllib.api.Query;
import me.zort.sqllib.api.data.QueryResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface CacheManager {

void set(@NotNull Query query, @NotNull QueryResult result);
@Nullable QueryResult get(@NotNull Query query, boolean isExec);

static CacheManager noCache() {
return new CacheManager() {
@Override
public void set(@NotNull Query query, @NotNull QueryResult result) {
}
@Override
public @Nullable QueryResult get(@NotNull Query query, boolean isExec) {
return null;
}
};
}

}
8 changes: 5 additions & 3 deletions core/src/main/java/me/zort/sqllib/SQLConnectionBuilder.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package me.zort.sqllib;

import lombok.RequiredArgsConstructor;
import me.zort.sqllib.api.ISQLConnectionBuilder;
import me.zort.sqllib.api.ISQLDatabaseOptions;
import me.zort.sqllib.api.SQLEndpoint;
import me.zort.sqllib.internal.Constants;
import me.zort.sqllib.internal.exception.SQLDriverNotFoundException;
Expand All @@ -18,7 +20,7 @@
import java.util.Objects;

@SuppressWarnings("unused")
public final class SQLConnectionBuilder implements Cloneable {
public final class SQLConnectionBuilder implements ISQLConnectionBuilder<SQLDatabaseConnection>, Cloneable {

public static @NotNull SQLConnectionBuilder of(String address, int port, String database, String username, String password) {
return of(new DefaultSQLEndpoint(address + ":" + port, database, username, password));
Expand Down Expand Up @@ -74,11 +76,11 @@ public SQLConnectionBuilder(@Nullable SQLEndpoint endpoint) {
return build(null);
}

public @NotNull SQLDatabaseConnection build(@Nullable SQLDatabaseOptions options) {
public @NotNull SQLDatabaseConnection build(@Nullable ISQLDatabaseOptions options) {
return build(driver, options);
}

public @NotNull SQLDatabaseConnection build(@Nullable String driver, @Nullable SQLDatabaseOptions options) {
public @NotNull SQLDatabaseConnection build(@Nullable String driver, @Nullable ISQLDatabaseOptions options) {
Objects.requireNonNull(endpoint, "Endpoint must be set!");
Objects.requireNonNull(jdbc);
if(driver == null) {
Expand Down
19 changes: 13 additions & 6 deletions core/src/main/java/me/zort/sqllib/SQLDatabaseConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Getter;
import me.zort.sqllib.api.Query;
import me.zort.sqllib.api.SQLConnection;
import me.zort.sqllib.api.cache.CacheManager;
import me.zort.sqllib.api.data.QueryResult;
import me.zort.sqllib.api.data.QueryRowsResult;
import me.zort.sqllib.api.data.Row;
Expand Down Expand Up @@ -128,6 +129,13 @@ public SQLDatabaseConnection(final @NotNull SQLConnectionFactory connectionFacto
@ApiStatus.Experimental
@Nullable
public abstract Transaction getTransaction();
/**
* Enabled caching for this connection.
*
* @param cacheManager Cache manager to use.
*/
@ApiStatus.Experimental
public abstract void enableCaching(CacheManager cacheManager);
public abstract boolean isTransactionActive();
protected abstract DefsVals buildDefsVals(Object obj);
public abstract boolean isLogSqlErrors();
Expand All @@ -141,19 +149,18 @@ public UpsertQuery save(final @NotNull String table, final @NotNull Object obj)
public UpsertQuery save(final @NotNull Object obj) {
DefsVals defsVals = buildDefsVals(obj);
if(defsVals == null) return null;

String[] defs = defsVals.getDefs();
SQLDatabaseConnectionImpl.UnknownValueWrapper[] vals = defsVals.getVals();
UpsertQuery upsert = upsert().into(null, defs);
UpsertQuery upsertQuery = upsert().into(null, defs);
for(SQLDatabaseConnectionImpl.UnknownValueWrapper wrapper : vals) {
upsert.appendVal(wrapper.getObject());
upsertQuery.appendVal(wrapper.getObject());
}
SetStatement<InsertQuery> setStmt = upsert.onDuplicateKey();
SetStatement<InsertQuery> setStatement = upsertQuery.onDuplicateKey();
for(int i = 0; i < defs.length; i++) {
setStmt.and(defs[i], vals[i].getObject());
setStatement.and(defs[i], vals[i].getObject());
}

return (UpsertQuery) setStmt.getAncestor();
return (UpsertQuery) setStatement.getAncestor();
}

public QueryResult insert(final @NotNull String table, final @NotNull Object obj) {
Expand Down
39 changes: 34 additions & 5 deletions core/src/main/java/me/zort/sqllib/SQLDatabaseConnectionImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.google.gson.Gson;
import lombok.*;
import me.zort.sqllib.api.ISQLDatabaseOptions;
import me.zort.sqllib.api.ObjectMapper;
import me.zort.sqllib.api.Query;
import me.zort.sqllib.api.StatementFactory;
import me.zort.sqllib.api.cache.CacheManager;
import me.zort.sqllib.api.data.QueryResult;
import me.zort.sqllib.api.data.QueryRowsResult;
import me.zort.sqllib.api.data.Row;
Expand Down Expand Up @@ -66,11 +68,12 @@ public class SQLDatabaseConnectionImpl extends PooledSQLDatabaseConnection {
// --***-- Options & Utilities --***--

@Getter
private final SQLDatabaseOptions options;
private final ISQLDatabaseOptions options;
private final transient StatementMappingFactory mappingFactory;
private final transient StatementMappingResultAdapter mappingResultAdapter;
private final transient List<ErrorStateObserver> errorStateHandlers;
private transient ObjectMapper objectMapper;
private transient CacheManager cacheManager;
@Setter
private transient Logger logger;
@Getter(onMethod_ = {@Nullable, @ApiStatus.Experimental})
Expand All @@ -81,7 +84,7 @@ public class SQLDatabaseConnectionImpl extends PooledSQLDatabaseConnection {
* Constructs new instance of this implementation with default
* options.
*
* @see SQLDatabaseConnectionImpl#SQLDatabaseConnectionImpl(SQLConnectionFactory, SQLDatabaseOptions)
* @see SQLDatabaseConnectionImpl#SQLDatabaseConnectionImpl(SQLConnectionFactory, ISQLDatabaseOptions)
*/
public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionFactory) {
this(connectionFactory, null);
Expand All @@ -93,7 +96,7 @@ public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionF
* @param connectionFactory Factory to use while opening connection.
* @param options Client options to use.
*/
public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionFactory, @Nullable SQLDatabaseOptions options) {
public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionFactory, @Nullable ISQLDatabaseOptions options) {
super(connectionFactory);
if (options == null) options = defaultOptions();

Expand All @@ -105,6 +108,8 @@ public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionF
this.transaction = null;
this.logger = Logger.getGlobal();

enableCaching(CacheManager.noCache());

// Default backup value resolvers.
registerBackupValueResolver(new LinkedOneFieldResolver());
registerBackupValueResolver(new ConstructorParameterResolver());
Expand Down Expand Up @@ -143,6 +148,17 @@ public void addErrorHandler(final @NotNull ErrorStateObserver observer) {
this.errorStateHandlers.add(observer);
}

/**
* Enabled caching for this connection.
*
* @param cacheManager Cache manager to use.
*/
@ApiStatus.Experimental
@Override
public void enableCaching(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}

/**
* Constructs a mapping proxy based on provided interface.
* The interface should follow rules for creating mapping repositories
Expand Down Expand Up @@ -292,11 +308,16 @@ public QueryRowsResult<Row> query(final @NotNull String query) {
return query(() -> query);
}

@NotNull QueryRowsResult<Row> query(final @NotNull Query query, boolean isRetry) {
@SuppressWarnings("unchecked")
@NotNull
QueryRowsResult<Row> query(final @NotNull Query query, boolean isRetry) {
Objects.requireNonNull(query);
if(!handleAutoReconnect())
return new QueryRowsResult<>(false, "Cannot connect to database!");

QueryResult cachedResult = cacheManager.get(query, false);
if (cachedResult instanceof QueryRowsResult) return (QueryRowsResult<Row>) cachedResult;

try(PreparedStatement stmt = buildStatement(query);
ResultSet resultSet = stmt.executeQuery()) {
QueryRowsResult<Row> result = new QueryRowsResult<>(true);
Expand All @@ -311,6 +332,8 @@ public QueryRowsResult<Row> query(final @NotNull String query) {
result.add(row);
}

cacheManager.set(query, result);

return result;
} catch (SQLException e) {
if (!isRetry && e.getMessage().contains("database connection closed")) {
Expand Down Expand Up @@ -347,9 +370,15 @@ public QueryResult exec(final @NotNull String query) {
if(!handleAutoReconnect()) {
return new QueryResultImpl(false, "Cannot connect to database!");
}

QueryResult cachedResult = cacheManager.get(query, true);
if (cachedResult != null) return cachedResult;

try(PreparedStatement stmt = buildStatement(query)) {
stmt.execute();
return new QueryResultImpl(true);
QueryResultImpl result = new QueryResultImpl(true);
cacheManager.set(query, result);
return result;
} catch (SQLException e) {
if (!isRetry && e.getMessage().contains("database connection closed")) {
reconnect();
Expand Down
15 changes: 8 additions & 7 deletions core/src/main/java/me/zort/sqllib/SQLDatabaseOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.zort.sqllib.api.ISQLDatabaseOptions;
import me.zort.sqllib.api.options.NamingStrategy;
import me.zort.sqllib.internal.Defaults;
import me.zort.sqllib.internal.impl.DefaultNamingStrategy;
Expand All @@ -12,7 +13,7 @@
@AllArgsConstructor
@NoArgsConstructor
@Data
public final class SQLDatabaseOptions {
public final class SQLDatabaseOptions implements ISQLDatabaseOptions {

private boolean autoReconnect = true;
private boolean debug = false;
Expand All @@ -27,12 +28,12 @@ public final class SQLDatabaseOptions {
*/
@SuppressWarnings("unused")
public void load(final @NotNull SQLDatabaseConnectionImpl connection) {
SQLDatabaseOptions options = connection.getOptions();
this.autoReconnect = options.autoReconnect;
this.debug = options.debug;
this.logSqlErrors = options.logSqlErrors;
this.namingStrategy = options.namingStrategy;
this.gson = options.gson;
ISQLDatabaseOptions options = connection.getOptions();
this.autoReconnect = options.isAutoReconnect();
this.debug = options.isDebug();
this.logSqlErrors = options.isLogSqlErrors();
this.namingStrategy = options.getNamingStrategy();
this.gson = options.getGson();
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.zort.sqllib;

import me.zort.sqllib.api.ISQLDatabaseOptions;
import me.zort.sqllib.api.Query;
import me.zort.sqllib.api.data.QueryResult;
import me.zort.sqllib.api.data.QueryRowsResult;
Expand Down Expand Up @@ -29,8 +30,7 @@ public SQLiteDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connecti
super(connectionFactory);
}

public SQLiteDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionFactory,
@Nullable SQLDatabaseOptions options) {
public SQLiteDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionFactory, @Nullable ISQLDatabaseOptions options) {
super(connectionFactory, options);
}

Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/me/zort/sqllib/TableSchemaBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.gson.internal.Primitives;
import lombok.RequiredArgsConstructor;
import me.zort.sqllib.api.ISQLDatabaseOptions;
import me.zort.sqllib.internal.annotation.JsonField;
import me.zort.sqllib.internal.annotation.NullableField;
import me.zort.sqllib.internal.annotation.PrimaryKey;
Expand Down Expand Up @@ -38,7 +39,7 @@ public String[] buildDefsFromType() {
}
debug("Building defs from type class: " + typeClass.getName());

SQLDatabaseOptions options = ((SQLDatabaseConnectionImpl) connection).getOptions();
ISQLDatabaseOptions options = ((SQLDatabaseConnectionImpl) connection).getOptions();
String[] defs = new String[0];

for (Field field : typeClass.getDeclaredFields()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package me.zort.sqllib.cache;

import me.zort.sqllib.api.Query;
import me.zort.sqllib.api.cache.CacheManager;
import me.zort.sqllib.api.data.QueryResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class ExpirableEntriesCacheManager implements CacheManager {
@Override
public void set(@NotNull Query query, @NotNull QueryResult result) {
// TODO: Implement
}

@Override
public @Nullable QueryResult get(@NotNull Query query, boolean isExec) {
// TODO: Implement
return null;
}
}
27 changes: 8 additions & 19 deletions core/src/main/java/me/zort/sqllib/internal/query/QueryNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public abstract class QueryNode<P extends QueryNode<?>> implements Query, Statem
@Getter(onMethod_ = {@Nullable})
private final transient P parent;
private final List<QueryNode<?>> children;
private final int priority;
private final Map<String, QueryDetails> details;
private final int priority;

public QueryNode(@Nullable P parent, List<QueryNode<?>> initial, QueryPriority priority) {
this(parent, initial, priority.getPrior());
Expand Down Expand Up @@ -75,7 +75,7 @@ public String buildQuery() {

public QueryDetails buildInnerQuery() {
List<QueryNode<?>> children = new ArrayList<>(this.children);
Collections.sort(children, Comparator.comparingInt(QueryNode::getPriority));
children.sort(Comparator.comparingInt(QueryNode::getPriority));

QueryDetails details = new QueryDetails("", new HashMap<>());

Expand Down Expand Up @@ -115,14 +115,18 @@ protected <T> T invokeToConnection(Function<SQLDatabaseConnection, T> func)
return result;
}

@SuppressWarnings("unchecked")
public QueryNode<?> then(String part) {
int maxPriority = children.stream()
.map(QueryNode::getPriority)
.max(Comparator.naturalOrder())
.orElse(0);

then(new LocalQueryNode(this, maxPriority + 1, part));
then(new QueryNode<QueryNode<?>>(parent, Collections.emptyList(), maxPriority + 1) {
@Override
public QueryDetails buildQueryDetails() {
return new QueryDetails(part, new HashMap<>());
}
});
return this;
}

Expand Down Expand Up @@ -190,19 +194,4 @@ private void debug(String message) {
}
}

private static class LocalQueryNode extends QueryNode {

private final String queryPartString;

public LocalQueryNode(@Nullable QueryNode parent, int priority, String queryPartString) {
super(parent, Collections.emptyList(), priority);
this.queryPartString = queryPartString;
}

@Override
public QueryDetails buildQueryDetails() {
return new QueryDetails(queryPartString, new HashMap<>());
}
}

}
Loading

0 comments on commit 4558302

Please sign in to comment.