Package org.apache.openjpa.lib.jdbc

Source Code of org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection

/*
* 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.openjpa.lib.jdbc;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Array;
import java.sql.BatchUpdateException;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.J2DoPrivHelper;

/**
* A {@link ConnectionDecorator} that creates logging connections and
* {@link ReportingSQLException}s.
*
* @author Marc Prud'hommeaux
* @nojavadoc
*/
public class LoggingConnectionDecorator implements ConnectionDecorator {

    private static final String SEP = J2DoPrivHelper.getLineSeparator();

    private static final int WARN_IGNORE = 0;
    private static final int WARN_LOG_TRACE = 1;
    private static final int WARN_LOG_INFO = 2;
    private static final int WARN_LOG_WARN = 3;
    private static final int WARN_LOG_ERROR = 4;
    private static final int WARN_THROW = 5;
    private static final int WARN_HANDLE = 6;
    private static final String[] WARNING_ACTIONS = new String[7];

    static {
        WARNING_ACTIONS[WARN_IGNORE] = "ignore";
        WARNING_ACTIONS[WARN_LOG_TRACE] = "trace";
        WARNING_ACTIONS[WARN_LOG_INFO] = "info";
        WARNING_ACTIONS[WARN_LOG_WARN] = "warn";
        WARNING_ACTIONS[WARN_LOG_ERROR] = "error";
        WARNING_ACTIONS[WARN_THROW] = "throw";
        WARNING_ACTIONS[WARN_HANDLE] = "handle";
    }

    private final DataSourceLogs _logs = new DataSourceLogs();
    private SQLFormatter _formatter;
    private boolean _prettyPrint;
    private int _prettyPrintLineLength = 60;
    private int _warningAction = WARN_IGNORE;
    private SQLWarningHandler _warningHandler;
    private boolean _trackParameters = true;

    /**
     * If set to <code>true</code>, pretty-print SQL by running it
     * through {@link SQLFormatter#prettyPrint}. If
     * <code>false</code>, don't pretty-print, and output SQL logs in
     * a single line. Pretty-printed SQL can be easier for a human to
     * read, but is harder to parse with tools like grep.
     */
    public void setPrettyPrint(boolean prettyPrint) {
        _prettyPrint = prettyPrint;
        if (_formatter == null && _prettyPrint) {
            _formatter = new SQLFormatter();
            _formatter.setLineLength(_prettyPrintLineLength);
        } else if (!_prettyPrint)
            _formatter = null;
    }

    /**
     * @see #setPrettyPrint
     */
    public boolean getPrettyPrint() {
        return _prettyPrint;
    }

    /**
     * The number of characters to print per line when
     * pretty-printing of SQL is enabled. Defaults to 60 to provide
     * some space for any ant-related characters on the left of a
     * standard 80-character display.
     */
    public void setPrettyPrintLineLength(int length) {
        _prettyPrintLineLength = length;
        if (_formatter != null)
            _formatter.setLineLength(length);
    }

    /**
     * @see #setPrettyPrintLineLength
     */
    public int getPrettyPrintLineLength() {
        return _prettyPrintLineLength;
    }

    /**
     * Whether to track parameters for the purposes of reporting exceptions.
     */
    public void setTrackParameters(boolean trackParameters) {
        _trackParameters = trackParameters;
    }

    /**
     * Whether to track parameters for the purposes of reporting exceptions.
     */
    public boolean getTrackParameters() {
        return _trackParameters;
    }

    /**
     * What to do with SQL warnings.
     */
    public void setWarningAction(String warningAction) {
        int index = Arrays.asList(WARNING_ACTIONS).indexOf(warningAction);
        if (index < 0)
            index = WARN_IGNORE;
        _warningAction = index;
    }

    /**
     * What to do with SQL warnings.
     */
    public String getWarningAction() {
        return WARNING_ACTIONS[_warningAction];
    }

    /**
     * What to do with SQL warnings.
     */
    public void setWarningHandler(SQLWarningHandler warningHandler) {
        _warningHandler = warningHandler;
    }

    /**
     * What to do with SQL warnings.
     */
    public SQLWarningHandler getWarningHandler() {
        return _warningHandler;
    }

    /**
     * The log to write to.
     */
    public DataSourceLogs getLogs() {
        return _logs;
    }

    public Connection decorate(Connection conn) throws SQLException {
        return new LoggingConnection(conn);
    }

    /**
     * Include SQL in exception.
     */
    private SQLException wrap(SQLException sqle, Statement stmnt) {
        if (sqle instanceof ReportingSQLException)
            return (ReportingSQLException) sqle;
        return new ReportingSQLException(sqle, stmnt);
    }

    /**
     * Include SQL in exception.
     */
    private SQLException wrap(SQLException sqle, String sql) {
        if (sqle instanceof ReportingSQLException)
            return (ReportingSQLException) sqle;
        return new ReportingSQLException(sqle, sql);
    }

    /**
     * Interface that allows customization of what to do when
     * {@link SQLWarning}s occur.
     */
    public static interface SQLWarningHandler {

        public void handleWarning(SQLWarning warning) throws SQLException;
    }

    /**
     * Logging connection.
     */
    private class LoggingConnection extends DelegatingConnection {

        public LoggingConnection(Connection conn) throws SQLException {
            super(conn);
        }

        protected PreparedStatement prepareStatement(String sql, boolean wrap)
            throws SQLException {
            try {
                PreparedStatement stmnt = super.prepareStatement(sql, false);
                return new LoggingPreparedStatement(stmnt, sql);
            } catch (SQLException se) {
                throw wrap(se, sql);
            }
        }

        protected PreparedStatement prepareStatement(String sql, int rsType,
            int rsConcur, boolean wrap) throws SQLException {
            try {
                PreparedStatement stmnt = super.prepareStatement
                    (sql, rsType, rsConcur, false);
                return new LoggingPreparedStatement(stmnt, sql);
            } catch (SQLException se) {
                throw wrap(se, sql);
            }
        }

        protected Statement createStatement(boolean wrap) throws SQLException {
            Statement stmnt = super.createStatement(false);
            return new LoggingStatement(stmnt);
        }

        protected Statement createStatement(int type, int concurrency,
            boolean wrap) throws SQLException {
            Statement stmnt = super.createStatement(type, concurrency, false);
            return new LoggingStatement(stmnt);
        }

        public void commit() throws SQLException {
            long start = System.currentTimeMillis();
            try {
                super.commit();
            } finally {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("commit", start, this);
                handleSQLWarning();
            }
        }

        public void rollback() throws SQLException {
            long start = System.currentTimeMillis();
            try {
                super.rollback();
            } finally {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("rollback", start, this);
                handleSQLWarning();
            }
        }

        public void close() throws SQLException {
            long start = System.currentTimeMillis();
            try {
                super.close();
            } finally {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("close", start, this);
            }
        }

        public Savepoint setSavepoint() throws SQLException {
            long start = System.currentTimeMillis();
            try {
                return super.setSavepoint();
            } finally {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("savepoint", start, this);
                handleSQLWarning();
            }
        }

        public Savepoint setSavepoint(String name) throws SQLException {
            long start = System.currentTimeMillis();
            try {
                return super.setSavepoint(name);
            } finally {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("savepoint: " + name, start, this);
                handleSQLWarning();
            }
        }

        public void rollback(Savepoint savepoint) throws SQLException {
            long start = System.currentTimeMillis();
            try {
                super.rollback(savepoint);
            } finally {
                if (_logs.isJDBCEnabled()) {
                    String name = null;
                    try {
                        name = savepoint.getSavepointName();
                    } catch (SQLException sqe) {
                        name = String.valueOf(savepoint.getSavepointId());
                    }
                    _logs.logJDBC("rollback: " + name, start, this);
                }
                handleSQLWarning();
            }
        }

        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
            long start = System.currentTimeMillis();
            try {
                super.releaseSavepoint(savepoint);
            } finally {
                if (_logs.isJDBCEnabled()) {
                    String name = null;
                    try {
                        name = savepoint.getSavepointName();
                    } catch (SQLException sqe) {
                        name = String.valueOf(savepoint.getSavepointId());
                    }
                    _logs.logJDBC("release: " + name, start, this);
                }
                handleSQLWarning();
            }
        }

