You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by dj...@apache.org on 2007/01/23 20:15:03 UTC

svn commit: r499100 - in /db/derby/code/trunk/java/testing/org/apache/derbyTesting: functionTests/tests/derbynet/ functionTests/tests/jdbcapi/ functionTests/tests/lang/ junit/

Author: djd
Date: Tue Jan 23 11:15:02 2007
New Revision: 499100

URL: http://svn.apache.org/viewvc?view=rev&rev=499100
Log:
DERBY-2087 Create a TestConfiguration.singleUseDatabaseDecorator(Test, String dbName, boolean asDefault)
and also the methods openConnection(databaseName) to BaseJDBCTestCase and all the required infrustructure.
TestConfiguration manages a list of databases in use in a usedDbNames property. The singleUseDatabaseDecorator
creates a new configuration and appends a passed (or generated) database name at the end of the old database list.
Optionally, if specified, the default database might be also changed. 
Renamed the TestConfiguration.getDatabaseName to getDefaultDatabaseName, since it is more accurate now. 
Contributed by Julius Stroffek - Julius.Stroffek@sun.com

Modified:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DRDAProtocolTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/ShutDownDBWhenNSShutsDownTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangScripts.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Connector.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ConnectorSetup.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DataSourceConnector.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DropDatabaseSetup.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/XADataSourceConnector.java

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DRDAProtocolTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DRDAProtocolTest.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DRDAProtocolTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/DRDAProtocolTest.java Tue Jan 23 11:15:02 2007
@@ -44,10 +44,7 @@
     /** Test whether the multiple connections to different databases
       * on a same derby instance are working without exceptions. */
     public void testMultipleConnections() throws Exception {
-        DataSource ds1 = JDBCDataSource.getDataSource("FIRSTDB1");
-        JDBCDataSource.setBeanProperty(ds1, "connectionAttributes",
-                                       "create=true");
-        Connection conn1 = ds1.getConnection();
+        Connection conn1 = openConnection("FIRSTDB1");
         conn1.setAutoCommit(false);
 
         Statement st = conn1.createStatement();
@@ -60,10 +57,7 @@
         rs1.next();
         rs1.close();
         
-        DataSource ds2 = JDBCDataSource.getDataSource("SECONDDB2");
-        JDBCDataSource.setBeanProperty(ds2, "connectionAttributes",
-                                       "create=true");
-        Connection conn2 = ds2.getConnection();
+        Connection conn2 = openConnection("SECONDDB2");
         conn2.setAutoCommit(false);
         Statement st2 = conn2.createStatement();
         st2.execute("create table SECONDDB_T1 (i int, j int, k int)");
@@ -87,7 +81,11 @@
     }
     
     public static Test suite() {
-        return TestConfiguration.clientServerSuite(DRDAProtocolTest.class);
+        Test test;
+        test = TestConfiguration.clientServerSuite(DRDAProtocolTest.class);
+        test = TestConfiguration.singleUseDatabaseDecorator(test, "FIRSTDB1", false);
+        test = TestConfiguration.singleUseDatabaseDecorator(test, "SECONDDB2", false);
+        return test;
     }
     
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/ShutDownDBWhenNSShutsDownTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/ShutDownDBWhenNSShutsDownTest.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/ShutDownDBWhenNSShutsDownTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/ShutDownDBWhenNSShutsDownTest.java Tue Jan 23 11:15:02 2007
@@ -193,7 +193,7 @@
         // check if db.lck exists
         String fileName = getSystemProperty("derby.system.home") +
                 java.io.File.separator +
-                TestConfiguration.getCurrent().getDatabaseName() +
+                TestConfiguration.getCurrent().getDefaultDatabaseName() +
                 java.io.File.separator + "db.lck";
 
         boolean fileNotFound = false;

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java Tue Jan 23 11:15:02 2007
@@ -596,7 +596,7 @@
         PreparedStatement ps =
             getConnection().prepareStatement("CALL RETRIEVE_EXTERNAL_RESULT(?,?,?)");
         
