org.bitbucket.bradleysmithllc.etlunit.feature.database.JDBCClientImpl Maven / Gradle / Ivy
package org.bitbucket.bradleysmithllc.etlunit.feature.database;
import org.apache.commons.io.IOUtils;
import org.bitbucket.bradleysmithllc.etlunit.Log;
import org.bitbucket.bradleysmithllc.etlunit.RuntimeSupport;
import org.bitbucket.bradleysmithllc.etlunit.TestExecutionError;
import org.bitbucket.bradleysmithllc.etlunit.io.file.DataFileMismatchException;
import org.bitbucket.bradleysmithllc.etlunit.util.VelocityUtil;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
public class JDBCClientImpl implements JDBCClient {
private DatabaseFeatureModule databaseFeatureModule;
private RuntimeSupport runtimeSupport;
private DatabaseImplementation databaseImplementation;
protected Log applicationLog;
@Inject
public void setApplicationLog(@Named("applicationLog") Log log) {
applicationLog = log;
}
@Override
public void worksFor(DatabaseImplementation dbi) {
databaseImplementation = dbi;
}
@Inject
public void receiveRuntimeSupport(RuntimeSupport runtimeSupport) {
this.runtimeSupport = runtimeSupport;
}
@Inject
public void setDatabaseFeatureModule(DatabaseFeatureModule databaseFeatureModule) {
this.databaseFeatureModule = databaseFeatureModule;
}
public void useConnection(DatabaseConnection connection, String mode, ConnectionClient client) throws TestExecutionError {
useConnection(connection, mode, client, DatabaseImplementation.DATABASE);
}
public void useConnection(DatabaseConnection connection, String mode, ConnectionClient client, int id) throws TestExecutionError {
DatabaseImplementation dbConn = databaseFeatureModule.getImplementation(connection.getId());
try {
Connection sqlConn = dbConn.getConnection(connection, mode, id);
boolean connectionOkay = false;
try {
client.connection(sqlConn, connection, mode, id);
connectionOkay = true;
} catch (SQLException exc) {
throw new TestExecutionError("", DatabaseConstants.ERR_SQL_FAILURE, exc);
} finally {
dbConn.returnConnection(sqlConn, connection, mode, id, connectionOkay);
}
} catch (TestExecutionError exc) {
throw exc;
} catch (DataFileMismatchException e) {
throw new TestExecutionError("", DatabaseConstants.ERR_DATA_FILE_SCHEMA_MISMATCH, e);
} catch (Exception exc) {
throw new TestExecutionError("", exc);
}
}
public void useStatement(DatabaseConnection connection, String mode, StatementClient client) throws TestExecutionError {
useStatement(connection, mode, client, DatabaseImplementation.DATABASE);
}
public void useStatement(DatabaseConnection connection, String mode, final StatementClient client, int id) throws TestExecutionError {
useConnection(connection, mode, new ConnectionClient() {
public void connection(Connection conn, DatabaseConnection connection, String mode, int id) throws Exception {
Statement st = conn.createStatement();
try {
client.connection(conn, st, connection, mode, id);
} finally {
st.close();
}
}
}, id);
}
public void usePreparedStatement(DatabaseConnection connection, String mode, PreparedStatementClient client) throws TestExecutionError {
usePreparedStatement(connection, mode, client, DatabaseImplementation.DATABASE);
}
public void usePreparedStatement(DatabaseConnection connection, String mode, final PreparedStatementClient client, int id) throws TestExecutionError {
useConnection(connection, mode, new ConnectionClient() {
public void connection(Connection conn, DatabaseConnection connection, String mode, int id) throws Exception {
PreparedStatement st = conn.prepareStatement(client.prepareText());
try {
client.connection(conn, st, connection, mode, id);
} finally {
st.close();
}
}
}, id);
}
@Override
public void useCallableStatement(final DatabaseConnection connection, final String mode, final CallableStatementClient client, int id) throws TestExecutionError {
useConnection(connection, mode, new ConnectionClient() {
public void connection(Connection conn, DatabaseConnection connection, String mode, int id) throws Exception {
DatabaseMetaData metaData = conn.getMetaData();
if (!metaData.supportsStoredProcedures()) {
throw new IllegalStateException("Database [" + metaData.getDatabaseProductName() + "] does not support stored procedures");
}
CallableStatement st = conn.prepareCall(client.callText());
try {
client.connection(conn, st, connection, mode, id);
} finally {
st.close();
}
}
}, id);
}
@Override
public void useCallableStatement(DatabaseConnection connection, String mode, CallableStatementClient client) throws TestExecutionError {
useCallableStatement(connection, mode, client, DatabaseImplementation.DATABASE);
}
@Override
public void useResultSet(DatabaseConnection connection, String mode, ResultSetClient client, String query) throws TestExecutionError {
useResultSet(connection, mode, client, query, DatabaseImplementation.DATABASE);
}
public void useResultSetImpl(Connection conn, Statement st, DatabaseConnection connection, String mode, final ResultSetClient client, final String query, int id) throws Exception {
if (client != null) {
ResultSet rs = st.executeQuery(query);
try {
client.beginSet(conn, rs, connection, mode, id);
try {
while (rs.next()) {
client.next(conn, rs, connection, mode, id);
}
} finally {
client.endSet(conn, connection, mode, id);
}
} finally {
rs.close();
}
} else {
st.execute(query);
}
}
public void useResultSet(DatabaseConnection connection, String mode, final ResultSetClient client, final String query, int id) throws TestExecutionError {
useStatement(connection, mode, new StatementClient() {
@Override
public void connection(Connection conn, Statement st, DatabaseConnection connection, String mode, int id) throws Exception {
useResultSetImpl(conn, st, connection, mode, client, query, id);
}
});
}
@Override
public void useResultSetScript(DatabaseConnection connection, String mode, ResultSetClient client, String script) throws TestExecutionError, IOException {
useResultSetScript(connection, mode, client, script, DatabaseImplementation.DATABASE);
}
@Override
public void useResultSetScript(DatabaseConnection connection, String mode, final ResultSetClient client, String script, int id) throws TestExecutionError, IOException {
final SQLAggregator sqlagg = databaseFeatureModule.resolveSQLRef(script);
final Map context = new HashMap();
context.put("jdbc-url", databaseImplementation.getJdbcUrl(connection, mode));
context.put("jdbc-driver", databaseImplementation.getJdbcDriverClass().getName());
context.put("database-name", databaseImplementation.getDatabaseName(connection, mode));
context.put("login-name", databaseImplementation.getLoginName(connection, mode));
context.put("password", databaseImplementation.getPassword(connection, mode));
// pass on the default server name if none specified
context.put("server-name", connection.getServerName());
context.put("database-connection", connection);
context.put("database-implementation", this);
context.put("database-connection-mode", mode == null ? "default" : mode);
context.put("runtime-support", runtimeSupport);
useStatement(connection, mode, new JDBCClient.StatementClient() {
public void connection(Connection conn, Statement st, DatabaseConnection connection, String mode, int id) throws Exception {
SQLAggregator.Aggregator statementAggregator = sqlagg.getStatementAggregator();
while (statementAggregator.hasNext()) {
String sql = statementAggregator.next().getLine();
// process as velocity template with the current connection
sql = VelocityUtil.writeTemplate(sql, context);
applicationLog.info(sql);
// row-by-row use a result set client
useResultSetImpl(conn, st, connection, mode, client, sql, id);
}
}
}, id);
}
@Override
public void useResultSetScriptResource(DatabaseConnection connection, String mode, ResultSetClient client, String script) throws TestExecutionError, IOException {
useResultSetScriptResource(connection, mode, client, script, DatabaseImplementation.DATABASE);
}
@Override
public void useResultSetScriptResource(DatabaseConnection connection, String mode, ResultSetClient client, String script, int id) throws TestExecutionError, IOException {
// load the script from the classpath
ClassLoader cl = Thread.currentThread().getContextClassLoader();
URL clr = cl.getResource(script);
String scriptText = IOUtils.toString(clr);
useResultSetScript(connection, mode, client, scriptText, id);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy