mirror of https://github.com/apache/openjpa.git
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.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@688111 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3ee2f9e40e
commit
04c292c761
|
@ -63,7 +63,7 @@ public class DelegatingCallableStatement
|
|||
_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 class DelegatingCallableStatement
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer("prepstmnt ").append(hashCode());
|
||||
StringBuffer buf = new StringBuffer("callstmnt ").append(hashCode());
|
||||
appendInfo(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.math.BigDecimal;
|
|||
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;
|
||||
|
@ -251,6 +252,16 @@ public class LoggingConnectionDecorator implements ConnectionDecorator {
|
|||
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();
|
||||
try {
|
||||
|
@ -892,7 +903,7 @@ public class LoggingConnectionDecorator implements ConnectionDecorator {
|
|||
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 @@ public class LoggingConnectionDecorator implements ConnectionDecorator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue