mirror of https://github.com/apache/cloudstack.git
233 lines
7.9 KiB
Java
233 lines
7.9 KiB
Java
/*
|
|
* Slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class
|
|
* from the iBATIS Apache project. Only removed dependency on Resource class
|
|
* and a constructor
|
|
*/
|
|
/*
|
|
* Copyright 2004 Clinton Begin
|
|
*
|
|
* 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.
|
|
*/
|
|
package com.cloud.utils.db;
|
|
|
|
import java.io.IOException;
|
|
import java.io.LineNumberReader;
|
|
import java.io.Reader;
|
|
import java.sql.Connection;
|
|
import java.sql.ResultSet;
|
|
import java.sql.ResultSetMetaData;
|
|
import java.sql.SQLException;
|
|
import java.sql.Statement;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
/**
|
|
* Tool to run database scripts
|
|
*/
|
|
public class ScriptRunner {
|
|
private static Logger s_logger = Logger.getLogger(ScriptRunner.class);
|
|
|
|
private static final String DEFAULT_DELIMITER = ";";
|
|
|
|
private Connection connection;
|
|
|
|
private boolean stopOnError;
|
|
private boolean autoCommit;
|
|
private boolean verbosity = true;
|
|
|
|
private String delimiter = DEFAULT_DELIMITER;
|
|
private boolean fullLineDelimiter = false;
|
|
|
|
private StringBuffer _logBuffer = new StringBuffer();
|
|
|
|
/**
|
|
* Default constructor
|
|
*/
|
|
public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) {
|
|
this.connection = connection;
|
|
this.autoCommit = autoCommit;
|
|
this.stopOnError = stopOnError;
|
|
}
|
|
|
|
public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError, boolean verbosity) {
|
|
this.connection = connection;
|
|
this.autoCommit = autoCommit;
|
|
this.stopOnError = stopOnError;
|
|
this.verbosity = verbosity;
|
|
}
|
|
|
|
public void setDelimiter(String delimiter, boolean fullLineDelimiter) {
|
|
this.delimiter = delimiter;
|
|
this.fullLineDelimiter = fullLineDelimiter;
|
|
}
|
|
|
|
/**
|
|
* Runs an SQL script (read in using the Reader parameter)
|
|
*
|
|
* @param reader
|
|
* - the source of the script
|
|
*/
|
|
public void runScript(Reader reader) throws IOException, SQLException {
|
|
try {
|
|
boolean originalAutoCommit = connection.getAutoCommit();
|
|
try {
|
|
if (originalAutoCommit != this.autoCommit) {
|
|
connection.setAutoCommit(this.autoCommit);
|
|
}
|
|
runScript(connection, reader);
|
|
} finally {
|
|
connection.setAutoCommit(originalAutoCommit);
|
|
}
|
|
} catch (IOException e) {
|
|
throw e;
|
|
} catch (SQLException e) {
|
|
throw e;
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Error running script. Cause: " + e, e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Runs an SQL script (read in using the Reader parameter) using the
|
|
* connection passed in
|
|
*
|
|
* @param conn
|
|
* - the connection to use for the script
|
|
* @param reader
|
|
* - the source of the script
|
|
* @throws SQLException
|
|
* if any SQL errors occur
|
|
* @throws IOException
|
|
* if there is an error reading from the Reader
|
|
*/
|
|
private void runScript(Connection conn, Reader reader) throws IOException, SQLException {
|
|
StringBuffer command = null;
|
|
try {
|
|
LineNumberReader lineReader = new LineNumberReader(reader);
|
|
String line = null;
|
|
while ((line = lineReader.readLine()) != null) {
|
|
if (command == null) {
|
|
command = new StringBuffer();
|
|
}
|
|
String trimmedLine = line.trim();
|
|
if (trimmedLine.startsWith("--")) {
|
|
println(trimmedLine);
|
|
} else if (trimmedLine.length() < 1 || trimmedLine.startsWith("//")) {
|
|
// Do nothing
|
|
} else if (trimmedLine.length() < 1 || trimmedLine.startsWith("--")) {
|
|
// Do nothing
|
|
} else if (trimmedLine.length() < 1 || trimmedLine.startsWith("#")) {
|
|
// Do nothing
|
|
} else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter()) || fullLineDelimiter && trimmedLine.equals(getDelimiter())) {
|
|
command.append(line.substring(0, line.lastIndexOf(getDelimiter())));
|
|
command.append(" ");
|
|
Statement statement = conn.createStatement();
|
|
|
|
println(command);
|
|
|
|
boolean hasResults = false;
|
|
if (stopOnError) {
|
|
hasResults = statement.execute(command.toString());
|
|
} else {
|
|
try {
|
|
statement.execute(command.toString());
|
|
} catch (SQLException e) {
|
|
e.fillInStackTrace();
|
|
printlnError("Error executing: " + command);
|
|
printlnError(e);
|
|
}
|
|
}
|
|
|
|
if (autoCommit && !conn.getAutoCommit()) {
|
|
conn.commit();
|
|
}
|
|
|
|
ResultSet rs = statement.getResultSet();
|
|
if (hasResults && rs != null) {
|
|
ResultSetMetaData md = rs.getMetaData();
|
|
int cols = md.getColumnCount();
|
|
for (int i = 0; i < cols; i++) {
|
|
String name = md.getColumnLabel(i);
|
|
print(name + "\t");
|
|
}
|
|
println("");
|
|
while (rs.next()) {
|
|
for (int i = 1; i <= cols; i++) {
|
|
String value = rs.getString(i);
|
|
print(value + "\t");
|
|
}
|
|
println("");
|
|
}
|
|
}
|
|
|
|
command = null;
|
|
try {
|
|
statement.close();
|
|
} catch (Exception e) {
|
|
// Ignore to workaround a bug in Jakarta DBCP
|
|
}
|
|
Thread.yield();
|
|
} else {
|
|
int idx = line.indexOf("--");
|
|
if (idx != -1)
|
|
command.append(line.substring(0, idx));
|
|
else
|
|
command.append(line);
|
|
command.append(" ");
|
|
}
|
|
}
|
|
if (!autoCommit) {
|
|
conn.commit();
|
|
}
|
|
} catch (SQLException e) {
|
|
e.fillInStackTrace();
|
|
printlnError("Error executing: " + command);
|
|
printlnError(e);
|
|
throw e;
|
|
} catch (IOException e) {
|
|
e.fillInStackTrace();
|
|
printlnError("Error executing: " + command);
|
|
printlnError(e);
|
|
throw e;
|
|
} finally {
|
|
conn.rollback();
|
|
flush();
|
|
}
|
|
}
|
|
|
|
private String getDelimiter() {
|
|
return delimiter;
|
|
}
|
|
|
|
private void print(Object o) {
|
|
_logBuffer.append(o);
|
|
}
|
|
|
|
private void println(Object o) {
|
|
_logBuffer.append(o);
|
|
if (verbosity)
|
|
s_logger.debug(_logBuffer.toString());
|
|
_logBuffer = new StringBuffer();
|
|
}
|
|
|
|
private void printlnError(Object o) {
|
|
s_logger.error("" + o);
|
|
}
|
|
|
|
private void flush() {
|
|
if (_logBuffer.length() > 0) {
|
|
s_logger.debug(_logBuffer.toString());
|
|
_logBuffer = new StringBuffer();
|
|
}
|
|
}
|
|
} |