4040import java .util .concurrent .CopyOnWriteArrayList ;
4141import java .util .logging .Logger ;
4242
43+ import static me .zort .sqllib .util .ExceptionsUtility .runCatching ;
44+
4345/**
4446 * Main database client object implementation.
4547 * This class is responsible for handling requests from query
@@ -52,11 +54,11 @@ public class SQLDatabaseConnectionImpl extends SQLDatabaseConnection {
5254
5355 // --***-- Default Constants --***--
5456
55- public static boolean DEFAULT_AUTO_RECONNECT = true ;
56- public static boolean DEFAULT_DEBUG = false ;
57- public static boolean DEFAULT_LOG_SQL_ERRORS = true ;
58- public static NamingStrategy DEFAULT_NAMING_STRATEGY = new DefaultNamingStrategy ();
59- public static Gson DEFAULT_GSON = Defaults .DEFAULT_GSON ;
57+ public static final boolean DEFAULT_AUTO_RECONNECT = true ;
58+ public static final boolean DEFAULT_DEBUG = false ;
59+ public static final boolean DEFAULT_LOG_SQL_ERRORS = true ;
60+ public static final NamingStrategy DEFAULT_NAMING_STRATEGY = new DefaultNamingStrategy ();
61+ public static final Gson DEFAULT_GSON = Defaults .DEFAULT_GSON ;
6062
6163 // --***-- Options & Utilities --***--
6264
@@ -66,6 +68,7 @@ public class SQLDatabaseConnectionImpl extends SQLDatabaseConnection {
6668 private final transient StatementMappingFactory mappingFactory ;
6769 @ ApiStatus .Experimental
6870 private final transient StatementMappingResultAdapter mappingResultAdapter ;
71+ private final transient List <ErrorStateObserver > errorStateHandlers ;
6972 private transient ObjectMapper objectMapper ;
7073 @ Setter
7174 private transient Logger logger ;
@@ -101,6 +104,7 @@ public SQLDatabaseConnectionImpl(SQLConnectionFactory connectionFactory, @Nullab
101104 this .objectMapper = new DefaultObjectMapper (this );
102105 this .mappingFactory = new DefaultStatementMappingFactory ();
103106 this .mappingResultAdapter = new DefaultResultAdapter ();
107+ this .errorStateHandlers = new CopyOnWriteArrayList <>();
104108 this .logger = Logger .getGlobal ();
105109
106110 // Default backup value resolvers.
@@ -131,6 +135,16 @@ public void setObjectMapper(@NotNull ObjectMapper objectMapper) {
131135 this .objectMapper = Objects .requireNonNull (objectMapper , "Object mapper cannot be null!" );
132136 }
133137
138+ /**
139+ * Adds an error state observer to the list of observers to be
140+ * notified when a fatal error occurs.
141+ *
142+ * @param observer Observer to add.
143+ */
144+ public void addErrorHandler (@ NotNull ErrorStateObserver observer ) {
145+ this .errorStateHandlers .add (observer );
146+ }
147+
134148 /**
135149 * Constructs a mapping repository based on provided interface.
136150 * The interface should follow rules for creating mapping repositories
@@ -283,6 +297,7 @@ private QueryRowsResult<Row> doQuery(Query query, boolean isRetry) {
283297 }
284298
285299 logSqlError (e );
300+ notifyError (ErrorCode .QUERY_FATAL );
286301 return new QueryRowsResult <>(false , e .getMessage ());
287302 }
288303 }
@@ -315,6 +330,7 @@ private QueryResult doExec(Query query, boolean isRetry) {
315330 }
316331
317332 logSqlError (e );
333+ notifyError (ErrorCode .QUERY_FATAL );
318334 return new QueryResultImpl (false , e .getMessage ());
319335 }
320336 }
@@ -441,15 +457,19 @@ public void debug(String message) {
441457 }
442458
443459 @ Override
444- public boolean isLogSqlErrors () {
460+ public final boolean isLogSqlErrors () {
445461 return options .isLogSqlErrors ();
446462 }
447463
448464 @ Override
449- public boolean isDebug () {
465+ public final boolean isDebug () {
450466 return options .isDebug ();
451467 }
452468
469+ private void notifyError (int code ) {
470+ this .errorStateHandlers .forEach (handler -> runCatching (() -> handler .onErrorState (code )));
471+ }
472+
453473 public final SQLDatabaseOptions cloneOptions () {
454474 SQLDatabaseOptions cloned = new SQLDatabaseOptions ();
455475 cloned .setDebug (options .isDebug ());
@@ -489,4 +509,12 @@ public static class UnknownValueWrapper {
489509 private Object object ;
490510 }
491511
512+ public interface ErrorStateObserver {
513+ void onErrorState (int code );
514+ }
515+
516+ public static final class ErrorCode {
517+ public static final int QUERY_FATAL = 0 ;
518+ }
519+
492520}
0 commit comments