You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by di...@apache.org on 2004/05/17 20:39:44 UTC

cvs commit: jakarta-commons/dbcp/src/java/org/apache/commons/dbcp PoolingDriver.java

dirkv       2004/05/17 11:39:44

  Modified:    dbcp/src/java/org/apache/commons/dbcp PoolingDriver.java
  Log:
  Bugzilla Bug 28912: (PoolingDriver) Connection re-use conflates logical and physical connections
  - implement a PoolGuardConnectionWrapper for PoolingDriver
  - make error reporting behave like PoolingDataSource
  
  Revision  Changes    Path
  1.12      +295 -4    jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolingDriver.java
  
  Index: PoolingDriver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/PoolingDriver.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- PoolingDriver.java	28 Feb 2004 12:18:17 -0000	1.11
  +++ PoolingDriver.java	17 May 2004 18:39:44 -0000	1.12
  @@ -18,12 +18,19 @@
   
   import java.io.IOException;
   import java.io.InputStream;
  +import java.sql.CallableStatement;
   import java.sql.Connection;
  +import java.sql.DatabaseMetaData;
   import java.sql.Driver;
   import java.sql.DriverManager;
   import java.sql.DriverPropertyInfo;
  +import java.sql.PreparedStatement;
   import java.sql.SQLException;
  +import java.sql.SQLWarning;
  +import java.sql.Statement;
   import java.util.HashMap;
  +import java.util.Map;
  +import java.util.NoSuchElementException;
   import java.util.Properties;
   import java.util.Set;
   
  @@ -53,10 +60,33 @@
       /** The map of registered pools. */
       protected static HashMap _pools = new HashMap();
   
  +    /** Controls access to the underlying connection */
  +    private static boolean accessToUnderlyingConnectionAllowed = false; 
  +
       public PoolingDriver() {
       }
   
       /**
  +     * Returns the value of the accessToUnderlyingConnectionAllowed property.
  +     * 
  +     * @return true if access to the underlying is allowed, false otherwise.
  +     */
  +    public static synchronized boolean isAccessToUnderlyingConnectionAllowed() {
  +        return accessToUnderlyingConnectionAllowed;
  +    }
  +
  +    /**
  +     * Sets the value of the accessToUnderlyingConnectionAllowed property.
  +     * It controls if the PoolGuard allows access to the underlying connection.
  +     * (Default: false)
  +     * 
  +     * @param allow Access to the underlying connection is granted when true.
  +     */
  +    public static synchronized void setAccessToUnderlyingConnectionAllowed(boolean allow) {
  +        accessToUnderlyingConnectionAllowed = allow;
  +    }
  +
  +    /**
        * WARNING: This method throws DbcpExceptions (RuntimeExceptions)
        * and will be replaced by the protected getConnectionPool method.
        * 
  @@ -142,11 +172,19 @@
                   throw new SQLException("No pool found for " + url + ".");
               } else {
                   try {
  -                    return (Connection)(pool.borrowObject());
  +                    Connection conn = (Connection)(pool.borrowObject());
  +                    if (conn != null) {
  +                        conn = new PoolGuardConnectionWrapper(conn);
  +                    } 
  +                    return conn;
                   } catch(SQLException e) {
                       throw e;
  -                } catch(Throwable e) {
  -                    throw new SQLNestedException("Connect failed", e);
  +                } catch(NoSuchElementException e) {
  +                    throw new SQLNestedException("Cannot get a connection, pool exhausted", e);
  +                } catch(RuntimeException e) {
  +                    throw e;
  +                } catch(Exception e) {
  +                    throw new SQLNestedException("Cannot get a connection, general error", e);
                   }
               }
           } else {
  @@ -178,4 +216,257 @@
       protected static int MAJOR_VERSION = 1;
       protected static int MINOR_VERSION = 0;
   
  +    /**
  +     * PoolGuardConnectionWrapper is a Connection wrapper that makes sure a 
  +     * closed connection cannot be used anymore.
  +     */
  +    private class PoolGuardConnectionWrapper extends DelegatingConnection {
  +
  +        private Connection delegate;
  +    
  +        PoolGuardConnectionWrapper(Connection delegate) {
  +            super(delegate);
  +            this.delegate = delegate;
  +        }
  +
  +        protected void checkOpen() throws SQLException {
  +            if(delegate == null) {
  +                throw new SQLException("Connection is closed.");
  +            }
  +        }
  +    
  +        public void close() throws SQLException {
  +            checkOpen();
  +            this.delegate.close();
  +            this.delegate = null;
  +            super.setDelegate(null);
  +        }
  +
  +        public boolean isClosed() throws SQLException {
  +            if (delegate == null) {
  +                return true;
  +            }
  +            return delegate.isClosed();
  +        }
  +
  +        public void clearWarnings() throws SQLException {
  +            checkOpen();
  +            delegate.clearWarnings();
  +        }
  +
  +        public void commit() throws SQLException {
  +            checkOpen();
  +            delegate.commit();
  +        }
  +
  +        public Statement createStatement() throws SQLException {
  +            checkOpen();
  +            return delegate.createStatement();
  +        }
  +
  +        public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
  +            checkOpen();
  +            return delegate.createStatement(resultSetType, resultSetConcurrency);
  +        }
  +
  +        public boolean equals(Object obj) {
  +            if (delegate == null){
  +                return false;
  +            }
  +            return delegate.equals(obj);
  +        }
  +
  +        public boolean getAutoCommit() throws SQLException {
  +            checkOpen();
  +            return delegate.getAutoCommit();
  +        }
  +
  +        public String getCatalog() throws SQLException {
  +            checkOpen();
  +            return delegate.getCatalog();
  +        }
  +
  +        public DatabaseMetaData getMetaData() throws SQLException {
  +            checkOpen();
  +            return delegate.getMetaData();
  +        }
  +
  +        public int getTransactionIsolation() throws SQLException {
  +            checkOpen();
  +            return delegate.getTransactionIsolation();
  +        }
  +
  +        public Map getTypeMap() throws SQLException {
  +            checkOpen();
  +            return delegate.getTypeMap();
  +        }
  +
  +        public SQLWarning getWarnings() throws SQLException {
  +            checkOpen();
  +            return delegate.getWarnings();
  +        }
  +
  +        public int hashCode() {
  +            if (delegate == null){
  +                return 0;
  +            }
  +            return delegate.hashCode();
  +        }
  +
  +        public boolean isReadOnly() throws SQLException {
  +            checkOpen();
  +            return delegate.isReadOnly();
  +        }
  +
  +        public String nativeSQL(String sql) throws SQLException {
  +            checkOpen();
  +            return delegate.nativeSQL(sql);
  +        }
  +
  +        public CallableStatement prepareCall(String sql) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareCall(sql);
  +        }
  +
  +        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareCall(sql, resultSetType, resultSetConcurrency);
  +        }
  +
  +        public PreparedStatement prepareStatement(String sql) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareStatement(sql);
  +        }
  +
  +        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareStatement(sql, resultSetType, resultSetConcurrency);
  +        }
  +
  +        public void rollback() throws SQLException {
  +            checkOpen();
  +            delegate.rollback();
  +        }
  +
  +        public void setAutoCommit(boolean autoCommit) throws SQLException {
  +            checkOpen();
  +            delegate.setAutoCommit(autoCommit);
  +        }
  +
  +        public void setCatalog(String catalog) throws SQLException {
  +            checkOpen();
  +            delegate.setCatalog(catalog);
  +        }
  +
  +        public void setReadOnly(boolean readOnly) throws SQLException {
  +            checkOpen();
  +            delegate.setReadOnly(readOnly);
  +        }
  +
  +        public void setTransactionIsolation(int level) throws SQLException {
  +            checkOpen();
  +            delegate.setTransactionIsolation(level);
  +        }
  +
  +        public void setTypeMap(Map map) throws SQLException {
  +            checkOpen();
  +            delegate.setTypeMap(map);
  +        }
  +
  +        public String toString() {
  +            if (delegate == null){
  +                return null;
  +            }
  +            return delegate.toString();
  +        }
  +
  +        // ------------------- JDBC 3.0 -----------------------------------------
  +        // Will be commented by the build process on a JDBC 2.0 system
  +
  +/* JDBC_3_ANT_KEY_BEGIN */
  +
  +        public int getHoldability() throws SQLException {
  +            checkOpen();
  +            return delegate.getHoldability();
  +        }
  +    
  +        public void setHoldability(int holdability) throws SQLException {
  +            checkOpen();
  +            delegate.setHoldability(holdability);
  +        }
  +
  +        public java.sql.Savepoint setSavepoint() throws SQLException {
  +            checkOpen();
  +            return delegate.setSavepoint();
  +        }
  +
  +        public java.sql.Savepoint setSavepoint(String name) throws SQLException {
  +            checkOpen();
  +            return delegate.setSavepoint(name);
  +        }
  +
  +        public void releaseSavepoint(java.sql.Savepoint savepoint) throws SQLException {
  +            checkOpen();
  +            delegate.releaseSavepoint(savepoint);
  +        }
  +
  +        public void rollback(java.sql.Savepoint savepoint) throws SQLException {
  +            checkOpen();
  +            delegate.rollback(savepoint);
  +        }
  +
  +        public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
  +            checkOpen();
  +            return delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
  +        }
  +
  +        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
  +        }
  +
  +        public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareStatement(sql, autoGeneratedKeys);
  +        }
  +
  +        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
  +        }
  +
  +        public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareStatement(sql, columnIndexes);
  +        }
  +
  +        public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
  +            checkOpen();
  +            return delegate.prepareStatement(sql, columnNames);
  +        }
  +
  +/* JDBC_3_ANT_KEY_END */
  +
  +        /**
  +         * @see org.apache.commons.dbcp.DelegatingConnection#getDelegate()
  +         */
  +        public Connection getDelegate() {
  +            if (isAccessToUnderlyingConnectionAllowed()) {
  +                return super.getDelegate();
  +            } else {
  +                return null;
  +            }
  +        }
  +
  +        /**
  +         * @see org.apache.commons.dbcp.DelegatingConnection#getInnermostDelegate()
  +         */
  +        public Connection getInnermostDelegate() {
  +            if (isAccessToUnderlyingConnectionAllowed()) {
  +                return super.getInnermostDelegate();
  +            } else {
  +                return null;
  +            }
  +        }
  +    }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org