glenn 02/05/16 14:25:38 Modified: dbcp/src/java/org/apache/commons/dbcp BasicDataSource.java BasicDataSourceFactory.java DelegatingConnection.java DelegatingPreparedStatement.java DelegatingStatement.java PoolableConnection.java PoolableConnectionFactory.java PoolablePreparedStatement.java PoolingDataSource.java Added: dbcp/src/java/org/apache/commons/dbcp AbandonedConfig.java AbandonedObjectPool.java AbandonedTrace.java DelegatingCallableStatement.java DelegatingResultSet.java Log: I have expanded upon the work James House did to generate stack traces for abandoned db connections. (Thanks James) The patch he provided was refactored and some new features added. Three new DBCP parameters were added: removeAbandoned - True or false. If true abandoned db connections are removed after the removeAbandonedTimout is exceeded if the dbcp is nearing exhaustion. removeAbandonedTimeout - Time in seconds since a connection was last used before it is considered abandoned. logAbandoned - True or false. If true Exception stack traces are created so that the source of an abandoned db connection can be logged. While reviewing the code I noticed that Statements and ResultSets were not being closed when a Connection was closed (recycled). This behaviour differs from the JDBC spec which states that the underlying Statements and ResultSets should be closed when a Connection is closed. This patch tracks Statements and ResultSets so that when the Connection which created them is closed they are closed also. This patch should be backward compatible with any code which uses the existing DBCP. Revision Changes Path 1.7 +76 -7 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSource.java Index: BasicDataSource.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSource.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- BasicDataSource.java 1 May 2002 06:27:52 -0000 1.6 +++ BasicDataSource.java 16 May 2002 21:25:37 -0000 1.7 @@ -1,6 +1,6 @@ -/** $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSource.java,v 1.6 2002/05/01 06:27:52 rwaldhoff Exp $ - * $Revision: 1.6 $ - * $Date: 2002/05/01 06:27:52 $ +/** $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSource.java,v 1.7 2002/05/16 21:25:37 glenn Exp $ + * $Revision: 1.7 $ + * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * @@ -79,8 +79,9 @@ * combine the <em>commons-dbcp</em> and <em>commons-pool</em> packages, * but provides a "one stop shopping" solution for basic requirements.</p> * + * @author Glenn L. Nielsen * @author Craig R. McClanahan - * @version $Revision: 1.6 $ $Date: 2002/05/01 06:27:52 $ + * @version $Revision: 1.7 $ $Date: 2002/05/16 21:25:37 $ */ public class BasicDataSource implements DataSource { @@ -382,6 +383,75 @@ } + private AbandonedConfig abandonedConfig; + + /** + * Flag to remove abandoned connections if they exceed the + * removeAbandonedTimout. + * + * Set to true or false, default false. + * If set to true a connection is considered abandoned and eligible + * for removal if it has been idle longer than the removeAbandonedTimeout. + * Setting this to true can recover db connections from poorly written + * applications which fail to close a connection. + */ + public boolean getRemoveAbandoned() { + if (abandonedConfig != null) { + return abandonedConfig.getRemoveAbandoned(); + } + return false; + } + + public void setRemoveAbandoned(boolean removeAbandoned) { + if (abandonedConfig == null) { + abandonedConfig = new AbandonedConfig(); + } + abandonedConfig.setRemoveAbandoned(removeAbandoned); + } + + /** + * Timeout in seconds before an abandoned connection can be removed. + * + * Defaults to 300 seconds. + */ + public int getRemoveAbandonedTimeout() { + if (abandonedConfig != null) { + return abandonedConfig.getRemoveAbandonedTimeout(); + } + return 300; + } + + public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) { + if (abandonedConfig == null) { + abandonedConfig = new AbandonedConfig(); + } + abandonedConfig.setRemoveAbandonedTimeout(removeAbandonedTimeout); + } + + /** + * Flag to log stack traces for application code which abandoned + * a Statement or Connection. + * + * Defaults to false. + * + * Logging of abandoned Statements and Connections adds overhead + * for every Connection open or new Statement because a stack + * trace has to be generated. + */ + public boolean getLogAbandoned() { + if (abandonedConfig != null) { + return abandonedConfig.getLogAbandoned(); + } + return false; + } + + public void setLogAbandoned(boolean logAbandoned) { + if (abandonedConfig == null) { + abandonedConfig = new AbandonedConfig(); + } + abandonedConfig.setLogAbandoned(logAbandoned); + } + // --------------------------------------------------------- Public Methods @@ -492,9 +562,8 @@ null, // FIXME - stmtPoolFactory? validationQuery, defaultReadOnly, - defaultAutoCommit); - } catch(SQLException e) { - throw e; + defaultAutoCommit, + abandonedConfig); } catch(RuntimeException e) { throw e; } catch(Exception e) { 1.2 +22 -7 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSourceFactory.java Index: BasicDataSourceFactory.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSourceFactory.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- BasicDataSourceFactory.java 16 Jan 2002 00:19:36 -0000 1.1 +++ BasicDataSourceFactory.java 16 May 2002 21:25:37 -0000 1.2 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSourceFactory.java,v 1.1 2002/01/16 00:19:36 craigmcc Exp $ - * $Revision: 1.1 $ - * $Date: 2002/01/16 00:19:36 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/BasicDataSourceFactory.java,v 1.2 2002/05/16 21:25:37 glenn Exp $ + * $Revision: 1.2 $ + * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * @@ -78,7 +78,7 @@ * <code>BasicDataSource</code> bean properties.</p> * * @author Craig R. McClanahan - * @version $Revision: 1.1 $ $Date: 2002/01/16 00:19:36 $ + * @version $Revision: 1.2 $ $Date: 2002/05/16 21:25:37 $ */ public class BasicDataSourceFactory implements ObjectFactory { @@ -176,12 +176,27 @@ dataSource.setValidationQuery(ra.getContent().toString()); } - // Return the configured data source instance - return (dataSource); + ra = ref.get("removeAbandoned"); + if (ra != null) { + dataSource.setRemoveAbandoned + (Boolean.getBoolean(ra.getContent().toString())); + } - } + ra = ref.get("removeAbandonedTimeout"); + if (ra != null) { + dataSource.setRemoveAbandonedTimeout + (Integer.parseInt(ra.getContent().toString())); + } + ra = ref.get("logAbandoned"); + if (ra != null) { + dataSource.setLogAbandoned + (Boolean.getBoolean(ra.getContent().toString())); + } + // Return the configured data source instance + return (dataSource); + } } 1.4 +103 -13 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingConnection.java Index: DelegatingConnection.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingConnection.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- DelegatingConnection.java 3 Apr 2002 11:57:16 -0000 1.3 +++ DelegatingConnection.java 16 May 2002 21:25:37 -0000 1.4 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingConnection.java,v 1.3 2002/04/03 11:57:16 rwaldhoff Exp $ - * $Revision: 1.3 $ - * $Date: 2002/04/03 11:57:16 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingConnection.java,v 1.4 2002/05/16 21:25:37 glenn Exp $ + * $Revision: 1.4 $ + * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * @@ -63,6 +63,8 @@ import java.sql.*; import java.util.Map; +import java.util.List; +import java.util.Iterator; /** * A base delegating implementation of {@link Connection}. @@ -71,21 +73,47 @@ * simply check to see that the {@link Connection} is active, * and call the corresponding method on the "delegate" * provided in my constructor. + * <p> + * Extends AbandonedTrace to implement Connection tracking and + * logging of code which created the Connection. Tracking the + * Connection ensures that the AbandonedObjectPool can close + * this connection and recycle it if its pool of connections + * is nearing exhaustion and this connection's last usage is + * older than the removeAbandonedTimeout. * * @author Rodney Waldhoff - * @version $Id: DelegatingConnection.java,v 1.3 2002/04/03 11:57:16 rwaldhoff Exp $ + * @author Glenn L. Nielsen + * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) + * @version $Id: DelegatingConnection.java,v 1.4 2002/05/16 21:25:37 glenn Exp $ */ -public class DelegatingConnection implements Connection { +public class DelegatingConnection extends AbandonedTrace + implements Connection { /** My delegate {@link Connection}. */ protected Connection _conn = null; protected boolean _closed = false; /** - * Constructor. + * Create a wrapper for the Connectin which traces this + * Connection in the AbandonedObjectPool. + * * @param c the {@link Connection} to delegate all calls to. */ public DelegatingConnection(Connection c) { + super(); + _conn = c; + } + + /** + * Create a wrapper for the Connection which traces + * the Statements created so that any unclosed Statements + * can be closed when this Connection is closed. + * + * @param Connection the {@link Connection} to delegate all calls to. + * @param AbandonedConfig the configuration for tracing abandoned objects + */ + public DelegatingConnection(Connection c, AbandonedConfig config) { + super(config); _conn = c; } @@ -128,11 +156,77 @@ _conn = c; } + /** + * Closes the underlying connection, and close + * any Statements that were not explicitly closed. + */ + public void close() throws SQLException + { + // The JDBC spec requires that a Connection close any open + // Statement's when it is closed. + List statements = getTrace(); + if( statements != null) { + Iterator it = statements.iterator(); + while(it.hasNext()) { + ((ResultSet)it.next()).close(); + } + clearTrace(); + } + passivate(); + _conn.close(); + } + + public Statement createStatement() throws SQLException { + checkOpen(); + + return new DelegatingStatement(this, _conn.createStatement()); + } + + public Statement createStatement(int resultSetType, + int resultSetConcurrency) + throws SQLException { + checkOpen(); + + return new DelegatingStatement + (this, _conn.createStatement(resultSetType,resultSetConcurrency)); + } + + public PreparedStatement prepareStatement(String sql) throws SQLException { + checkOpen(); + + return new DelegatingPreparedStatement + (this, _conn.prepareStatement(sql)); + } + + public PreparedStatement prepareStatement(String sql, + int resultSetType, + int resultSetConcurrency) + throws SQLException { + checkOpen(); + + return new DelegatingPreparedStatement + (this, _conn.prepareStatement + (sql,resultSetType,resultSetConcurrency)); + } + + public CallableStatement prepareCall(String sql) throws SQLException { + checkOpen(); + + return new DelegatingCallableStatement(this, _conn.prepareCall(sql)); + } + + public CallableStatement prepareCall(String sql, + int resultSetType, + int resultSetConcurrency) + throws SQLException { + checkOpen(); + + return new DelegatingCallableStatement + (this, _conn.prepareCall(sql, resultSetType,resultSetConcurrency)); + } + public void clearWarnings() throws SQLException { checkOpen(); _conn.clearWarnings();} - public void close() throws SQLException { passivate(); _conn.close();} public void commit() throws SQLException { checkOpen(); _conn.commit();} - public Statement createStatement() throws SQLException { checkOpen(); return _conn.createStatement();} - public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { checkOpen(); return _conn.createStatement(resultSetType,resultSetConcurrency);} public boolean getAutoCommit() throws SQLException { checkOpen(); return _conn.getAutoCommit();} public String getCatalog() throws SQLException { checkOpen(); return _conn.getCatalog();} public DatabaseMetaData getMetaData() throws SQLException { checkOpen(); return _conn.getMetaData();} @@ -142,10 +236,6 @@ public boolean isClosed() throws SQLException { return _closed || _conn.isClosed();} public boolean isReadOnly() throws SQLException { checkOpen(); return _conn.isReadOnly();} public String nativeSQL(String sql) throws SQLException { checkOpen(); return _conn.nativeSQL(sql);} - public CallableStatement prepareCall(String sql) throws SQLException { checkOpen(); return _conn.prepareCall(sql);} - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { checkOpen(); return _conn.prepareCall(sql,resultSetType,resultSetConcurrency);} - public PreparedStatement prepareStatement(String sql) throws SQLException { checkOpen(); return _conn.prepareStatement(sql);} - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { checkOpen(); return _conn.prepareStatement(sql,resultSetType,resultSetConcurrency);} public void rollback() throws SQLException { checkOpen(); _conn.rollback();} public void setAutoCommit(boolean autoCommit) throws SQLException { checkOpen(); _conn.setAutoCommit(autoCommit);} public void setCatalog(String catalog) throws SQLException { checkOpen(); _conn.setCatalog(catalog);} 1.3 +73 -11 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java Index: DelegatingPreparedStatement.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DelegatingPreparedStatement.java 19 Mar 2002 06:05:34 -0000 1.2 +++ DelegatingPreparedStatement.java 16 May 2002 21:25:37 -0000 1.3 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java,v 1.2 2002/03/19 06:05:34 craigmcc Exp $ - * $Revision: 1.2 $ - * $Date: 2002/03/19 06:05:34 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingPreparedStatement.java,v 1.3 2002/05/16 21:25:37 glenn Exp $ + * $Revision: 1.3 $ + * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * @@ -66,6 +66,8 @@ import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; +import java.util.List; +import java.util.Iterator; /** * A base delegating implementation of {@link PreparedStatement}. @@ -74,19 +76,36 @@ * simply check to see that the {@link PreparedStatement} is active, * and call the corresponding method on the "delegate" * provided in my constructor. + * <p> + * Extends AbandonedTrace to implement Statement tracking and + * logging of code which created the Statement. Tracking the + * Statement ensures that the Connection which created it can + * close any open Statement's on Connection close. * * @author Rodney Waldhoff + * @author Glenn L. Nielsen + * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) */ -public class DelegatingPreparedStatement implements PreparedStatement { +public class DelegatingPreparedStatement extends AbandonedTrace + implements PreparedStatement { /** My delegate. */ protected PreparedStatement _stmt = null; + /** The connection that created me. **/ + protected DelegatingConnection _conn = null; /** - * Constructor. + * Create a wrapper for the Statement which traces this + * Statement to the Connection which created it and the + * code which created it. + * * @param s the {@link PreparedStatement} to delegate all calls to. + * @param c the {@link DelegatingConnection} that created this statement. */ - public DelegatingPreparedStatement(PreparedStatement s) { + public DelegatingPreparedStatement(DelegatingConnection c, + PreparedStatement s) { + super(c); _stmt = s; + _conn = c; } /** @@ -128,9 +147,55 @@ _stmt = s; } - public ResultSet executeQuery(String sql) throws SQLException { checkOpen(); return _stmt.executeQuery(sql);} + /** + * Close this DelegatingPreparedStatement, and close + * any ResultSets that were not explicitly closed. + */ + public void close() throws SQLException { + if(_conn != null) { + _conn.removeTrace(this); + _conn = null; + } + + // The JDBC spec requires that a statment close any open + // ResultSet's when it is closed. + List resultSets = getTrace(); + if( resultSets != null) { + Iterator it = resultSets.iterator(); + while(it.hasNext()) { + ((ResultSet)it.next()).close(); + } + clearTrace(); + } + + passivate(); + _stmt.close(); + } + + public Connection getConnection() throws SQLException { + checkOpen(); + return _conn; // return the delegating connection that created this + } + + public ResultSet executeQuery(String sql) throws SQLException { + checkOpen(); + + return new DelegatingResultSet(this, _stmt.executeQuery(sql)); + } + + public ResultSet getResultSet() throws SQLException { + checkOpen(); + + return new DelegatingResultSet(this, _stmt.getResultSet()); + } + + public ResultSet executeQuery() throws SQLException { + checkOpen(); + + return new DelegatingResultSet(this, _stmt.executeQuery()); + } + public int executeUpdate(String sql) throws SQLException { checkOpen(); return _stmt.executeUpdate(sql);} - public void close() throws SQLException { passivate(); _stmt.close(); } public int getMaxFieldSize() throws SQLException { checkOpen(); return _stmt.getMaxFieldSize();} public void setMaxFieldSize(int max) throws SQLException { checkOpen();_stmt.setMaxFieldSize(max);} public int getMaxRows() throws SQLException { checkOpen();return _stmt.getMaxRows();} @@ -143,7 +208,6 @@ public void clearWarnings() throws SQLException { checkOpen(); _stmt.clearWarnings();} public void setCursorName(String name) throws SQLException { checkOpen(); _stmt.setCursorName(name);} public boolean execute(String sql) throws SQLException { checkOpen(); return _stmt.execute(sql);} - public ResultSet getResultSet() throws SQLException { checkOpen(); return _stmt.getResultSet();} public int getUpdateCount() throws SQLException { checkOpen(); return _stmt.getUpdateCount();} public boolean getMoreResults() throws SQLException { checkOpen(); return _stmt.getMoreResults();} public void setFetchDirection(int direction) throws SQLException { checkOpen(); _stmt.setFetchDirection(direction);} @@ -155,9 +219,7 @@ public void addBatch(String sql) throws SQLException { checkOpen(); _stmt.addBatch(sql);} public void clearBatch() throws SQLException { checkOpen(); _stmt.clearBatch();} public int[] executeBatch() throws SQLException { checkOpen(); return _stmt.executeBatch();} - public Connection getConnection() throws SQLException { checkOpen(); return _stmt.getConnection();} - public ResultSet executeQuery() throws SQLException { checkOpen(); return _stmt.executeQuery();} public int executeUpdate() throws SQLException { checkOpen(); return _stmt.executeUpdate();} public void setNull(int parameterIndex, int sqlType) throws SQLException { checkOpen(); _stmt.setNull(parameterIndex,sqlType);} public void setBoolean(int parameterIndex, boolean x) throws SQLException { checkOpen(); _stmt.setBoolean(parameterIndex,x);} 1.3 +66 -10 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingStatement.java Index: DelegatingStatement.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingStatement.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- DelegatingStatement.java 19 Mar 2002 06:05:34 -0000 1.2 +++ DelegatingStatement.java 16 May 2002 21:25:38 -0000 1.3 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingStatement.java,v 1.2 2002/03/19 06:05:34 craigmcc Exp $ - * $Revision: 1.2 $ - * $Date: 2002/03/19 06:05:34 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingStatement.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ + * $Revision: 1.3 $ + * $Date: 2002/05/16 21:25:38 $ * * ==================================================================== * @@ -63,6 +63,9 @@ import java.sql.*; +import java.util.List; +import java.util.Iterator; + /** * A base delegating implementation of {@link Statement}. * <p> @@ -70,19 +73,34 @@ * simply check to see that the {@link Statement} is active, * and call the corresponding method on the "delegate" * provided in my constructor. + * <p> + * Extends AbandonedTrace to implement Statement tracking and + * logging of code which created the Statement. Tracking the + * Statement ensures that the Connection which created it can + * close any open Statement's on Connection close. * * @author Rodney Waldhoff (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) + * @author Glenn L. Nielsen + * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) */ -public class DelegatingStatement implements Statement { +public class DelegatingStatement extends AbandonedTrace implements Statement { /** My delegate. */ protected Statement _stmt = null; + /** The connection that created me. **/ + protected DelegatingConnection _conn = null; /** - * Constructor. + * Create a wrapper for the Statement which traces this + * Statement to the Connection which created it and the + * code which created it. + * * @param s the {@link Statement} to delegate all calls to. + * @param c the {@link DelegatingConnection} that created this statement. */ - public DelegatingStatement(Statement s) { + public DelegatingStatement(DelegatingConnection c, Statement s) { + super(c); _stmt = s; + _conn = c; } /** @@ -124,9 +142,49 @@ _stmt = s; } - public ResultSet executeQuery(String sql) throws SQLException { checkOpen(); return _stmt.executeQuery(sql);} + /** + * Close this DelegatingStatement, and close + * any ResultSets that were not explicitly closed. + */ + public void close() throws SQLException { + if (_conn != null) { + _conn.removeTrace(this); + _conn = null; + } + + // The JDBC spec requires that a statment close any open + // ResultSet's when it is closed. + List resultSets = getTrace(); + if( resultSets != null) { + Iterator it = resultSets.iterator(); + while(it.hasNext()) { + ((ResultSet)it.next()).close(); + } + clearTrace(); + } + + passivate(); + _stmt.close(); + } + + public Connection getConnection() throws SQLException { + checkOpen(); + return _conn; // return the delegating connection that created this + } + + public ResultSet executeQuery(String sql) throws SQLException { + checkOpen(); + + return new DelegatingResultSet(this, _stmt.executeQuery(sql)); + } + + public ResultSet getResultSet() throws SQLException { + checkOpen(); + + return new DelegatingResultSet(this, _stmt.getResultSet()); + } + public int executeUpdate(String sql) throws SQLException { checkOpen(); return _stmt.executeUpdate(sql);} - public void close() throws SQLException { passivate(); _stmt.close();} public int getMaxFieldSize() throws SQLException { checkOpen(); return _stmt.getMaxFieldSize();} public void setMaxFieldSize(int max) throws SQLException { checkOpen(); _stmt.setMaxFieldSize(max);} public int getMaxRows() throws SQLException { checkOpen(); return _stmt.getMaxRows();} @@ -139,7 +197,6 @@ public void clearWarnings() throws SQLException { checkOpen(); _stmt.clearWarnings();} public void setCursorName(String name) throws SQLException { checkOpen(); _stmt.setCursorName(name);} public boolean execute(String sql) throws SQLException { checkOpen(); return _stmt.execute(sql);} - public ResultSet getResultSet() throws SQLException { checkOpen(); return _stmt.getResultSet();} public int getUpdateCount() throws SQLException { checkOpen(); return _stmt.getUpdateCount();} public boolean getMoreResults() throws SQLException { checkOpen(); return _stmt.getMoreResults();} public void setFetchDirection(int direction) throws SQLException { checkOpen(); _stmt.setFetchDirection(direction);} @@ -151,7 +208,6 @@ public void addBatch(String sql) throws SQLException { checkOpen(); _stmt.addBatch(sql);} public void clearBatch() throws SQLException { checkOpen(); _stmt.clearBatch();} public int[] executeBatch() throws SQLException { checkOpen(); return _stmt.executeBatch();} - public Connection getConnection() throws SQLException { checkOpen(); return _stmt.getConnection();} protected void checkOpen() throws SQLException { if(_closed) { 1.3 +21 -4 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnection.java Index: PoolableConnection.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnection.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PoolableConnection.java 17 Mar 2002 14:55:20 -0000 1.2 +++ PoolableConnection.java 16 May 2002 21:25:38 -0000 1.3 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnection.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ - * $Revision: 1.2 $ - * $Date: 2002/03/17 14:55:20 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnection.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ + * $Revision: 1.3 $ + * $Date: 2002/05/16 21:25:38 $ * * ==================================================================== * @@ -71,7 +71,9 @@ * closed. * * @author Rodney Waldhoff - * @version $Id: PoolableConnection.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ + * @author Glenn L. Nielsen + * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) + * @version $Id: PoolableConnection.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ */ public class PoolableConnection extends DelegatingConnection { /** The pool to which I should return. */ @@ -88,10 +90,24 @@ } /** + * + * @param conn my underlying connection + * @param pool the pool to which I should return when closed + * @param config the abandoned configuration settings + */ + public PoolableConnection(Connection conn, ObjectPool pool, + AbandonedConfig config) { + super(conn, config); + _pool = pool; + } + + + /** * Returns me to my pool. */ public void close() throws SQLException { try { + setLastUsed(0); _pool.returnObject(this); } catch(SQLException e) { throw e; @@ -108,5 +124,6 @@ public void reallyClose() throws SQLException { _conn.close(); } + } 1.3 +32 -6 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java Index: PoolableConnectionFactory.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PoolableConnectionFactory.java 17 Mar 2002 14:55:20 -0000 1.2 +++ PoolableConnectionFactory.java 16 May 2002 21:25:38 -0000 1.3 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ - * $Revision: 1.2 $ - * $Date: 2002/03/17 14:55:20 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolableConnectionFactory.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ + * $Revision: 1.3 $ + * $Date: 2002/05/16 21:25:38 $ * * ==================================================================== * @@ -72,7 +72,9 @@ * {@link PoolableConnection}s. * * @author Rodney Waldhoff - * @version $Id: PoolableConnectionFactory.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ + * @author Glenn L. Nielsen + * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) + * @version $Id: PoolableConnectionFactory.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ */ public class PoolableConnectionFactory implements PoolableObjectFactory { /** @@ -95,6 +97,27 @@ } /** + * Create a new <tt>PoolableConnectionFactory</tt>. + * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s + * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s + * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link PreparedStatement}s, or <tt>null</tt> to disable {@link PreparedStatement} pooling + * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s. Should return at least one row. May be <tt>null</tt> + * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s + * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s + * @param config the AbandonedConfig if tracing SQL objects + */ + public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, boolean defaultReadOnly, boolean defaultAutoCommit, AbandonedConfig config) { + _connFactory = connFactory; + _pool = pool; + _config = config; + _pool.setFactory(this); + _stmtPoolFactory = stmtPoolFactory; + _validationQuery = validationQuery; + _defaultReadOnly = defaultReadOnly; + _defaultAutoCommit = defaultAutoCommit; + } + + /** * Sets the {@link ConnectionFactory} from which to obtain base {@link Connection}s. * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s */ @@ -174,7 +197,7 @@ conn = new PoolingConnection(conn,stmtpool); stmtpool.setFactory((PoolingConnection)conn); } - return new PoolableConnection(conn,_pool); + return new PoolableConnection(conn,_pool,_config); } public void destroyObject(Object obj) throws Exception { @@ -212,6 +235,8 @@ return false; } } catch(Exception e) { + return false; + } finally { try { rset.close(); } catch(Exception t) { @@ -222,7 +247,7 @@ } catch(Exception t) { // ignored } - return false; + } } else { return true; @@ -283,4 +308,5 @@ protected KeyedObjectPoolFactory _stmtPoolFactory = null; protected boolean _defaultReadOnly = false; protected boolean _defaultAutoCommit = true; + protected AbandonedConfig _config = null; } 1.3 +7 -5 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java Index: PoolablePreparedStatement.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PoolablePreparedStatement.java 17 Mar 2002 14:55:20 -0000 1.2 +++ PoolablePreparedStatement.java 16 May 2002 21:25:38 -0000 1.3 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ - * $Revision: 1.2 $ - * $Date: 2002/03/17 14:55:20 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolablePreparedStatement.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ + * $Revision: 1.3 $ + * $Date: 2002/05/16 21:25:38 $ * * ==================================================================== * @@ -74,7 +74,9 @@ * * @see PoolingConnection * @author Rodney Waldhoff - * @version $Id: PoolablePreparedStatement.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ + * @author Glenn L. Nielsen + * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) + * @version $Id: PoolablePreparedStatement.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ */ public class PoolablePreparedStatement extends DelegatingPreparedStatement implements PreparedStatement { /** @@ -100,7 +102,7 @@ * @param conn the {@link Connection} from which I was created */ public PoolablePreparedStatement(PreparedStatement stmt, Object key, KeyedObjectPool pool, Connection conn) { - super(stmt); + super((DelegatingConnection) conn, stmt); _pool = pool; _key = key; _conn = conn; 1.3 +7 -5 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolingDataSource.java Index: PoolingDataSource.java =================================================================== RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolingDataSource.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- PoolingDataSource.java 17 Mar 2002 14:55:20 -0000 1.2 +++ PoolingDataSource.java 16 May 2002 21:25:38 -0000 1.3 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolingDataSource.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ - * $Revision: 1.2 $ - * $Date: 2002/03/17 14:55:20 $ + * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolingDataSource.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ + * $Revision: 1.3 $ + * $Date: 2002/05/16 21:25:38 $ * * ==================================================================== * @@ -77,7 +77,9 @@ * {@link Connection}s from the specified {@link ObjectPool}. * * @author Rodney Waldhoff - * @version $Id: PoolingDataSource.java,v 1.2 2002/03/17 14:55:20 rwaldhoff Exp $ + * @author Glenn L. Nielsen + * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) + * @version $Id: PoolingDataSource.java,v 1.3 2002/05/16 21:25:38 glenn Exp $ */ public class PoolingDataSource implements DataSource { public PoolingDataSource() { @@ -103,7 +105,7 @@ * Return a {@link java.sql.Connection} from my pool, * according to the contract specified by {@link ObjectPool#borrowObject}. */ - public synchronized Connection getConnection() throws SQLException { + public Connection getConnection() throws SQLException { try { return (Connection)(_pool.borrowObject()); } catch(SQLException e) { 1.1 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/AbandonedConfig.java Index: AbandonedConfig.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/AbandonedConfig.java,v 1.1 2002/05/16 21:25:37 glenn Exp $ * $Revision: 1.1 $ * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.commons.dbcp; /** * Configuration settings for handling abandoned db connections. * * @author Glenn L. Nielsen * @version $Revision: 1.1 $ $Date: 2002/05/16 21:25:37 $ */ public class AbandonedConfig { private boolean removeAbandoned = false; /** * Flag to remove abandoned connections if they exceed the * removeAbandonedTimeout. * * Set to true or false, default false. * If set to true a connection is considered abandoned and eligible * for removal if it has been idle longer than the removeAbandonedTimeout. * Setting this to true can recover db connections from poorly written * applications which fail to close a connection. * * @return boolean */ public boolean getRemoveAbandoned() { return (this.removeAbandoned); } /** * Flag to remove abandoned connections if they exceed the * removeAbandonedTimeout. * * Set to true or false, default false. * If set to true a connection is considered abandoned and eligible * for removal if it has been idle longer than the removeAbandonedTimeout. * Setting this to true can recover db connections from poorly written * applications which fail to close a connection. * * @param boolean */ public void setRemoveAbandoned(boolean removeAbandoned) { this.removeAbandoned = removeAbandoned; } private int removeAbandonedTimeout = 300; /** * Timeout in seconds before an abandoned connection can be removed. * * Defaults to 300 seconds. * * @return int remove abandoned timeout in seconds */ public int getRemoveAbandonedTimeout() { return (this.removeAbandonedTimeout); } /** * Timeout in seconds before an abandoned connection can be removed. * * Defaults to 300 seconds. * * @param int remove abandoned timeout in seconds */ public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) { this.removeAbandonedTimeout = removeAbandonedTimeout; } private boolean logAbandoned = false; /** * Flag to log stack traces for application code which abandoned * a Statement or Connection. * * Defaults to false. * Logging of abandoned Statements and Connections adds overhead * for every Connection open or new Statement because a stack * trace has to be generated. * * @return boolean */ public boolean getLogAbandoned() { return (this.logAbandoned); } /** * Flag to log stack traces for application code which abandoned * a Statement or Connection. * * Defaults to false. * Logging of abandoned Statements and Connections adds overhead * for every Connection open or new Statement because a stack * trace has to be generated. * * @param boolean */ public void setLogAbandoned(boolean logAbandoned) { this.logAbandoned = logAbandoned; } } 1.1 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/AbandonedObjectPool.java Index: AbandonedObjectPool.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/AbandonedObjectPool.java,v 1.1 2002/05/16 21:25:37 glenn Exp $ * $Revision: 1.1 $ * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.commons.dbcp; import java.sql.SQLException; import java.util.Date; import java.util.Iterator; import java.util.List; import org.apache.commons.collections.FastArrayList; import org.apache.commons.pool.PoolableObjectFactory; import org.apache.commons.pool.impl.GenericObjectPool; /** * <p>An implementation of a Jakarta-Commons ObjectPool which * tracks JDBC connections and can recover abandoned db connections. * If logAbandoned=true, a stack trace will be printed for any * abandoned db connections recovered. * * @author Glenn L. Nielsen * @version $Revision: 1.1 $ $Date: 2002/05/16 21:25:37 $ */ public class AbandonedObjectPool extends GenericObjectPool { // DBCP AbandonedConfig private AbandonedConfig config = null; // A list of connections in use private List trace = new FastArrayList(); /** * Create an ObjectPool which tracks db connections. * * @param PoolableObjectFactory factory used to create this * @param AbandonedConfig configuration for abandoned db connections */ public AbandonedObjectPool(PoolableObjectFactory factory, AbandonedConfig config) { super(factory); this.config = config; ((FastArrayList)trace).setFast(true); } /** * Get a db connection from the pool. * * If removeAbandoned=true, recovers db connections which * have been idle > removeAbandonedTimeout. * * @return Object jdbc Connection */ public Object borrowObject() throws Exception { if (config != null && config.getRemoveAbandoned() && (getNumIdle() < 2) && (getNumActive() > getMaxActive() - 3) ) { removeAbandoned(); } Object obj = super.borrowObject(); if (obj != null && config != null && config.getRemoveAbandoned()) { trace.add(obj); } return obj; } /** * Return a db connection to the pool. * * @param Object db Connection to return */ public void returnObject(Object obj) throws Exception { if (config != null && config.getRemoveAbandoned()) { trace.remove(obj); } super.returnObject(obj); } /** * Recover abandoned db connections which have been idle * greater than the removeAbandonedTimeout. */ private synchronized void removeAbandoned() { long now = new Date().getTime(); long timeout = now - (config.getRemoveAbandonedTimeout() * 1000); Iterator it = trace.iterator(); while (it.hasNext()) { PoolableConnection pc = (PoolableConnection)it.next(); if (pc.getLastUsed() > timeout) { return; } if (pc.getLastUsed() > 0) { if (config.getLogAbandoned()) { pc.printStackTrace(); } try { pc.close(); } catch(SQLException e) { e.printStackTrace(); } } } } } 1.1 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/AbandonedTrace.java Index: AbandonedTrace.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/AbandonedTrace.java,v 1.1 2002/05/16 21:25:37 glenn Exp $ * $Revision: 1.1 $ * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.commons.dbcp; import java.util.Date; import java.util.Iterator; import java.util.List; import org.apache.commons.collections.FastArrayList; /** * Tracks db connection usage for recovering and reporting * abandoned db connections. * * The JDBC Connection, Statement, and ResultSet classes * extend this class. * * @author Glenn L. Nielsen * @version $Revision: 1.1 $ $Date: 2002/05/16 21:25:37 $ */ public class AbandonedTrace { private static String MESSAGE = "DBCP object was created, but never closed by the following code: "; // DBCP AbandonedConfig private AbandonedConfig config = null; // Parent object private AbandonedTrace parent; // A stack trace of the code that created me (if in debug mode) **/ private Exception createdBy; // A list of objects created by children of this object private List trace = new FastArrayList(); // Last time this connection was used private long lastUsed = 0; /** * Create a new AbandonedTrace without config and * without doing abandoned tracing. */ public AbandonedTrace() { init(parent); } /** * Construct a new AbandonedTrace with no parent object. * * @param AbandonedConfig */ public AbandonedTrace(AbandonedConfig config) { this.config = config; init(parent); } /** * Construct a new AbandonedTrace with a parent object. * * @param AbandonedTrace parent object */ public AbandonedTrace(AbandonedTrace parent) { this.config = parent.getConfig(); init(parent); } /** * Initialize abandoned tracing for this object. * * @param AbandonedTrace parent object */ private void init(AbandonedTrace parent) { if (parent != null) { parent.addTrace(this); } ((FastArrayList)trace).setFast(true); if (config == null) { return; } if (config.getLogAbandoned()) { createdBy = new Exception(MESSAGE); } } /** * Get the abandoned config for this object. * * @return AbandonedConfig for this object */ protected AbandonedConfig getConfig() { return config; } /** * Get the last time this object was used in ms. * * @return long time in ms */ protected long getLastUsed() { if (parent != null) { return parent.getLastUsed(); } return lastUsed; } /** * Set the time this object was last used to the * current time in ms. */ protected void setLastUsed() { if (parent != null) { parent.setLastUsed(); } else { lastUsed = new Date().getTime(); } } /** * Set the time in ms this object was last used. * * @param long time in ms */ protected void setLastUsed(long time) { if (parent != null) { parent.setLastUsed(time); } else { lastUsed = time; } } /** * If logAbandoned=true generate a stack trace * for this object then add this object to the parent * object trace list. */ protected void setStackTrace() { if (config == null) { return; } if (config.getLogAbandoned()) { createdBy = new Exception(MESSAGE); } if (parent != null) { parent.addTrace(this); } } /** * Add an object to the list of objects being * traced. * * @param AbandonedTrace object to add */ protected void addTrace(AbandonedTrace trace) { this.trace.add(trace); setLastUsed(); } /** * Clear the list of objects being traced by this * object. */ protected void clearTrace() { if (trace != null) { trace.clear(); } } /** * Get a list of objects being traced by this object. * * @return List of objects */ protected List getTrace() { return trace; } /** * If logAbandoned=true, print a stack trace of the code that * created this object. */ public void printStackTrace() { if (createdBy != null) { createdBy.printStackTrace(); } Iterator it = trace.iterator(); while (it.hasNext()) { AbandonedTrace at = (AbandonedTrace)it.next(); at.printStackTrace(); } } /** * Remove a child object this object is tracing. * * @param AbandonedTrace object to remvoe */ protected void removeTrace(AbandonedTrace trace) { if (this.trace != null) { this.trace.remove(trace); } } } 1.1 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java Index: DelegatingCallableStatement.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingCallableStatement.java,v 1.1 2002/05/16 21:25:37 glenn Exp $ * $Revision: 1.1 $ * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.commons.dbcp; import java.sql.CallableStatement; import java.math.BigDecimal; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.util.Map; import java.sql.Ref; import java.sql.Blob; import java.sql.Clob; import java.sql.Array; import java.util.Calendar; import java.sql.ResultSet; import java.io.InputStream; import java.io.Reader; import java.sql.ResultSetMetaData; import java.sql.SQLWarning; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import java.util.Iterator; /** * A base delegating implementation of {@link CallableStatement}. * <p> * All of the methods from the {@link CallableStatement} interface * simply call the corresponding method on the "delegate" * provided in my constructor. * <p> * Extends AbandonedTrace to implement Statement tracking and * logging of code which created the Statement. Tracking the * Statement ensures that the Connection which created it can * close any open Statement's on Connection close. * * @author Glenn L. Nielsen * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) */ public class DelegatingCallableStatement extends AbandonedTrace implements CallableStatement { /** My delegate. */ protected CallableStatement _stmt = null; /** The connection that created me. **/ protected DelegatingConnection _conn = null; /** * Create a wrapper for the Statement which traces this * Statement to the Connection which created it and the * code which created it. * * @param cs the {@link CallableStatement} to delegate all calls to. */ public DelegatingCallableStatement(DelegatingConnection c, CallableStatement s) { super(c); _conn = c; _stmt = s; } /** * Close this DelegatingCallableStatement, and close * any ResultSets that were not explicitly closed. */ public void close() throws SQLException { if(_conn != null) { _conn.removeTrace(this); _conn = null; } // The JDBC spec requires that a statment close any open // ResultSet's when it is closed. List resultSets = getTrace(); if( resultSets != null) { Iterator it = resultSets.iterator(); while(it.hasNext()) { ((ResultSet)it.next()).close(); } clearTrace(); } _stmt.close(); } public Connection getConnection() throws SQLException { return _conn; } public ResultSet executeQuery() throws SQLException { return new DelegatingResultSet(this, _stmt.executeQuery()); } public ResultSet getResultSet() throws SQLException { return new DelegatingResultSet(this, _stmt.getResultSet()); } public ResultSet executeQuery(String sql) throws SQLException { return new DelegatingResultSet(this, _stmt.executeQuery(sql)); } public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException { _stmt.registerOutParameter( parameterIndex, sqlType); } public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException { _stmt.registerOutParameter( parameterIndex, sqlType, scale); } public boolean wasNull() throws SQLException { return _stmt.wasNull(); } public String getString(int parameterIndex) throws SQLException { return _stmt.getString( parameterIndex); } public boolean getBoolean(int parameterIndex) throws SQLException { return _stmt.getBoolean( parameterIndex); } public byte getByte(int parameterIndex) throws SQLException { return _stmt.getByte( parameterIndex); } public short getShort(int parameterIndex) throws SQLException { return _stmt.getShort( parameterIndex); } public int getInt(int parameterIndex) throws SQLException { return _stmt.getInt( parameterIndex); } public long getLong(int parameterIndex) throws SQLException { return _stmt.getLong( parameterIndex); } public float getFloat(int parameterIndex) throws SQLException { return _stmt.getFloat( parameterIndex); } public double getDouble(int parameterIndex) throws SQLException { return _stmt.getDouble( parameterIndex); } public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { return _stmt.getBigDecimal( parameterIndex, scale); } public byte[] getBytes(int parameterIndex) throws SQLException { return _stmt.getBytes( parameterIndex); } public Date getDate(int parameterIndex) throws SQLException { return _stmt.getDate( parameterIndex); } public Time getTime(int parameterIndex) throws SQLException { return _stmt.getTime( parameterIndex); } public Timestamp getTimestamp(int parameterIndex) throws SQLException { return _stmt.getTimestamp( parameterIndex); } public Object getObject(int parameterIndex) throws SQLException { return _stmt.getObject( parameterIndex); } public BigDecimal getBigDecimal(int parameterIndex) throws SQLException { return _stmt.getBigDecimal( parameterIndex); } public Object getObject(int i, Map map) throws SQLException { return _stmt.getObject( i, map); } public Ref getRef(int i) throws SQLException { return _stmt.getRef( i); } public Blob getBlob(int i) throws SQLException { return _stmt.getBlob( i); } public Clob getClob(int i) throws SQLException { return _stmt.getClob( i); } public Array getArray(int i) throws SQLException { return _stmt.getArray( i); } public Date getDate(int parameterIndex, Calendar cal) throws SQLException { return _stmt.getDate( parameterIndex, cal); } public Time getTime(int parameterIndex, Calendar cal) throws SQLException { return _stmt.getTime( parameterIndex, cal); } public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException { return _stmt.getTimestamp( parameterIndex, cal); } public void registerOutParameter(int paramIndex, int sqlType, String typeName) throws SQLException { _stmt.registerOutParameter( paramIndex, sqlType, typeName); } public int executeUpdate() throws SQLException { return _stmt.executeUpdate(); } public void setNull(int parameterIndex, int sqlType) throws SQLException { _stmt.setNull( parameterIndex, sqlType); } public void setBoolean(int parameterIndex, boolean x) throws SQLException { _stmt.setBoolean( parameterIndex, x); } public void setByte(int parameterIndex, byte x) throws SQLException { _stmt.setByte( parameterIndex, x); } public void setShort(int parameterIndex, short x) throws SQLException { _stmt.setShort( parameterIndex, x); } public void setInt(int parameterIndex, int x) throws SQLException { _stmt.setInt( parameterIndex, x); } public void setLong(int parameterIndex, long x) throws SQLException { _stmt.setLong( parameterIndex, x); } public void setFloat(int parameterIndex, float x) throws SQLException { _stmt.setFloat( parameterIndex, x); } public void setDouble(int parameterIndex, double x) throws SQLException { _stmt.setDouble( parameterIndex, x); } public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { _stmt.setBigDecimal( parameterIndex, x); } public void setString(int parameterIndex, String x) throws SQLException { _stmt.setString( parameterIndex, x); } public void setBytes(int parameterIndex, byte[] x) throws SQLException { _stmt.setBytes( parameterIndex, x); } public void setDate(int parameterIndex, Date x) throws SQLException { _stmt.setDate( parameterIndex, x); } public void setTime(int parameterIndex, Time x) throws SQLException { _stmt.setTime( parameterIndex, x); } public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { _stmt.setTimestamp( parameterIndex, x); } public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { _stmt.setAsciiStream( parameterIndex, x, length); } public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { _stmt.setUnicodeStream( parameterIndex, x, length); } public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { _stmt.setBinaryStream( parameterIndex, x, length); } public void clearParameters() throws SQLException { _stmt.clearParameters(); } public void setObject(int parameterIndex, Object x, int targetSqlType, int scale) throws SQLException { _stmt.setObject( parameterIndex, x, targetSqlType, scale); } public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { _stmt.setObject( parameterIndex, x, targetSqlType); } public void setObject(int parameterIndex, Object x) throws SQLException { _stmt.setObject( parameterIndex, x); } public boolean execute() throws SQLException { return _stmt.execute(); } public void addBatch() throws SQLException { _stmt.addBatch(); } public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { _stmt.setCharacterStream( parameterIndex, reader, length); } public void setRef(int i, Ref x) throws SQLException { _stmt.setRef( i, x); } public void setBlob(int i, Blob x) throws SQLException { _stmt.setBlob( i, x); } public void setClob(int i, Clob x) throws SQLException { _stmt.setClob( i, x); } public void setArray(int i, Array x) throws SQLException { _stmt.setArray( i, x); } public ResultSetMetaData getMetaData() throws SQLException { return _stmt.getMetaData(); } public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { _stmt.setDate( parameterIndex, x, cal); } public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { _stmt.setTime( parameterIndex, x, cal); } public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { _stmt.setTimestamp( parameterIndex, x, cal); } public void setNull(int paramIndex, int sqlType, String typeName) throws SQLException { _stmt.setNull( paramIndex, sqlType, typeName); } public int executeUpdate(String sql) throws SQLException { return _stmt.executeUpdate( sql); } public int getMaxFieldSize() throws SQLException { return _stmt.getMaxFieldSize(); } public void setMaxFieldSize(int max) throws SQLException { _stmt.setMaxFieldSize( max); } public int getMaxRows() throws SQLException { return _stmt.getMaxRows(); } public void setMaxRows(int max) throws SQLException { _stmt.setMaxRows( max); } public void setEscapeProcessing(boolean enable) throws SQLException { _stmt.setEscapeProcessing( enable); } public int getQueryTimeout() throws SQLException { return _stmt.getQueryTimeout(); } public void setQueryTimeout(int seconds) throws SQLException { _stmt.setQueryTimeout( seconds); } public void cancel() throws SQLException { _stmt.cancel(); } public SQLWarning getWarnings() throws SQLException { return _stmt.getWarnings(); } public void clearWarnings() throws SQLException { _stmt.clearWarnings(); } public void setCursorName(String name) throws SQLException { _stmt.setCursorName( name); } public boolean execute(String sql) throws SQLException { return _stmt.execute( sql); } public int getUpdateCount() throws SQLException { return _stmt.getUpdateCount(); } public boolean getMoreResults() throws SQLException { return _stmt.getMoreResults(); } public void setFetchDirection(int direction) throws SQLException { _stmt.setFetchDirection( direction); } public int getFetchDirection() throws SQLException { return _stmt.getFetchDirection(); } public void setFetchSize(int rows) throws SQLException { _stmt.setFetchSize( rows); } public int getFetchSize() throws SQLException { return _stmt.getFetchSize(); } public int getResultSetConcurrency() throws SQLException { return _stmt.getResultSetConcurrency(); } public int getResultSetType() throws SQLException { return _stmt.getResultSetType(); } public void addBatch(String sql) throws SQLException { _stmt.addBatch( sql); } public void clearBatch() throws SQLException { _stmt.clearBatch(); } public int[] executeBatch() throws SQLException { return _stmt.executeBatch(); } } 1.1 jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingResultSet.java Index: DelegatingResultSet.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/DelegatingResultSet.java,v 1.1 2002/05/16 21:25:37 glenn Exp $ * $Revision: 1.1 $ * $Date: 2002/05/16 21:25:37 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * */ package org.apache.commons.dbcp; import java.sql.ResultSet; import java.math.BigDecimal; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.io.InputStream; import java.sql.SQLWarning; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.io.Reader; import java.sql.Statement; import java.util.Map; import java.sql.Ref; import java.sql.Blob; import java.sql.Clob; import java.sql.Array; import java.util.Calendar; /** * A base delegating implementation of {@link ResultSet}. * <p> * All of the methods from the {@link ResultSet} interface * simply call the corresponding method on the "delegate" * provided in my constructor. * <p> * Extends AbandonedTrace to implement result set tracking and * logging of code which created the ResultSet. Tracking the * ResultSet ensures that the Statment which created it can * close any open ResultSet's on Statement close. * * @author Glenn L. Nielsen * @author James House (<a href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>) */ public class DelegatingResultSet extends AbandonedTrace implements ResultSet { /** My delegate. **/ private ResultSet _res; /** The Statement that created me, if any. **/ private Statement _stmt; /** * Create a wrapper for the ResultSet which traces this * ResultSet to the Statement which created it and the * code which created it. * * @param Statement stmt which create this ResultSet * @param ResultSet to wrap */ public DelegatingResultSet(Statement stmt, ResultSet res) { super((AbandonedTrace)stmt); this._stmt = stmt; this._res = res; } public Statement getStatement() throws SQLException { return _stmt; } /** * Wrapper for close of ResultSet which removes this * result set from being traced then calls close on * the original ResultSet. */ public void close() throws SQLException { if(_stmt != null) { ((AbandonedTrace)_stmt).removeTrace(this); _stmt = null; } _res.close(); } public boolean next() throws SQLException { return _res.next(); } public boolean wasNull() throws SQLException { return _res.wasNull(); } public String getString(int columnIndex) throws SQLException { return _res.getString(columnIndex); } public boolean getBoolean(int columnIndex) throws SQLException { return _res.getBoolean(columnIndex); } public byte getByte(int columnIndex) throws SQLException { return _res.getByte(columnIndex); } public short getShort(int columnIndex) throws SQLException { return _res.getShort(columnIndex); } public int getInt(int columnIndex) throws SQLException { return _res.getInt(columnIndex); } public long getLong(int columnIndex) throws SQLException { return _res.getLong(columnIndex); } public float getFloat(int columnIndex) throws SQLException { return _res.getFloat(columnIndex); } public double getDouble(int columnIndex) throws SQLException { return _res.getDouble(columnIndex); } public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { return _res.getBigDecimal(columnIndex); } public byte[] getBytes(int columnIndex) throws SQLException { return _res.getBytes(columnIndex); } public Date getDate(int columnIndex) throws SQLException { return _res.getDate(columnIndex); } public Time getTime(int columnIndex) throws SQLException { return _res.getTime(columnIndex); } public Timestamp getTimestamp(int columnIndex) throws SQLException { return _res.getTimestamp(columnIndex); } public InputStream getAsciiStream(int columnIndex) throws SQLException { return _res.getAsciiStream(columnIndex); } public InputStream getUnicodeStream(int columnIndex) throws SQLException { return _res.getUnicodeStream(columnIndex); } public InputStream getBinaryStream(int columnIndex) throws SQLException { return _res.getBinaryStream(columnIndex); } public String getString(String columnName) throws SQLException { return _res.getString(columnName); } public boolean getBoolean(String columnName) throws SQLException { return _res.getBoolean(columnName); } public byte getByte(String columnName) throws SQLException { return _res.getByte(columnName); } public short getShort(String columnName) throws SQLException { return _res.getShort(columnName); } public int getInt(String columnName) throws SQLException { return _res.getInt(columnName); } public long getLong(String columnName) throws SQLException { return _res.getLong(columnName); } public float getFloat(String columnName) throws SQLException { return _res.getFloat(columnName); } public double getDouble(String columnName) throws SQLException { return _res.getDouble(columnName); } public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { return _res.getBigDecimal(columnName); } public byte[] getBytes(String columnName) throws SQLException { return _res.getBytes(columnName); } public Date getDate(String columnName) throws SQLException { return _res.getDate(columnName); } public Time getTime(String columnName) throws SQLException { return _res.getTime(columnName); } public Timestamp getTimestamp(String columnName) throws SQLException { return _res.getTimestamp(columnName); } public InputStream getAsciiStream(String columnName) throws SQLException { return _res.getAsciiStream(columnName); } public InputStream getUnicodeStream(String columnName) throws SQLException { return _res.getUnicodeStream(columnName); } public InputStream getBinaryStream(String columnName) throws SQLException { return _res.getBinaryStream(columnName); } public SQLWarning getWarnings() throws SQLException { return _res.getWarnings(); } public void clearWarnings() throws SQLException { _res.clearWarnings(); } public String getCursorName() throws SQLException { return _res.getCursorName(); } public ResultSetMetaData getMetaData() throws SQLException { return _res.getMetaData(); } public Object getObject(int columnIndex) throws SQLException { return _res.getObject(columnIndex); } public Object getObject(String columnName) throws SQLException { return _res.getObject(columnName); } public int findColumn(String columnName) throws SQLException { return _res.findColumn(columnName); } public Reader getCharacterStream(int columnIndex) throws SQLException { return _res.getCharacterStream(columnIndex); } public Reader getCharacterStream(String columnName) throws SQLException { return _res.getCharacterStream(columnName); } public BigDecimal getBigDecimal(int columnIndex) throws SQLException { return _res.getBigDecimal(columnIndex); } public BigDecimal getBigDecimal(String columnName) throws SQLException { return _res.getBigDecimal(columnName); } public boolean isBeforeFirst() throws SQLException { return _res.isBeforeFirst(); } public boolean isAfterLast() throws SQLException { return _res.isAfterLast(); } public boolean isFirst() throws SQLException { return _res.isFirst(); } public boolean isLast() throws SQLException { return _res.isLast(); } public void beforeFirst() throws SQLException { _res.beforeFirst(); } public void afterLast() throws SQLException { _res.afterLast(); } public boolean first() throws SQLException { return _res.first(); } public boolean last() throws SQLException { return _res.last(); } public int getRow() throws SQLException { return _res.getRow(); } public boolean absolute(int row) throws SQLException { return _res.absolute(row); } public boolean relative(int rows) throws SQLException { return _res.relative(rows); } public boolean previous() throws SQLException { return _res.previous(); } public void setFetchDirection(int direction) throws SQLException { _res.setFetchDirection(direction); } public int getFetchDirection() throws SQLException { return _res.getFetchDirection(); } public void setFetchSize(int rows) throws SQLException { _res.setFetchSize(rows); } public int getFetchSize() throws SQLException { return _res.getFetchSize(); } public int getType() throws SQLException { return _res.getType(); } public int getConcurrency() throws SQLException { return _res.getConcurrency(); } public boolean rowUpdated() throws SQLException { return _res.rowUpdated(); } public boolean rowInserted() throws SQLException { return _res.rowInserted(); } public boolean rowDeleted() throws SQLException { return _res.rowDeleted(); } public void updateNull(int columnIndex) throws SQLException { _res.updateNull(columnIndex); } public void updateBoolean(int columnIndex, boolean x) throws SQLException { _res.updateBoolean(columnIndex, x); } public void updateByte(int columnIndex, byte x) throws SQLException { _res.updateByte(columnIndex, x); } public void updateShort(int columnIndex, short x) throws SQLException { _res.updateShort(columnIndex, x); } public void updateInt(int columnIndex, int x) throws SQLException { _res.updateInt(columnIndex, x); } public void updateLong(int columnIndex, long x) throws SQLException { _res.updateLong(columnIndex, x); } public void updateFloat(int columnIndex, float x) throws SQLException { _res.updateFloat(columnIndex, x); } public void updateDouble(int columnIndex, double x) throws SQLException { _res.updateDouble(columnIndex, x); } public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { _res.updateBigDecimal(columnIndex, x); } public void updateString(int columnIndex, String x) throws SQLException { _res.updateString(columnIndex, x); } public void updateBytes(int columnIndex, byte[] x) throws SQLException { _res.updateBytes(columnIndex, x); } public void updateDate(int columnIndex, Date x) throws SQLException { _res.updateDate(columnIndex, x); } public void updateTime(int columnIndex, Time x) throws SQLException { _res.updateTime(columnIndex, x); } public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { _res.updateTimestamp(columnIndex, x); } public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { _res.updateAsciiStream(columnIndex, x, length); } public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { _res.updateBinaryStream(columnIndex, x, length); } public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { _res.updateCharacterStream(columnIndex, x, length); } public void updateObject(int columnIndex, Object x, int scale) throws SQLException { _res.updateObject(columnIndex, x); } public void updateObject(int columnIndex, Object x) throws SQLException { _res.updateObject(columnIndex, x); } public void updateNull(String columnName) throws SQLException { _res.updateNull(columnName); } public void updateBoolean(String columnName, boolean x) throws SQLException { _res.updateBoolean(columnName, x); } public void updateByte(String columnName, byte x) throws SQLException { _res.updateByte(columnName, x); } public void updateShort(String columnName, short x) throws SQLException { _res.updateShort(columnName, x); } public void updateInt(String columnName, int x) throws SQLException { _res.updateInt(columnName, x); } public void updateLong(String columnName, long x) throws SQLException { _res.updateLong(columnName, x); } public void updateFloat(String columnName, float x) throws SQLException { _res.updateFloat(columnName, x); } public void updateDouble(String columnName, double x) throws SQLException { _res.updateDouble(columnName, x); } public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { _res.updateBigDecimal(columnName, x); } public void updateString(String columnName, String x) throws SQLException { _res.updateString(columnName, x); } public void updateBytes(String columnName, byte[] x) throws SQLException { _res.updateBytes(columnName, x); } public void updateDate(String columnName, Date x) throws SQLException { _res.updateDate(columnName, x); } public void updateTime(String columnName, Time x) throws SQLException { _res.updateTime(columnName, x); } public void updateTimestamp(String columnName, Timestamp x) throws SQLException { _res.updateTimestamp(columnName, x); } public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException { _res.updateAsciiStream(columnName, x, length); } public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException { _res.updateBinaryStream(columnName, x, length); } public void updateCharacterStream(String columnName, Reader reader, int length) throws SQLException { _res.updateCharacterStream(columnName, reader, length); } public void updateObject(String columnName, Object x, int scale) throws SQLException { _res.updateObject(columnName, x); } public void updateObject(String columnName, Object x) throws SQLException { _res.updateObject(columnName, x); } public void insertRow() throws SQLException { _res.insertRow(); } public void updateRow() throws SQLException { _res.updateRow(); } public void deleteRow() throws SQLException { _res.deleteRow(); } public void refreshRow() throws SQLException { _res.refreshRow(); } public void cancelRowUpdates() throws SQLException { _res.cancelRowUpdates(); } public void moveToInsertRow() throws SQLException { _res.moveToInsertRow(); } public void moveToCurrentRow() throws SQLException { _res.moveToCurrentRow(); } public Object getObject(int i, Map map) throws SQLException { return _res.getObject(i, map); } public Ref getRef(int i) throws SQLException { return _res.getRef(i); } public Blob getBlob(int i) throws SQLException { return _res.getBlob(i); } public Clob getClob(int i) throws SQLException { return _res.getClob(i); } public Array getArray(int i) throws SQLException { return _res.getArray(i); } public Object getObject(String colName, Map map) throws SQLException { return _res.getObject(colName, map); } public Ref getRef(String colName) throws SQLException { return _res.getRef(colName); } public Blob getBlob(String colName) throws SQLException { return _res.getBlob(colName); } public Clob getClob(String colName) throws SQLException { return _res.getClob(colName); } public Array getArray(String colName) throws SQLException { return _res.getArray(colName); } public Date getDate(int columnIndex, Calendar cal) throws SQLException { return _res.getDate(columnIndex, cal); } public Date getDate(String columnName, Calendar cal) throws SQLException { return _res.getDate(columnName, cal); } public Time getTime(int columnIndex, Calendar cal) throws SQLException { return _res.getTime(columnIndex, cal); } public Time getTime(String columnName, Calendar cal) throws SQLException { return _res.getTime(columnName, cal); } public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { return _res.getTimestamp(columnIndex, cal); } public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { return _res.getTimestamp(columnName, cal); } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>