/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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 org.apache.tools.ant.taskdefs;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.io.StringReader;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.sql.Types;
import java.util.Enumeration;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.Appendable;
import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.Union;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.KeepAliveOutputStream;
import org.apache.tools.ant.util.StringUtils;

/**
 * Executes a series of SQL statements on a database using JDBC.
 *
 * <p>Statements can
 * either be read in from a text file using the <i>src</i> attribute or from
 * between the enclosing SQL tags.</p>
 *
 * <p>Multiple statements can be provided, separated by semicolons (or the
 * defined <i>delimiter</i>). Individual lines within the statements can be
 * commented using either --, // or REM at the start of the line.</p>
 *
 * <p>The <i>autocommit</i> attribute specifies whether auto-commit should be
 * turned on or off whilst executing the statements. If auto-commit is turned
 * on each statement will be executed and committed. If it is turned off the
 * statements will all be executed as one transaction.</p>
 *
 * <p>The <i>onerror</i> attribute specifies how to proceed when an error occurs
 * during the execution of one of the statements.
 * The possible values are: <b>continue</b> execution, only show the error;
 * <b>stop</b> execution and commit transaction;
 * and <b>abort</b> execution and transaction and fail task.</p>
 *
 * @since Ant 1.2
 *
 * @ant.task name="sql" category="database"
 */
public class SQLExec extends JDBCTask {

    /**
     * delimiters we support, "normal" and "row"
     */
    public static class DelimiterType extends EnumeratedAttribute {
        /** The enumerated strings */
        public static final String NORMAL = "normal", ROW = "row";
        /** @return the enumerated strings */
        @Override
        public String[] getValues() {
            return new String[] {NORMAL, ROW};
        }
    }

    private int goodSql = 0;

    private int totalSql = 0;

    /**
     * Database connection
     */
    private Connection conn = null;

    /**
     * files to load
     */
    private Union resources;

    /**
     * SQL statement
     */
    private Statement statement = null;

    /**
     * SQL input file
     */
    private File srcFile = null;

    /**
     * SQL input command
     */
    private String sqlCommand = "";

    /**
     * SQL transactions to perform
     */
    private Vector transactions = new Vector();

    /**
     * SQL Statement delimiter
     */
    private String delimiter = ";";

    /**
     * The delimiter type indicating whether the delimiter will
     * only be recognized on a line by itself
     */
    private String delimiterType = DelimiterType.NORMAL;

    /**
     * Print SQL results.
     */
    private boolean print = false;

    /**
     * Print header columns.
     */
    private boolean showheaders = true;

    /**
     * Print SQL stats (rows affected)
     */
    private boolean showtrailers = true;

    /**
     * Results Output Resource.
     */
    private Resource output = null;

    /**
     * Output encoding.
     */
    private String outputEncoding = null;

    /**
     * Action to perform if an error is found
     */
    private String onError = "abort";

    /**
     * Encoding to use when reading SQL statements from a file
     */
    private String encoding = null;

    /**
     * Append to an existing file or overwrite it?
     */
    private boolean append = false;

    /**
     * Keep the format of a sql block?
     */
    private boolean keepformat = false;

    /**
     * Argument to Statement.setEscapeProcessing
     *
     * @since Ant 1.6
     */
    private boolean escapeProcessing = true;

    /**
     * should properties be expanded in text?
     * false for backwards compatibility
     *
     * @since Ant 1.7
     */
    private boolean expandProperties = true;

    /**
     * should we print raw BLOB data?
     * @since Ant 1.7.1
     */
    private boolean rawBlobs;

    /**
     * delimiters must match in case and whitespace is significant.
     * @since Ant 1.8.0
     */
    private boolean strictDelimiterMatching = true;

    /**
     * whether to show SQLWarnings as WARN messages.
     * @since Ant 1.8.0
     */
    private boolean showWarnings = false;

    /**
     * The column separator used when printing the results.
     *
     * <p>Defaults to ","</p>
     *
     * @since Ant 1.8.0
     */
    private String csvColumnSep = ",";

