jmcnally    2002/11/16 11:18:28

  Modified:    dbcp/src/java/org/apache/commons/dbcp/jdbc2pool
                        CPDSConnectionFactory.java Jdbc2PoolDataSource.java
                        KeyedCPDSConnectionFactory.java PoolKey.java
                        UserPassKey.java
               dbcp/src/test/org/apache/commons/dbcp/jdbc2pool
                        TestJdbc2PoolDataSource.java
  Added:       dbcp/src/java/org/apache/commons/dbcp/jdbc2pool
                        PooledConnectionAndInfo.java
  Log:
  Removed pools of PoolKey and UserPassKey and made the keys immutable.
  
  Storing the username and password used to obtain a PooledConnection along
  with the connection, so that it can be checked on later requests for the
  same connection.
  
  Revision  Changes    Path
  1.3       +34 -13    
jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/CPDSConnectionFactory.java
  
  Index: CPDSConnectionFactory.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/CPDSConnectionFactory.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- CPDSConnectionFactory.java        1 Nov 2002 16:03:20 -0000       1.2
  +++ CPDSConnectionFactory.java        16 Nov 2002 19:18:27 -0000      1.3
  @@ -63,6 +63,7 @@
   
   import java.util.Map;
   import java.util.HashMap;
  +import java.util.WeakHashMap;
   import java.sql.*;
   import javax.sql.ConnectionPoolDataSource;
   import javax.sql.PooledConnection;
  @@ -153,9 +154,10 @@
   
   
       synchronized public Object makeObject() {
  -        PooledConnection pc = null;
  +        Object obj;
           try
           {
  +            PooledConnection pc = null;
               if ( _username == null ) 
               {
                   pc = _cpds.getPooledConnection();
  @@ -167,18 +169,21 @@
               // should we add this object as a listener or the pool.
               // consider the validateObject method in decision
               pc.addConnectionEventListener(this);
  +            obj = new PooledConnectionAndInfo(pc, _username, _password);
  +            pcMap.put(pc, obj);
           }
           catch (SQLException e)
           {
               throw new RuntimeException(e.getMessage());
           }
  -        return pc;
  +        return obj;
       }
   
       public void destroyObject(Object obj) {
  -        if(obj instanceof PooledConnection) {
  +        if(obj instanceof PooledConnectionAndInfo) {
               try {
  -                ((PooledConnection)obj).close();
  +                ((PooledConnectionAndInfo)obj)
  +                    .getPooledConnection().close();
               } catch(RuntimeException e) {
                   throw e;
               } catch(SQLException e) {
  @@ -189,8 +194,9 @@
   
       public boolean validateObject(Object obj) {
           boolean valid = false;
  -        if(obj instanceof PooledConnection) {
  -            PooledConnection pconn = (PooledConnection)obj;
  +        if(obj instanceof PooledConnectionAndInfo) {
  +            PooledConnection pconn = 
  +                ((PooledConnectionAndInfo)obj).getPooledConnection();
               String query = _validationQuery;
               if(null != query) {
                   Connection conn = null;
  @@ -264,13 +270,19 @@
           // otherwise return the connection to the pool.
           if (!validatingMap.containsKey(pc)) 
           {
  +            Object info = pcMap.get(pc);
  +            if (info == null) 
  +            {
  +                throw new IllegalStateException(NO_KEY_MESSAGE);
  +            }            
  +
               try
               {
  -                _pool.returnObject(pc);
  +                _pool.returnObject(info);
               }
               catch (Exception e)
               {
  -                destroyObject(pc);
  +                destroyObject(info);
                   System.err.println("CLOSING DOWN CONNECTION AS IT COULD " + 
                                      "NOT BE RETURNED TO THE POOL");
               }
  @@ -300,9 +312,17 @@
               // ignore
           }
   
  -        destroyObject(pc);
  +        Object info = pcMap.get(pc);
  +        if (info == null) 
  +        {
  +            throw new IllegalStateException(NO_KEY_MESSAGE);
  +        }            
  +        destroyObject(info);
       }
   
  +    private static final String NO_KEY_MESSAGE = 
  +        "close() was called on a Connection, but " + 
  +        "I have no record of the underlying PooledConnection.";
   
       protected ConnectionPoolDataSource _cpds = null;
       protected String _validationQuery = null;
  @@ -310,4 +330,5 @@
       protected String _username = null;
       protected String _password = null;
       private Map validatingMap = new HashMap();
  +    private WeakHashMap pcMap = new WeakHashMap();
   }
  
  
  
  1.7       +65 -63    
jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/Jdbc2PoolDataSource.java
  
  Index: Jdbc2PoolDataSource.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/Jdbc2PoolDataSource.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Jdbc2PoolDataSource.java  8 Nov 2002 19:17:24 -0000       1.6
  +++ Jdbc2PoolDataSource.java  16 Nov 2002 19:18:27 -0000      1.7
  @@ -83,12 +83,13 @@
   import javax.sql.PooledConnection;
   
   import org.apache.commons.collections.FastHashMap;
  +import org.apache.commons.collections.LRUMap;
   import org.apache.commons.lang.SerializationUtils;
  +import org.apache.commons.lang.ObjectUtils;
   import org.apache.commons.pool.KeyedObjectPool;
   import org.apache.commons.pool.ObjectPool;
   import org.apache.commons.pool.impl.GenericKeyedObjectPool;
   import org.apache.commons.pool.impl.GenericObjectPool;
  -import org.apache.commons.pool.impl.StackObjectPool;
   
   /**
    * <p>
  @@ -155,11 +156,8 @@
   
       private static Map dsInstanceMap = new HashMap();
   
  -    private static ObjectPool userPassKeyPool = 
  -        new StackObjectPool(new UserPassKey.Factory(), 256);
  -
  -    private static ObjectPool poolKeyPool = 
  -        new StackObjectPool(new PoolKey.Factory(), 256);
  +    private static final Map userKeys = new LRUMap(10);
  +    private static final Map poolKeys = new HashMap();
   
       private boolean getConnectionCalled = false;
   
  @@ -1042,6 +1040,7 @@
                   "through setDataSourceName or setConnectionPoolDataSource " + 
                   "before calling getConnection.");
           }
  +
           getConnectionCalled = true;
           Map pools = (Map)dsInstanceMap.get(instanceKey);
           PoolKey key = getPoolKey(username);
  @@ -1059,29 +1058,33 @@
                   throw new SQLException(e.getMessage());
               }
           }
  -        returnPoolKey(key);
   
  -        PooledConnection pc = null;
  +        PooledConnectionAndInfo info = null;        
           if (pool instanceof ObjectPool) 
           {
               try
               {
  -                pc = (PooledConnection)((ObjectPool)pool).borrowObject();
  +                info = (PooledConnectionAndInfo)
  +                    ((ObjectPool)pool).borrowObject();
               } 
               catch(NoSuchElementException e) 
               {
  +                closeDueToException(info);
                   throw new SQLException(e.getMessage());
               }
               catch(RuntimeException e) 
               {
  +                closeDueToException(info);
                   throw e;
               }
               catch(SQLException e) 
               {
  +                closeDueToException(info);
                   throw e;
               }
               catch(Exception e) 
               {
  +                closeDueToException(info);
                   throw new SQLException(e.getMessage());
               }
           }
  @@ -1089,29 +1092,39 @@
           { 
               try
               {
  -                UserPassKey upkey = getPCKey(username, password);
  -                pc = (PooledConnection)
  +                UserPassKey upkey = getUserPassKey(username, password);
  +                info = (PooledConnectionAndInfo)
                       ((KeyedObjectPool)pool).borrowObject(upkey);
  -                returnPCKey(upkey);
               }
               catch(NoSuchElementException e) 
               {
  +                closeDueToException(info);
                   throw new SQLException(e.getMessage());
               }
               catch(RuntimeException e) 
               {
  +                closeDueToException(info);
                   throw e;
               }
               catch(SQLException e) 
  -            {
  +            {            
  +                closeDueToException(info);
                   throw e;
               }
               catch(Exception e) 
               {
  +                closeDueToException(info);
                   throw new SQLException(e.getMessage());
               }
           }
  -        
  +        if (!ObjectUtils.equals(password, info.getPassword())) 
  +        {
  +            closeDueToException(info);
  +            throw new SQLException("Given password did not match password used "
  +                                   + "to create the PooledConnection.");
  +        }
  +        PooledConnection pc = info.getPooledConnection();
  +
           boolean defaultAutoCommit = isDefaultAutoCommit();
           if ( username != null ) 
           {
  @@ -1139,38 +1152,22 @@
           con.setReadOnly(defaultReadOnly);
           return con;
       }
  -
  -    private UserPassKey getPCKey(String username, String password)
  -    {
  -        UserPassKey upk = null;
  -        try
  -        {
  -            upk = (UserPassKey)userPassKeyPool.borrowObject();
  -        }
  -        catch (Exception e)
  -        {
  -            getLogWriter().println("[WARN] Jdbc2PoolDataSource::getPCKey"
  -                + " could not get key from pool. Created a new instance. "
  -                + e.getMessage());
  -            upk = new UserPassKey();
  -        }
  -        upk.init(username, password);
  -        return upk;
  -    }
  -
  -    private void returnPCKey(UserPassKey key)
  +        
  +    private void closeDueToException(PooledConnectionAndInfo info)
       {
  -        if (key.isReusable()) 
  +        if (info != null) 
           {
  -            try
  +            try 
               {
  -                userPassKeyPool.returnObject(key);
  +                info.getPooledConnection().getConnection().close();
               }
               catch (Exception e)
               {
  -                getLogWriter().println(
  -                    "[WARN] Jdbc2PoolDataSource::returnPCKey could not return"
  -                    + " key to pool. " + e.getMessage());
  +                // do not throw this exception because we are in the middle
  +                // of handling another exception.  But record it because
  +                // it potentially leaks connections from the pool.
  +                getLogWriter().println("[ERROR] Could not return connection to "
  +                    + "pool during exception handling. " + e.getMessage());   
               }
           }
       }
  @@ -1178,41 +1175,46 @@
       private PoolKey getPoolKey(String username)
       {
           PoolKey key = null;
  -        try
  -        {
  -            key = (PoolKey)poolKeyPool.borrowObject();
  -        }
  -        catch (Exception e)
  -        {
  -            getLogWriter().println("[WARN] Jdbc2PoolDataSource::getPoolKey"
  -                + " could not get key from pool. Created a new instance. "
  -                + e.getMessage());
  -            key = new PoolKey();
  -        }
  +
           if ( username != null && 
                (perUserMaxActive == null 
                 || !perUserMaxActive.containsKey(username)) ) 
           {
               username = null;
           }
  -        key.init(getDataSourceName(), username);
  -        return key;
  -    }
   
  -    private void returnPoolKey(PoolKey key)
  -    {
  -        try
  +        String dsName = getDataSourceName();
  +        Map dsMap = (Map)poolKeys.get(dsName);
  +        if (dsMap != null) 
           {
  -            poolKeyPool.returnObject(key);
  +            key = (PoolKey)dsMap.get(username);
           }
  -        catch (Exception e)
  +        
  +        if (key == null) 
           {
  -            getLogWriter().println(
  -                "[WARN] Jdbc2PoolDataSource::returnPoolKey could not return"
  -                + " key to pool. " + e.getMessage());
  +            key = new PoolKey(dsName, username);
  +            if (dsMap == null) 
  +            {
  +                dsMap = new HashMap();
  +                poolKeys.put(dsName, dsMap);
  +            }
  +            dsMap.put(username, key);
           }
  +        
  +        return key;
       }
   
  +    private UserPassKey getUserPassKey(String username, String password)
  +    {
  +        UserPassKey key = (UserPassKey)userKeys.get(username);
  +        if (key == null) 
  +        {
  +            key = new UserPassKey(username, password);
  +            userKeys.put(username, key);
  +        }
  +        return key;
  +    }
  +        
       synchronized private void registerInstance()
       {
           if (isNew) 
  
  
  
  1.3       +26 -24    
jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/KeyedCPDSConnectionFactory.java
  
  Index: KeyedCPDSConnectionFactory.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/KeyedCPDSConnectionFactory.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- KeyedCPDSConnectionFactory.java   1 Nov 2002 16:03:21 -0000       1.2
  +++ KeyedCPDSConnectionFactory.java   16 Nov 2002 19:18:27 -0000      1.3
  @@ -147,38 +147,38 @@
       }
   
       synchronized public Object makeObject(Object key) {
  +        Object obj = null;
           UserPassKey upkey = (UserPassKey)key;
  -        // since we are using the key to make a new object, we will
  -        // declare the key invalid for reuse.
  -        upkey.setReusable(false);
  -        String username = upkey.getUsername();
  -        PooledConnection pc = null;
           try
           {
  +            PooledConnection pc = null;
  +            String username = upkey.getUsername();
  +            String password = upkey.getPassword();
               if ( username == null ) 
               {
                   pc = _cpds.getPooledConnection();
               }
               else 
               {
  -                pc = _cpds.getPooledConnection(username, upkey.getPassword());
  +                pc = _cpds.getPooledConnection(username, password);
               }
               // should we add this object as a listener or the pool.
               // consider the validateObject method in decision
               pc.addConnectionEventListener(this);
  -            pcKeyMap.put(pc, key);
  +            obj = new PooledConnectionAndInfo(pc, username, password);
  +            pcMap.put(pc, obj);
           }
           catch (SQLException e)
           {
               throw new RuntimeException(e.getMessage());
           }
  -        return pc;
  +        return obj;
       }
   
       public void destroyObject(Object key, Object obj) {
  -        if(obj instanceof PooledConnection) {
  +        if(obj instanceof PooledConnectionAndInfo) {
               try {
  -                ((PooledConnection)obj).close();
  +                ((PooledConnectionAndInfo)obj).getPooledConnection().close();
               } catch(RuntimeException e) {
                   throw e;
               } catch(SQLException e) {
  @@ -189,8 +189,9 @@
   
       public boolean validateObject(Object key, Object obj) {
           boolean valid = false;
  -        if(obj instanceof PooledConnection) {
  -            PooledConnection pconn = (PooledConnection)obj;
  +        if(obj instanceof PooledConnectionAndInfo) {
  +            PooledConnection pconn = 
  +                ((PooledConnectionAndInfo)obj).getPooledConnection();
               String query = _validationQuery;
               if(null != query) {
                   Connection conn = null;
  @@ -264,18 +265,19 @@
           // otherwise return the connection to the pool.
           if (!validatingMap.containsKey(pc)) 
           {
  -            Object key = pcKeyMap.get(pc);
  -            if (key == null) 
  +            PooledConnectionAndInfo info = 
  +                (PooledConnectionAndInfo)pcMap.get(pc);
  +            if (info == null) 
               {
                   throw new IllegalStateException(NO_KEY_MESSAGE);
               }            
               try
               {
  -                _pool.returnObject(key, pc);
  +                _pool.returnObject(info.getUserPassKey(), info);
               }
               catch (Exception e)
               {
  -                destroyObject(key, pc);
  +                destroyObject(info.getUserPassKey(), info);
                   System.err.println("CLOSING DOWN CONNECTION AS IT COULD " + 
                                      "NOT BE RETURNED TO THE POOL");
               }
  @@ -305,12 +307,12 @@
               // ignore
           }
   
  -        Object key = pcKeyMap.get(pc);
  -        if (key == null) 
  +        PooledConnectionAndInfo info = (PooledConnectionAndInfo)pcMap.get(pc);
  +        if (info == null) 
           {
               throw new IllegalStateException(NO_KEY_MESSAGE);
           }            
  -        destroyObject(key, pc);
  +        destroyObject(info.getUserPassKey(), info);
       }
   
       private static final String NO_KEY_MESSAGE = 
  @@ -321,5 +323,5 @@
       protected String _validationQuery = null;
       protected KeyedObjectPool _pool = null;
       private Map validatingMap = new HashMap();
  -    private WeakHashMap pcKeyMap = new WeakHashMap();
  +    private WeakHashMap pcMap = new WeakHashMap();
   }
  
  
  
  1.2       +5 -64     
jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/PoolKey.java
  
  Index: PoolKey.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/PoolKey.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PoolKey.java      5 Aug 2002 06:42:01 -0000       1.1
  +++ PoolKey.java      16 Nov 2002 19:18:27 -0000      1.2
  @@ -56,17 +56,17 @@
    
   import java.io.Serializable;
   import org.apache.commons.lang.ObjectUtils;
  -import org.apache.commons.pool.BasePoolableObjectFactory;
   
   class PoolKey
       implements Serializable
   {
       private String datasourceName;
  -    private boolean reusable;
       private String username;
       
  -    PoolKey()
  +    PoolKey(String datasourceName, String username)
       {
  +        this.datasourceName = datasourceName;
  +        this.username = username;
       }
           
       /* *
  @@ -79,15 +79,6 @@
       }
       
       /* *
  -     * Set the value of datasourceName.
  -     * @param v  Value to assign to datasourceName.
  -     * /
  -    public void setDatasourceName(String  v) 
  -    {
  -        this.datasourceName = v;
  -    }
  -    
  -    /* *
        * Get the value of username.
        * @return value of username.
        * /
  @@ -95,30 +86,8 @@
       {
           return username;
       }
  +    */
       
  -    /* *
  -     * Set the value of username.
  -     * @param v  Value to assign to username.
  -     * /
  -    public void setUsername(String  v) 
  -    {
  -        this.username = v;
  -    }
  -    */    
  -
  -    /**
  -     * Initialize key for method with no arguments.
  -     *
  -     * @param instanceOrClass the Object on which the method is invoked.  if 
  -     * the method is static, a String representing the class name is used.
  -     * @param method the method name
  -     */
  -    void init(String username, String datasourceName) 
  -    {
  -        this.datasourceName = datasourceName;
  -        this.username = username;
  -    }
  -
       public boolean equals(Object obj)
       {
           boolean equal = false;
  @@ -141,7 +110,7 @@
           }
           if (username != null) 
           {
  -            h += username.hashCode();
  +            h = 29 * h + username.hashCode();
           }
           return h;
       }
  @@ -153,33 +122,5 @@
           sb.append(username).append(", ").append(datasourceName);
           sb.append(')');
           return sb.toString();
  -    }
  -
  -    // ************* PoolableObjectFactory implementation *******************
  -
  -    static class Factory 
  -        extends BasePoolableObjectFactory
  -    {
  -        /**
  -         * Creates an instance that can be returned by the pool.
  -         * @return an instance that can be returned by the pool.
  -         */
  -        public Object makeObject() 
  -            throws Exception
  -        {
  -            return new PoolKey();
  -        }
  -        
  -        /**
  -         * Uninitialize an instance to be returned to the pool.
  -         * @param obj the instance to be passivated
  -         */
  -        public void passivateObject(Object obj) 
  -            throws Exception
  -        {
  -            PoolKey key = (PoolKey)obj;
  -            key.datasourceName = null;
  -            key.username = null;
  -        }
       }
   }
  
  
  
  1.2       +4 -86     
jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/UserPassKey.java
  
  Index: UserPassKey.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/UserPassKey.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- UserPassKey.java  5 Aug 2002 06:42:01 -0000       1.1
  +++ UserPassKey.java  16 Nov 2002 19:18:27 -0000      1.2
  @@ -56,17 +56,17 @@
    
   import java.io.Serializable;
   import org.apache.commons.lang.ObjectUtils;
  -import org.apache.commons.pool.BasePoolableObjectFactory;
   
   class UserPassKey
       implements Serializable
   {
       private String password;
  -    private boolean reusable;
       private String username;
       
  -    UserPassKey()
  +    UserPassKey(String username, String password)
       {
  +        this.username = username;
  +        this.password = password;
       }
           
       /**
  @@ -79,35 +79,6 @@
       }
       
       /**
  -     * Set the value of password.
  -     * @param v  Value to assign to password.
  -     */
  -    public void setPassword(String  v) 
  -    {
  -        this.password = v;
  -    }
  -    
  -    
  -    /**
  -     * Get the value of reusable.
  -     * @return value of reusable.
  -     */
  -    public boolean isReusable() 
  -    {
  -        return reusable;
  -    }
  -    
  -    /**
  -     * Set the value of reusable.
  -     * @param v  Value to assign to reusable.
  -     */
  -    public void setReusable(boolean  v) 
  -    {
  -        this.reusable = v;
  -    }
  -
  -    
  -    /**
        * Get the value of username.
        * @return value of username.
        */
  @@ -116,29 +87,6 @@
           return username;
       }
       
  -    /**
  -     * Set the value of username.
  -     * @param v  Value to assign to username.
  -     */
  -    public void setUsername(String  v) 
  -    {
  -        this.username = v;
  -    }
  -    
  -    /**
  -     * Initialize key for method with no arguments.
  -     *
  -     * @param instanceOrClass the Object on which the method is invoked.  if 
  -     * the method is static, a String representing the class name is used.
  -     * @param method the method name
  -     */
  -    void init(String username, String password) 
  -    {
  -        this.reusable = true;
  -        this.username = username;
  -        this.password = password;
  -    }
  -
       public boolean equals(Object obj)
       {
           boolean equal = false;
  @@ -165,37 +113,7 @@
       {
           StringBuffer sb = new StringBuffer(50);
           sb.append("UserPassKey(");
  -        sb.append(username).append(", ").append(password)
  -            .append(", ").append(reusable);
  -        sb.append(')');
  +        sb.append(username).append(", ").append(password).append(')');
           return sb.toString();
  -    }
  -
  -    // ************* PoolableObjectFactory implementation *******************
  -
  -    static class Factory 
  -        extends BasePoolableObjectFactory
  -    {
  -        /**
  -         * Creates an instance that can be returned by the pool.
  -         * @return an instance that can be returned by the pool.
  -         */
  -        public Object makeObject() 
  -            throws Exception
  -        {
  -            return new UserPassKey();
  -        }
  -        
  -        /**
  -         * Uninitialize an instance to be returned to the pool.
  -         * @param obj the instance to be passivated
  -         */
  -        public void passivateObject(Object obj) 
  -            throws Exception
  -        {
  -            UserPassKey key = (UserPassKey)obj;
  -            key.username = null;
  -            key.password = null;
  -        }
       }
   }
  
  
  
  1.1                  
jakarta-commons/dbcp/src/java/org/apache/commons/dbcp/jdbc2pool/PooledConnectionAndInfo.java
  
  Index: PooledConnectionAndInfo.java
  ===================================================================
  package org.apache.commons.dbcp.jdbc2pool;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 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 acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and 
   *    "Apache Turbine" 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",
   *    "Apache Turbine", nor may "Apache" appear in their name, without 
   *    prior written permission of the Apache Software Foundation.
   *
   * 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/>.
   */
   
  //import org.apache.commons.lang.ObjectUtils;
  import javax.sql.PooledConnection;
  
  final class PooledConnectionAndInfo
  {
      private final PooledConnection pooledConnection;
      private final String password;
      private final String username;
      private final UserPassKey upkey;
  
      PooledConnectionAndInfo(PooledConnection pc, 
                              String username, String password)
      {
          this.pooledConnection = pc;
          this.username = username;
          this.password = password;
          upkey = new UserPassKey(username, password);
      }
  
      final PooledConnection getPooledConnection()
      {
          return pooledConnection;
      }
  
      final UserPassKey getUserPassKey()
      {
          return upkey;
      }
  
      /**
       * Get the value of password.
       * @return value of password.
       */
      final String getPassword() 
      {
          return password;
      }
      
      /**
       * Get the value of username.
       * @return value of username.
       */
      final String getUsername() 
      {
          return username;
      }
  }
  
  
  
  1.4       +212 -4    
jakarta-commons/dbcp/src/test/org/apache/commons/dbcp/jdbc2pool/TestJdbc2PoolDataSource.java
  
  Index: TestJdbc2PoolDataSource.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons/dbcp/src/test/org/apache/commons/dbcp/jdbc2pool/TestJdbc2PoolDataSource.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestJdbc2PoolDataSource.java      8 Nov 2002 19:37:26 -0000       1.3
  +++ TestJdbc2PoolDataSource.java      16 Nov 2002 19:18:27 -0000      1.4
  @@ -64,6 +64,7 @@
   import java.sql.Connection;
   import java.sql.PreparedStatement;
   import java.sql.ResultSet;
  +import java.sql.SQLException;
   
   import javax.sql.DataSource;
   import junit.framework.Test;
  @@ -107,6 +108,213 @@
           tds.setPerUserMaxWait("foo",new Integer((int)(getMaxWait())));
   
           ds = tds;
  +    }
  +
  +    public void testSimple() throws Exception 
  +    {
  +        Connection conn = ds.getConnection();
  +        assertTrue(null != conn);
  +        PreparedStatement stmt = conn.prepareStatement("select * from dual");
  +        assertTrue(null != stmt);
  +        ResultSet rset = stmt.executeQuery();
  +        assertTrue(null != rset);
  +        assertTrue(rset.next());
  +        rset.close();
  +        stmt.close();
  +        conn.close();
  +    }
  +
  +    public void testSimpleWithUsername() throws Exception 
  +    {
  +        Connection conn = ds.getConnection("u", "p");
  +        assertTrue(null != conn);
  +        PreparedStatement stmt = conn.prepareStatement("select * from dual");
  +        assertTrue(null != stmt);
  +        ResultSet rset = stmt.executeQuery();
  +        assertTrue(null != rset);
  +        assertTrue(rset.next());
  +        rset.close();
  +        stmt.close();
  +        conn.close();
  +    }
  +
  +    public void testClosingWithUserName() 
  +        throws Exception 
  +    {
  +        Connection[] c = new Connection[getMaxActive()];
  +        // open the maximum connections
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i] = ds.getConnection("u", "p");
  +        }
  +
  +        // close one of the connections
  +        c[0].close();
  +        assertTrue(c[0].isClosed());
  +        // get a new connection
  +        c[0] = ds.getConnection("u", "p");
  +
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i].close();
  +        }
  +
  +        // open the maximum connections
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i] = ds.getConnection("u", "p");
  +        }
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i].close();
  +        }
  +    }
  +
  +    public void testIncorrectPassword() 
  +        throws Exception 
  +    {
  +        ds.getConnection("u", "p").close();
  +        try 
  +        {
  +            ds.getConnection("u", "x").close();
  +            fail("Able to retrieve connection with incorrect password");
  +        }
  +        catch (SQLException e)
  +        {
  +            if (!e.getMessage().startsWith("Given password did not match")) 
  +            {
  +                throw e;
  +            }
  +            // else the exception was expected
  +        }
  +    }
  +
  +    public void testSimple2() 
  +        throws Exception 
  +    {
  +        Connection conn = ds.getConnection();
  +        assertTrue(null != conn);
  +
  +        PreparedStatement stmt = 
  +            conn.prepareStatement("select * from dual");
  +        assertTrue(null != stmt);
  +        ResultSet rset = stmt.executeQuery();
  +        assertTrue(null != rset);
  +        assertTrue(rset.next());
  +        rset.close();
  +        stmt.close();
  +        
  +        stmt = conn.prepareStatement("select * from dual");
  +        assertTrue(null != stmt);
  +        rset = stmt.executeQuery();
  +        assertTrue(null != rset);
  +        assertTrue(rset.next());
  +        rset.close();
  +        stmt.close();
  +        
  +        conn.close();
  +        try 
  +        {
  +            conn.createStatement();
  +            fail("Can't use closed connections");
  +        } 
  +        catch(SQLException e) 
  +        {
  +            // expected
  +        }
  +
  +        conn = ds.getConnection();
  +        assertTrue(null != conn);
  +
  +        stmt = conn.prepareStatement("select * from dual");
  +        assertTrue(null != stmt);
  +        rset = stmt.executeQuery();
  +        assertTrue(null != rset);
  +        assertTrue(rset.next());
  +        rset.close();
  +        stmt.close();
  +
  +        stmt = conn.prepareStatement("select * from dual");
  +        assertTrue(null != stmt);
  +        rset = stmt.executeQuery();
  +        assertTrue(null != rset);
  +        assertTrue(rset.next());
  +        rset.close();
  +        stmt.close();
  +        
  +        conn.close();
  +        conn = null;
  +    }
  +
  +    public void testOpening() 
  +        throws Exception 
  +    {
  +        Connection[] c = new Connection[getMaxActive()];
  +        // test that opening new connections is not closing previous
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i] = ds.getConnection();
  +            assertTrue(c[i] != null);
  +            for (int j=0; j<=i; j++) 
  +            {
  +                assertTrue(!c[j].isClosed());
  +            }
  +        }
  +
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i].close();
  +        }
  +    }
  +
  +    public void testClosing() 
  +        throws Exception 
  +    {
  +        Connection[] c = new Connection[getMaxActive()];
  +        // open the maximum connections
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i] = ds.getConnection();
  +        }
  +
  +        // close one of the connections
  +        c[0].close();
  +        assertTrue(c[0].isClosed());
  +        
  +        // get a new connection
  +        c[0] = ds.getConnection();
  +
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i].close();
  +        }
  +    }
  +
  +    public void testMaxActive() 
  +        throws Exception 
  +    {
  +        Connection[] c = new Connection[getMaxActive()];
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i] = ds.getConnection();
  +            assertTrue(c[i] != null);            
  +        }
  +
  +        try
  +        {
  +            ds.getConnection();
  +            fail("Allowed to open more than DefaultMaxActive connections.");
  +        }
  +        catch(java.sql.SQLException e)
  +        {
  +            // should only be able to open 10 connections, so this test should
  +            // throw an exception
  +        }
  +
  +        for (int i=0; i<c.length; i++) 
  +        {
  +            c[i].close();
  +        }
       }
       
       public void testMultipleThreads() throws Exception {
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to