All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bitbucket.bradleysmithllc.etlunit.feature.database.JDBCClientImpl Maven / Gradle / Ivy

There is a newer version: 4.6.0-eu
Show newest version
package org.bitbucket.bradleysmithllc.etlunit.feature.database;

/*
 * #%L
 * etlunit-database
 * %%
 * Copyright (C) 2010 - 2014 bradleysmithllc
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

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