    /**
     * The character used to quote column values.
     *
     * <p>If set, columns that contain either the column separator or
     * the quote character itself will be surrounded by the quote
     * character.  The quote character itself will be doubled if it
     * appears inside of the column's value.</p>
     *
     * <p>If this value is not set (the default), no column values
     * will be quoted, not even if they contain the column
     * separator.</p>
     *
     * <p><b>Note:<b> BLOB values will never be quoted.</p>
     *
     * <p>Defaults to "not set"</p>
     *
     * @since Ant 1.8.0
     */
    private String csvQuoteChar = null;

    /**
     * Whether a warning is an error - in which case onError applies.
     * @since Ant 1.8.0
     */
    private boolean treatWarningsAsErrors = false;

    /**
     * The name of the property to set in the event of an error
     * @since Ant 1.8.0
     */
    private String errorProperty = null;

    /**
     * The name of the property to set in the event of a warning
     * @since Ant 1.8.0
     */
    private String warningProperty = null;

    /**
     * The name of the property that receives the number of rows
     * returned
     * @since Ant 1.8.0
     */
    private String rowCountProperty = null;

    /**
     * Set the name of the SQL file to be run.
     * Required unless statements are enclosed in the build file
     * @param srcFile the file containing the SQL command.
     */
    public void setSrc(File srcFile) {
        this.srcFile = srcFile;
    }

    /**
     * Enable property expansion inside nested text
     *
     * @param expandProperties if true expand properties.
     * @since Ant 1.7
     */
    public void setExpandProperties(boolean expandProperties) {
        this.expandProperties = expandProperties;
    }

    /**
     * is property expansion inside inline text enabled?
     *
     * @return true if properties are to be expanded.
     * @since Ant 1.7
     */
    public boolean getExpandProperties() {
        return expandProperties;
    }

    /**
     * Set an inline SQL command to execute.
     * NB: Properties are not expanded in this text unless {@link #expandProperties}
     * is set.
     * @param sql an inline string containing the SQL command.
     */
    public void addText(String sql) {
        //there is no need to expand properties here as that happens when Transaction.addText is
        //called; to do so here would be an error.
        this.sqlCommand += sql;
    }

    /**
     * Adds a set of files (nested fileset attribute).
     * @param set a set of files contains SQL commands, each File is run in
     *            a separate transaction.
     */
    public void addFileset(FileSet set) {
        add(set);
    }

    /**
     * Adds a collection of resources (nested element).
     * @param rc a collection of resources containing SQL commands,
     * each resource is run in a separate transaction.
     * @since Ant 1.7
     */
    public void add(ResourceCollection rc) {
        if (rc == null) {
            throw new BuildException("Cannot add null ResourceCollection");
        }
        synchronized (this) {
            if (resources == null) {
                resources = new Union();
            }
        }
        resources.add(rc);
    }

    /**
     * Add a SQL transaction to execute
     * @return a Transaction to be configured.
     */
    public Transaction createTransaction() {
        Transaction t = new Transaction();
        transactions.addElement(t);
        return t;
    }

    /**
     * Set the file encoding to use on the SQL files read in
     *
     * @param encoding the encoding to use on the files
     */
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    /**
     * Set the delimiter that separates SQL statements. Defaults to &quot;;&quot;;
     * optional
     *
     * <p>For example, set this to "go" and delimitertype to "ROW" for
     * Sybase ASE or MS SQL Server.</p>
     * @param delimiter the separator.
     */
    public void setDelimiter(String delimiter) {
        this.delimiter = delimiter;
    }

    /**
     * Set the delimiter type: "normal" or "row" (default "normal").
     *
     * <p>The delimiter type takes two values - normal and row. Normal
     * means that any occurrence of the delimiter terminate the SQL
     * command whereas with row, only a line containing just the
     * delimiter is recognized as the end of the command.</p>
     * @param delimiterType the type of delimiter - "normal" or "row".
     */
    public void setDelimiterType(DelimiterType delimiterType) {
        this.delimiterType = delimiterType.getValue();
    }

    /**
     * Print result sets from the statements;
     * optional, default false
     * @param print if true print result sets.
     */
    public void setPrint(boolean print) {
        this.print = print;
    }

    /**
     * Print headers for result sets from the
     * statements; optional, default true.
     * @param showheaders if true print headers of result sets.
     */
    public void setShowheaders(boolean showheaders) {
        this.showheaders = showheaders;
    }

    /**
     * Print trailing info (rows affected) for the SQL
     * Addresses Bug/Request #27446
     * @param showtrailers if true prints the SQL rows affected
     * @since Ant 1.7
     */
    public void setShowtrailers(boolean showtrailers) {
        this.showtrailers = showtrailers;
    }

    /**
     * Set the output file;
     * optional, defaults to the Ant log.
     * @param output the output file to use for logging messages.
     */
    public void setOutput(File output) {
        setOutput(new FileResource(getProject(), output));
    }

    /**
     * Set the output Resource;
     * optional, defaults to the Ant log.
     * @param output the output Resource to store results.
     * @since Ant 1.8
     */
    public void setOutput(Resource output) {
        this.output = output;
    }

    /**
     * The encoding to use when writing the result to a resource.
     * <p>Default's to the platform's default encoding</p>
     * @param outputEncoding the name of the encoding or null for the
     * platform's default encoding
     * @since Ant 1.9.4
     */
    public void setOutputEncoding(String outputEncoding) {
        this.outputEncoding = outputEncoding;
    }

    /**
     * whether output should be appended to or overwrite
     * an existing file.  Defaults to false.
     *
     * @since Ant 1.5
     * @param append if true append to an existing file.
     */
    public void setAppend(boolean append) {
        this.append = append;
    }


    /**
     * Action to perform when statement fails: continue, stop, or abort
     * optional; default &quot;abort&quot;
     * @param action the action to perform on statement failure.
     */
    public void setOnerror(OnError action) {
        this.onError = action.getValue();
    }

    /**
     * whether or not format should be preserved.
     * Defaults to false.
     *
     * @param keepformat The keepformat to set
     */
    public void setKeepformat(boolean keepformat) {
        this.keepformat = keepformat;
    }

    /**
     * Set escape processing for statements.
     * @param enable if true enable escape processing, default is true.
     * @since Ant 1.6
     */
    public void setEscapeProcessing(boolean enable) {
        escapeProcessing = enable;
    }

    /**
     * Set whether to print raw BLOBs rather than their string (hex) representations.
     * @param rawBlobs whether to print raw BLOBs.
     * @since Ant 1.7.1
     */
    public void setRawBlobs(boolean rawBlobs) {
        this.rawBlobs = rawBlobs;
    }

    /**
     * If false, delimiters will be searched for in a case-insensitive
     * manner (i.e. delimiter="go" matches "GO") and surrounding
     * whitespace will be ignored (delimiter="go" matches "GO ").
     * @since Ant 1.8.0
     */
    public void setStrictDelimiterMatching(boolean b) {
        strictDelimiterMatching = b;
    }

    /**
     * whether to show SQLWarnings as WARN messages.
     * @since Ant 1.8.0
     */
    public void setShowWarnings(boolean b) {
        showWarnings = b;
    }

    /**
     * Whether a warning is an error - in which case onError applies.
     * @since Ant 1.8.0
     */
    public void setTreatWarningsAsErrors(boolean b) {
        treatWarningsAsErrors =  b;
    }

    /**
     * The column separator used when printing the results.
     *
     * <p>Defaults to ","</p>
     *
     * @since Ant 1.8.0
     */
    public void setCsvColumnSeparator(String s) {
        csvColumnSep = s;
    }

    /**
     * The character used to quote column values.
     *
     * <p>If set, columns that contain either the column separator or
     * the quote character itself will be surrounded by the quote
     * character.  The quote character itself will be doubled if it
     * appears inside of the column's value.</p>
     *
     * <p>If this value is not set (the default), no column values
     * will be quoted, not even if they contain the column
     * separator.</p>
     *
     * <p><b>Note:</b> BLOB values will never be quoted.</p>
     *
     * <p>Defaults to "not set"</p>
     *
     * @since Ant 1.8.0
     */
    public void setCsvQuoteCharacter(String s) {
        if (s != null && s.length() > 1) {
            throw new BuildException("The quote character must be a single"
                                     + " character.");
        }
        csvQuoteChar = s;
    }

    /**
     * Property to set to "true" if a statement throws an error.
     *
     * @param errorProperty the name of the property to set in the
     * event of an error.
     * @since Ant 1.8.0
     */
    public void setErrorProperty(String errorProperty) {
        this.errorProperty = errorProperty;
    }

    /**
     * Property to set to "true" if a statement produces a warning.
     *
     * @param warningProperty the name of the property to set in the
     * event of a warning.
     * @since Ant 1.8.0
     */
    public void setWarningProperty(String warningProperty) {
        this.warningProperty = warningProperty;
    }

    /**
     * Sets a given property to the number of rows in the first
     * statement that returned a row count.
     * @since Ant 1.8.0
     */
    public void setRowCountProperty(String rowCountProperty) {
        this.rowCountProperty = rowCountProperty;
    }

    /**
     * Load the sql file and then execute it
     * @throws BuildException on error.
     */
    @Override
    public void execute() throws BuildException {
        Vector savedTransaction = (Vector) transactions.clone();
        String savedSqlCommand = sqlCommand;

        sqlCommand = sqlCommand.trim();

        try {
            if (srcFile == null && sqlCommand.length() == 0 && resources == null) {
                if (transactions.size() == 0) {
                    throw new BuildException("Source file or resource collection, "
                                             + "transactions or sql statement "
                                             + "must be set!", getLocation());
                }
            }

            if (srcFile != null && !srcFile.isFile()) {
                throw new BuildException("Source file " + srcFile
                        + " is not a file!", getLocation());
            }

            if (resources != null) {
                // deal with the resources
                for (Resource r : resources) {
                    // Make a transaction for each resource
                    Transaction t = createTransaction();
                    t.setSrcResource(r);
                }
            }

            // Make a transaction group for the outer command
            Transaction t = createTransaction();
            t.setSrc(srcFile);
            t.addText(sqlCommand);

            if (getConnection() == null) {
                // not a valid rdbms
                return;
            }

            try {
                PrintStream out = KeepAliveOutputStream.wrapSystemOut();
                try {
                    if (output != null) {
                        log("Opening PrintStream to output Resource " + output, Project.MSG_VERBOSE);
                        OutputStream os = null;
                        FileProvider fp =
                            output.as(FileProvider.class);
                        if (fp != null) {
                            os = new FileOutputStream(fp.getFile(), append);
                        } else {
                            if (append) {
                                Appendable a =
                                    output.as(Appendable.class);
                                if (a != null) {
                                    os = a.getAppendOutputStream();
                                }
                            }
                            if (os == null) {
                                os = output.getOutputStream();
                                if (append) {
                                    log("Ignoring append=true for non-appendable"
                                        + " resource " + output,
                                        Project.MSG_WARN);
                                }
                            }
                        }
                        if (outputEncoding != null) {
                            out = new PrintStream(new BufferedOutputStream(os),
                                                  false, outputEncoding);
                        } else {
                            out = new PrintStream(new BufferedOutputStream(os));
                        }
                    }

                    // Process all transactions
                    for (Enumeration e = transactions.elements();
                         e.hasMoreElements();) {

                        ((Transaction) e.nextElement()).runTransaction(out);
                        if (!isAutocommit()) {
                            log("Committing transaction", Project.MSG_VERBOSE);
                            getConnection().commit();
                        }
                    }
                } finally {
                    FileUtils.close(out);
                }
            } catch (IOException e) {
                closeQuietly();
                setErrorProperty();
                if (onError.equals("abort")) {
                    throw new BuildException(e, getLocation());
                }
            } catch (SQLException e) {
                closeQuietly();
                setErrorProperty();
                if (onError.equals("abort")) {
                    throw new BuildException(e, getLocation());
                }
            } finally {
                try {
                    if (getStatement() != null) {
                        getStatement().close();
                    }
                } catch (SQLException ex) {
                    // ignore
                }
                try {
                    if (getConnection() != null) {
                        getConnection().close();
                    }
                } catch (SQLException ex) {
                    // ignore
                }
            }

            log(goodSql + " of " + totalSql + " SQL statements executed successfully");
        } finally {
            transactions = savedTransaction;
            sqlCommand = savedSqlCommand;
        }
    }

    /**
     * read in lines and execute them
     * @param reader the reader contains sql lines.
     * @param out the place to output results.
     * @throws SQLException on sql problems
     * @throws IOException on io problems
     */
    protected void runStatements(Reader reader, PrintStream out)
        throws SQLException, IOException {
        StringBuffer sql = new StringBuffer();
        String line;

        BufferedReader in = new BufferedReader(reader);

        while ((line = in.readLine()) != null) {
            if (!keepformat) {
                line = line.trim();
            }
            if (expandProperties) {
                line = getProject().replaceProperties(line);
            }
            if (!keepformat) {
                if (line.startsWith("//")) {
                    continue;
                }
                if (line.startsWith("--")) {
                    continue;
                }
                StringTokenizer st = new StringTokenizer(line);
                if (st.hasMoreTokens()) {
                    String token = st.nextToken();
                    if ("REM".equalsIgnoreCase(token)) {
                        continue;
                    }
                }
            }

            sql.append(keepformat ? "\n" : " ").append(line);

            // SQL defines "--" as a comment to EOL
            // and in Oracle it may contain a hint
            // so we cannot just remove it, instead we must end it
            if (!keepformat && line.indexOf("--") >= 0) {
                sql.append("\n");
            }
            int lastDelimPos = lastDelimiterPosition(sql, line);
            if (lastDelimPos > -1) {
                execSQL(sql.substring(0, lastDelimPos), out);
                sql.replace(0, sql.length(), "");
            }
        }
        // Catch any statements not followed by ;
        if (sql.length() > 0) {
            execSQL(sql.toString(), out);
        }
    }

    /**
     * Exec the sql statement.
     * @param sql the SQL statement to execute
     * @param out the place to put output
     * @throws SQLException on SQL problems
     */
    protected void execSQL(String sql, PrintStream out) throws SQLException {
        // Check and ignore empty statements
        if ("".equals(sql.trim())) {
            return;
        }

        ResultSet resultSet = null;
        try {
            totalSql++;
            log("SQL: " + sql, Project.MSG_VERBOSE);

            boolean ret;
            int updateCount = 0, updateCountTotal = 0;

            ret = getStatement().execute(sql);
            updateCount = getStatement().getUpdateCount();
            do {
                if (updateCount != -1) {
                    updateCountTotal += updateCount;
                }
                if (ret) {
                    resultSet = getStatement().getResultSet();
                    printWarnings(resultSet.getWarnings(), false);
                    resultSet.clearWarnings();
                    if (print) {
                        printResults(resultSet, out);
                    }
                }
                ret = getStatement().getMoreResults();
                updateCount = getStatement().getUpdateCount();
            } while (ret || updateCount != -1);

            printWarnings(getStatement().getWarnings(), false);
            getStatement().clearWarnings();

            log(updateCountTotal + " rows affected", Project.MSG_VERBOSE);
            if (updateCountTotal != -1) {
                setRowCountProperty(updateCountTotal);
            }

            if (print && showtrailers) {
                out.println(updateCountTotal + " rows affected");
            }
            SQLWarning warning = getConnection().getWarnings();
            printWarnings(warning, true);
            getConnection().clearWarnings();
            goodSql++;
        } catch (SQLException e) {
            log("Failed to execute: " + sql, Project.MSG_ERR);
            setErrorProperty();
            if (!onError.equals("abort")) {
                log(e.toString(), Project.MSG_ERR);
            }
            if (!onError.equals("continue")) {
                throw e;
            }
        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    //ignore
                }
            }
        }
    }

    /**
     * print any results in the statement
     * @deprecated since 1.6.x.
     *             Use {@link #printResults(java.sql.ResultSet, java.io.PrintStream)
     *             the two arg version} instead.
     * @param out the place to print results
     * @throws SQLException on SQL problems.
     */
    @Deprecated
    protected void printResults(PrintStream out) throws SQLException {
        ResultSet rs = getStatement().getResultSet();
        try {
            printResults(rs, out);
        } finally {
            if (rs != null) {
                rs.close();
            }
        }
    }

    /**
     * print any results in the result set.
     * @param rs the resultset to print information about
     * @param out the place to print results
     * @throws SQLException on SQL problems.
     * @since Ant 1.6.3
     */
    protected void printResults(ResultSet rs, PrintStream out) throws SQLException {
        if (rs != null) {
            log("Processing new result set.", Project.MSG_VERBOSE);
            ResultSetMetaData md = rs.getMetaData();
            int columnCount = md.getColumnCount();
            if (columnCount > 0) {
                if (showheaders) {
                    out.print(md.getColumnName(1));
                    for (int col = 2; col <= columnCount; col++) {
                         out.print(csvColumnSep);
                         out.print(maybeQuote(md.getColumnName(col)));
                    }
                    out.println();
                }
                while (rs.next()) {
                    printValue(rs, 1, out);
                    for (int col = 2; col <= columnCount; col++) {
                        out.print(csvColumnSep);
                        printValue(rs, col, out);
                    }
                    out.println();
                    printWarnings(rs.getWarnings(), false);
                }
            }
        }
        out.println();
    }

    private void printValue(ResultSet rs, int col, PrintStream out)
            throws SQLException {
        if (rawBlobs && rs.getMetaData().getColumnType(col) == Types.BLOB) {
            Blob blob = rs.getBlob(col);
            if (blob != null) {
                new StreamPumper(rs.getBlob(col).getBinaryStream(), out).run();
            }
        } else {
            out.print(maybeQuote(rs.getString(col)));
        }
    }

    private String maybeQuote(String s) {
        if (csvQuoteChar == null || s == null
            || (s.indexOf(csvColumnSep) == -1 && s.indexOf(csvQuoteChar) == -1)
            ) {
            return s;
        }
        StringBuffer sb = new StringBuffer(csvQuoteChar);
        int len = s.length();
        char q = csvQuoteChar.charAt(0);
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (c == q) {
                sb.append(q);
            }
            sb.append(c);
        }
        return sb.append(csvQuoteChar).toString();
    }

    /*
     * Closes an unused connection after an error and doesn't rethrow
     * a possible SQLException
     * @since Ant 1.7
     */
    private void closeQuietly() {
        if (!isAutocommit() && getConnection() != null && onError.equals("abort")) {
            try {
                getConnection().rollback();
            } catch (SQLException ex) {
                // ignore
            }
        }
    }


    /**
     * Caches the connection returned by the base class's getConnection method.
     *
     * <p>Subclasses that need to provide a different connection than
     * the base class would, should override this method but keep in
     * mind that this class expects to get the same connection
     * instance on consecutive calls.</p>
     *
     * <p>returns null if the connection does not connect to the
     * expected RDBMS.</p>
     */
    @Override
    protected Connection getConnection() {
        if (conn == null) {
            conn = super.getConnection();
            if (!isValidRdbms(conn)) {
                conn = null;
            }
        }
        return conn;
    }

    /**
     * Creates and configures a Statement instance which is then
     * cached for subsequent calls.
     *
     * <p>Subclasses that want to provide different Statement
     * instances, should override this method but keep in mind that
     * this class expects to get the same connection instance on
     * consecutive calls.</p>
     */
    protected Statement getStatement() throws SQLException {
        if (statement == null) {
            statement = getConnection().createStatement();
            statement.setEscapeProcessing(escapeProcessing);
        }

        return statement;
    }

    /**
     * The action a task should perform on an error,
     * one of "continue", "stop" and "abort"
     */
    public static class OnError extends EnumeratedAttribute {
        /** @return the enumerated values */
        @Override
        public String[] getValues() {
            return new String[] {"continue", "stop", "abort"};
        }
    }

    /**
     * Contains the definition of a new transaction element.
     * Transactions allow several files or blocks of statements
     * to be executed using the same JDBC connection and commit
     * operation in between.
     */
    public class Transaction {
        private Resource tSrcResource = null;
        private String tSqlCommand = "";

        /**
         * Set the source file attribute.
         * @param src the source file
         */
        public void setSrc(File src) {
            //there are places (in this file, and perhaps elsewhere, where it is assumed
            //that null is an acceptable parameter.
            if (src != null) {
                setSrcResource(new FileResource(src));
            }
        }

        /**
         * Set the source resource attribute.
         * @param src the source file
         * @since Ant 1.7
         */
        public void setSrcResource(Resource src) {
            if (tSrcResource != null) {
                throw new BuildException("only one resource per transaction");
            }
            tSrcResource = src;
        }

        /**
         * Set inline text
         * @param sql the inline text
         */
        public void addText(String sql) {
            if (sql != null) {
                this.tSqlCommand += sql;
            }
        }

        /**
         * Set the source resource.
         * @param a the source resource collection.
         * @since Ant 1.7
         */
        public void addConfigured(ResourceCollection a) {
            if (a.size() != 1) {
                throw new BuildException("only single argument resource "
                                         + "collections are supported.");
            }
            setSrcResource(a.iterator().next());
        }

        /**
         *
         */
        private void runTransaction(PrintStream out)
            throws IOException, SQLException {
            if (tSqlCommand.length() != 0) {
                log("Executing commands", Project.MSG_INFO);
                runStatements(new StringReader(tSqlCommand), out);
            }

            if (tSrcResource != null) {
                log("Executing resource: " + tSrcResource.toString(),
                    Project.MSG_INFO);
                InputStream is = null;
                Reader reader = null;
                try {
                    is = tSrcResource.getInputStream();
                    reader = (encoding == null) ? new InputStreamReader(is)
                        : new InputStreamReader(is, encoding);
                    runStatements(reader, out);
                } finally {
                    FileUtils.close(is);
                    FileUtils.close(reader);
                }
            }
        }
    }

    public int lastDelimiterPosition(StringBuffer buf, String currentLine) {
        if (strictDelimiterMatching) {
            if ((delimiterType.equals(DelimiterType.NORMAL)
                 && StringUtils.endsWith(buf, delimiter)) ||
                (delimiterType.equals(DelimiterType.ROW)
                 && currentLine.equals(delimiter))) {
                return buf.length() - delimiter.length();
            }
            // no match
            return -1;
        } else {
            String d = delimiter.trim().toLowerCase(Locale.ENGLISH);
            if (delimiterType.equals(DelimiterType.NORMAL)) {
                // still trying to avoid wasteful copying, see
                // StringUtils.endsWith
                int endIndex = delimiter.length() - 1;
                int bufferIndex = buf.length() - 1;
                while (bufferIndex >= 0
                       && Character.isWhitespace(buf.charAt(bufferIndex))) {
                    --bufferIndex;
                }
                if (bufferIndex < endIndex) {
                    return -1;
                }
                while (endIndex >= 0) {
                    if (buf.substring(bufferIndex, bufferIndex + 1)
                        .toLowerCase(Locale.ENGLISH).charAt(0)
                        != d.charAt(endIndex)) {
                        return -1;
                    }
                    bufferIndex--;
                    endIndex--;
                }
                return bufferIndex + 1;
            } else {
                return currentLine.trim().toLowerCase(Locale.ENGLISH).equals(d)
                    ? buf.length() - currentLine.length() : -1;
            }
        }
    }

    private void printWarnings(SQLWarning warning, boolean force)
        throws SQLException {
        SQLWarning initialWarning = warning;
        if (showWarnings || force) {
            while (warning != null) {
                log(warning + " sql warning",
                    showWarnings ? Project.MSG_WARN : Project.MSG_VERBOSE);
                warning = warning.getNextWarning();
            }
        }
        if (initialWarning != null) {
            setWarningProperty();
        }
        if (treatWarningsAsErrors && initialWarning != null) {
            throw initialWarning;
        }
    }

    protected final void setErrorProperty() {
        setProperty(errorProperty, "true");
    }

    protected final void setWarningProperty() {
        setProperty(warningProperty, "true");
    }

    protected final void setRowCountProperty(int rowCount) {
        setProperty(rowCountProperty, Integer.toString(rowCount));
    }

    private void setProperty(String name, String value) {
        if (name != null) {
            getProject().setNewProperty(name, value);
        }
    }
}
