Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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