/****************************************************************************** * Copyright © 2013-2016 The Nxt Core Developers. * * * * See the AUTHORS.txt, DEVELOPER-AGREEMENT.txt and LICENSE.txt files at * * the top-level directory of this distribution for the individual copyright * * holder information and the developer policies on copyright and licensing. * * * * Unless otherwise agreed in a custom licensing agreement, no part of the * * Nxt software, including this file, may be copied, modified, propagated, * * or distributed except according to the terms contained in the LICENSE.txt * * file. * * * * Removal or modification of this copyright notice is prohibited. * * * ******************************************************************************/ package nxt.db; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Iterator; import java.util.NoSuchElementException; public final class DbIterator<T> implements Iterator<T>, Iterable<T>, AutoCloseable { public interface ResultSetReader<T> { T get(Connection con, ResultSet rs) throws Exception; } private final Connection con; private final PreparedStatement pstmt; private final ResultSetReader<T> rsReader; private final ResultSet rs; private boolean hasNext; private boolean iterated; public DbIterator(Connection con, PreparedStatement pstmt, ResultSetReader<T> rsReader) { this.con = con; this.pstmt = pstmt; this.rsReader = rsReader; try { this.rs = pstmt.executeQuery(); this.hasNext = rs.next(); } catch (SQLException e) { DbUtils.close(pstmt, con); throw new RuntimeException(e.toString(), e); } } @Override public boolean hasNext() { if (! hasNext) { DbUtils.close(rs, pstmt, con); } return hasNext; } @Override public T next() { if (! hasNext) { DbUtils.close(rs, pstmt, con); throw new NoSuchElementException(); } try { T result = rsReader.get(con, rs); hasNext = rs.next(); return result; } catch (Exception e) { DbUtils.close(rs, pstmt, con); throw new RuntimeException(e.toString(), e); } } @Override public void remove() { throw new UnsupportedOperationException("Removal not supported"); } @Override public void close() { DbUtils.close(rs, pstmt, con); } @Override public Iterator<T> iterator() { if (iterated) { throw new IllegalStateException("Already iterated"); } iterated = true; return this; } }