        protected Statement createStatement(int resultSetType,
            int resultSetConcurrency, int resultSetHoldability, boolean wrap)
            throws SQLException {
            Statement stmnt = super.createStatement(resultSetType,
                resultSetConcurrency, resultSetHoldability, false);
            handleSQLWarning();
            return new LoggingStatement(stmnt);
        }

        protected PreparedStatement prepareStatement(String sql,
            int resultSetType, int resultSetConcurrency,
            int resultSetHoldability, boolean wrap) throws SQLException {
            try {
                PreparedStatement stmnt = super.prepareStatement
                    (sql, resultSetType, resultSetConcurrency,
                        resultSetHoldability, false);
                handleSQLWarning();
                return new LoggingPreparedStatement(stmnt, sql);
            } catch (SQLException se) {
                throw wrap(se, sql);
            }
        }

        protected PreparedStatement prepareStatement(String sql,
            int autoGeneratedKeys, boolean wrap) throws SQLException {
            try {
                PreparedStatement stmnt = super.prepareStatement
                    (sql, autoGeneratedKeys, false);
                handleSQLWarning();
                return new LoggingPreparedStatement(stmnt, sql);
            } catch (SQLException se) {
                throw wrap(se, sql);
            }
        }

        protected PreparedStatement prepareStatement(String sql,
            int[] columnIndexes, boolean wrap) throws SQLException {
            try {
                PreparedStatement stmnt = super.prepareStatement
                    (sql, columnIndexes, false);
                handleSQLWarning();
                return new LoggingPreparedStatement(stmnt, sql);
            } catch (SQLException se) {
                throw wrap(se, sql);
            }
        }

        protected PreparedStatement prepareStatement(String sql,
            String[] columnNames, boolean wrap) throws SQLException {
            try {
                PreparedStatement stmnt = super.prepareStatement
                    (sql, columnNames, false);
                handleSQLWarning();
                return new LoggingPreparedStatement(stmnt, sql);
            } catch (SQLException se) {
                throw wrap(se, sql);
            }
        }

        protected DatabaseMetaData getMetaData(boolean wrap)
            throws SQLException {
            return new LoggingDatabaseMetaData(super.getMetaData(false));
        }

        /**
         * Log time elapsed since given start.
         */
        private void logTime(long startTime) throws SQLException {
            if (_logs.isSQLEnabled())
                _logs.logSQL("spent", startTime, this);
        }

        /**
         * Log time elapsed since given start.
         */
        private void logSQL(Statement stmnt) throws SQLException {
            if (_logs.isSQLEnabled())
                _logs.logSQL("executing " + stmnt, this);
        }

        /**
         * Log time elapsed since given start.
         */
        private void logBatchSQL(Statement stmnt) throws SQLException {
            if (_logs.isSQLEnabled())
                _logs.logSQL("executing batch " + stmnt, this);
        }

        /**
         * Handle any {@link SQLWarning}s on the current {@link Connection}.
         *
         * @see #handleSQLWarning(SQLWarning)
         */
        private void handleSQLWarning() throws SQLException {
            if (_warningAction == WARN_IGNORE)
                return;

            try {
                handleSQLWarning(getWarnings());
            } finally {
                clearWarnings();
            }
        }

        /**
         * Handle any {@link SQLWarning}s on the specified {@link Statement}.
         *
         * @see #handleSQLWarning(SQLWarning)
         */
        private void handleSQLWarning(Statement stmnt) throws SQLException {
            if (_warningAction == WARN_IGNORE)
                return;

            try {
                handleSQLWarning(stmnt.getWarnings());
            } finally {
                stmnt.clearWarnings();
            }
        }

        /**
         * Handle any {@link SQLWarning}s on the specified {@link ResultSet}.
         *
         * @see #handleSQLWarning(SQLWarning)
         */
        private void handleSQLWarning(ResultSet rs) throws SQLException {
            if (_warningAction == WARN_IGNORE)
                return;

            try {
                handleSQLWarning(rs.getWarnings());
            } finally {
                rs.clearWarnings();
            }
        }

        /**
         * Handle the specified {@link SQLWarning} depending on the
         * setting of the {@link #setWarningAction} attribute.
         *
         * @param warning the warning to handle
         */
        private void handleSQLWarning(SQLWarning warning) throws SQLException {
            if (warning == null)
                return;
            if (_warningAction == WARN_IGNORE)
                return;

            Log log = _logs.getJDBCLog();
            for (; warning != null; warning = warning.getNextWarning()) {
                switch (_warningAction) {
                    case WARN_LOG_TRACE:
                        if (log.isTraceEnabled())
                            log.trace(warning);
                        break;
                    case WARN_LOG_INFO:
                        if (log.isInfoEnabled())
                            log.info(warning);
                        break;
                    case WARN_LOG_WARN:
                        if (log.isWarnEnabled())
                            log.warn(warning);
                        break;
                    case WARN_LOG_ERROR:
                        if (log.isErrorEnabled())
                            log.error(warning);
                        break;
                    case WARN_THROW:
                        // just throw it as if it were a SQLException
                        throw warning;
                    case WARN_HANDLE:
                        if (_warningHandler != null)
                            _warningHandler.handleWarning(warning);
                        break;
                    default:
                        // ignore
                        break;
                }
            }
        }

        /**
         * Metadata wrapper that logs actions.
         */
        private class LoggingDatabaseMetaData
            extends DelegatingDatabaseMetaData {

            public LoggingDatabaseMetaData(DatabaseMetaData meta) {
                super(meta, LoggingConnection.this);
            }

            public ResultSet getBestRowIdentifier(String catalog,
                String schema, String table, int scope, boolean nullable)
                throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getBestRowIdentifier: "
                        + catalog + ", " + schema + ", " + table,
                        LoggingConnection.this);
                return super.getBestRowIdentifier(catalog, schema,
                    table, scope, nullable);
            }

            public ResultSet getCatalogs() throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getCatalogs", LoggingConnection.this);
                return super.getCatalogs();
            }

            public ResultSet getColumnPrivileges(String catalog, String schema,
                String table, String columnNamePattern) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getColumnPrivileges: "
                        + catalog + ", " + schema + ", " + table,
                        LoggingConnection.this);
                return super.getColumnPrivileges(catalog, schema,
                    table, columnNamePattern);
            }

            public ResultSet getColumns(String catalog, String schemaPattern,
                String tableNamePattern, String columnNamePattern)
                throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getColumns: "
                        + catalog + ", " + schemaPattern + ", "
                        + tableNamePattern + ", " + columnNamePattern,
                        LoggingConnection.this);
                return super.getColumns(catalog, schemaPattern,
                    tableNamePattern, columnNamePattern);
            }

            public ResultSet getCrossReference(String primaryCatalog,
                String primarySchema, String primaryTable,
                String foreignCatalog, String foreignSchema,
                String foreignTable) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getCrossReference: "
                        + primaryCatalog + ", " + primarySchema + ", "
                        + primaryTable + ", " + foreignCatalog + ", "
                        + foreignSchema + ", " + foreignSchema,
                        LoggingConnection.this);
                return super.getCrossReference(primaryCatalog, primarySchema,
                    primaryTable, foreignCatalog, foreignSchema, foreignTable);
            }

            public ResultSet getExportedKeys(String catalog, String schema,
                String table) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getExportedKeys: "
                        + catalog + ", " + schema + ", " + table,
                        LoggingConnection.this);
                return super.getExportedKeys(catalog, schema, table);
            }

            public ResultSet getImportedKeys(String catalog, String schema,
                String table) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getImportedKeys: "
                        + catalog + ", " + schema + ", " + table,
                        LoggingConnection.this);
                return super.getImportedKeys(catalog, schema, table);
            }

            public ResultSet getIndexInfo(String catalog, String schema,
                String table, boolean unique, boolean approximate)
                throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getIndexInfo: "
                        + catalog + ", " + schema + ", " + table,
                        LoggingConnection.this);
                return super.getIndexInfo(catalog, schema, table, unique,
                    approximate);
            }

            public ResultSet getPrimaryKeys(String catalog, String schema,
                String table) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getPrimaryKeys: "
                        + catalog + ", " + schema + ", " + table,
                        LoggingConnection.this);
                return super.getPrimaryKeys(catalog, schema, table);
            }

            public ResultSet getProcedureColumns(String catalog,
                String schemaPattern, String procedureNamePattern,
                String columnNamePattern) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getProcedureColumns: "
                        + catalog + ", " + schemaPattern + ", "
                        + procedureNamePattern + ", " + columnNamePattern,
                        LoggingConnection.this);
                return super.getProcedureColumns(catalog, schemaPattern,
                    procedureNamePattern, columnNamePattern);
            }

            public ResultSet getProcedures(String catalog,
                String schemaPattern, String procedureNamePattern)
                throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getProcedures: "
                        + catalog + ", " + schemaPattern + ", "
                        + procedureNamePattern, LoggingConnection.this);
                return super.getProcedures(catalog, schemaPattern,
                    procedureNamePattern);
            }

            public ResultSet getSchemas() throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getSchemas", LoggingConnection.this);
                return super.getSchemas();
            }

            public ResultSet getTablePrivileges(String catalog,
                String schemaPattern, String tableNamePattern)
                throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getTablePrivileges", LoggingConnection.this);
                return super.getTablePrivileges(catalog, schemaPattern,
                    tableNamePattern);
            }

            public ResultSet getTables(String catalog, String schemaPattern,
                String tableNamePattern, String[] types) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getTables: "
                        + catalog + ", " + schemaPattern + ", "
                        + tableNamePattern, LoggingConnection.this);
                return super.getTables(catalog, schemaPattern,
                    tableNamePattern, types);
            }

            public ResultSet getTableTypes() throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getTableTypes", LoggingConnection.this);
                return super.getTableTypes();
            }

            public ResultSet getTypeInfo() throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getTypeInfo", LoggingConnection.this);
                return super.getTypeInfo();
            }

            public ResultSet getUDTs(String catalog, String schemaPattern,
                String typeNamePattern, int[] types) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getUDTs", LoggingConnection.this);
                return super.getUDTs(catalog, schemaPattern,
                    typeNamePattern, types);
            }

            public ResultSet getVersionColumns(String catalog,
                String schema, String table) throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("getVersionColumns: "
                        + catalog + ", " + schema + ", " + table,
                        LoggingConnection.this);
                return super.getVersionColumns(catalog, schema, table);
            }
        }

        /**
         * Statement wrapper that logs SQL to the parent data source and
         * remembers the last piece of SQL to be executed on it.
         */
        private class LoggingStatement extends DelegatingStatement {

            private String _sql = null;

            public LoggingStatement(Statement stmnt) throws SQLException {
                super(stmnt, LoggingConnection.this);
            }

            public void appendInfo(StringBuffer buf) {
                if (_sql != null) {
                    buf.append(" ");
                    if (_formatter != null) {
                        buf.append(SEP);
                        buf.append(_formatter.prettyPrint(_sql));
                    } else {
                        buf.append(_sql);
                    }
                }
            }

            protected ResultSet wrapResult(ResultSet rs, boolean wrap) {
                if (!wrap || rs == null)
                    return super.wrapResult(rs, wrap);
                return new LoggingResultSet(rs, this);
            }

            public void cancel() throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("cancel " + this, LoggingConnection.this);
                super.cancel();
            }

            protected ResultSet executeQuery(String sql, boolean wrap)
                throws SQLException {
                _sql = sql;
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.executeQuery(sql, wrap);
                } catch (SQLException se) {
                    throw wrap(se, LoggingStatement.this);
                } finally {
                    logTime(start);
                    handleSQLWarning(LoggingStatement.this);
                }
            }

            public int executeUpdate(String sql) throws SQLException {
                _sql = sql;
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.executeUpdate(sql);
                } catch (SQLException se) {
                    throw wrap(se, LoggingStatement.this);
                } finally {
                    logTime(start);
                    handleSQLWarning(LoggingStatement.this);
                }
            }

            public boolean execute(String sql) throws SQLException {
                _sql = sql;
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.execute(sql);
                } catch (SQLException se) {
                    throw wrap(se, LoggingStatement.this);
                } finally {
                    logTime(start);
                    handleSQLWarning(LoggingStatement.this);
                }
            }
        }

        private class LoggingPreparedStatement
            extends DelegatingPreparedStatement {

            private final String _sql;
            private List _params = null;
            private List _paramBatch = null;

            public LoggingPreparedStatement(PreparedStatement stmnt, String sql)
                throws SQLException {
                super(stmnt, LoggingConnection.this);
                _sql = sql;
            }

            protected ResultSet wrapResult(ResultSet rs, boolean wrap) {
                if (!wrap || rs == null)
                    return super.wrapResult(rs, wrap);
                return new LoggingResultSet(rs, this);
            }

            protected ResultSet executeQuery(String sql, boolean wrap)
                throws SQLException {
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.executeQuery(sql, wrap);
                } catch (SQLException se) {
                    throw wrap(se, LoggingPreparedStatement.this);
                } finally {
                    logTime(start);
                    clearLogParameters(true);
                    handleSQLWarning(LoggingPreparedStatement.this);
                }
            }

            public int executeUpdate(String sql) throws SQLException {
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.executeUpdate(sql);
                } catch (SQLException se) {
                    throw wrap(se, LoggingPreparedStatement.this);
                } finally {
                    logTime(start);
                    clearLogParameters(true);
                    handleSQLWarning(LoggingPreparedStatement.this);
                }
            }

            public boolean execute(String sql) throws SQLException {
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.execute(sql);
                } catch (SQLException se) {
                    throw wrap(se, LoggingPreparedStatement.this);
                } finally {
                    logTime(start);
                    clearLogParameters(true);
                    handleSQLWarning(LoggingPreparedStatement.this);
                }
            }

            protected ResultSet executeQuery(boolean wrap) throws SQLException {
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.executeQuery(wrap);
                } catch (SQLException se) {
                    throw wrap(se, LoggingPreparedStatement.this);
                } finally {
                    logTime(start);
                    clearLogParameters(true);
                    handleSQLWarning(LoggingPreparedStatement.this);
                }
            }

            public int executeUpdate() throws SQLException {
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.executeUpdate();
                } catch (SQLException se) {
                    throw wrap(se, LoggingPreparedStatement.this);
                } finally {
                    logTime(start);
                    clearLogParameters(true);
                    handleSQLWarning(LoggingPreparedStatement.this);
                }
            }

            public int[] executeBatch() throws SQLException {
                logBatchSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.executeBatch();
                } catch (SQLException se) {
                    // if the exception is a BatchUpdateException, and
                    // we are tracking parameters, then set the current
                    // parameter set to be the index of the failed
                    // statement so that the ReportingSQLException will
                    // show the correct param
                    if (se instanceof BatchUpdateException
                        && _paramBatch != null && shouldTrackParameters()) {
                        int[] count = ((BatchUpdateException) se).
                            getUpdateCounts();
                        if (count != null && count.length <= _paramBatch.size())
                        {
                            int index = -1;
                            for (int i = 0; i < count.length; i++) {
                                // -3 is Statement.STATEMENT_FAILED, but is
                                // only available in JDK 1.4+
                                if (count[i] == -3) {
                                    index = i;
                                    break;
                                }
                            }

                            // no -3 element: it may be that the server stopped
                            // processing, so the size of the count will be
                            // the index
                            if (index == -1)
                                index = count.length + 1;

                            // set the current params to the saved values
                            if (index < _paramBatch.size())
                                _params = (List) _paramBatch.get(index);
                        }
                    }
                    throw wrap(se, LoggingPreparedStatement.this);
                } finally {
                    logTime(start);
                    clearLogParameters(true);
                    handleSQLWarning(LoggingPreparedStatement.this);
                }
            }

            public boolean execute() throws SQLException {
                logSQL(this);
                long start = System.currentTimeMillis();
                try {
                    return super.execute();
                } catch (SQLException se) {
                    throw wrap(se, LoggingPreparedStatement.this);
                } finally {
                    logTime(start);
                    clearLogParameters(true);
                    handleSQLWarning(LoggingPreparedStatement.this);
                }
            }

            public void cancel() throws SQLException {
                if (_logs.isJDBCEnabled())
                    _logs.logJDBC("cancel " + this + ": " + _sql,
                        LoggingConnection.this);

                super.cancel();
            }

            public void setNull(int i1, int i2) throws SQLException {
                setLogParameter(i1, "null", null);
                super.setNull(i1, i2);
            }

            public void setBoolean(int i, boolean b) throws SQLException {
                setLogParameter(i, b);
                super.setBoolean(i, b);
            }

            public void setByte(int i, byte b) throws SQLException {
                setLogParameter(i, b);
                super.setByte(i, b);
            }

            public void setShort(int i, short s) throws SQLException {
                setLogParameter(i, s);
                super.setShort(i, s);
            }

            public void setInt(int i1, int i2) throws SQLException {
                setLogParameter(i1, i2);
                super.setInt(i1, i2);
            }

            public void setLong(int i, long l) throws SQLException {
                setLogParameter(i, l);
                super.setLong(i, l);
            }

            public void setFloat(int i, float f) throws SQLException {
                setLogParameter(i, f);
                super.setFloat(i, f);
            }

            public void setDouble(int i, double d) throws SQLException {
                setLogParameter(i, d);
                super.setDouble(i, d);
            }

            public void setBigDecimal(int i, BigDecimal bd)
                throws SQLException {
                setLogParameter(i, "BigDecimal", bd);
                super.setBigDecimal(i, bd);
            }

            public void setString(int i, String s) throws SQLException {
                setLogParameter(i, "String", s);
                super.setString(i, s);
            }

            public void setBytes(int i, byte[] b) throws SQLException {
                setLogParameter(i, "byte[]", b);
                super.setBytes(i, b);
            }

            public void setDate(int i, Date d) throws SQLException {
                setLogParameter(i, "Date", d);
                super.setDate(i, d);
            }

            public void setTime(int i, Time t) throws SQLException {
                setLogParameter(i, "Time", t);
                super.setTime(i, t);
            }

            public void setTimestamp(int i, Timestamp t) throws SQLException {
                setLogParameter(i, "Timestamp", t);
                super.setTimestamp(i, t);
            }

            public void setAsciiStream(int i1, InputStream is, int i2)
                throws SQLException {
                setLogParameter(i1, "InputStream", is);
                super.setAsciiStream(i1, is, i2);
            }

            public void setUnicodeStream(int i1, InputStream is, int i2)
                throws SQLException {
                setLogParameter(i1, "InputStream", is);
                super.setUnicodeStream(i2, is, i2);
            }

            public void setBinaryStream(int i1, InputStream is, int i2)
                throws SQLException {
                setLogParameter(i1, "InputStream", is);
                super.setBinaryStream(i1, is, i2);
            }

            public void clearParameters() throws SQLException {
                clearLogParameters(false);
                super.clearParameters();
            }

            public void setObject(int i1, Object o, int i2, int i3)
                throws SQLException {
                setLogParameter(i1, "Object", o);
                super.setObject(i1, o, i2, i3);
            }

            public void setObject(int i1, Object o, int i2)
                throws SQLException {
                setLogParameter(i1, "Object", o);
                super.setObject(i1, o, i2);
            }

            public void setObject(int i, Object o) throws SQLException {
                setLogParameter(i, "Object", o);
                super.setObject(i, o);
            }

            public void addBatch() throws SQLException {
                if (_logs.isSQLEnabled())
                    _logs.logSQL("batching " + this, LoggingConnection.this);
                long start = System.currentTimeMillis();
                try {
                    super.addBatch();
                    if (shouldTrackParameters()) {
                        // make sure our list is initialized
                        if (_paramBatch == null)
                            _paramBatch = new ArrayList();
                        // copy parameters since they will be re-used
                        if (_params != null)
                            _paramBatch.add(new ArrayList(_params));
                        else
                            _paramBatch.add(null);
                    }
                }
                finally {
                    logTime(start);
                }
            }

            public void setCharacterStream(int i1, Reader r, int i2)
                throws SQLException {
                setLogParameter(i1, "Reader", r);
                super.setCharacterStream(i1, r, i2);
            }

            public void setRef(int i, Ref r) throws SQLException {
                setLogParameter(i, "Ref", r);
                super.setRef(i, r);
            }

            public void setBlob(int i, Blob b) throws SQLException {
                setLogParameter(i, "Blob", b);
                super.setBlob(i, b);
            }

            public void setClob(int i, Clob c) throws SQLException {
                setLogParameter(i, "Clob", c);
                super.setClob(i, c);
            }

            public void setArray(int i, Array a) throws SQLException {
                setLogParameter(i, "Array", a);
                super.setArray(i, a);
            }

            public ResultSetMetaData getMetaData() throws SQLException {
                return super.getMetaData();
            }

            public void setDate(int i, Date d, Calendar c) throws SQLException {
                setLogParameter(i, "Date", d);
                super.setDate(i, d, c);
            }

            public void setTime(int i, Time t, Calendar c) throws SQLException {
                setLogParameter(i, "Time", t);
                super.setTime(i, t, c);
            }

            public void setTimestamp(int i, Timestamp t, Calendar c)
                throws SQLException {
                setLogParameter(i, "Timestamp", t);
                super.setTimestamp(i, t, c);
            }

            public void setNull(int i1, int i2, String s) throws SQLException {
                setLogParameter(i1, "null", null);
                super.setNull(i1, i2, s);
            }

            protected void appendInfo(StringBuffer buf) {
                buf.append(" ");
                if (_formatter != null) {
                    buf.append(SEP);
                    buf.append(_formatter.prettyPrint(_sql));
                    buf.append(SEP);
                } else {
                    buf.append(_sql);
                }

                StringBuffer paramBuf = null;
                if (_params != null && !_params.isEmpty()) {
                    paramBuf = new StringBuffer();
                    for (Iterator itr = _params.iterator(); itr.hasNext();) {
                        paramBuf.append(itr.next());
                        if (itr.hasNext())
                            paramBuf.append(", ");
                    }
                }

                if (paramBuf != null) {
                    if (!_prettyPrint)
                        buf.append(" ");
                    buf.append("[params=").
                        append(paramBuf.toString()).append("]");
                }
                super.appendInfo(buf);
            }

            private void clearLogParameters(boolean batch) {
                if (_params != null)
                    _params.clear();
                if (batch && _paramBatch != null)
                    _paramBatch.clear();
            }

            private boolean shouldTrackParameters() {
                return _trackParameters || _logs.isSQLEnabled();
            }

            private void setLogParameter(int index, boolean val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(boolean) " + val);
            }

            private void setLogParameter(int index, byte val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(byte) " + val);
            }

            private void setLogParameter(int index, double val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(double) " + val);
            }

            private void setLogParameter(int index, float val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(float) " + val);
            }

            private void setLogParameter(int index, int val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(int) " + val);
            }

            private void setLogParameter(int index, long val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(long) " + val);
            }

            private void setLogParameter(int index, short val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(short) " + val);
            }

            private void setLogParameter(int index, String type, Object val) {
                if (shouldTrackParameters())
                    setLogParameter(index, "(" + type + ") " + val);
            }

            private void setLogParameter(int index, String val) {
                if (_params == null)
                    _params = new ArrayList();
                while (_params.size() < index)
                    _params.add(null);
                if (val.length() > 80)
                    val = val.substring(0, 77) + "...";
                _params.set(index - 1, val);
            }
        }

        /**
         * Warning-handling result set.
         */
        private class LoggingResultSet extends DelegatingResultSet {

            public LoggingResultSet(ResultSet rs, Statement stmnt) {
                super(rs, stmnt);
            }

            public boolean next() throws SQLException {
                try {
                    return super.next();
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public void close() throws SQLException {
                try {
                    super.close();
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public void beforeFirst() throws SQLException {
                try {
                    super.beforeFirst();
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public void afterLast() throws SQLException {
                try {
                    super.afterLast();
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public boolean first() throws SQLException {
                try {
                    return super.first();
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public boolean last() throws SQLException {
                try {
                    return super.last();
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public boolean absolute(int a) throws SQLException {
                try {
                    return super.absolute(a);
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public boolean relative(int a) throws SQLException {
                try {
                    return super.relative(a);
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }

            public boolean previous() throws SQLException {
                try {
                    return super.previous();
                } finally {
                    handleSQLWarning(LoggingResultSet.this);
                }
            }
        }
    }
}
TOP

Related Classes of org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.