/*
* Craftsman Spy.
* Copyright (C) 2005 S�bastien LECACHEUR
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package craftsman.spy;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This classe represents the JDBC connection to the database.
*
* @author S�bastien LECACHEUR
*/
public class SpyConnection implements Connection {
/**
* Internal used logger.
*/
protected Log log = LogFactory.getLog(this.getClass().getName());
/**
* The real JDBC connection instance.
*/
private Connection real = null;
/**
* The JDBC connection ID.
*/
private int id = 0;
/**
* Constructs a new Spy JDBC connection.
* @param con Connection The real JDBC connection.
* @param conIdSql String The SQL string to execute
* in order to retrieve the real JDBC connection ID.
*/
protected SpyConnection ( Connection con, String conIdSql) {
real = con;
id = hashCode();
if ( conIdSql!=null) {
try {
Statement s = con.createStatement();
ResultSet r = s.executeQuery(conIdSql);
if ( r.next()) {
id = r.getInt(1);
}
r.close();
s.close();
} catch ( SQLException e) {
e.printStackTrace();
}
}
}
/**
* Returns the used JDBC connection identifier.
* @return int The JDBC connection SPID or hash code
* otherwise <code>0</code>.
*/
protected int getId() {
return id;
}
/**
* @see Connection#getHoldability()
*/
public int getHoldability() throws SQLException {
return real.getHoldability();
}
/**
* @see Connection#getTransactionIsolation()
*/
public int getTransactionIsolation() throws SQLException {
return real.getTransactionIsolation();
}
/**
* @see Connection#clearWarnings()
*/
public void clearWarnings() throws SQLException {
real.clearWarnings();
}
/**
* @see Connection#close()
*/
public void close() throws SQLException {
real.close();
}
/**
* @see Connection#commit()
*/
public void commit() throws SQLException {
long end, start = System.currentTimeMillis();
try {
real.commit();
end = System.currentTimeMillis();
if ( log.isInfoEnabled()) log.info(getId()+":commit succeed ("+(end-start)+" ms)");
} catch ( SQLException e) {
end = System.currentTimeMillis();
if ( log.isErrorEnabled()) log.error(getId()+":commit failed state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(end-start)+" ms)",e);
throw e;
}
}
/**
* @see Connection#rollback()
*/
public void rollback() throws SQLException {
long end, start = System.currentTimeMillis();
try {
real.rollback();
end = System.currentTimeMillis();
if ( log.isInfoEnabled()) log.info(getId()+":rollback succeed ("+(end-start)+" ms)");
} catch ( SQLException e) {
end = System.currentTimeMillis();
if ( log.isErrorEnabled()) log.error(getId()+":rollback failed state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(end-start)+" ms)",e);
throw e;
}
}
/**
* @see Connection#getAutoCommit()
*/
public boolean getAutoCommit() throws SQLException {
return real.getAutoCommit();
}
/**
* @see Connection#isClosed()
*/
public boolean isClosed() throws SQLException {
return real.isClosed();
}
/**
* @see Connection#isReadOnly()
*/
public boolean isReadOnly() throws SQLException {
return real.isReadOnly();
}
/**
* @see Connection#setHoldability(int)
*/
public void setHoldability(int holdability) throws SQLException {
real.setHoldability(holdability);
}
/**
* @see Connection#setTransactionIsolation(int)
*/
public void setTransactionIsolation(int level) throws SQLException {
real.setTransactionIsolation(level);
}
/**
* @see Connection#setAutoCommit(boolean)
*/
public void setAutoCommit(boolean autoCommit) throws SQLException {
long end, start = System.currentTimeMillis();
try {
real.setAutoCommit(autoCommit);
end = System.currentTimeMillis();
if ( log.isInfoEnabled()) log.info(getId()+":autocommit("+autoCommit+") succeed ("+(end-start)+" ms)");
} catch ( SQLException e) {
end = System.currentTimeMillis();
if ( log.isErrorEnabled()) log.error(getId()+":autocommit("+autoCommit+") failed state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(end-start)+" ms)",e);
throw e;
}
}
/**
* @see Connection#setReadOnly(boolean)
*/
public void setReadOnly(boolean readOnly) throws SQLException {
real.setReadOnly(readOnly);
}
/**
* @see Connection#getCatalog()
*/
public String getCatalog() throws SQLException {
return real.getCatalog();
}
/**
* @see Connection#setCatalog(java.lang.String)
*/
public void setCatalog(String catalog) throws SQLException {
real.setCatalog(catalog);
}
/**
* @see Connection#getMetaData()
*/
public DatabaseMetaData getMetaData() throws SQLException {
return real.getMetaData();
}
/**
* @see Connection#getWarnings()
*/
public SQLWarning getWarnings() throws SQLException {
SQLWarning current, sw = real.getWarnings();
if ( (current = sw)!=null) {
do {
if ( log.isInfoEnabled()) log.info(getId()+":sql warning state="+current.getSQLState()+",code="+current.getErrorCode()+",message="+current.getMessage());
} while ( (current = current.getNextWarning())!=null);
}
return sw;
}
/**
* @see Connection#setSavepoint()
*/
public Savepoint setSavepoint() throws SQLException {
long end, start = System.currentTimeMillis();
Savepoint savepoint = null;
try {
savepoint = real.setSavepoint();
end = System.currentTimeMillis();
if ( log.isInfoEnabled()) log.info(getId()+":savepoint("+savepoint.getSavepointName()+") succeed ("+(end-start)+" ms)");
} catch ( SQLException e) {
end = System.currentTimeMillis();
if ( log.isErrorEnabled()) log.error(getId()+":savepoint("+"unnamed"+") failed state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(end-start)+" ms)",e);
throw e;
}
return savepoint;
}
/**
* @see Connection#releaseSavepoint(java.sql.Savepoint)
*/
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
long end, start = System.currentTimeMillis();
try {
real.releaseSavepoint(savepoint);
end = System.currentTimeMillis();
if ( log.isInfoEnabled()) log.info(getId()+":savepoint("+savepoint.getSavepointName()+") succeed ("+(end-start)+" ms)");
} catch ( SQLException e) {
end = System.currentTimeMillis();
if ( log.isErrorEnabled()) log.error(getId()+":release savepoint("+savepoint.getSavepointName()+") failed state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(end-start)+" ms)",e);
throw e;
}
}
/**
* @see Connection#rollback(java.sql.Savepoint)
*/
public void rollback(Savepoint savepoint) throws SQLException {
real.rollback(savepoint);
}
/**
* @see Connection#createStatement()
*/
public Statement createStatement() throws SQLException {
return new SpyStatement ( this, real.createStatement());
}
/**
* @see Connection#createStatement(int, int)
*/
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return new SpyStatement ( this, real.createStatement(resultSetType,resultSetConcurrency));
}
/**
* @see Connection#createStatement(int, int, int)
*/
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return new SpyStatement ( this, real.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability));
}
/**
* @see Connection#getTypeMap()
*/
public Map getTypeMap() throws SQLException {
return real.getTypeMap();
}
/**
* @see Connection#setTypeMap(java.util.Map)
*/
public void setTypeMap(Map map) throws SQLException {
real.setTypeMap(map);
}
/**
* @see Connection#nativeSQL(java.lang.String)
*/
public String nativeSQL(String sql) throws SQLException {
return real.nativeSQL(sql);
}
/**
* @see Connection#prepareCall(java.lang.String)
*/
public CallableStatement prepareCall(String sql) throws SQLException {
return new SpyCallableStatement ( this, real.prepareCall(sql), sql);
}
/**
* @see Connection#prepareCall(java.lang.String, int, int)
*/
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return new SpyCallableStatement ( this, real.prepareCall(sql,resultSetType,resultSetConcurrency), sql);
}
/**
* @see Connection#prepareCall(java.lang.String, int, int, int)
*/
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return new SpyCallableStatement ( this, real.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability), sql);
}
/**
* @see Connection#prepareStatement(java.lang.String)
*/
public PreparedStatement prepareStatement(String sql) throws SQLException {
return new SpyPreparedStatement ( this, real.prepareStatement(sql), sql);
}
/**
* @see Connection#prepareStatement(java.lang.String, int)
*/
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return new SpyPreparedStatement ( this, real.prepareStatement(sql,autoGeneratedKeys), sql);
}
/**
* @see Connection#prepareStatement(java.lang.String, int, int)
*/
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return new SpyPreparedStatement ( this, real.prepareStatement(sql,resultSetType,resultSetConcurrency), sql);
}
/**
* @see Connection#prepareStatement(java.lang.String, int, int, int)
*/
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return new SpyPreparedStatement ( this, real.prepareStatement(sql,resultSetType,resultSetConcurrency,resultSetHoldability), sql);
}
/**
* @see Connection#prepareStatement(java.lang.String, int[])
*/
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return new SpyPreparedStatement ( this, real.prepareStatement(sql,columnIndexes), sql);
}
/**
* @see Connection#setSavepoint(java.lang.String)
*/
public Savepoint setSavepoint(String name) throws SQLException {
long end ,start = System.currentTimeMillis();
Savepoint savepoint = null;
try {
savepoint = real.setSavepoint(name);
end = System.currentTimeMillis();
if ( log.isInfoEnabled()) log.info(getId()+":savepoint("+name+") succeed ("+(end-start)+" ms)");
} catch ( SQLException e) {
end = System.currentTimeMillis();
if ( log.isErrorEnabled()) log.error(getId()+":savepoint("+name+") failed state="+e.getSQLState()+",code="+e.getErrorCode()+" ("+(end-start)+" ms)",e);
throw e;
}
return savepoint;
}
/**
* @see Connection#prepareStatement(java.lang.String, java.lang.String[])
*/
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return new SpyPreparedStatement ( this, real.prepareStatement(sql,columnNames), sql);
}
}