/**
*
*/
package ecologylab.sql;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* Wraps a java.sql.Connection object, keeping track of all of the statements it produces. On close,
* automatically closes all open connections and releases them for garbage collection.
*
* TODO Ultimately, this class should implement java.sql.Connection, but for now, it only implements
* a few select methods; adding others as needed should be straightforward.
*
* @author Zachary O. Toups (zach@ecologylab.net)
*/
public class ConnectionWithAutoClose
{
Connection conn;
List<StatementWithAutoClose> stmts = null;
public ConnectionWithAutoClose(Connection conn)
{
this.conn = conn;
}
public PreparedStatementWithAutoClose prepareStatement(String sql) throws SQLException
{
PreparedStatement ps = conn.prepareStatement(sql);
PreparedStatementWithAutoClose psac = new PreparedStatementWithAutoClose(ps);
stmts().add(psac);
return psac;
}
public PreparedStatementWithAutoClose prepareStatement(String sql, int autoGeneratedKeys) throws SQLException
{
PreparedStatement ps = conn.prepareStatement(sql, autoGeneratedKeys);
PreparedStatementWithAutoClose psac = new PreparedStatementWithAutoClose(ps);
stmts().add(psac);
return psac;
}
public StatementWithAutoClose<Statement> createStatement() throws SQLException
{
StatementWithAutoClose sac = new StatementWithAutoClose(conn.createStatement());
stmts().add(sac);
return sac;
}
private List<StatementWithAutoClose> stmts()
{
if (stmts == null)
{
synchronized (this)
{
if (stmts == null)
{
stmts = new LinkedList<StatementWithAutoClose>();
}
}
}
return stmts;
}
/**
* Wraps PreparedStatement.close() and eats its exceptions. Before invoking stmt.close(), closes
* all open ResultSets that were returned by this.
*/
public void close()
{
if (stmts != null)
{
Iterator<StatementWithAutoClose> stmtIter = stmts.iterator();
while (stmtIter.hasNext())
{
StatementWithAutoClose stmt = stmtIter.next();
stmtIter.remove();
stmt.close();
}
}
try
{
conn.close();
}
catch (SQLException e)
{
}
conn = null;
}
}