You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2008/08/22 18:19:11 UTC

svn commit: r688111 - in /openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc: DelegatingCallableStatement.java LoggingConnectionDecorator.java

Author: ppoddar
Date: Fri Aug 22 09:19:07 2008
New Revision: 688111

URL: http://svn.apache.org/viewvc?rev=688111&view=rev
Log:
OPENJPA-698: Decorate callable statements with logging. Added a new inner class LoggingConnection.LoggingCallableStatement which is almost a duplicate of LoggingPreparedStatement -- but existing hierarchy prohibits a direct inheritance. The logging with parameter tracking code needs to be refactored for a cleaner and less duplicated code, but has not be done with this commit.

Modified:
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingCallableStatement.java
    openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/LoggingConnectionDecorator.java

Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingCallableStatement.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingCallableStatement.java?rev=688111&r1=688110&r2=688111&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingCallableStatement.java (original)
+++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/DelegatingCallableStatement.java Fri Aug 22 09:19:07 2008
@@ -63,7 +63,7 @@
             _del = null;
     }
 
-    private ResultSet wrapResult(boolean wrap, ResultSet rs) {
+    protected ResultSet wrapResult(boolean wrap, ResultSet rs) {
         if (!wrap)
             return rs;
 
@@ -102,7 +102,7 @@
     }
 
     public String toString() {
-        StringBuffer buf = new StringBuffer("prepstmnt ").append(hashCode());
+        StringBuffer buf = new StringBuffer("callstmnt ").append(hashCode());
         appendInfo(buf);
         return buf.toString();
     }

Modified: openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/LoggingConnectionDecorator.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/LoggingConnectionDecorator.java?rev=688111&r1=688110&r2=688111&view=diff
==============================================================================
--- openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/LoggingConnectionDecorator.java (original)
+++ openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/jdbc/LoggingConnectionDecorator.java Fri Aug 22 09:19:07 2008
@@ -24,6 +24,7 @@
 import java.sql.Array;
 import java.sql.BatchUpdateException;
 import java.sql.Blob;
+import java.sql.CallableStatement;
 import java.sql.Clob;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
@@ -250,6 +251,16 @@
             Statement stmnt = super.createStatement(type, concurrency, false);
             return new LoggingStatement(stmnt);
         }
+        
+        protected CallableStatement prepareCall(String sql, boolean wrap) 
+            throws SQLException {
+        	try {
+        		CallableStatement stmt = super.prepareCall(sql, wrap);
+        		return new LoggingCallableStatement(stmt, sql);
+        	} catch (SQLException se) {
+        		throw wrap(se, sql);
+        	}
+        }
 
         public void commit() throws SQLException {
             long start = System.currentTimeMillis();
@@ -892,7 +903,7 @@
                             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) {
+                                if (count[i] == Statement.EXECUTE_FAILED) {
                                     index = i;
                                     break;
                                 }
@@ -1295,5 +1306,442 @@
                 }
             }
         }
-    }
+        
+        /**
+         * CallableStatement decorated with logging.
+         * Similar to {@link LoggingPreparedStatement} but can not be extended
+         * due to the existing delegation hierarchy.
+         */
+        private class LoggingCallableStatement extends 
+            DelegatingCallableStatement {
+            private final String _sql;
+            private List _params = null;
+            private List _paramBatch = null;
+
+            public LoggingCallableStatement(CallableStatement stmt, String sql) 
+                throws SQLException {
+        		super(stmt, LoggingConnection.this);
+        		_sql = sql;
+        	}
+        	
+            protected ResultSet wrapResult(ResultSet rs, boolean wrap) {
+                if (!wrap || rs == null)
+                    return super.wrapResult(wrap, rs);
+                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, LoggingCallableStatement.this);
+                } finally {
+                    logTime(start);
+                    clearLogParameters(true);
+                    handleSQLWarning(LoggingCallableStatement.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, LoggingCallableStatement.this);
+                } finally {
+                    logTime(start);
+                    clearLogParameters(true);
+                    handleSQLWarning(LoggingCallableStatement.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, LoggingCallableStatement.this);
+                } finally {
+                    logTime(start);
+                    clearLogParameters(true);
+                    handleSQLWarning(LoggingCallableStatement.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, LoggingCallableStatement.this);
+                } finally {
+                    logTime(start);
+                    clearLogParameters(true);
+                    handleSQLWarning(LoggingCallableStatement.this);
+                }
+            }
+
+            public int executeUpdate() throws SQLException {
+                logSQL(this);
+                long start = System.currentTimeMillis();
+                try {
+                    return super.executeUpdate();
+                } catch (SQLException se) {
+                    throw wrap(se, LoggingCallableStatement.this);
+                } finally {
+                    logTime(start);
+                    clearLogParameters(true);
+                    handleSQLWarning(LoggingCallableStatement.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] == Statement.EXECUTE_FAILED) {
+                                    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, LoggingCallableStatement.this);
+                } finally {
+                    logTime(start);
+                    clearLogParameters(true);
+                    handleSQLWarning(LoggingCallableStatement.this);
+                }
+            }
+
+            public boolean execute() throws SQLException {
+                logSQL(this);
+                long start = System.currentTimeMillis();
+                try {
+                    return super.execute();
+                } catch (SQLException se) {
+                    throw wrap(se, LoggingCallableStatement.this);
+                } finally {
+                    logTime(start);
+                    clearLogParameters(true);
+                    handleSQLWarning(LoggingCallableStatement.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);
+            }
+
+            protected 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);
+            }
+        }
+    }   
 }