package org.jdbcdslog;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PreparedStatementLoggingProxy implements InvocationHandler {
static Logger logger = LoggerFactory.getLogger(PreparedStatementLoggingProxy.class);
TreeMap parameters = new TreeMap();
Object target = null;
String sql = null;
static List setMethods = Arrays.asList(new String[]{"setAsciiStream", "setBigDecimal", "setBinaryStream"
, "setBoolean", "setByte", "setBytes", "setCharacterStream", "setDate", "setDouble", "setFloat"
, "setInt", "setLong", "setObject", "setShort", "setString", "setTime", "setTimestamp", "setURL"});
static List executeMethods = Arrays.asList(new String[]{"addBatch", "execute", "executeQuery", "executeUpdate"});
public PreparedStatementLoggingProxy(PreparedStatement ps, String sql) {
target = ps;
this.sql = sql;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object r = null;
try {
long t1 = 0;
boolean toLog = (StatementLogger.logger.isInfoEnabled()
|| SlowQueryLogger.logger.isInfoEnabled()) && executeMethods.contains(method.getName());
if(toLog)
t1 = System.currentTimeMillis();
r = method.invoke(target, args);
if(setMethods.contains(method.getName()) && args[0] instanceof Integer)
parameters.put(args[0], args[1]);
if("clearParameters".equals(method.getName()))
parameters = new TreeMap();
if(toLog) {
long t2 = System.currentTimeMillis();
long time = t2 - t1;
StringBuffer sb = LogUtils.createLogEntry(method, sql, parametersToString(), null);
String logEntry = sb.append(" ").append(time).append(" ms.").toString();
StatementLogger.logger.info(logEntry);
if(time >= ConfigurationParameters.slowQueryThreshold)
SlowQueryLogger.logger.info(logEntry);
}
if(r instanceof ResultSet)
r = ResultSetLoggingProxy.wrapByResultSetProxy((ResultSet)r);
} catch(Throwable t) {
LogUtils.handleException(t, StatementLogger.logger, LogUtils.createLogEntry(method, sql, parametersToString(), null));
}
return r;
}
String parametersToString() {
StringBuffer sb2 = new StringBuffer();
sb2.setLength(0);
sb2.append("{");
int maxParamNumber = 0;
if(parameters.size() > 0)
maxParamNumber = ((Integer)parameters.lastKey()).intValue();
if(maxParamNumber > 0) {
Integer key = new Integer(1);
if(parameters.containsKey(key))
sb2.append(LogUtils.sqlValueToString(parameters.get(key)));
else
sb2.append("(null)");
}
for(int i = 2; i <= maxParamNumber; i ++) {
Integer key = new Integer(i);
sb2.append(", ");
if(parameters.containsKey(key))
sb2.append(LogUtils.sqlValueToString(parameters.get(key)));
else
sb2.append("(null)");
}
sb2.append("}");
return sb2.toString();
}
}