Skip to content

Commit 36865fa

Browse files
committed
Added:
* JavaDocs * ExpirableEntriesCacheManager.java implementation * toString(), equals(), hashCode() implementations in QueryNode.java * SQLConnectionBuilder#withCacheManager * TestCase3.java Changed: * Optimized some imports * DefaultNamingStrategy.java is now SymbolSeparatedNamingStrategy.java * SymbolSeparatedNamingStrategy.java now has option to specify symbol and case type * TestCase1#test6_Pool now prints SQLException stack trace
1 parent dae9fef commit 36865fa

13 files changed

Lines changed: 186 additions & 57 deletions

File tree

api/src/main/java/me/zort/sqllib/api/cache/CacheManager.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,43 @@
55
import org.jetbrains.annotations.NotNull;
66
import org.jetbrains.annotations.Nullable;
77

8+
/**
9+
* A cache manager that caches query results. This is used
10+
* primarly in {@link me.zort.sqllib.api.SQLConnection} instances
11+
* that hold a cache manager.
12+
*
13+
* @author ZorTik
14+
*/
815
public interface CacheManager {
916

17+
/**
18+
* Sets a query result to the cache.
19+
* If the query is already cached, it should be overwritten.
20+
*
21+
* @param query Query that was executed
22+
* @param result Result
23+
*/
1024
void set(@NotNull Query query, @NotNull QueryResult result);
25+
26+
/**
27+
* Returns a query result from the cache, or null if
28+
* the query is not cached.
29+
*
30+
* @param query Query that was executed
31+
* @param isExec Whether the query is an exec (no ResultSet) query
32+
* @return The nullable query result
33+
*/
1134
@Nullable QueryResult get(@NotNull Query query, boolean isExec);
1235

36+
/**
37+
* Returns a cache manager that does not cache anything.
38+
*
39+
* @return The cache manager
40+
*/
1341
static CacheManager noCache() {
1442
return new CacheManager() {
1543
@Override
16-
public void set(@NotNull Query query, @NotNull QueryResult result) {
17-
}
44+
public void set(@NotNull Query query, @NotNull QueryResult result) {}
1845
@Override
1946
public @Nullable QueryResult get(@NotNull Query query, boolean isExec) {
2047
return null;

api/src/main/java/me/zort/sqllib/api/options/NamingStrategy.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package me.zort.sqllib.api.options;
22

3+
/**
4+
* A naming strategy that converts field names to column names.
5+
*
6+
* @author ZorTik
7+
*/
38
public interface NamingStrategy {
49

510
String fieldNameToColumn(String str);

core/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ dependencies {
1414
implementation project(":shared")
1515
implementation group: 'org.jetbrains', name: 'annotations', version: '20.1.0'
1616
implementation 'com.google.code.gson:gson:2.9.0'
17+
implementation 'com.google.guava:guava:31.0-jre'
1718
compileOnly 'org.projectlombok:lombok:1.18.24'
1819
annotationProcessor 'org.projectlombok:lombok:1.18.24'
1920
}

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

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import me.zort.sqllib.api.ISQLConnectionBuilder;
55
import me.zort.sqllib.api.ISQLDatabaseOptions;
66
import me.zort.sqllib.api.SQLEndpoint;
7+
import me.zort.sqllib.api.cache.CacheManager;
78
import me.zort.sqllib.internal.Constants;
89
import me.zort.sqllib.internal.exception.SQLDriverNotFoundException;
910
import me.zort.sqllib.internal.exception.SQLEndpointNotValidException;
@@ -34,14 +35,15 @@ public final class SQLConnectionBuilder implements ISQLConnectionBuilder<SQLData
3435
return of(new SQLEndpointImpl("jdbc:sqlite:" + path, null, null)).withDriver("org.sqlite.JDBC");
3536
}
3637

37-
public static SQLConnectionBuilder of(SQLEndpoint endpoint) {
38+
public static @NotNull SQLConnectionBuilder of(SQLEndpoint endpoint) {
3839
if(!endpoint.isValid()) throw new SQLEndpointNotValidException(endpoint);
3940
return new SQLConnectionBuilder(endpoint);
4041
}
4142

4243
private SQLEndpoint endpoint;
4344
private String jdbc;
4445
private String driver = null;
46+
private CacheManager cacheManager = null;
4547

4648
public SQLConnectionBuilder() {
4749
this(null);
@@ -72,6 +74,11 @@ public SQLConnectionBuilder(@Nullable SQLEndpoint endpoint) {
7274
return this;
7375
}
7476

77+
public @NotNull SQLConnectionBuilder withCacheManager(final @Nullable CacheManager cacheManager) {
78+
this.cacheManager = cacheManager;
79+
return this;
80+
}
81+
7582
public @NotNull SQLDatabaseConnection build() {
7683
return build(null);
7784
}
@@ -81,12 +88,16 @@ public SQLConnectionBuilder(@Nullable SQLEndpoint endpoint) {
8188
}
8289

8390
public @NotNull SQLDatabaseConnection build(@Nullable String driver, @Nullable ISQLDatabaseOptions options) {
91+
SQLDatabaseConnection connection = buildConnection(driver, options);
92+
if(cacheManager != null) connection.enableCaching(cacheManager);
93+
return connection;
94+
}
95+
96+
private @NotNull SQLDatabaseConnection buildConnection(@Nullable String driver, @Nullable ISQLDatabaseOptions options) {
8497
Objects.requireNonNull(endpoint, "Endpoint must be set!");
8598
Objects.requireNonNull(jdbc);
86-
if(driver == null) {
87-
driver = Constants.DEFAULT_DRIVER;
88-
}
89-
SQLConnectionFactory connectionFactory = new BuilderSQLConnectionFactory(this, driver);
99+
if (driver == null) driver = Constants.DEFAULT_DRIVER;
100+
SQLConnectionFactory connectionFactory = new LocalConnectionFactory(driver);
90101
return jdbc.contains("jdbc:sqlite")
91102
? new SQLiteDatabaseConnectionImpl(connectionFactory, options)
92103
: new SQLDatabaseConnectionImpl(connectionFactory, options);
@@ -102,22 +113,20 @@ protected SQLConnectionBuilder clone() throws CloneNotSupportedException {
102113
}
103114

104115
@RequiredArgsConstructor
105-
public static class BuilderSQLConnectionFactory implements SQLConnectionFactory {
116+
class LocalConnectionFactory implements SQLConnectionFactory {
106117

107-
private final SQLConnectionBuilder builder;
108-
private final String driver;
118+
private final String localDriver;
109119

110120
@Nullable
111121
@Override
112122
public Connection connect() throws SQLException {
113123
try {
114-
Class.forName(driver);
124+
Class.forName(localDriver);
115125
} catch (ClassNotFoundException e) {
116-
throw new SQLDriverNotFoundException(driver, e);
126+
throw new SQLDriverNotFoundException(localDriver, e);
117127
}
118-
String jdbc = builder.jdbc;
119-
String usr = builder.endpoint.getUsername();
120-
String pwd = builder.endpoint.getPassword();
128+
String usr = endpoint.getUsername();
129+
String pwd = endpoint.getPassword();
121130
return DriverManager.getConnection(jdbc, usr, pwd);
122131
}
123132

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package me.zort.sqllib;
22

33
import com.google.gson.Gson;
4-
import lombok.*;
4+
import lombok.Getter;
5+
import lombok.RequiredArgsConstructor;
6+
import lombok.Setter;
7+
import lombok.SneakyThrows;
58
import me.zort.sqllib.api.ISQLDatabaseOptions;
69
import me.zort.sqllib.api.ObjectMapper;
710
import me.zort.sqllib.api.Query;
@@ -20,10 +23,9 @@
2023
import me.zort.sqllib.internal.factory.SQLConnectionFactory;
2124
import me.zort.sqllib.internal.fieldResolver.ConstructorParameterResolver;
2225
import me.zort.sqllib.internal.fieldResolver.LinkedOneFieldResolver;
23-
import me.zort.sqllib.internal.impl.DefaultNamingStrategy;
26+
import me.zort.sqllib.naming.SymbolSeparatedNamingStrategy;
2427
import me.zort.sqllib.internal.impl.DefaultObjectMapper;
2528
import me.zort.sqllib.internal.impl.QueryResultImpl;
26-
import me.zort.sqllib.mapping.DefaultResultAdapter;
2729
import me.zort.sqllib.mapping.DefaultStatementMappingFactory;
2830
import me.zort.sqllib.pool.PooledSQLDatabaseConnection;
2931
import me.zort.sqllib.transaction.Transaction;
@@ -62,7 +64,7 @@ public class SQLDatabaseConnectionImpl extends PooledSQLDatabaseConnection {
6264
public static final boolean DEFAULT_AUTO_RECONNECT = true;
6365
public static final boolean DEFAULT_DEBUG = false;
6466
public static final boolean DEFAULT_LOG_SQL_ERRORS = true;
65-
public static final NamingStrategy DEFAULT_NAMING_STRATEGY = new DefaultNamingStrategy();
67+
public static final NamingStrategy DEFAULT_NAMING_STRATEGY = new SymbolSeparatedNamingStrategy('_');
6668
public static final Gson DEFAULT_GSON = Defaults.DEFAULT_GSON;
6769

6870
// --***-- Options & Utilities --***--
@@ -97,9 +99,7 @@ public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionF
9799
*/
98100
public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionFactory, @Nullable ISQLDatabaseOptions options) {
99101
super(connectionFactory);
100-
if (options == null) options = defaultOptions();
101-
102-
this.options = options;
102+
this.options = options == null ? defaultOptions() : options;
103103
this.objectMapper = new DefaultObjectMapper(this);
104104
this.mappingFactory = new DefaultStatementMappingFactory();
105105
this.errorStateHandlers = new CopyOnWriteArrayList<>();

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import me.zort.sqllib.api.ISQLDatabaseOptions;
88
import me.zort.sqllib.api.options.NamingStrategy;
99
import me.zort.sqllib.internal.Defaults;
10-
import me.zort.sqllib.internal.impl.DefaultNamingStrategy;
10+
import me.zort.sqllib.naming.SymbolSeparatedNamingStrategy;
1111
import org.jetbrains.annotations.NotNull;
1212

1313
@AllArgsConstructor
@@ -18,7 +18,7 @@ public final class SQLDatabaseOptions implements ISQLDatabaseOptions {
1818
private boolean autoReconnect = true;
1919
private boolean debug = false;
2020
private boolean logSqlErrors = true;
21-
private transient NamingStrategy namingStrategy = new DefaultNamingStrategy();
21+
private transient NamingStrategy namingStrategy = SQLDatabaseConnectionImpl.DEFAULT_NAMING_STRATEGY;
2222
private transient Gson gson = Defaults.DEFAULT_GSON;
2323

2424
/**
Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,38 @@
11
package me.zort.sqllib.cache;
22

3+
import com.google.common.cache.Cache;
4+
import com.google.common.cache.CacheBuilder;
35
import me.zort.sqllib.api.Query;
46
import me.zort.sqllib.api.cache.CacheManager;
57
import me.zort.sqllib.api.data.QueryResult;
68
import org.jetbrains.annotations.NotNull;
79
import org.jetbrains.annotations.Nullable;
810

11+
import java.util.concurrent.TimeUnit;
12+
913
public class ExpirableEntriesCacheManager implements CacheManager {
14+
15+
private final Cache<Query, QueryResult> cache;
16+
17+
/**
18+
* Creates a new cache manager with provided expiration duration
19+
* in milliseconds.
20+
*
21+
* @param expirationDuration The expiration duration
22+
*/
23+
public ExpirableEntriesCacheManager(long expirationDuration) {
24+
cache = CacheBuilder.newBuilder()
25+
.expireAfterWrite(expirationDuration, TimeUnit.MILLISECONDS)
26+
.build();
27+
}
28+
1029
@Override
1130
public void set(@NotNull Query query, @NotNull QueryResult result) {
12-
// TODO: Implement
31+
cache.put(query, result);
1332
}
1433

1534
@Override
1635
public @Nullable QueryResult get(@NotNull Query query, boolean isExec) {
17-
// TODO: Implement
18-
return null;
36+
return cache.getIfPresent(query);
1937
}
2038
}

core/src/main/java/me/zort/sqllib/internal/impl/DefaultNamingStrategy.java

Lines changed: 0 additions & 29 deletions
This file was deleted.

core/src/main/java/me/zort/sqllib/internal/query/QueryDetails.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package me.zort.sqllib.internal.query;
22

3+
import com.google.gson.Gson;
34
import lombok.*;
45
import me.zort.sqllib.SQLConnectionRegistry;
56
import me.zort.sqllib.util.Pair;
@@ -129,6 +130,10 @@ public int length() {
129130
return queryStr.length();
130131
}
131132

133+
public String toString() {
134+
return "QueryDetails{str=" + queryStr + ", values=" + new Gson().toJson(values) + "}";
135+
}
136+
132137
@RequiredArgsConstructor
133138
public static class Builder {
134139

core/src/main/java/me/zort/sqllib/internal/query/QueryNode.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,19 @@ private void debug(String message) {
194194
}
195195
}
196196

197+
public String toString() {
198+
return "QueryNode{details=" + buildQueryDetails().toString() + "}";
199+
}
200+
201+
@Override
202+
public boolean equals(Object obj) {
203+
if (!(obj instanceof QueryNode)) return false;
204+
QueryNode<?> other = (QueryNode<?>) obj;
205+
return toString().equals(other.toString());
206+
}
207+
208+
@Override
209+
public int hashCode() {
210+
return toString().hashCode();
211+
}
197212
}

0 commit comments

Comments
 (0)