instead of throwing an Exception.
Per report from Victor Sergienko.
import java.sql.Types;
import java.util.Vector;
-/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.41.2.3 2004/02/03 05:13:55 jurka Exp $
+/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.41.2.4 2004/02/24 13:11:44 jurka Exp $
* This class defines methods of the jdbc1 specification. This class is
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
private boolean m_useServerPrepare = false;
+ private boolean isClosed = false;
+
// m_preparedCount is used for naming of auto-cursors and must
// be synchronized so that multiple threads using the same
// connection don't stomp over each others cursors.
*/
public void close() throws SQLException
{
+ // closing an already closed Statement is a no-op.
+ if (isClosed)
+ return;
+
// Force the ResultSet to close
java.sql.ResultSet rs = getResultSet();
if (rs != null)
// Disasociate it from us (For Garbage Collection)
result = null;
+ isClosed = true;
}
/**
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @author Csaba Nagy (ncsaba@yahoo.com)
- * @version $Revision: 1.7.4.2 $
+ * @version $Revision: 1.7.4.3 $
*/
public class PooledConnectionImpl implements PooledConnection
{
{
return con == null ? Boolean.TRUE : Boolean.FALSE;
}
- if (con == null)
+ if (con == null && !method.getName().equals("close"))
{
throw new SQLException(automatic ? "Connection has been closed automatically because a new connection was opened for the same PooledConnection or the PooledConnection has been closed" : "Connection has been closed");
}
if (method.getName().equals("close"))
{
+ // we are already closed and a double close
+ // is not an error.
+ if (con == null)
+ return null;
+
SQLException ex = null;
if (!con.getAutoCommit())
{
return method.invoke(st, args);
}
// All the rest is from the Statement interface
- if (st == null || con.isClosed())
- {
- throw new SQLException("Statement has been closed");
- }
if (method.getName().equals("close"))
{
+ // closing an already closed object is a no-op
+ if (st == null || con.isClosed())
+ return null;
+
try {
st.close();
} finally {
}
return null;
}
+ if (st == null || con.isClosed())
+ {
+ throw new SQLException("Statement has been closed");
+ }
else if (method.getName().equals("getConnection"))
{
return con.getProxy(); // the proxied connection, not a physical connection
*
* PS: Do you know how difficult it is to type on a train? ;-)
*
- * $Id: ConnectionTest.java,v 1.10 2002/10/17 05:33:52 barry Exp $
+ * $Id: ConnectionTest.java,v 1.10.6.1 2004/02/24 13:11:44 jurka Exp $
*/
public class ConnectionTest extends TestCase
assertTrue(ex.getMessage(), false);
}
}
+
+ /**
+ * Closing a Connection more than once is not an error.
+ */
+ public void testDoubleClose() throws SQLException
+ {
+ Connection con = TestUtil.openDB();
+ con.close();
+ con.close();
+ }
}
* interface to the PooledConnection is through the CPDS.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
- * @version $Revision: 1.6.4.3 $
+ * @version $Revision: 1.6.4.4 $
*/
public class ConnectionPoolTest extends BaseDataSourceTest
{
}
catch (SQLException e)
{}
- try
- {
- con.close();
- fail("Original connection wrapper should be closed when new connection wrapper is generated");
- }
- catch (SQLException e)
- {}
con2.close();
pc.close();
}
con.close();
assertTrue(cc.getCount() == 2);
assertTrue(cc.getErrorCount() == 0);
- try
- {
+ // a double close shouldn't fire additional events
con.close();
- fail("Should not be able to close a connection wrapper twice");
- }
- catch (SQLException e)
- {}
assertTrue(cc.getCount() == 2);
assertTrue(cc.getErrorCount() == 0);
pc.close();
package org.postgresql.test.jdbc2.optional;
import java.sql.SQLException;
+import java.sql.Statement;
import org.postgresql.test.TestUtil;
import org.postgresql.jdbc2.optional.PoolingDataSource;
import org.postgresql.jdbc2.optional.BaseDataSource;
* Minimal tests for pooling DataSource. Needs many more.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
- * @version $Revision: 1.1.6.1 $
+ * @version $Revision: 1.1.6.2 $
*/
public class PoolingDataSourceTest extends BaseDataSourceTest
{
{
}
}
+
+ /**
+ * Closing a Connection twice is not an error.
+ */
+ public void testDoubleConnectionClose() throws SQLException
+ {
+ con = getDataSourceConnection();
+ con.close();
+ con.close();
+ }
+
+ /**
+ * Closing a Statement twice is not an error.
+ */
+ public void testDoubleStatementClose() throws SQLException
+ {
+ con = getDataSourceConnection();
+ Statement stmt = con.createStatement();
+ stmt.close();
+ stmt.close();
+ con.close();
+ }
}