diff --git a/db/apichanges.xml b/db/apichanges.xml --- a/db/apichanges.xml +++ b/db/apichanges.xml @@ -105,6 +105,20 @@ + + + Add ability to test a connection for validity + + + + + + This change allows you to make sure a DatabaseConnection is valid + before you use it to issue commands to the database. + + + + Add support for always quoting and for unquoting SQL identifiers. diff --git a/db/arch.xml b/db/arch.xml --- a/db/arch.xml +++ b/db/arch.xml @@ -339,6 +339,16 @@ method.

+ +

+ You may want to test to make sure a connection is open and valid before you + get the underlying physical JDBC connection. This can be achieved using the + + DatabaseConnection.getJDBCConnection(boolean test) + method, which validates the underlying connection before returning it. If the + connection is invalid, it marks the DatabaseConnection as invalid and returns null. +

+

A component which provides database functionality (such as the SQL Editor diff --git a/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java b/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java --- a/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java +++ b/db/src/org/netbeans/api/db/explorer/DatabaseConnection.java @@ -219,10 +219,29 @@ * ConnectionManager. */ public Connection getJDBCConnection() { + return getJDBCConnection(false); + } + + /** + * Get a JDBCConnection, with an option to test the connection before returning it + * + * @param test If this is set to true, the connection is tested for validity. If + * it is invalid, the DatabaseConnection is marked as no longer connected and + * null is returned. If this is set to false, then no test is performed + * + * @return the physical connection or null if not connected (or invalid if test is true) + * + * @throws IllegalStateException if this connection is not added to the + * ConnectionManager. + * + * @since 1.29 + */ + public Connection getJDBCConnection(boolean test) { if (!ConnectionList.getDefault().contains(delegate)) { throw new IllegalStateException("This connection is not added to the ConnectionManager."); // NOI18N } - return delegate.getJDBCConnection(); + + return delegate.getJDBCConnection(test); } /** diff --git a/db/src/org/netbeans/modules/db/explorer/Bundle.properties b/db/src/org/netbeans/modules/db/explorer/Bundle.properties --- a/db/src/org/netbeans/modules/db/explorer/Bundle.properties +++ b/db/src/org/netbeans/modules/db/explorer/Bundle.properties @@ -35,3 +35,4 @@ # # Portions Copyrighted 2008 Sun Microsystems, Inc. ERR_CONN_ALREADY_EXISTS = The connection with the name {0} already exists +MSG_TestFailed = The connection {0} does not appear to have a valid connection to the database: {1} diff --git a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java b/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java --- a/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java +++ b/db/src/org/netbeans/modules/db/explorer/DatabaseConnection.java @@ -212,6 +212,41 @@ } } return useDriver; + } + + public Connection getJDBCConnection(boolean test) { + if (test) { + if (! test()) { + try { + this.disconnect(); + } catch (DatabaseException e) { + LOGGER.log(Level.FINE, null, e); + } + + return null; + } + } + + return getJDBCConnection(); + } + + private boolean test() { + try { + Connection conn = getJDBCConnection(); + if (conn == null || conn.isClosed()) { + return false; + } + + // Send a command to the server, if it fails we know the connection is invalid. + conn.getMetaData().getTables(null, null, " ", new String[] { "TABLE" }).close(); + } catch (SQLException e) { + LOGGER.log(Level.INFO, NbBundle.getMessage(DatabaseConnection.class, + "MSG_TestFailed", this.getName(), e.getMessage())); + LOGGER.log(Level.FINE, null, e); + return false; + } + return true; + } private Collection getOpenConnections() { diff --git a/db/test/unit/src/org/netbeans/api/db/explorer/DatabaseConnectionTest.java b/db/test/unit/src/org/netbeans/api/db/explorer/DatabaseConnectionTest.java --- a/db/test/unit/src/org/netbeans/api/db/explorer/DatabaseConnectionTest.java +++ b/db/test/unit/src/org/netbeans/api/db/explorer/DatabaseConnectionTest.java @@ -41,7 +41,7 @@ package org.netbeans.api.db.explorer; -import org.netbeans.modules.db.explorer.ConnectionList; +import java.sql.Connection; import org.netbeans.modules.db.test.Util; import org.netbeans.modules.db.util.DBTestBase; @@ -117,5 +117,19 @@ ConnectionManager.getDefault().removeConnection(dbconn); assertEquals(0, ConnectionManager.getDefault().getConnections().length); - } + } + + public void testGetJDBCConnectionWithTest() throws Exception { + DatabaseConnection dbconn = getDatabaseConnection(); + ConnectionManager.getDefault().disconnect(dbconn); + assertNull(dbconn.getJDBCConnection(true)); + ConnectionManager.getDefault().connect(dbconn); + assertNotNull(dbconn.getJDBCConnection(true)); + assertNotNull(dbconn.getJDBCConnection(false)); + + dbconn.getJDBCConnection(true).close(); + assertNotNull(dbconn.getJDBCConnection(false)); + assertNull(dbconn.getJDBCConnection(true)); + assertNull(dbconn.getJDBCConnection(false)); + } } diff --git a/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionTest.java b/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionTest.java --- a/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionTest.java +++ b/db/test/unit/src/org/netbeans/modules/db/explorer/DatabaseConnectionTest.java @@ -43,13 +43,13 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import org.netbeans.modules.db.test.TestBase; +import org.netbeans.modules.db.util.DBTestBase; /** * * @author Andrei Badea */ -public class DatabaseConnectionTest extends TestBase { +public class DatabaseConnectionTest extends DBTestBase { public DatabaseConnectionTest(String testName) { super(testName); diff --git a/db/test/unit/src/org/netbeans/modules/db/util/DBTestBase.java b/db/test/unit/src/org/netbeans/modules/db/util/DBTestBase.java --- a/db/test/unit/src/org/netbeans/modules/db/util/DBTestBase.java +++ b/db/test/unit/src/org/netbeans/modules/db/util/DBTestBase.java @@ -89,8 +89,8 @@ private static int unquotedCaseRule = RULE_UNDEFINED; private static int quotedCaseRule = RULE_UNDEFINED; - private static JDBCDriver jdbcDriver; - private static DatabaseConnection dbConnection; + private JDBCDriver jdbcDriver; + private DatabaseConnection dbConnection; protected Connection conn; @@ -98,7 +98,7 @@ super(name); } - protected static JDBCDriver getJDBCDriver() throws Exception{ + protected JDBCDriver getJDBCDriver() throws Exception{ if (jdbcDriver == null) { jdbcDriver = JDBCDriver.create("derbydriver", "derbydriver", driverClass, new URL[] {driverJarUrl}); assertNotNull(jdbcDriver); @@ -113,7 +113,7 @@ * Get the DatabaseConnection for the configured Java DB database. This * method will create and register the connection the first time it is called */ - protected static DatabaseConnection getDatabaseConnection() throws Exception { + protected DatabaseConnection getDatabaseConnection() throws Exception { if (dbConnection == null) { JDBCDriver driver = getJDBCDriver();