/*
* $Id: ScriptRunner.java,v 1.1 2007-02-27 12:45:30 eugen Exp $
*
* Copyright (c) 2003 Brockmann Consult GmbH. All right reserved.
* http://www.brockmann-consult.de
*/
package com.bc.util.sql;
import java.io.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Logger;
public class ScriptRunner {
private Connection connection;
private LineNumberReader reader;
private StringBuffer buffer;
private ErrorHandler errorHandler;
private Logger logger;
private int lineNumber;
private String sql;
public ScriptRunner() {
errorHandler = null;
lineNumber = 0;
sql = "";
}
public Logger getLogger() {
return logger;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public ErrorHandler getErrorHandler() {
return errorHandler;
}
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
public int getLineNumber() {
return lineNumber;
}
public String getSql() {
return sql;
}
public void logError(SQLException e, String statement) {
if (logger != null) {
logger.severe("SQL script error, before or at line " + lineNumber + ": " + e.getMessage() + "\n" +
" sql=\"" + this.sql + "\"");
if (statement != null) {
logger.severe(statement);
}
}
}
public void runScriptFromText(final Connection connection, final String scriptText) throws SQLException {
try {
runScript(connection, new StringReader(scriptText));
} catch (IOException e) {
throw new IllegalStateException("unexpected I/O error");
}
}
public void runScriptFromResourcePath(final Connection connection, final String scriptResourcePath) throws SQLException {
if (logger != null) {
logger.info("executing SQL script '" + scriptResourcePath + "'...");
}
final InputStream resourceAsStream = getClass().getResourceAsStream(scriptResourcePath);
//final InputStream resourceAsStream = ClassLoader.getSystemResourceAsStream(scriptResourcePath);
final Reader reader = new InputStreamReader(resourceAsStream);
try {
runScript(connection, reader);
if (logger != null) {
logger.info("SQL script '" + scriptResourcePath + "' successfully executed");
}
} catch (IOException e) {
throw new RuntimeException("unexpected I/O error", e);
} finally {
try {
reader.close();
} catch (IOException e) {
}
}
}
public void runScript(final Connection connection, final Reader reader) throws IOException,
SQLException {
initScriptExecution(connection, reader);
try {
runScriptImpl();
} finally {
endScriptExecution();
}
}
private void runScriptImpl() throws IOException,
SQLException {
String line;
while (true) {
line = this.reader.readLine();
lineNumber = reader.getLineNumber();
if (line == null) {
break;
}
line = line.trim();
if (!line.startsWith("--")) {
buffer.append(line);
if (line.endsWith(";")) {
consumeSql();
} else {
buffer.append(' ');
}
}
}
consumeSql();
}
private void initScriptExecution(Connection connection, Reader reader) {
this.connection = connection;
this.reader = new LineNumberReader(reader);
this.buffer = new StringBuffer();
this.sql = "";
this.lineNumber = 0;
}
private void endScriptExecution() {
this.connection = null;
this.reader = null;
this.buffer = null;
}
private void consumeSql() throws SQLException {
String sql = buffer.toString().trim();
if (sql.length() > 0) {
try {
executeSql(sql);
} catch (SQLException e) {
logError(e, sql);
if (errorHandler != null) {
errorHandler.handleError(this, e);
} else {
logError(e, sql);
throw e;
}
}
}
buffer.setLength(0);
}
private void executeSql(final String sql) throws SQLException {
this.sql = sql;
final Statement stmt = connection.createStatement();
stmt.executeUpdate(this.sql);
stmt.close();
}
public static interface ErrorHandler {
void handleError(ScriptRunner scriptRunner, SQLException e) throws SQLException;
}
}