2020import com .zaxxer .hikari .HikariConfig ;
2121import com .zaxxer .hikari .HikariDataSource ;
2222import io .supertokens .pluginInterface .exceptions .DbInitException ;
23+ import io .supertokens .pluginInterface .exceptions .StorageQueryException ;
2324import io .supertokens .storage .postgresql .config .Config ;
2425import io .supertokens .storage .postgresql .config .PostgreSQLConfig ;
2526import io .supertokens .storage .postgresql .output .Logging ;
@@ -35,12 +36,14 @@ public class ConnectionPool extends ResourceDistributor.SingletonResource {
3536 private static final String RESOURCE_KEY = "io.supertokens.storage.postgresql.ConnectionPool" ;
3637 private HikariDataSource hikariDataSource ;
3738 private final Start start ;
39+ private PostConnectCallback postConnectCallback ;
3840
39- private ConnectionPool (Start start ) {
41+ private ConnectionPool (Start start , PostConnectCallback postConnectCallback ) {
4042 this .start = start ;
43+ this .postConnectCallback = postConnectCallback ;
4144 }
4245
43- private synchronized void initialiseHikariDataSource () throws SQLException {
46+ private synchronized void initialiseHikariDataSource () throws SQLException , StorageQueryException {
4447 if (this .hikariDataSource != null ) {
4548 return ;
4649 }
@@ -99,6 +102,19 @@ private synchronized void initialiseHikariDataSource() throws SQLException {
99102 } catch (Exception e ) {
100103 throw new SQLException (e );
101104 }
105+
106+ try {
107+ try (Connection con = hikariDataSource .getConnection ()) {
108+ this .postConnectCallback .apply (con );
109+ }
110+ } catch (StorageQueryException e ) {
111+ // if an exception happens here, we want to set the hikariDataSource to null once again so that
112+ // whenever the getConnection is called again, we want to re-attempt creation of tables and tenant
113+ // entries for this storage
114+ hikariDataSource .close ();
115+ hikariDataSource = null ;
116+ throw e ;
117+ }
102118 }
103119
104120 private static int getTimeToWaitToInit (Start start ) {
@@ -133,7 +149,7 @@ static boolean isAlreadyInitialised(Start start) {
133149 return getInstance (start ) != null && getInstance (start ).hikariDataSource != null ;
134150 }
135151
136- static void initPool (Start start , boolean shouldWait ) throws DbInitException {
152+ static void initPool (Start start , boolean shouldWait , PostConnectCallback postConnectCallback ) throws DbInitException {
137153 if (isAlreadyInitialised (start )) {
138154 return ;
139155 }
@@ -146,7 +162,7 @@ static void initPool(Start start, boolean shouldWait) throws DbInitException {
146162 " specified the correct values for ('postgresql_host' and 'postgresql_port') or for "
147163 + "'postgresql_connection_uri'" ;
148164 try {
149- ConnectionPool con = new ConnectionPool (start );
165+ ConnectionPool con = new ConnectionPool (start , postConnectCallback );
150166 start .getResourceDistributor ().setResource (RESOURCE_KEY , con );
151167 while (true ) {
152168 try {
@@ -189,7 +205,7 @@ static void initPool(Start start, boolean shouldWait) throws DbInitException {
189205 }
190206 }
191207
192- public static Connection getConnection (Start start ) throws SQLException {
208+ public static Connection getConnection (Start start ) throws SQLException , StorageQueryException {
193209 if (getInstance (start ) == null ) {
194210 throw new IllegalStateException ("Please call initPool before getConnection" );
195211 }
@@ -216,4 +232,9 @@ static void close(Start start) {
216232 }
217233 }
218234 }
235+
236+ @ FunctionalInterface
237+ public static interface PostConnectCallback {
238+ void apply (Connection connection ) throws StorageQueryException ;
239+ }
219240}
0 commit comments