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);
+ }
+ }
+ }
}