/** * */ 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; } }