/*
Copyright (C) 2002 MySQL AB
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 com.mysql.jdbc.jdbc2.optional;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
/**
* This class serves as a wrapper for the org.gjt.mm.mysql.jdbc2.Connection
* class. It is returned to the application server which may wrap it again
* and then return it to the application client in response to
* dataSource.getConnection().
*
* <p>
* All method invocations are forwarded to org.gjt.mm.mysql.jdbc2.Connection
* unless the close method was previously called, in which case a sqlException
* is thrown. The close method performs a 'logical close' on the connection.
* </p>
*
* <p>
* All sqlExceptions thrown by the physical connection are intercepted and sent
* to connectionEvent listeners before being thrown to client.
* </p>
*
* @author Todd Wolff todd.wolff_at_prodigy.net
*
* @see org.gjt.mm.mysql.jdbc2.Connection
* @see org.gjt.mm.mysql.jdbc2.optional.MysqlPooledConnection
*/
public class LogicalHandle implements Connection {
private Connection mc = null;
private MysqlPooledConnection mpc = null;
private String invalidHandleStr = "Logical handle no longer valid";
private boolean closed;
/**
* Construct a new LogicalHandle and set instance variables
*
* @param mysqlPooledConnection reference to object that instantiated this
* object
* @param mysqlConnection physical connection to db
*
* @throws SQLException if an error occurs.
*/
public LogicalHandle(MysqlPooledConnection mysqlPooledConnection,
Connection mysqlConnection) throws SQLException {
mpc = mysqlPooledConnection;
mc = mysqlConnection;
closed = false;
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#setAutoCommit
*/
public void setAutoCommit(boolean autoCommit) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.setAutoCommit(autoCommit);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#getAutoCommit()
*/
public boolean getAutoCommit() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.getAutoCommit();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#setCatalog()
*/
public void setCatalog(String catalog) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.setCatalog(catalog);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @return the current catalog
*
* @throws SQLException if an error occurs
*/
public String getCatalog() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.getCatalog();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#isClosed()
*/
public boolean isClosed() throws SQLException {
return (closed || mc.isClosed());
}
/**
* @see Connection#setHoldability(int)
*/
public void setHoldability(int arg0) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.setHoldability(arg0);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#getHoldability()
*/
public int getHoldability() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.getHoldability();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Allows clients to determine how long this connection has been idle.
*
* @return how long the connection has been idle.
*/
public long getIdleFor() {
return ((com.mysql.jdbc.Connection) mc).getIdleFor();
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @return a metadata instance
*
* @throws SQLException if an error occurs
*/
public java.sql.DatabaseMetaData getMetaData() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.getMetaData();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#setReadOnly()
*/
public void setReadOnly(boolean readOnly) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.setReadOnly(readOnly);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#isReadOnly()
*/
public boolean isReadOnly() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.isReadOnly();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#setSavepoint()
*/
public java.sql.Savepoint setSavepoint() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.setSavepoint();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#setSavepoint(String)
*/
public java.sql.Savepoint setSavepoint(String arg0)
throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.setSavepoint(arg0);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#setTransactionIsolation()
*/
public void setTransactionIsolation(int level) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.setTransactionIsolation(level);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#getTransactionIsolation()
*/
public int getTransactionIsolation() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.getTransactionIsolation();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#setTypeMap()
*/
public void setTypeMap(java.util.Map map) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.setTypeMap(map);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#getTypeMap()
*/
public java.util.Map getTypeMap() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.getTypeMap();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#getWarnings
*/
public java.sql.SQLWarning getWarnings() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.getWarnings();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @throws SQLException if an error occurs
*/
public void clearWarnings() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.clearWarnings();
} catch (SQLException sqlException) {
mpc.callListener(2, sqlException);
throw sqlException;
}
}
}
/**
* The physical connection is not actually closed. the physical connection
* is closed when the application server calls
* mysqlPooledConnection.close(). this object is de-referenced by the
* pooled connection each time mysqlPooledConnection.getConnection() is
* called by app server.
*
* @throws SQLException if an error occurs
*/
public void close() throws SQLException {
close(true);
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @throws SQLException if an error occurs
*/
public void commit() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.commit();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#createStatement()
*/
public java.sql.Statement createStatement() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.createStatement();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#createStatement()
*/
public java.sql.Statement createStatement(int resultSetType,
int resultSetConcurrency) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.createStatement(resultSetType, resultSetConcurrency);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#createStatement(int, int, int)
*/
public java.sql.Statement createStatement(int arg0, int arg1, int arg2)
throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.createStatement(arg0, arg1, arg2);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#nativeSQL()
*/
public String nativeSQL(String sql) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.nativeSQL(sql);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#prepareCall()
*/
public java.sql.CallableStatement prepareCall(String sql)
throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareCall(sql);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#prepareCall()
*/
public java.sql.CallableStatement prepareCall(String sql,
int resultSetType, int resultSetConcurrency) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareCall(sql, resultSetType, resultSetConcurrency);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#prepareCall(String, int, int, int)
*/
public java.sql.CallableStatement prepareCall(String arg0, int arg1,
int arg2, int arg3) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareCall(arg0, arg1, arg2, arg3);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#prepareStatement()
*/
public java.sql.PreparedStatement prepareStatement(String sql)
throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareStatement(sql);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#prepareStatement()
*/
public java.sql.PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareStatement(sql, resultSetType,
resultSetConcurrency);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#prepareStatement(String, int, int, int)
*/
public java.sql.PreparedStatement prepareStatement(String arg0, int arg1,
int arg2, int arg3) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareStatement(arg0, arg1, arg2, arg3);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#prepareStatement(String, int)
*/
public java.sql.PreparedStatement prepareStatement(String arg0, int arg1)
throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareStatement(arg0, arg1);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#prepareStatement(String, int[])
*/
public java.sql.PreparedStatement prepareStatement(String arg0, int[] arg1)
throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareStatement(arg0, arg1);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#prepareStatement(String, String[])
*/
public java.sql.PreparedStatement prepareStatement(String arg0,
String[] arg1) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
return mc.prepareStatement(arg0, arg1);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#releaseSavepoint(Savepoint)
*/
public void releaseSavepoint(Savepoint arg0) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.releaseSavepoint(arg0);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* Passes call to method on physical connection instance. Notifies
* listeners of any caught exceptions before re-throwing to client.
*
* @see java.sql.Connection#rollback()
*/
public void rollback() throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.rollback();
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
/**
* @see Connection#rollback(Savepoint)
*/
public void rollback(Savepoint arg0) throws SQLException {
if (closed) {
throw new SQLException(invalidHandleStr);
} else {
try {
mc.rollback(arg0);
} catch (SQLException sqlException) {
mpc.callListener(MysqlPooledConnection.CONNECTION_ERROR_EVENT,
sqlException);
throw sqlException;
}
}
}
protected void close(boolean fireClosedEvent)
throws SQLException {
synchronized (this.mpc) {
if (closed) {
return;
}
if (fireClosedEvent) {
mpc.callListener(MysqlPooledConnection.CONNECTION_CLOSED_EVENT, null);
}
// set closed status to true so that if application client tries to make additional
// calls a sqlException will be thrown. The physical connection is
// re-used by the pooled connection each time getConnection is called.
closed = true;
}
}
}