Add support for a list of "queries for new connections", to be ran when new connections are opened

This commit is contained in:
2025-01-03 16:44:18 -06:00
parent 5ecae928ac
commit 6a5f8fadad
4 changed files with 179 additions and 1 deletions

View File

@ -0,0 +1,110 @@
/*
* QQQ - Low-code Application Framework for Engineers.
* Copyright (C) 2021-2025. Kingsrook, LLC
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
* contact@kingsrook.com
* https://github.com/Kingsrook/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.kingsrook.qqq.backend.module.rdbms.jdbc;
import java.sql.Connection;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.mchange.v2.c3p0.ConnectionCustomizer;
/*******************************************************************************
** Basic version of a C3P0 Connection Customizer used by QQQ - that does things
** expected for an RDBMS backend - specifically:
** - runs queriesForNewConnections, if they are set.
*******************************************************************************/
public class BaseC3P0ConnectionCustomizer implements ConnectionCustomizer
{
private static Map<String, List<String>> queriesForNewConnections = new HashMap<>();
/***************************************************************************
*
***************************************************************************/
@Override
public void onAcquire(Connection connection, String dataSourceIdentityToken) throws Exception
{
List<String> queries = queriesForNewConnections.get(dataSourceIdentityToken);
if(CollectionUtils.nullSafeHasContents(queries))
{
for(String sql : queries)
{
Statement statement = connection.createStatement();
statement.execute(sql);
}
}
}
/***************************************************************************
*
***************************************************************************/
@Override
public void onDestroy(Connection connection, String dataSourceIdentityToken) throws Exception
{
//////////
// noop //
//////////
}
/***************************************************************************
*
***************************************************************************/
@Override
public void onCheckOut(Connection connection, String dataSourceIdentityToken) throws Exception
{
//////////
// noop //
//////////
}
/***************************************************************************
*
***************************************************************************/
@Override
public void onCheckIn(Connection connection, String dataSourceIdentityToken) throws Exception
{
//////////
// noop //
//////////
}
/***************************************************************************
*
***************************************************************************/
public static void setQueriesForNewConnections(String backendName, List<String> queriesForNewConnections)
{
BaseC3P0ConnectionCustomizer.queriesForNewConnections.put(backendName, queriesForNewConnections);
}
}

View File

@ -26,6 +26,7 @@ import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.ConnectionPoolSettings; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.ConnectionPoolSettings;
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData;
import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.ComboPooledDataSource;
@ -110,6 +111,17 @@ public class C3P0PooledConnectionProvider implements ConnectionProviderInterface
} }
} }
pool.setIdentityToken(backend.getName());
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// if the backend specifies queries to run for new connections, then set up a connection customizer to run them //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(CollectionUtils.nullSafeHasContents(backend.getQueriesForNewConnections()))
{
BaseC3P0ConnectionCustomizer.setQueriesForNewConnections(backend.getName(), backend.getQueriesForNewConnections());
pool.setConnectionCustomizerClassName(BaseC3P0ConnectionCustomizer.class.getName());
}
customizePool(pool); customizePool(pool);
this.connectionPool = pool; this.connectionPool = pool;

View File

@ -25,6 +25,8 @@ package com.kingsrook.qqq.backend.module.rdbms.jdbc;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement;
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData;
import static com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager.getJdbcUrl; import static com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager.getJdbcUrl;
@ -57,7 +59,28 @@ public class SimpleConnectionProvider implements ConnectionProviderInterface
public Connection getConnection() throws SQLException public Connection getConnection() throws SQLException
{ {
String jdbcURL = getJdbcUrl(backend); String jdbcURL = getJdbcUrl(backend);
return DriverManager.getConnection(jdbcURL, backend.getUsername(), backend.getPassword()); Connection connection = DriverManager.getConnection(jdbcURL, backend.getUsername(), backend.getPassword());
if(CollectionUtils.nullSafeHasContents(backend.getQueriesForNewConnections()))
{
runQueriesForNewConnections(connection);
}
return (connection);
}
/***************************************************************************
*
***************************************************************************/
private void runQueriesForNewConnections(Connection connection) throws SQLException
{
for(String sql : backend.getQueriesForNewConnections())
{
Statement statement = connection.createStatement();
statement.execute(sql);
}
} }
} }

View File

@ -22,6 +22,7 @@
package com.kingsrook.qqq.backend.module.rdbms.model.metadata; package com.kingsrook.qqq.backend.module.rdbms.model.metadata;
import java.util.List;
import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter; import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
@ -49,6 +50,8 @@ public class RDBMSBackendMetaData extends QBackendMetaData
private RDBMSBackendMetaData readOnlyBackendMetaData; private RDBMSBackendMetaData readOnlyBackendMetaData;
private List<String> queriesForNewConnections = null;
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// define well-known (and fully supported) vendor values // // define well-known (and fully supported) vendor values //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -453,4 +456,34 @@ public class RDBMSBackendMetaData extends QBackendMetaData
return (this); return (this);
} }
/*******************************************************************************
** Getter for queriesForNewConnections
*******************************************************************************/
public List<String> getQueriesForNewConnections()
{
return (this.queriesForNewConnections);
}
/*******************************************************************************
** Setter for queriesForNewConnections
*******************************************************************************/
public void setQueriesForNewConnections(List<String> queriesForNewConnections)
{
this.queriesForNewConnections = queriesForNewConnections;
}
/*******************************************************************************
** Fluent setter for queriesForNewConnections
*******************************************************************************/
public RDBMSBackendMetaData withQueriesForNewConnections(List<String> queriesForNewConnections)
{
this.queriesForNewConnections = queriesForNewConnections;
return (this);
}
} }