com.caucho.sql.spy.SpyConnection Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source 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.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.sql.spy;
import com.caucho.sql.DriverConfig;
import com.caucho.util.Alarm;
import com.caucho.util.CurrentTime;
import com.caucho.util.L10N;
import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.logging.*;
/**
* Spying on a connection.
*/
public class SpyConnection implements java.sql.Connection {
protected final static Logger log
= Logger.getLogger(SpyConnection.class.getName());
protected final static Logger logXA =
Logger.getLogger(SpyConnection.class.getName() + ".XA");
protected final static L10N L = new L10N(SpyConnection.class);
private SpyDataSource _spyDataSource;
private String _id;
private int _stmtIdCount;
// The underlying connection
private Connection _conn;
/**
* Creates a new SpyConnection.
*/
public SpyConnection(Connection conn,
SpyDataSource spyDataSource,
DriverConfig driver)
{
_spyDataSource = spyDataSource;
_conn = conn;
_id = _spyDataSource.createConnectionId(driver);
}
/**
* Creates a new SpyConnection.
*/
public SpyConnection(Connection conn,
SpyDataSource spyDataSource,
String id)
{
_spyDataSource = spyDataSource;
_conn = conn;
_id = id;
}
/**
* Returns the underlying connection.
*/
public Connection getConnection()
{
return _conn;
}
/**
* Returns the id.
*/
public String getId()
{
return _id;
}
/**
* Returns a new statement id.
*/
public String createStatementId()
{
return getId() + "." + _stmtIdCount++;
}
/**
* JDBC api to return the connection's catalog.
*
* @return the JDBC catalog.
*/
public String getCatalog()
throws SQLException
{
try {
String catalog = _conn.getCatalog();
log.fine(getId() + ":getCatalog() -> " + catalog);
return catalog;
} catch (SQLException e) {
log.fine(getId() + ":exn-getCatalog(" + e + ")");
throw e;
}
}
/**
* Sets the JDBC catalog.
*/
public void setCatalog(String catalog)
throws SQLException
{
try {
log.fine(getId() + ":setCatalog(" + catalog + ")");
_conn.setCatalog(catalog);
} catch (SQLException e) {
log.fine(getId() + ":exn-setCatalog(" + e + ")");
throw e;
}
}
/**
* Gets the connection's metadata.
*/
public DatabaseMetaData getMetaData()
throws SQLException
{
try {
DatabaseMetaData metaData = _conn.getMetaData();
// Avoid logging result of metaData.toString() here
// because it may not be overloaded. The default
// toString() result contains a hex representation
// of the memory location that can't be matched in a
// regression test.
String ident = metaData.getClass().getName();
log.fine(getId() + ":getMetaData() -> " + ident);
return metaData;
} catch (SQLException e) {
log.fine(getId() + ":exn-getMetaData(" + e + ")");
throw e;
}
}
/**
* Returns the connection's type map.
*/
public Map> getTypeMap()
throws SQLException
{
try {
Map> map = _conn.getTypeMap();
log.fine(getId() + ":getTypeMap() -> " + map);
return map;
} catch (SQLException e) {
log.fine(getId() + ":exn-getTypeMap(" + e + ")");
throw e;
}
}
/**
* Sets the connection's type map.
*/
public void setTypeMap(Map> map)
throws SQLException
{
try {
log.fine(getId() + ":setTypeMap(" + map + ")");
_conn.setTypeMap(map);
} catch (SQLException e) {
log.fine(getId() + ":exn-setTypeMap(" + e + ")");
throw e;
}
}
/**
* Calls the nativeSQL method for the connection.
*/
public String nativeSQL(String sql)
throws SQLException
{
try {
String nativeSQL = _conn.nativeSQL(sql);
log.fine(getId() + ":nativeSQL() -> " + nativeSQL);
return nativeSQL;
} catch (SQLException e) {
log.fine(getId() + ":exn-nativeSQL(" + e + ")");
throw e;
}
}
public int getTransactionIsolation()
throws SQLException
{
try {
int isolation = _conn.getTransactionIsolation();
log.fine(getId() + ":getTransactionIsolation() -> " + isolation);
return isolation;
} catch (SQLException e) {
log.fine(getId() + ":exn-getTransactionIsolation(" + e + ")");
throw e;
}
}
public void setTransactionIsolation(int isolation)
throws SQLException
{
try {
log.fine(getId() + ":setTransactionIsolation(" + isolation + ")");
_conn.setTransactionIsolation(isolation);
} catch (SQLException e) {
log.fine(getId() + ":exn-setTransactionIsolation(" + e + ")");
throw e;
}
}
public SQLWarning getWarnings()
throws SQLException
{
try {
SQLWarning warning = _conn.getWarnings();
log.fine(getId() + ":getWarnings() -> " + warning);
return warning;
} catch (SQLException e) {
log.fine(getId() + ":exn-getWarnings(" + e + ")");
throw e;
}
}
public void clearWarnings()
throws SQLException
{
try {
log.fine(getId() + ":clearWarnings()");
_conn.clearWarnings();
} catch (SQLException e) {
log.fine(getId() + ":exn-clearWarnings(" + e + ")");
throw e;
}
}
public void setReadOnly(boolean readOnly)
throws SQLException
{
try {
log.fine(getId() + ":setReadOnly(" + readOnly + ")");
_conn.setReadOnly(readOnly);
} catch (SQLException e) {
log.fine(getId() + ":exn-setReadOnly(" + e + ")");
throw e;
}
}
public boolean isReadOnly()
throws SQLException
{
try {
boolean isReadOnly = _conn.isReadOnly();
log.fine(getId() + "isReadOnly() -> " + isReadOnly);
return isReadOnly;
} catch (SQLException e) {
log.fine(getId() + ":exn-isReadOnly(" + e + ")");
throw e;
}
}
/**
* JDBC api to create a new statement. Any SQL exception thrown here
* will make the connection invalid, i.e. it can't be put back into
* the pool.
*
* @return a new JDBC statement.
*/
public Statement createStatement()
throws SQLException
{
try {
String stmtId = null;
if (log.isLoggable(Level.FINE)) {
stmtId = createStatementId();
log.fine(stmtId + ":createStatement()");
}
Statement stmt;
stmt = _conn.createStatement();
return new SpyStatement(stmtId, this, stmt);
} catch (SQLException e) {
log.fine(getId() + ":exn-createStatement(" + e + ")");
throw e;
}
}
/**
* JDBC api to create a new statement. Any SQL exception thrown here
* will make the connection invalid, i.e. it can't be put back into
* the pool.
*
* @return a new JDBC statement.
*/
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException
{
try {
String stmtId = null;
if (log.isLoggable(Level.FINE)) {
stmtId = createStatementId();
log.fine(stmtId + ":createStatement(type=" + resultSetType +
",concurrency=" + resultSetConcurrency + ")");
}
Statement stmt;
stmt = _conn.createStatement(resultSetType, resultSetConcurrency);
return new SpyStatement(stmtId, this, stmt);
} catch (SQLException e) {
log.fine(getId() + ":exn-createStatement(" + e + ")");
throw e;
}
}
public Statement createStatement(int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
{
try {
String stmtId = null;
if (log.isLoggable(Level.FINE)) {
stmtId = createStatementId();
log.fine(stmtId + ":createStatement(type=" + resultSetType +
",concurrency=" + resultSetConcurrency +
",holdability=" + resultSetHoldability + ")");
}
Statement stmt;
stmt = _conn.createStatement(resultSetType,
resultSetConcurrency,
resultSetHoldability);
return new SpyStatement(stmtId, this, stmt);
} catch (SQLException e) {
log.fine(getId() + ":exn-createStatement(" + e + ")");
throw e;
}
}
public PreparedStatement prepareStatement(String sql)
throws SQLException
{
try {
String stmtId = null;
if (log.isLoggable(Level.FINE)) {
stmtId = createStatementId();
log.fine(stmtId + ":prepareStatement(" + sql + ")");
}
PreparedStatement stmt;
stmt = _conn.prepareStatement(sql);
return new SpyPreparedStatement(stmtId, this, stmt, sql);
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareStatement(" + e + ")");
throw e;
}
}
public PreparedStatement prepareStatement(String sql,
int resultSetType)
throws SQLException
{
try {
String stmtId = null;
if (log.isLoggable(Level.FINE)) {
stmtId = createStatementId();
log.fine(stmtId + ":prepareStatement(" + sql + ",type=" + resultSetType + ")");
}
PreparedStatement stmt;
stmt = _conn.prepareStatement(sql, resultSetType);
return new SpyPreparedStatement(stmtId, this, stmt, sql);
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareStatement(" + e + ")");
throw e;
}
}
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException
{
try {
String stmtId = null;
if (log.isLoggable(Level.FINE)) {
stmtId = createStatementId();
log.fine(stmtId + ":prepareStatement(" + sql + ",type=" + resultSetType +
",concurrency=" + resultSetConcurrency + ")");
}
PreparedStatement stmt;
stmt = _conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
return new SpyPreparedStatement(stmtId, this, stmt, sql);
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareStatement(" + e + ")");
throw e;
}
}
public PreparedStatement prepareStatement(String sql,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
{
try {
if (log.isLoggable(Level.FINE))
log.fine(L.l(
"{0}:prepareStatement({1}, resultSetType={2}, resultSetConcurrency={3}, resultSetHoldability={4})",
getId(),
sql,
resultSetType,
resultSetConcurrency,
resultSetHoldability));
PreparedStatement stmt;
stmt = _conn.prepareStatement(sql,
resultSetType,
resultSetConcurrency,
resultSetHoldability);
return stmt;
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareStatement(" + e + ")");
throw e;
}
}
public PreparedStatement prepareStatement(String sql,
int []columnIndexes)
throws SQLException
{
try {
if (log.isLoggable(Level.FINE)) {
List list = new ArrayList();
for (int i : columnIndexes)
list.add(i);
log.fine(L.l("{0}:prepareStatement({1}, columnIndexes={2})", getId(), sql, list));
}
PreparedStatement stmt;
stmt = _conn.prepareStatement(sql, columnIndexes);
return stmt;
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareStatement(" + e + ")");
throw e;
}
}
public PreparedStatement prepareStatement(String sql,
String []columnNames)
throws SQLException
{
try {
if (log.isLoggable(Level.FINE)) {
log.fine(L.l("{0}:prepareStatement({1}, columnNames={2})",
getId(),
sql,
Arrays.asList(columnNames)));
}
PreparedStatement stmt;
stmt = _conn.prepareStatement(sql, columnNames);
return stmt;
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareStatement(" + e + ")");
throw e;
}
}
public CallableStatement prepareCall(String sql)
throws SQLException
{
try {
if (log.isLoggable(Level.FINE))
log.fine(getId() + ":prepareCall(" + sql + ")");
CallableStatement stmt;
stmt = _conn.prepareCall(sql);
return stmt;
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareCall(" + e + ")");
throw e;
}
}
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency)
throws SQLException
{
try {
if (log.isLoggable(Level.FINE))
log.fine(getId() + ":prepareCall(" + sql + ",type=" + resultSetType +
",concurrency=" + resultSetConcurrency + ")");
CallableStatement stmt;
stmt = _conn.prepareCall(sql);
return stmt;
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareCall(" + e + ")");
throw e;
}
}
public CallableStatement prepareCall(String sql,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
{
try {
if (log.isLoggable(Level.FINE))
log.fine(getId() + ":prepareCall(" + sql + ",type=" + resultSetType +
",concurrency=" + resultSetConcurrency + ")");
CallableStatement stmt;
stmt = _conn.prepareCall(sql,
resultSetType,
resultSetConcurrency,
resultSetHoldability);
return stmt;
} catch (SQLException e) {
log.fine(getId() + ":exn-prepareCall(" + e + ")");
throw e;
}
}
@Override
public boolean getAutoCommit()
throws SQLException
{
try {
boolean autoCommit = _conn.getAutoCommit();
log.fine(getId() + ":getAutoCommit() -> " + autoCommit);
return autoCommit;
} catch (SQLException e) {
log.fine(getId() + ":exn-getAutoCommit(" + e + ")");
throw e;
}
}
@Override
public void setAutoCommit(boolean autoCommit)
throws SQLException
{
try {
logXA.fine(getId() + ":setAutoCommit(" + autoCommit + ")");
_conn.setAutoCommit(autoCommit);
} catch (SQLException e) {
logXA.fine(getId() + ":exn-setAutoCommit(" + e + ")");
throw e;
}
}
@Override
public void commit()
throws SQLException
{
long start = start();
try {
_conn.commit();
if (logXA.isLoggable(Level.FINE))
logXA(start, "commit()");
} catch (SQLException e) {
logXA(start, "exn-commit(" + e + ")");
throw e;
}
}
@Override
public void rollback()
throws SQLException
{
long start = start();
try {
_conn.rollback();
if (logXA.isLoggable(Level.FINE))
logXA(start, "rollback()");
} catch (SQLException e) {
logXA(start, "exn-rollback(" + e + ")");
throw e;
}
}
/**
* Returns true if the connection is closed.
*/
public boolean isClosed()
throws SQLException
{
try {
boolean isClosed = _conn.isClosed();
log.fine(getId() + ":isClosed() -> " + isClosed);
return isClosed;
} catch (SQLException e) {
log.fine(getId() + ":exn-isClosed(" + e + ")");
throw e;
}
}
/**
* Reset the connection and return the underlying JDBC connection to
* the pool.
*/
@Override
public void close() throws SQLException
{
long start = start();
try {
_conn.close();
log(start, "close()");
} catch (SQLException e) {
log(start, "exn-close(" + e + ")");
throw e;
}
}
public void setHoldability(int hold)
throws SQLException
{
log.fine(getId() + ":setHoldability(" + hold + ")");
try {
_conn.setHoldability(hold);
} catch (SQLException e) {
log.fine(getId() + ":exn-setHoldability(" + e + ")");
throw e;
}
}
public int getHoldability()
throws SQLException
{
try {
int holdability = _conn.getHoldability();
log.fine(getId() + ":getHoldability() -> " + holdability);
return holdability;
} catch (SQLException e) {
log.fine(getId() + ":exn-getHoldability(" + e + ")");
throw e;
}
}
public Savepoint setSavepoint()
throws SQLException
{
log.fine(getId() + ":setSavepoint()");
try {
return _conn.setSavepoint();
} catch (SQLException e) {
log.fine(getId() + ":exn-setSavepoint(" + e + ")");
throw e;
}
}
public Savepoint setSavepoint(String name)
throws SQLException
{
log.fine(getId() + ":setSavepoint(" + name + ")");
try {
return _conn.setSavepoint(name);
} catch (SQLException e) {
log.fine(getId() + ":exn-setSavepoint(" + e + ")");
throw e;
}
}
public void releaseSavepoint(Savepoint savepoint)
throws SQLException
{
log.fine(getId() + ":releaseSavepoint(" + savepoint + ")");
try {
_conn.releaseSavepoint(savepoint);
} catch (SQLException e) {
log.fine(getId() + ":exn-releaseSavepoint(" + e + ")");
throw e;
}
}
public void rollback(Savepoint savepoint)
throws SQLException
{
log.fine(getId() + ":rollback(" + savepoint + ")");
try {
_conn.rollback(savepoint);
} catch (SQLException e) {
log.fine(getId() + ":exn-rollback(" + e + ")");
throw e;
}
}
public Clob createClob()
throws SQLException
{
try {
Clob clob = _conn.createClob();
log.fine(getId() + ":createClob() -> " + clob);
return clob;
} catch (SQLException e) {
log.fine(getId() + ":exn-createClob(" + e + ")");
throw e;
}
}
public Blob createBlob()
throws SQLException
{
try {
Blob blob = _conn.createBlob();
log.fine(getId() + ":createBlob() -> " + blob);
return blob;
} catch (SQLException e) {
log.fine(getId() + ":exn-createBlob(" + e + ")");
throw e;
}
}
public NClob createNClob()
throws SQLException
{
try {
NClob nclob = _conn.createNClob();
log.fine(getId() + ":createNClob() -> " + nclob);
return nclob;
} catch (SQLException e) {
log.fine(getId() + ":exn-createNClob(" + e + ")");
throw e;
}
}
public SQLXML createSQLXML()
throws SQLException
{
try {
SQLXML xml = _conn.createSQLXML();
log.fine(getId() + ":createSQLXML() -> " + xml);
return xml;
} catch (SQLException e) {
log.fine(getId() + ":exn-createSQLXML(" + e + ")");
throw e;
}
}
public Array createArrayOf(String typeName, Object[] elements)
throws SQLException
{
try {
Array array = _conn.createArrayOf(typeName, elements);
log.fine(getId()
+ ":createArrayOf(typeName="
+ typeName
+ ", elements="
+ Arrays.asList(elements)
+ ") -> "
+ array);
return array;
} catch (SQLException e) {
log.fine(getId() + ":exn-createArrayOf(" + e + ")");
throw e;
}
}
public Struct createStruct(String typeName, Object[] attributes)
throws SQLException
{
try {
Struct struct = _conn.createStruct(typeName, attributes);
log.fine(getId()
+ ":createStruct(typeName="
+ typeName
+ ", attributes="
+ Arrays.asList(attributes)
+ ") -> "
+ struct);
return struct;
} catch (SQLException e) {
log.fine(getId() + ":exn-createStruct(" + e + ")");
throw e;
}
}
public boolean isValid(int timeout)
throws SQLException
{
try {
boolean valid = _conn.isValid(timeout);
log.fine(getId() + ":isValid(" + timeout + ") -> " + valid);
return valid;
} catch (SQLException e) {
log.fine(getId() + ":exn-isValid(" + e + ")");
throw e;
}
}
public void setClientInfo(String name, String value)
throws SQLClientInfoException
{
log.fine(getId() + ":setClientInfo(" + name + "=" + value + ")");
try {
_conn.setClientInfo(name, value);
} catch (SQLClientInfoException e) {
log.fine(getId() + ":exn-setClientInfo(" + e + ")");
throw e;
}
}
public void setClientInfo(Properties properties)
throws SQLClientInfoException
{
try {
log.fine(getId() + ":setClientInfo(" + properties + ")");
_conn.setClientInfo(properties);
} catch (SQLClientInfoException e) {
log.fine(getId() + ":exn-setClientInfo(" + e + ")");
throw e;
}
}
public String getClientInfo(String name)
throws SQLException
{
try {
String value = _conn.getClientInfo(name);
log.fine(getId() + ":getClientInfo(" + name + ") -> " + value);
return value;
} catch (SQLException e) {
log.fine(getId() + ":getClientInfo");
throw e;
}
}
public Properties getClientInfo()
throws SQLException
{
try {
Properties clientInfo = _conn.getClientInfo();
log.fine(getId() + ":getClientInfo() -> " + clientInfo);
return clientInfo;
} catch (SQLException e) {
log.fine(getId() + ":exn-getClientInfo(" + e + ")");
throw e;
}
}
public T unwrap(Class iface)
throws SQLException
{
try {
T t = _conn.unwrap(iface);
log.fine(getId() + ":unwrap(" + iface + ") -> " + t);
return t;
} catch (SQLException e) {
log.fine(getId() + ":exn-unwrap(" + e + ")");
throw e;
}
}
public boolean isWrapperFor(Class> iface)
throws SQLException
{
try {
boolean isWrapper = _conn.isWrapperFor(iface);
return isWrapper;
} catch (SQLException e) {
log.fine(getId() + ":exn-isWrapperFor(" + e + ")");
throw e;
}
}
public void abort(Executor arg0) throws SQLException
{
}
public int getNetworkTimeout() throws SQLException
{
return 0;
}
public String getSchema() throws SQLException
{
return null;
}
public void setNetworkTimeout(Executor arg0, int arg1) throws SQLException
{
}
public void setSchema(String arg0) throws SQLException
{
}
protected long start()
{
return CurrentTime.getExactTime();
}
protected void logXA(long start, String msg)
{
long delta = CurrentTime.getExactTime() - start;
logXA.fine("[" + delta + "ms] " + getId() + ":" + msg);
}
protected void log(long start, String msg)
{
long delta = CurrentTime.getExactTime() - start;
log.fine("[" + delta + "ms] " + getId() + ":" + msg);
}
public String toString()
{
return "SpyConnection[id=" + getId() + ",conn=" + _conn + "]";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy