22
33import com .google .gson .Gson ;
44import lombok .*;
5+ import me .zort .sqllib .api .ISQLDatabaseOptions ;
56import me .zort .sqllib .api .ObjectMapper ;
67import me .zort .sqllib .api .Query ;
78import me .zort .sqllib .api .StatementFactory ;
9+ import me .zort .sqllib .api .cache .CacheManager ;
810import me .zort .sqllib .api .data .QueryResult ;
911import me .zort .sqllib .api .data .QueryRowsResult ;
1012import me .zort .sqllib .api .data .Row ;
@@ -66,11 +68,12 @@ public class SQLDatabaseConnectionImpl extends PooledSQLDatabaseConnection {
6668 // --***-- Options & Utilities --***--
6769
6870 @ Getter
69- private final SQLDatabaseOptions options ;
71+ private final ISQLDatabaseOptions options ;
7072 private final transient StatementMappingFactory mappingFactory ;
7173 private final transient StatementMappingResultAdapter mappingResultAdapter ;
7274 private final transient List <ErrorStateObserver > errorStateHandlers ;
7375 private transient ObjectMapper objectMapper ;
76+ private transient CacheManager cacheManager ;
7477 @ Setter
7578 private transient Logger logger ;
7679 @ Getter (onMethod_ = {@ Nullable , @ ApiStatus .Experimental })
@@ -81,7 +84,7 @@ public class SQLDatabaseConnectionImpl extends PooledSQLDatabaseConnection {
8184 * Constructs new instance of this implementation with default
8285 * options.
8386 *
84- * @see SQLDatabaseConnectionImpl#SQLDatabaseConnectionImpl(SQLConnectionFactory, SQLDatabaseOptions )
87+ * @see SQLDatabaseConnectionImpl#SQLDatabaseConnectionImpl(SQLConnectionFactory, ISQLDatabaseOptions )
8588 */
8689 public SQLDatabaseConnectionImpl (final @ NotNull SQLConnectionFactory connectionFactory ) {
8790 this (connectionFactory , null );
@@ -93,7 +96,7 @@ public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionF
9396 * @param connectionFactory Factory to use while opening connection.
9497 * @param options Client options to use.
9598 */
96- public SQLDatabaseConnectionImpl (final @ NotNull SQLConnectionFactory connectionFactory , @ Nullable SQLDatabaseOptions options ) {
99+ public SQLDatabaseConnectionImpl (final @ NotNull SQLConnectionFactory connectionFactory , @ Nullable ISQLDatabaseOptions options ) {
97100 super (connectionFactory );
98101 if (options == null ) options = defaultOptions ();
99102
@@ -105,6 +108,8 @@ public SQLDatabaseConnectionImpl(final @NotNull SQLConnectionFactory connectionF
105108 this .transaction = null ;
106109 this .logger = Logger .getGlobal ();
107110
111+ enableCaching (CacheManager .noCache ());
112+
108113 // Default backup value resolvers.
109114 registerBackupValueResolver (new LinkedOneFieldResolver ());
110115 registerBackupValueResolver (new ConstructorParameterResolver ());
@@ -143,6 +148,17 @@ public void addErrorHandler(final @NotNull ErrorStateObserver observer) {
143148 this .errorStateHandlers .add (observer );
144149 }
145150
151+ /**
152+ * Enabled caching for this connection.
153+ *
154+ * @param cacheManager Cache manager to use.
155+ */
156+ @ ApiStatus .Experimental
157+ @ Override
158+ public void enableCaching (CacheManager cacheManager ) {
159+ this .cacheManager = cacheManager ;
160+ }
161+
146162 /**
147163 * Constructs a mapping proxy based on provided interface.
148164 * The interface should follow rules for creating mapping repositories
@@ -292,11 +308,16 @@ public QueryRowsResult<Row> query(final @NotNull String query) {
292308 return query (() -> query );
293309 }
294310
295- @ NotNull QueryRowsResult <Row > query (final @ NotNull Query query , boolean isRetry ) {
311+ @ SuppressWarnings ("unchecked" )
312+ @ NotNull
313+ QueryRowsResult <Row > query (final @ NotNull Query query , boolean isRetry ) {
296314 Objects .requireNonNull (query );
297315 if (!handleAutoReconnect ())
298316 return new QueryRowsResult <>(false , "Cannot connect to database!" );
299317
318+ QueryResult cachedResult = cacheManager .get (query , false );
319+ if (cachedResult instanceof QueryRowsResult ) return (QueryRowsResult <Row >) cachedResult ;
320+
300321 try (PreparedStatement stmt = buildStatement (query );
301322 ResultSet resultSet = stmt .executeQuery ()) {
302323 QueryRowsResult <Row > result = new QueryRowsResult <>(true );
@@ -311,6 +332,8 @@ public QueryRowsResult<Row> query(final @NotNull String query) {
311332 result .add (row );
312333 }
313334
335+ cacheManager .set (query , result );
336+
314337 return result ;
315338 } catch (SQLException e ) {
316339 if (!isRetry && e .getMessage ().contains ("database connection closed" )) {
@@ -347,9 +370,15 @@ public QueryResult exec(final @NotNull String query) {
347370 if (!handleAutoReconnect ()) {
348371 return new QueryResultImpl (false , "Cannot connect to database!" );
349372 }
373+
374+ QueryResult cachedResult = cacheManager .get (query , true );
375+ if (cachedResult != null ) return cachedResult ;
376+
350377 try (PreparedStatement stmt = buildStatement (query )) {
351378 stmt .execute ();
352- return new QueryResultImpl (true );
379+ QueryResultImpl result = new QueryResultImpl (true );
380+ cacheManager .set (query , result );
381+ return result ;
353382 } catch (SQLException e ) {
354383 if (!isRetry && e .getMessage ().contains ("database connection closed" )) {
355384 reconnect ();
0 commit comments