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 my...@apache.org on 2007/04/17 08:56:41 UTC
svn commit: r529505 - in /db/derby/code/trunk/java:
client/org/apache/derby/client/am/ client/org/apache/derby/jdbc/
testing/org/apache/derbyTesting/functionTests/master/
testing/org/apache/derbyTesting/functionTests/suites/
testing/org/apache/derbyTes...
Author: myrnavl
Date: Mon Apr 16 23:56:40 2007
New Revision: 529505
URL: http://svn.apache.org/viewvc?view=rev&rev=529505
Log:
DERBY-2296 - implement setShutdownDatabase, getShutdownDatabase, setCreateDatabase and getCreateDatabase methods for client datasources.
Also added a new junit test, DSCreateShutdownDBTest, and converted the only test that was affected by the client code change, dataSourceReference.java, to junit test DataSourceReferenceTest.java.
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DSCreateShutdownDBTest.java (with props)
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceReferenceTest.java (with props)
Removed:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dataSourceReference.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/dataSourceReference.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/dataSourceReference_app.properties
Modified:
db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientBaseDataSource.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc20.runall
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/JDBCHarnessJavaTest.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java?view=diff&rev=529505&r1=529504&r2=529505
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Connection.java Mon Apr 16 23:56:40 2007
@@ -184,8 +184,22 @@
// "setConnectionAttributes" method.
databaseName_ = dataSource.getDatabaseName();
String connAtrrs = dataSource.getConnectionAttributes();
+ if (dataSource.getCreateDatabase() != null) // can be "create" or null
+ {
+ if (connAtrrs == null)
+ connAtrrs = "create=true";
+ else
+ connAtrrs = connAtrrs + ";create=true";
+ }
+ if (dataSource.getShutdownDatabase() != null) // "shutdown" or null
+ {
+ if (connAtrrs == null)
+ connAtrrs = "shutdown=true";
+ else
+ connAtrrs = connAtrrs + ";shutdown=true";
+ }
if(databaseName_ != null && connAtrrs != null)
- databaseName_ = databaseName_ + ";" + connAtrrs;
+ databaseName_ = databaseName_ + ";" + connAtrrs;
retrieveMessageText_ = dataSource.getRetrieveMessageText();
Modified: db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientBaseDataSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientBaseDataSource.java?view=diff&rev=529505&r1=529504&r2=529505
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientBaseDataSource.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/jdbc/ClientBaseDataSource.java Mon Apr 16 23:56:40 2007
@@ -677,7 +677,8 @@
new ClientMessageId(SQLState.INVALID_ATTRIBUTE_SYNTAX),
attributeString);
}
-
+ //if (shutdownDatabase != null )
+
augmentedProperties.setProperty((v.substring(0, eqPos)).trim(), (v.substring(eqPos + 1)).trim());
}
} catch (NoSuchElementException e) {
@@ -852,6 +853,63 @@
return getUpgradedSecurityMechanism(password);
return securityMechanism;
+ }
+
+ // ----------------------- set/getCreate/ShutdownDatabase ---------------------------
+ /**
+ * Set to true if the database should be created.
+ */
+ private boolean createDatabase;
+
+ /**
+ * Set to true if the database should be shutdown.
+ */
+ private boolean shutdownDatabase;
+
+ /**
+ * Set this property to create a new database. If this property is not
+ * set, the database (identified by databaseName) is assumed to be already
+ * existing.
+ * @param create if set to the string "create", this data source will try
+ * to create a new database of databaseName, or boot the
+ * database if one by that name already exists.
+ *
+ */
+ public final void setCreateDatabase(String create) {
+ if (create != null && create.equalsIgnoreCase("create"))
+ this.createDatabase = true;
+ }
+
+ /** @return "create" if create is set, or null if not
+ */
+ public final String getCreateDatabase() {
+ String createstr=null;
+ if (createDatabase)
+ createstr="create";
+ return createstr;
+ }
+
+ /**
+ * Set this property if one wishes to shutdown the database identified by
+ * databaseName.
+ * @param shutdown if set to the string "shutdown", this data source will
+ * shutdown the database if it is running.
+ *
+ */
+ public final void setShutdownDatabase(String shutdown) {
+ if (shutdown != null && shutdown.equalsIgnoreCase("shutdown"))
+ this.shutdownDatabase = true;
+ }
+
+ /** @return "shutdown" if shutdown is set, or null if not
+ */
+ public final String getShutdownDatabase() {
+ String shutdownstr=null;
+ if (shutdownDatabase)
+ {
+ shutdownstr = "shutdown";
+ }
+ return shutdownstr;
}
protected String connectionAttributes = null;
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude?view=diff&rev=529505&r1=529504&r2=529505
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude Mon Apr 16 23:56:40 2007
@@ -5,7 +5,6 @@
# excluding jdbcapi/SetQueryTimeoutTest.java because neither the JCC driver nor the ClientDriver support setQueryTimeout() yet.
# excluding jdbcapi/rsgetXXXcolumnNames.java as it fails incorrectly, according to JDBC spec. Forwarding test case to JCC team.
# excluding jdbcapi/statementJdbc30.java - Client behaves differently. Need to look into this
-# excluding jdbcapi/dataSourceReference.java - client side only tests, tests all data sources
# regardless of framework
# excluding largedata/LobLimits.java to run with the network server because currently lobs are materialized and this test tests for 2G lobs.
# see DERBY-326 and DERBY-550 issues
@@ -17,7 +16,6 @@
jdbcapi/SetQueryTimeoutTest.java
jdbcapi/blobSetBinaryStream.java
jdbcapi/statementJdbc30.java
-jdbcapi/dataSourceReference.java
#no XA for JCC
jdbcapi/savepointJdbc30_XA.java
# excluding jdbcapi/derbyStress.java - jcc runs out of memory with this test
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude?view=diff&rev=529505&r1=529504&r2=529505
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude Mon Apr 16 23:56:40 2007
@@ -1,7 +1,6 @@
# excluding TestErrorStreamTarget.java since it's not relevant for clients
# excluding statementJdbc20.java because this tests fetch_reverse throughout the test
# excluding jdbcapi/statementJdbc30.java - Client behaves differently. Need to look into this
-# excluding jdbcapi/dataSourceReference.java - client side only tests, tests all data sources
# regardless of framework
# excluding largedata/LobLimits.java to run with the network server because currently lobs are materialized and this test tests for 2G lobs.
# see DERBY-326 and DERBY-550 issues
@@ -9,7 +8,6 @@
#
jdbcapi/statementJdbc20.java
jdbcapi/statementJdbc30.java
-jdbcapi/dataSourceReference.java
largedata/LobLimits.java
#
# This test brings the network server up and down by itself
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc20.runall
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc20.runall?view=diff&rev=529505&r1=529504&r2=529505
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc20.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbc20.runall Mon Apr 16 23:56:40 2007
@@ -1,2 +1 @@
jdbcapi/getCurConnJdbc20.sql
-jdbcapi/dataSourceReference.java
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DSCreateShutdownDBTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DSCreateShutdownDBTest.java?view=auto&rev=529505
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DSCreateShutdownDBTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DSCreateShutdownDBTest.java Mon Apr 16 23:56:40 2007
@@ -0,0 +1,389 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.derbyTesting.functionTests.tests.jdbcapi;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.sql.SQLException;
+
+import javax.sql.DataSource;
+
+import junit.extensions.TestSetup;
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.BaseTestCase;
+import org.apache.derbyTesting.junit.JDBCDataSource;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+public class DSCreateShutdownDBTest extends BaseJDBCTestCase {
+
+ static final String[] ADDITIONAL_DBS = {
+ "dscreateshutdowndb1",
+ "dscreateshutdowndb2",
+ "conflict1",
+ "conflict2",
+ "conflict3",
+ "conflict4",
+ "conflict5",
+ "conflict6",
+ "conflict7"
+ };
+
+ static String DBNotFoundState;
+
+ public DSCreateShutdownDBTest(String name) {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite("DSCreateShutdownTest");
+ Test test = TestConfiguration.defaultSuite(DSCreateShutdownDBTest.class);
+ //Test test = TestConfiguration.clientServerSuite(DSCreateShutdownDBTest.class);
+ suite.addTest(test);
+
+ TestSetup setup = TestConfiguration.singleUseDatabaseDecorator(suite);
+ // we need a couple extra databases to test they get created
+ for (int i = 0; i < ADDITIONAL_DBS.length; i++)
+ {
+ setup = TestConfiguration.additionalDatabaseDecorator(setup,
+ "emb" + ADDITIONAL_DBS[i]);
+ setup = TestConfiguration.additionalDatabaseDecorator(setup,
+ "srv" + ADDITIONAL_DBS[i]);
+ }
+
+ return suite;
+ }
+
+ public void tearDown() throws Exception {
+ // attempt to get rid of any databases.
+ // only 4 dbs (in addition to defaultdb) should actually get
+ // created, but just in case...
+ AccessController.doPrivileged(new java.security.PrivilegedAction() {
+ public Object run() {
+ for (int i=0 ; i < ADDITIONAL_DBS.length ; i++)
+ {
+ removeDatabase("emb" + ADDITIONAL_DBS[i]);
+ removeDatabase("srv" + ADDITIONAL_DBS[i]);
+ }
+ return null;
+ }
+
+ void removeDatabase(String dbName)
+ {
+ //TestConfiguration config = TestConfiguration.getCurrent();
+ dbName = dbName.replace('/', File.separatorChar);
+ String dsh = BaseTestCase.getSystemProperty("derby.system.home");
+ if (dsh == null) {
+ fail("not implemented");
+ } else {
+ dbName = dsh + File.separator + dbName;
+ }
+ removeDirectory(dbName);
+ }
+
+ void removeDirectory(String path)
+ {
+ final File dir = new File(path);
+ removeDir(dir);
+ }
+
+ private void removeDir(File dir) {
+
+ // Check if anything to do!
+ // Database may not have been created.
+ if (!dir.exists())
+ return;
+
+ String[] list = dir.list();
+
+ // Some JVMs return null for File.list() when the
+ // directory is empty.
+ if (list != null) {
+ for (int i = 0; i < list.length; i++) {
+ File entry = new File(dir, list[i]);
+
+ if (entry.isDirectory()) {
+ removeDir(entry);
+ } else {
+ entry.delete();
+ //assertTrue(entry.getPath(), entry.delete());
+ }
+ }
+ }
+ dir.delete();
+ //assertTrue(dir.getPath(), dir.delete());
+ }
+ });
+ super.tearDown();
+ }
+
+ public void testCreateAndShutdown() throws SQLException {
+
+ if (usingEmbedded())
+ DBNotFoundState = "XJ004";
+ else
+ DBNotFoundState = "08004";
+
+ // first play with default db, which is already created.
+ String dbName =
+ TestConfiguration.getCurrent().getDefaultDatabaseName();
+ // just check that we really access the database
+ assertUpdateCount(createStatement(), 0, "set schema APP");
+
+ // check that first the value is null
+ assertGetNull(dbName);
+ // check that we can set & that when set we can get
+ // doesn't actually open connections so a little silly.
+ assertSetAndGet(dbName, "shutdownDatabase", "shutdown");
+ assertSetAndGet(dbName, "createDatabase", "create");
+ // set to an invalid value, should get ignored
+ assertNotSetAndGet(dbName, "shutdownDatabase", "boo");
+ assertNotSetAndGet(dbName, "createDatabase", "boo");
+ assertNotSetAndGet(dbName, "shutdownDatabase", "false");
+ assertNotSetAndGet(dbName, "createDatabase", "false");
+
+ // check that shutting down using Attributes works
+ assertShutdownUsingConnAttrsOK(dbName);
+ // re-vive db
+ getConnection();
+
+ // now, actually create, and shutdown a database
+ // first ensure it's not there yet
+ dbName = composeDatabaseName(ADDITIONAL_DBS[0]);
+ assertNoDB(dbName);
+ // straightforward create and shutdown
+ assertPositive(dbName);
+
+ // what happens when you combine set*Database and
+ // matching connection attribute? (should work)
+ dbName = composeDatabaseName(ADDITIONAL_DBS[1]);
+ assertNoDB(dbName);
+ assertTwiceOK(dbName);
+
+ // the rest of the testing is on conflicted settings
+ // the result is not defined, so a change in behavior does not
+ // necessarily indicate a bug, but may be relevant for existing apps
+ // what happens when you combine create and shutdown connattr?
+ // database does not get created.
+ assertShutdownAndCreateConnAttr(DBNotFoundState,
+ composeDatabaseName(ADDITIONAL_DBS[2]),
+ "shutdown=true;create=true");
+ assertShutdownAndCreateConnAttr(DBNotFoundState,
+ composeDatabaseName(ADDITIONAL_DBS[3]),
+ "create=true;shutdown=true");
+
+ // and when you set both setShutdownDatabase and setCreateDatabase?
+ // database does not get created
+ assertConflictedSettersOK(composeDatabaseName(ADDITIONAL_DBS[4]));
+
+ // what happens when you combine set*Database and
+ // opposing connection attributes? database does not get created.
+ assertConflictedSetterConnAttrOK();
+ }
+
+ protected String composeDatabaseName(String dbName) {
+ if (usingEmbedded())
+ return "emb" + dbName;
+ else
+ return "srv" + dbName;
+ }
+
+ protected void assertGetNull(String dbName) throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSourceLogical(dbName);
+ assertNull(getBeanProperty(ds, "shutdownDatabase"));
+ assertNull(getBeanProperty(ds, "createDatabase"));
+ }
+
+ protected void assertSetAndGet(
+ String dbName, String propertyString, String setValue)
+ throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSourceLogical(dbName);
+ JDBCDataSource.setBeanProperty(ds, propertyString, setValue);
+ assertEquals(setValue,getBeanProperty(ds, propertyString).toString());
+ }
+
+ protected void assertNotSetAndGet(
+ String dbName, String propertyString, String setValue)
+ throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSourceLogical(dbName);
+ JDBCDataSource.setBeanProperty(ds, propertyString, setValue);
+ assertNull(getBeanProperty(ds, propertyString));
+ }
+
+ public static Object getBeanProperty(Object ds, String propertyString)
+ {
+ String getterName = getGetterName(propertyString);
+
+ // Base the type of the setter method from the value's class.
+
+ Object retObject=null;
+ try {
+ Method getter = ds.getClass().getMethod(getterName, null);
+ retObject = getter.invoke(ds, null);
+ } catch (Exception e) {
+ Assert.fail(e.getMessage());
+ }
+ return retObject;
+ }
+
+ private static String getGetterName(String attribute) {
+ return "get" + Character.toUpperCase(attribute.charAt(0))
+ + attribute.substring(1);
+ }
+
+ // if the connattr parameter is true, we set both setShutdownDatabase
+ // and ConnectionAttribute shutdown=true.
+ protected void assertShutdownUsingSetOK(String dbName, boolean connAttr)
+ throws SQLException {
+
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+ JDBCDataSource.setBeanProperty(ds, "shutdownDatabase", "shutdown");
+ if (connAttr)
+ JDBCDataSource.setBeanProperty(
+ ds, "ConnectionAttributes", "shutdown=true");
+ assertDSConnectionFailed("08006", ds);
+ }
+
+ protected void assertShutdownUsingConnAttrsOK(String dbName)
+ throws SQLException {
+
+ DataSource ds = JDBCDataSource.getDataSourceLogical(dbName);
+ JDBCDataSource.setBeanProperty(
+ ds, "ConnectionAttributes", "shutdown=true");
+ assertDSConnectionFailed("08006", ds);
+ }
+
+ protected void assertShutdownAndCreateConnAttr(
+ String expectedSQLState, String dbName, String twoPropertyString)
+ throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+ JDBCDataSource.setBeanProperty(
+ ds, "ConnectionAttributes", twoPropertyString);
+ assertDSConnectionFailed(expectedSQLState, ds);
+ }
+
+ protected void assertDSConnectionFailed(
+ String expectedSQLState, DataSource ds) throws SQLException {
+ try {
+ ds.getConnection();
+ fail("expected an sqlexception " + expectedSQLState);
+ } catch (SQLException sqle) {
+ assertSQLState(expectedSQLState, sqle);
+ }
+ }
+
+ protected void assertNoDB(String dbName) throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+ assertDSConnectionFailed(DBNotFoundState, ds);
+ }
+
+ protected void assertPositive(String dbName) throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+ JDBCDataSource.setBeanProperty(ds, "CreateDatabase", "create");
+ // check that the db exists; execute an unnecessary, but harmless, stmt
+ assertUpdateCount(
+ ds.getConnection().createStatement(), 0, "set schema APP");
+ JDBCDataSource.clearStringBeanProperty(ds, "CreateDatabase");
+ assertShutdownUsingSetOK(dbName, false);
+ }
+
+ protected void assertTwiceOK(String dbName) throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+ JDBCDataSource.setBeanProperty(ds, "CreateDatabase", "create");
+ JDBCDataSource.setBeanProperty(
+ ds, "ConnectionAttributes", "create=true");
+ // check that the db exists; execute an unnecessary, but harmless, stmt
+ assertUpdateCount(
+ ds.getConnection().createStatement(), 0, "set schema APP");
+ JDBCDataSource.clearStringBeanProperty(ds, "CreateDatabase");
+ JDBCDataSource.clearStringBeanProperty(ds, "ConnectionAttributes");
+ assertShutdownUsingSetOK(dbName, true);
+ }
+
+ protected void assertConflictedSettersOK(String dbName) throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+ JDBCDataSource.setBeanProperty(ds, "CreateDatabase", "create");
+ JDBCDataSource.setBeanProperty(ds, "shutdownDatabase", "shutdown");
+ try {
+ ds.getConnection();
+ } catch (SQLException se) {
+ assertSQLState(DBNotFoundState, se);
+ }
+ }
+
+ protected void assertConflictedSetterConnAttrOK()
+ throws SQLException {
+ assertConSetOK(DBNotFoundState, composeDatabaseName(ADDITIONAL_DBS[5]),
+ "shutdown=true", "CreateDatabase", "create");
+ // with the new networkserver methods, this actually works...
+ assertConSetOK(DBNotFoundState, composeDatabaseName(ADDITIONAL_DBS[6]),
+ "create=true", "ShutdownDatabase", "shutdown");
+ assertSetConOK(DBNotFoundState, composeDatabaseName(ADDITIONAL_DBS[7]),
+ "shutdown=true", "CreateDatabase", "create");
+ // with the new networkserver methods, this actually works...
+ assertSetConOK(DBNotFoundState, composeDatabaseName(ADDITIONAL_DBS[8]),
+ "create=true", "ShutdownDatabase", "shutdown");
+
+ }
+
+ // first sets setCreate/ShutdownDB, then sets ConnectionAttributes
+ protected void assertConSetOK(String expectedSQLState, String dbName,
+ String connAttrValue, String setter, String setValue)
+ throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+
+ JDBCDataSource.setBeanProperty(ds, setter, setValue);
+ JDBCDataSource.setBeanProperty(
+ ds, "ConnectionAttributes", connAttrValue);
+ // check that the db exists; execute an unnecessary, but harmless, stmt
+ try {
+ ds.getConnection();
+ } catch (SQLException se) {
+ assertSQLState(expectedSQLState, se);
+ }
+ JDBCDataSource.clearStringBeanProperty(ds, setter);
+ JDBCDataSource.clearStringBeanProperty(ds, "ConnectionAttributes");
+ }
+
+ // sets ConnectionAttributes first, then SetCreate/ShutdownDB
+ protected void assertSetConOK(String expectedSQLState, String dbName,
+ String connAttrValue, String setter, String setValue)
+ throws SQLException {
+ DataSource ds = JDBCDataSource.getDataSource(dbName);
+
+ JDBCDataSource.setBeanProperty(
+ ds, "ConnectionAttributes", connAttrValue);
+ JDBCDataSource.setBeanProperty(ds, setter, setValue);
+ // check that the db exists; execute an unnecessary, but harmless, stmt
+ try {
+ ds.getConnection();
+ } catch (SQLException se) {
+ assertSQLState(expectedSQLState, se);
+ }
+ JDBCDataSource.clearStringBeanProperty(ds, "ConnectionAttributes");
+ JDBCDataSource.clearStringBeanProperty(ds, setter);
+ }
+
+}
\ No newline at end of file
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DSCreateShutdownDBTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceReferenceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceReferenceTest.java?view=auto&rev=529505
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceReferenceTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceReferenceTest.java Mon Apr 16 23:56:40 2007
@@ -0,0 +1,381 @@
+/*
+
+ Derby - Class org.apache.derbyTesting.functionTests.tests.jdbcapi.DataSourceReferenceTest
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.jdbcapi;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.spi.ObjectFactory;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.J2EEDataSource;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.JDBCDataSource;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+
+/**
+ * Test obtaining a javax.naming.Reference from a Derby data source
+ * and recreating a Derby data source from it. Tests that the recreated
+ * value has the same value for all the properties the data source supports.
+ * The list of properties is obtained dynamically from the getXXX methods
+ * that return int, String, boolean, short, long. Should Derby data sources
+ * support any other bean property types then this test should be modified
+ * to pick them up and handle them. Hopefully the test should fail when such
+ * a property is added.
+ *
+ * At no point does this test attempt to connect using these data sources.
+ */
+public class DataSourceReferenceTest extends BaseJDBCTestCase {
+
+ private static String[][][] expectedValues = {
+ // org.apache.derby.jdbc.Embedded*DataSource
+ {{"attributesAsPassword", "false"}, null, null, null, null, null,
+ {"loginTimeout", "0"}, null, null, null},
+ {{"attributesAsPassword", "true"},
+ {"connectionAttributes", "XX_connectionAttributes_2135"},
+ {"createDatabase", "create"},
+ {"dataSourceName", "XX_dataSourceName_1420"},
+ {"databaseName", "XX_databaseName_1206"},
+ {"description", "XX_description_1188"},
+ {"loginTimeout", "1280"},
+ {"password", "XX_password_883"},
+ {"shutdownDatabase", "shutdown"},
+ {"user", "XX_user_447"}},
+ // org.apache.derby.jdbc.Client*DataSource
+ { null, null, null, null, null, {"loginTimeout", "0"}, null,
+ {"portNumber", "tmpportno"},
+ {"retrieveMessageText", "true"},
+ {"securityMechanism", "4"},
+ {"serverName", "tmphostName"}, null, null, null,
+ {"traceFileAppend", "false"},
+ {"traceLevel", "-1"},
+ {"user", "tmpUserName"}},
+ {{"connectionAttributes", "XX_connectionAttributes_2135"},
+ {"createDatabase", "create"},
+ {"dataSourceName", "XX_dataSourceName_1420"},
+ {"databaseName", "XX_databaseName_1206"},
+ {"description", "XX_description_1188"},
+ {"loginTimeout", "1280"},
+ {"password", "XX_password_883"},
+ {"portNumber", "1070"},
+ {"retrieveMessageText", "false"},
+ {"securityMechanism", "1805"},
+ {"serverName", "XX_serverName_1048"},
+ {"shutdownDatabase", "shutdown"},
+ {"traceDirectory", "XX_traceDirectory_1476"},
+ {"traceFile", "XX_traceFile_911"},
+ {"traceFileAppend", "true"},
+ {"traceLevel", "1031"},
+ {"user", "XX_user_447"}}
+ };
+
+ public DataSourceReferenceTest(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ if (JDBC.vmSupportsJSR169())
+ {
+ // Referencable is not supported with JSR169
+ TestSuite suite =
+ new TestSuite("DatasourceTest cannot run with JSR169");
+ return suite;
+ }
+ else
+ {
+ return
+ TestConfiguration.defaultSuite(DataSourceReferenceTest.class);
+ }
+ }
+
+ /**
+ * Test a data source
+ * <OL>
+ * <LI> Create an empty one from the class name
+ * <LI> Discover the property list
+ * <LI> Create a reference and recreate a data source
+ * <LI> Compare the two
+ * <LI> Serialize the data source and recreate
+ * <LI> Compare the two
+ * <LI> Set every property for the data source
+ * <LI> Create a reference and recreate a data source
+ * <LI> Compare the two
+ * </OL>
+ * @throws Exception
+ */
+ public static void testDSReference() throws Exception
+ {
+ String ds;
+ ds = JDBCDataSource.getDataSource().getClass().getName();
+ int expectedArray=0;
+ if (usingDerbyNetClient())
+ expectedArray = 2;
+ assertDataSourceReference(expectedArray, ds);
+ ds = J2EEDataSource.getConnectionPoolDataSource().getClass().getName();
+ assertDataSourceReference(expectedArray, ds);
+ ds = J2EEDataSource.getXADataSource().getClass().getName();
+ assertDataSourceReference(expectedArray, ds);
+ }
+
+ public static void assertDataSourceReference(
+ int expectedArrayIndex, String dsName) throws Exception {
+
+ if (usingDerbyNetClient())
+ {
+ expectedValues[expectedArrayIndex][7][1] =
+ String.valueOf(TestConfiguration.getCurrent().getPort());
+ expectedValues[expectedArrayIndex][10][1] =
+ TestConfiguration.getCurrent().getHostName();
+ expectedValues[expectedArrayIndex][16][1] =
+ TestConfiguration.getCurrent().getUserName();
+ }
+
+ Object ds = Class.forName(dsName).newInstance();
+
+ println("DataSource class " + dsName);
+ String[] properties = getPropertyBeanList(ds);
+ assertEquals(
+ expectedValues[expectedArrayIndex+1].length, properties.length);
+ println(" property list");
+
+ for (int i = 0; i < properties.length; i++)
+ {
+ assertEquals(
+ expectedValues[expectedArrayIndex+1][i][0], properties[i]);
+ println(" " + properties[i]);
+ }
+
+ Referenceable refDS = (Referenceable) ds;
+
+ Reference dsAsReference = refDS.getReference();
+
+ String factoryClassName = dsAsReference.getFactoryClassName();
+
+ ObjectFactory factory =
+ (ObjectFactory) Class.forName(factoryClassName).newInstance();
+
+ Object recreatedDS =
+ factory.getObjectInstance(dsAsReference, null, null, null);
+
+ println(" empty DataSource recreated using Reference as " +
+ recreatedDS.getClass().getName());
+ // empty DataSource recreated using Reference should not be
+ // the same as the original
+ assertNotSame(recreatedDS, ds);
+
+ compareDS(expectedArrayIndex, properties, ds, recreatedDS);
+
+ // now serialize and recreate
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(ds);
+ oos.flush();
+ oos.close();
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+ recreatedDS = ois.readObject();
+ println(" empty DataSource recreated using serialization");
+ compareDS(expectedArrayIndex, properties, ds, recreatedDS);
+
+ // now populate the data source
+ for (int i = 0; i < properties.length; i++)
+ {
+ String property = properties[i];
+ Method getMethod = getGet(property, ds);
+
+ Method setMethod = getSet(getMethod, ds);
+
+ Class pt = getMethod.getReturnType();
+
+ // generate a somewhat unique value for a property
+ int val = 0;
+ for (int j = 0; j < property.length(); j++)
+ val += property.charAt(j);
+
+ if (pt.equals(Integer.TYPE))
+ {
+ setMethod.invoke(ds, new Object[] {new Integer(val)});
+ continue;
+ }
+ if (pt.equals(String.class))
+ {
+ String value;
+ if (property.equals("createDatabase"))
+ value = "create";
+ else if (property.equals("shutdownDatabase"))
+ value = "shutdown";
+ else
+ value = "XX_" + property + "_" + val;
+
+ setMethod.invoke(ds, new Object[] {value});
+ continue;
+ }
+ if (pt.equals(Boolean.TYPE))
+ {
+ // set the opposite value
+ Object gbv = getMethod.invoke(ds, null);
+ Boolean sbv =
+ Boolean.FALSE.equals(gbv) ? Boolean.TRUE : Boolean.FALSE;
+ setMethod.invoke(ds, new Object[] {sbv});
+ continue;
+ }
+ if (pt.equals(Short.TYPE))
+ {
+ setMethod.invoke(ds, new Object[] {new Short((short)val)});
+ continue;
+ }
+ if (pt.equals(Long.TYPE))
+ {
+ setMethod.invoke(ds, new Object[] {new Long(val)});
+ continue;
+ }
+ fail ( property + " not settable - update test!!");
+ }
+
+ dsAsReference = refDS.getReference();
+ recreatedDS =
+ factory.getObjectInstance(dsAsReference, null, null, null);
+ println(" populated DataSource recreated using Reference as "
+ + recreatedDS.getClass().getName());
+ // again, recreated should not be same instance
+ assertNotSame(recreatedDS, ds);
+
+ compareDS(expectedArrayIndex+1, properties, ds, recreatedDS);
+
+ // now serialize and recreate
+ baos = new ByteArrayOutputStream();
+ oos = new ObjectOutputStream(baos);
+ oos.writeObject(ds);
+ oos.flush();
+ oos.close();
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ ois = new ObjectInputStream(bais);
+ recreatedDS = ois.readObject();
+ println(" populated DataSource recreated using serialization");
+ compareDS(expectedArrayIndex+1, properties, ds, recreatedDS);
+ }
+
+ private static String[] getPropertyBeanList(Object ds) throws Exception
+ {
+ Method[] allMethods = ds.getClass().getMethods();
+
+ ArrayList properties = new ArrayList();
+ for (int i = 0; i < allMethods.length; i++)
+ {
+ Method m = allMethods[i];
+ String methodName = m.getName();
+ // Need at least getXX
+ if (methodName.length() < 5)
+ continue;
+ if (!methodName.startsWith("get"))
+ continue;
+ if (m.getParameterTypes().length != 0)
+ continue;
+
+ Class rt = m.getReturnType();
+
+ if (rt.equals(Integer.TYPE) || rt.equals(String.class) ||
+ rt.equals(Boolean.TYPE) || rt.equals(Short.TYPE) ||
+ rt.equals(Long.TYPE))
+ {
+ // valid Java Bean property
+ String beanName = methodName.substring(3,4).toLowerCase()
+ + methodName.substring(4);
+
+ properties.add(beanName);
+ continue;
+ }
+
+
+ assertFalse(rt.isPrimitive());
+ println("if rt.isPrimitive, method " + methodName +
+ " not supported - update test!!");
+
+ }
+
+ String[] propertyList = (String[]) properties.toArray(new String[0]);
+
+ Arrays.sort(propertyList);
+
+ return propertyList;
+ }
+
+ private static Method getGet(String property, Object ds) throws Exception
+ {
+ String methodName =
+ "get" + property.substring(0,1).toUpperCase()
+ + property.substring(1);
+ Method m = ds.getClass().getMethod(methodName, null);
+ return m;
+ }
+
+ private static Method getSet(Method getMethod, Object ds) throws Exception
+ {
+ String methodName = "s" + getMethod.getName().substring(1);
+ Method m = ds.getClass().getMethod(
+ methodName, new Class[] {getMethod.getReturnType()});
+ return m;
+ }
+
+ private static void compareDS(int expectedValuesArrayIndex,
+ String[] properties, Object ds, Object rds) throws Exception
+ {
+ println(" Start compare recreated");
+ for (int i = 0; i < properties.length; i++)
+ {
+ Method getMethod = getGet(properties[i], ds);
+
+ Object dsValue = getMethod.invoke(ds, null);
+ Object rdsValue = getMethod.invoke(rds, null);
+
+ if (dsValue == null)
+ {
+ // properties[i] originally null, should be recreated as null.
+ assertNull(rdsValue);
+ }
+ else
+ {
+ // properties[i] originally dsValue, should be recreated as
+ // rdsValue
+ assertEquals(dsValue, rdsValue);
+ }
+ if (dsValue != null)
+ {
+ assertEquals(expectedValues[expectedValuesArrayIndex][i][0],
+ properties[i]);
+ assertEquals(expectedValues[expectedValuesArrayIndex][i][1],
+ dsValue.toString());
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceReferenceTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/JDBCHarnessJavaTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/JDBCHarnessJavaTest.java?view=diff&rev=529505&r1=529504&r2=529505
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/JDBCHarnessJavaTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/JDBCHarnessJavaTest.java Mon Apr 16 23:56:40 2007
@@ -49,7 +49,6 @@
"connectionJdbc20",
// "statementJdbc20", runs in embedded only
"resultsetJdbc20",
- // "dataSourceReference", TODO: investigate failure/convert
// from old jdbcapi.runall
"derbyStress",
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java?view=diff&rev=529505&r1=529504&r2=529505
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/_Suite.java Mon Apr 16 23:56:40 2007
@@ -101,7 +101,10 @@
// Tests uses JDBC 3.0 datasources
suite.addTest(PoolDSAuthenticationTest.suite());
suite.addTest(XADSAuthenticationTest.suite());
-
+
+ // Test uses JDBC 3.0 datasources, and javax.naming.Reference etc.
+ suite.addTest(DataSourceReferenceTest.suite());
+
// Test uses DriverManager, Pooled and XADataSources, and
// an inner class implements ConnectionEventListener.
suite.addTest(DataSourceTest.suite());