-        ps.setString(1, getTestConfiguration().getDatabaseName());
+        ps.setString(1, getTestConfiguration().getDefaultDatabaseName());
         ps.setString(2, getTestConfiguration().getUserName());
         ps.setString(3, getTestConfiguration().getUserPassword());
         try {
@@ -619,7 +619,7 @@
         PreparedStatement ps =
             getConnection().prepareStatement("CALL RETRIEVE_EXTERNAL_RESULT(?,?,?)");
         
-        ps.setString(1, getTestConfiguration().getDatabaseName());
+        ps.setString(1, getTestConfiguration().getDefaultDatabaseName());
         ps.setString(2, getTestConfiguration().getUserName());
         ps.setString(3, getTestConfiguration().getUserPassword());
         

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/DatabaseClassLoadingTest.java Tue Jan 23 11:15:02 2007
@@ -586,7 +586,7 @@
 
         cs.close();
         
-        final String db = getTestConfiguration().getDatabaseName();
+        final String db = getTestConfiguration().getDefaultDatabaseName();
         AccessController.doPrivileged
         (new java.security.PrivilegedExceptionAction(){
             

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangScripts.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangScripts.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangScripts.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangScripts.java Tue Jan 23 11:15:02 2007
@@ -66,6 +66,7 @@
         "aggregate",
         "arithmetic",
         "case",
+        "cast",
         "comparisons",
         "constantExpression",
         "delete",
@@ -90,7 +91,6 @@
      * (ie. can not run on JSR169).
      */
     private static final String[] JDBC3_TESTS = {
-        "cast",  // DERBY-2228 (also never ran with J2ME with old harness)
     };
 
 	/**

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java Tue Jan 23 11:15:02 2007
@@ -198,6 +198,23 @@
     }
     
     /**
+     * Open a connection to the specified database.
+     * If the database does not exist, it will be created.
+     * A default username and password will be used for the connection.
+     * Requires that the test has been decorated with a
+     * singleUseDatabaseDecorator with the matching name.
+     *
+     * @return connection to default database.
+     * @see TestConfiguration#singleUseDatabaseDecorator(Test, String, boolean)
+     */
+    public Connection openConnection(String databaseName)
+        throws SQLException {
+        Connection conn =  getTestConfiguration().openConnection(databaseName);
+        initializeConnection(conn);
+        return conn;
+    }
+    
+    /**
      * Run a SQL script through ij discarding the output
      * using this object's default connection. Intended for
      * setup scripts.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Connector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Connector.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Connector.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/Connector.java Tue Jan 23 11:15:02 2007
@@ -54,11 +54,26 @@
     abstract Connection openConnection() throws SQLException;
    
     /**
+     * Open a connection with the database, user and password
+     * defined by the configuration passed to setConfiguration.
+     * If the database does not exist then it should be created.
+     */
+    abstract Connection openConnection(String databaseName) throws SQLException;
+   
+    /**
      * Open a connection to the database
      * defined by the configuration passed to setConfiguration.
      * If the database does not exist then it should be created.
      */
      abstract Connection openConnection(String user, String password)
+         throws SQLException;
+
+    /**
+     * Open a connection to the database
+     * defined by the configuration passed to setConfiguration.
+     * If the database does not exist then it should be created.
+     */
+     abstract Connection openConnection(String databaseName, String user, String password)
          throws SQLException;
 
     /**

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ConnectorSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ConnectorSetup.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ConnectorSetup.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/ConnectorSetup.java Tue Jan 23 11:15:02 2007
@@ -39,7 +39,7 @@
         // Copy the current configuration by creating one
         // with the same database name
         TestConfiguration newConfig = 
-            new TestConfiguration(old, old.getDatabaseName());
+            new TestConfiguration(old, old.getDefaultDatabaseName(), true);
         
         try {
             newConfig.connector = (Connector)

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DataSourceConnector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DataSourceConnector.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DataSourceConnector.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DataSourceConnector.java Tue Jan 23 11:15:02 2007
@@ -68,6 +68,28 @@
        }
     }
 
+    public Connection openConnection(String databaseName) throws SQLException {
+        JDBCDataSource.setBeanProperty(ds, "databaseName", databaseName);
+        try {
+            return ds.getConnection();
+        } catch (SQLException e) {
+            // Expected state for database not found.
+            // For the client the generic 08004 is returned,
+            // will just retry on that.
+            String expectedState = 
+                config.getJDBCClient().isEmbedded() ? "XJ004" : "08004";
+
+            // If there is a database not found exception
+            // then retry the connection request with
+            // a new DataSource with the createDtabase property set.
+            if (!expectedState.equals(e.getSQLState()))
+                throw e;
+            DataSource tmpDs = singleUseDS("createDatabase", "create");
+            JDBCDataSource.setBeanProperty(tmpDs, "databaseName", databaseName);
+            return tmpDs.getConnection();
+       }
+    }
+
     public Connection openConnection(String user, String password)
             throws SQLException {
         try {
@@ -80,6 +102,23 @@
                 throw e;
             return singleUseDS(
                     "createDatabase", "create").getConnection(user, password); 
+       }
+    }
+
+    public Connection openConnection(String databaseName, String user, String password)
+            throws SQLException {
+        JDBCDataSource.setBeanProperty(ds, "databaseName", databaseName);
+        try {
+            return ds.getConnection(user, password);
+        } catch (SQLException e) {
+            // If there is a database not found exception
+            // then retry the connection request with
+            // a new DataSource with the createDatabase property set.
+            if (!"XJ004".equals(e.getSQLState()))
+                throw e;
+            DataSource tmpDs = singleUseDS("createDatabase", "create");
+            JDBCDataSource.setBeanProperty(tmpDs, "databaseName", databaseName);
+            return tmpDs.getConnection(user, password); 
        }
     }
 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DatabaseChangeSetup.java Tue Jan 23 11:15:02 2007
@@ -29,13 +29,15 @@
 final class DatabaseChangeSetup extends ChangeConfigurationSetup {
 
     private final String dbName;
+    private final boolean defaultDb;
     
-    public DatabaseChangeSetup(Test test, String dbName) {
+    public DatabaseChangeSetup(Test test, String dbName, boolean defaultDb) {
         super(test);
         this.dbName = dbName;
+        this.defaultDb = defaultDb;
    }
 
     TestConfiguration getNewConfiguration(TestConfiguration old) {
-        return new TestConfiguration(old, dbName);
+        return new TestConfiguration(old, dbName, defaultDb);
     }
 }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DriverManagerConnector.java Tue Jan 23 11:15:02 2007
@@ -40,7 +40,15 @@
     }
 
     public Connection openConnection() throws SQLException {
-        return openConnection(config.getUserName(), config.getUserPassword());
+        return openConnection(config.getDefaultDatabaseName(), config.getUserName(), config.getUserPassword());
+    }
+
+    public Connection openConnection(String databaseName) throws SQLException {
+        return openConnection(databaseName, config.getUserName(), config.getUserPassword());
+    }
+
+    public Connection openConnection(String user, String password) throws SQLException {
+        return openConnection(config.getDefaultDatabaseName(), user, password);
     }
 
     /**
@@ -53,10 +61,10 @@
      * (database not found) then the connection is retried
      * with attributes create=true.
      */
-    public Connection openConnection(String user, String password)
+    public Connection openConnection(String databaseName, String user, String password)
             throws SQLException {
 
-        String url = config.getJDBCUrl();
+        String url = config.getJDBCUrl(databaseName);
 
         try {
             DriverManager.getDriver(url);

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DropDatabaseSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DropDatabaseSetup.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DropDatabaseSetup.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/DropDatabaseSetup.java Tue Jan 23 11:15:02 2007
@@ -22,6 +22,7 @@
 import java.io.File;
 import java.security.AccessController;
 import java.sql.SQLException;
+import java.util.ArrayList;
 
 import junit.extensions.TestSetup;
 import junit.framework.Test;
@@ -37,7 +38,7 @@
      }
     
     /**
-     * Drop the current database.
+     * Drop the last database added to the list of used databases.
      */
     protected void tearDown() throws Exception {
         
@@ -48,7 +49,8 @@
         
         TestConfiguration.getCurrent().shutdownDatabase();
 
-        String dbName = TestConfiguration.getCurrent().getDatabaseName();
+        ArrayList usedDbs = TestConfiguration.getCurrent().getUsedDatabaseNames();
+        String dbName = (String) usedDbs.get(usedDbs.size()-1);
         dbName = dbName.replace('/', File.separatorChar);
         
         String dsh = BaseTestCase.getSystemProperty("derby.system.home");

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBCDataSource.java Tue Jan 23 11:15:02 2007
@@ -88,7 +88,7 @@
             beanProperties.put("portNumber", new Integer(config.getPort()));
         }
         
-        beanProperties.put("databaseName", config.getDatabaseName());
+        beanProperties.put("databaseName", config.getDefaultDatabaseName());
         beanProperties.put("user", config.getUserName());
         beanProperties.put("password", config.getUserPassword());
 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/TestConfiguration.java Tue Jan 23 11:15:02 2007
@@ -26,6 +26,8 @@
 import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.util.Properties;
+import java.util.ArrayList;
+import java.util.Collection;
 
 import junit.extensions.TestSetup;
 import junit.framework.Assert;
@@ -35,6 +37,14 @@
 
 /**
  * Class which holds information about the configuration of a Test.
+ * 
+ * A configuration manages the pool of databases in use
+ * in <code>usedDbNames</code> property. One of those databases
+ * is supposed to be the default database. A new database name
+ * is added to the pool by one of singleUseDatabaseDecorator functions.
+ * The database files are supposed to be local and they will be
+ * removed by <code>DropDatabaseSetup</code>.
+ *
  */
 public class TestConfiguration {
     /**
@@ -101,7 +111,7 @@
             assumeHarness = true;
         
         // Assume harness if database name is not default
-        if (!DERBY_HARNESS_CONFIG.getDatabaseName().equals(DEFAULT_DBNAME))
+        if (!DERBY_HARNESS_CONFIG.getDefaultDatabaseName().equals(DEFAULT_DBNAME))
             assumeHarness = true;
         
         // Assume harness if user name is not default
@@ -266,7 +276,10 @@
      * Decorate a test to use a new database that is created upon the
      * first connection request to the database and shutdown & deleted at
      * tearDown. The configuration differs only from the current configuration
-     * by the database name.
+     * by the list of used databases. The new database name
+     * is generated automatically as 'singleUse/oneuseXX' where 'XX' is
+     * the unique number. The generated database name is added at the end
+     * of <code>usedDbNames</code> and assigned as a default database name.
      * This decorator expects the database file to be local so it
      * can be removed.
      * @param test Test to be decorated
@@ -284,7 +297,26 @@
             dbName = dbName.concat(Integer.toHexString(uniqueDB++));
         }
 
-        return new DatabaseChangeSetup(new DropDatabaseSetup(test), dbName);
+        return new DatabaseChangeSetup(new DropDatabaseSetup(test), dbName, true);
+    }
+    
+    /**
+     * Decorate a test to use a new database that is created upon the
+     * first connection request to the database and shutdown & deleted at
+     * tearDown. The configuration differs only from the current configuration
+     * by the list of used databases. The default database name is changed
+     * according the <code>defaultDb</code> parameter. The passed database name
+     * is added at the end of <code>usedDbNames</code>.
+     * This decorator expects the database file to be local so it
+     * can be removed.
+     * @param test Test to be decorated
+     * @param dbName The database name to be added to the list of used databases.
+     * @param defaultDb Indicates that the passed database name should be used as a default database.
+     * @return decorated test.
+     */
+    public static TestSetup singleUseDatabaseDecorator(Test test, String dbName, boolean defaultDb)
+    {
+        return new DatabaseChangeSetup(new DropDatabaseSetup(test), dbName, defaultDb);
     }
     
     /**
@@ -334,7 +366,7 @@
             }
         };
 
-        return new DatabaseChangeSetup(setSQLAuthMode, DEFAULT_DBNAME_SQL);
+        return new DatabaseChangeSetup(setSQLAuthMode, DEFAULT_DBNAME_SQL, true);
     }
     
     /**
@@ -390,14 +422,15 @@
      *
      */
     private TestConfiguration() {
-        this.dbName = DEFAULT_DBNAME;
+        this.defaultDbName = DEFAULT_DBNAME;
+        usedDbNames.add(DEFAULT_DBNAME);
         this.userName = DEFAULT_USER_NAME;
         this.userPassword = DEFAULT_USER_PASSWORD;
         this.hostName = null;
         this.port = -1;
         
         this.jdbcClient = JDBCClient.getDefaultEmbedded();
-        url = createJDBCUrlWithDatabaseName(dbName);
+        url = createJDBCUrlWithDatabaseName(defaultDbName);
         initConnector(null);
  
     }
@@ -405,7 +438,8 @@
     TestConfiguration(TestConfiguration copy, JDBCClient client,
             String hostName, int port)
     {
-        this.dbName = copy.dbName;
+        this.defaultDbName = copy.defaultDbName;
+        this.usedDbNames.addAll(copy.usedDbNames);        
         this.userName = copy.userName;
         this.userPassword = copy.userPassword;
 
@@ -415,7 +449,7 @@
         this.jdbcClient = client;
         this.hostName = hostName;
         
-        this.url = createJDBCUrlWithDatabaseName(dbName);
+        this.url = createJDBCUrlWithDatabaseName(defaultDbName);
         initConnector(copy.connector);
     }
 
@@ -429,7 +463,8 @@
      */
     TestConfiguration(TestConfiguration copy, String user, String password)
     {
-        this.dbName = copy.dbName;
+        this.defaultDbName = copy.defaultDbName;
+        this.usedDbNames.addAll(copy.usedDbNames);
         this.userName = user;
         this.userPassword = password;
 
@@ -444,13 +479,25 @@
     }
     /**
      * Obtain a new configuration identical to the passed in
-     * one except for the database name.
+     * one except for the database name. The passed database name
+     * is added at the end of the list of used databases.
+     * If the <code>defaulDb</code> parameter is <code>true</code>
+     * the new database name is used as a default database.
      * @param copy Configuration to copy.
-     * @param dbName New database name
-      */
-    TestConfiguration(TestConfiguration copy, String dbName)
-    {
-        this.dbName = dbName;
+     * @param defaultDbName New database name
+     * @param defaultDb Indicates that the passed <code>dbName</code> is supposed
+     * to be used as the default database name.
+     */
+    TestConfiguration(TestConfiguration copy, String dbName, boolean defaultDb)
+    {
+        this.usedDbNames.addAll(copy.usedDbNames);
+        this.usedDbNames.add(dbName);
+        if (defaultDb) {
+            this.defaultDbName = dbName;
+        } else {
+            this.defaultDbName = copy.defaultDbName;
+        }
+        
         this.userName = copy.userName;
         this.userPassword = copy.userPassword;
 
@@ -460,7 +507,7 @@
         this.jdbcClient = copy.jdbcClient;
         this.hostName = copy.hostName;
         
-        this.url = createJDBCUrlWithDatabaseName(dbName);
+        this.url = createJDBCUrlWithDatabaseName(this.defaultDbName);
         initConnector(copy.connector);
     }
   
@@ -472,7 +519,7 @@
     private TestConfiguration(Properties props) 
         throws NumberFormatException {
 
-        dbName = props.getProperty(KEY_DBNAME, DEFAULT_DBNAME);
+        defaultDbName = props.getProperty(KEY_DBNAME, DEFAULT_DBNAME);
         userName = props.getProperty(KEY_USER_NAME, DEFAULT_USER_NAME);
         userPassword = props.getProperty(KEY_USER_PASSWORD, 
                                          DEFAULT_USER_PASSWORD);
@@ -500,7 +547,7 @@
         } else {
             jdbcClient = JDBCClient.getDefaultEmbedded();
         }
-        url = createJDBCUrlWithDatabaseName(dbName);
+        url = createJDBCUrlWithDatabaseName(defaultDbName);
         initConnector(null);
     }
 
@@ -610,11 +657,20 @@
      * 
      * @return default database name.
      */
-    public String getDatabaseName() {
-        return dbName;
+    public String getDefaultDatabaseName() {
+        return defaultDbName;
     }
     
     /**
+     * Return the names of all used databases.
+     * 
+     * @return The ArrayList containing the database names.
+     */
+    public ArrayList getUsedDatabaseNames() {
+        return usedDbNames;
+    }
+
+    /**
      * Return the user name.
      * 
      * @return user name.
@@ -663,6 +719,23 @@
     }
     
     /**
+     * Open connection to the specified database.
+     * If the database does not exist, it will be created.
+     * A default username and password will be used for the connection.
+     * Requires that the test has been decorated with a
+     * singleUseDatabaseDecorator with the matching name.
+     * @return connection to specified database.
+     */
+    Connection openConnection(String databaseName)
+        throws SQLException {
+        if (usedDbNames.contains(databaseName))
+            return connector.openConnection(databaseName);
+        else
+            throw new SQLException("Database name \"" + databaseName + "\" is not in a list of used databases. "
+                                 + "Use method TestConfiguration.singleUseDatabaseDecorator first.");
+    }
+    
+    /**
      * Shutdown the database for this configuration
      * assuming it is booted.
      *
@@ -786,10 +859,15 @@
         
     }
     
-    /**
+    /*
      * Immutable data members in test configuration
      */
-    private final String dbName;
+    
+    /** The default database name for tests. */
+    private final String defaultDbName;
+    /** Holds the names of all other databases used in a test to perform a proper cleanup.
+     * The <code>defaultDbName</code> is also contained here.  */
+    private final ArrayList usedDbNames = new ArrayList();
     private final String url;
     private final String userName; 
     private final String userPassword; 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/XADataSourceConnector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/XADataSourceConnector.java?view=diff&rev=499100&r1=499099&r2=499100
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/XADataSourceConnector.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/XADataSourceConnector.java Tue Jan 23 11:15:02 2007
@@ -70,6 +70,28 @@
        }
     }
 
+    public Connection openConnection(String databaseName) throws SQLException {
+        JDBCDataSource.setBeanProperty(ds, "databaseName", databaseName);
+        try {
+            return ds.getXAConnection().getConnection();
+        } catch (SQLException e) {
+            // Expected state for database not found.
+            // For the client the generic 08004 is returned,
+            // will just retry on that.
+            String expectedState = 
+                config.getJDBCClient().isEmbedded() ? "XJ004" : "08004";
+
+            // If there is a database not found exception
+            // then retry the connection request with
+            // a new DataSource with the createDtabase property set.
+            if (!expectedState.equals(e.getSQLState()))
+                throw e;
+            XADataSource tmpDs = singleUseDS("createDatabase", "create");
+            JDBCDataSource.setBeanProperty(tmpDs, "databaseName", databaseName);
+            return tmpDs.getXAConnection().getConnection();
+       }
+    }
+
     public Connection openConnection(String user, String password)
             throws SQLException {
         try {
@@ -81,7 +103,24 @@
             if (!"XJ004".equals(e.getSQLState()))
                 throw e;
             return singleUseDS("createDatabase", "create").
-                         getXAConnection(user, password).getConnection(); 
+                   getXAConnection(user, password).getConnection(); 
+       }
+    }
+
+    public Connection openConnection(String databaseName, String user, String password)
+            throws SQLException {
+        JDBCDataSource.setBeanProperty(ds, "databaseName", databaseName);
+        try {
+            return ds.getXAConnection(user, password).getConnection();
+        } catch (SQLException e) {
+            // If there is a database not found exception
+            // then retry the connection request with
+            // a new DataSource with the createDatabase property set.
+            if (!"XJ004".equals(e.getSQLState()))
+                throw e;
+            XADataSource tmpDs = singleUseDS("createDatabase", "create");
+            JDBCDataSource.setBeanProperty(tmpDs, "databaseName", databaseName);
+            return tmpDs.getXAConnection(user, password).getConnection(); 
        }
     }