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;
|
_del = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultSet wrapResult(boolean wrap, ResultSet rs) {
|
protected ResultSet wrapResult(boolean wrap, ResultSet rs) {
|
||||||
if (!wrap)
|
if (!wrap)
|
||||||
return rs;
|
return rs;
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ public class DelegatingCallableStatement
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer buf = new StringBuffer("prepstmnt ").append(hashCode());
|
StringBuffer buf = new StringBuffer("callstmnt ").append(hashCode());
|
||||||
appendInfo(buf);
|
appendInfo(buf);
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.math.BigDecimal;
|
||||||
import java.sql.Array;
|
import java.sql.Array;
|
||||||
import java.sql.BatchUpdateException;
|
import java.sql.BatchUpdateException;
|
||||||
import java.sql.Blob;
|
import java.sql.Blob;
|
||||||
|
import java.sql.CallableStatement;
|
||||||
import java.sql.Clob;
|
import java.sql.Clob;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
|
@ -250,6 +251,16 @@ public class LoggingConnectionDecorator implements ConnectionDecorator {
|
||||||
Statement stmnt = super.createStatement(type, concurrency, false);
|
Statement stmnt = super.createStatement(type, concurrency, false);
|
||||||
return new LoggingStatement(stmnt);
|
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 {
|
public void commit() throws SQLException {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
@ -892,7 +903,7 @@ public class LoggingConnectionDecorator implements ConnectionDecorator {
|
||||||
for (int i = 0; i < count.length; i++) {
|
for (int i = 0; i < count.length; i++) {
|
||||||
// -3 is Statement.STATEMENT_FAILED, but is
|
// -3 is Statement.STATEMENT_FAILED, but is
|
||||||
// only available in JDK 1.4+
|
// only available in JDK 1.4+
|
||||||
if (count[i] == -3) {
|
if (count[i] == Statement.EXECUTE_FAILED) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
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