org.rimudb.ScriptRunner.java Source code

Java tutorial

Introduction

Here is the source code for org.rimudb.ScriptRunner.java

Source

/*
 * Copyright (c) 2008-2011 Simon Ritchie.
 * All rights reserved. 
 * 
 * This program is free software: you can redistribute it and/or modify 
 * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License 
 * along with this program.  If not, see http://www.gnu.org/licenses/>.
 */
package org.rimudb;

import java.io.*;
import java.sql.*;

import org.apache.commons.logging.*;
import org.rimudb.exception.*;

/**
 * 
 * @author Simon Ritchie
 * 
 */
public class ScriptRunner {
    private final static Log log = LogFactory.getLog(ScriptRunner.class);
    private String filename = null;
    private String resourceName = null;
    private Database database = null;
    private final boolean continueOnFailure;
    private String endOfQueryDelimiter = ";";

    public ScriptRunner(Database database, boolean continueOnFailure) {
        this.database = database;
        this.continueOnFailure = continueOnFailure;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public String getFilename() {
        return filename;
    }

    public void executeScript() throws Exception {
        if (getFilename() == null && getResourceName() == null) {
            throw new IOException("Either a resource name or a filename must be defined");
        }
        if (getDatabase() == null) {
            throw new RimuDBException("Database is not defined");
        }
        if (!getDatabase().isConnected()) {
            throw new RimuDBException("Database is not connected");
        }

        log.info("Executing script: " + getFilename());

        Connection connection = null;
        Statement statement = null;

        String sqlQuery = "";

        int lineNumber = 0;

        try {

            connection = getDatabase().getDatabaseConnection();
            statement = connection.createStatement();

            StringBuffer query = new StringBuffer();

            BufferedReader reader = null;
            if (getResourceName() != null) {
                InputStream is = getClass().getResourceAsStream(getResourceName());
                reader = new BufferedReader(new InputStreamReader(is));
            } else if (getFilename() != null) {
                reader = new BufferedReader(new FileReader(getFilename()));
            } else {
                throw new IllegalArgumentException("Either a resource name or a filename needs to be set");
            }

            while (reader.ready()) {
                String line = reader.readLine();

                lineNumber++;

                // Check for EOF
                if (line == null) {
                    break;
                }

                // Ignore comments
                if (isComment(line)) {
                    continue;
                }

                // Change delimiter command
                boolean changeDelimiter = line.matches("\\{delimiter=.+\\}");
                if (changeDelimiter) {
                    String s = line.substring(11);
                    int pos = s.indexOf("}");
                    String delimiter = s.substring(0, pos);
                    setEndOfQueryDelimiter(delimiter);
                    log.info("Changing to delimiter '" + delimiter + "'");
                    continue;
                }

                boolean ignoreErrorLine = (line.startsWith("{ignoreError}"));
                if (ignoreErrorLine) {
                    line = line.substring(13);
                }

                boolean endOfStatement = isEndOfStatement(line);

                if (query.length() > 0) {
                    query.append(" ");
                }
                query.append(line.trim());

                if (endOfStatement) {

                    // Remove the query delimiter
                    sqlQuery = trimQueryDelimiter(query.toString());

                    query.setLength(0);

                    // Execute the statement
                    try {
                        boolean result = statement.execute(sqlQuery);
                        if (result) {
                            log.warn("SQL statement returned a result set. [" + sqlQuery + "]");
                        } else {
                            int updateCount = statement.getUpdateCount();
                            log.info("Update count = " + updateCount + " [" + sqlQuery + "]");
                        }
                    } catch (SQLException sqle) {
                        if (!continueOnFailure && !ignoreErrorLine) {
                            throw sqle;
                        } else {
                            log.error("Line: " + lineNumber + " Error executing SQL=" + sqlQuery, sqle);
                        }
                    }

                }
            }

        } catch (SQLException e) {
            log.error("Line: " + lineNumber + " Error executing SQL=" + sqlQuery);
            throw new RimuDBException("Line: " + lineNumber + ": " + e.toString());

        } finally {
            if (statement != null) {
                try {
                    statement.close();
                } catch (Exception e) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception e) {
                }
            }
            log.info("Completed script: " + getFilename());
        }
    }

    /**
     * @param line
     * @return
     */
    private boolean isComment(String line) {
        return line.length() == 0 || line.startsWith("/*") || line.startsWith("//") || line.startsWith("#");
    }

    /**
     * @param sql
     * @return
     */
    private boolean isEndOfStatement(String s) {
        return (s.indexOf(getEndOfQueryDelimiter()) != -1);
    }

    /**
     * Trim the delimiter string from the query.
     *  
     * @param s String
     * @return String
     */
    private String trimQueryDelimiter(String s) {
        int endPos = s.indexOf(getEndOfQueryDelimiter());
        return s.substring(0, endPos).trim();
    }

    public Database getDatabase() {
        return database;
    }

    public void setEndOfQueryDelimiter(String endOfQueryDelimiter) {
        this.endOfQueryDelimiter = endOfQueryDelimiter;
    }

    public String getEndOfQueryDelimiter() {
        return endOfQueryDelimiter;
    }

    public void setResourceName(String resourceName) {
        this.resourceName = resourceName;
    }

    public String getResourceName() {
        return resourceName;
    }

}