001: //$Id: IteratorImpl.java 9944 2006-05-24 21:14:56Z steve.ebersole@jboss.com $
002: package org.hibernate.impl;
003:
004: import java.sql.PreparedStatement;
005: import java.sql.ResultSet;
006: import java.sql.SQLException;
007: import java.util.NoSuchElementException;
008:
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011: import org.hibernate.HibernateException;
012: import org.hibernate.JDBCException;
013: import org.hibernate.engine.HibernateIterator;
014: import org.hibernate.event.EventSource;
015: import org.hibernate.exception.JDBCExceptionHelper;
016: import org.hibernate.hql.HolderInstantiator;
017: import org.hibernate.type.EntityType;
018: import org.hibernate.type.Type;
019:
020: /**
021: * An implementation of <tt>java.util.Iterator</tt> that is
022: * returned by <tt>iterate()</tt> query execution methods.
023: * @author Gavin King
024: */
025: public final class IteratorImpl implements HibernateIterator {
026:
027: private static final Log log = LogFactory
028: .getLog(IteratorImpl.class);
029:
030: private ResultSet rs;
031: private final EventSource session;
032: private final Type[] types;
033: private final boolean single;
034: private Object currentResult;
035: private boolean hasNext;
036: private final String[][] names;
037: private PreparedStatement ps;
038: private Object nextResult;
039: private HolderInstantiator holderInstantiator;
040:
041: public IteratorImpl(ResultSet rs, PreparedStatement ps,
042: EventSource sess, Type[] types, String[][] columnNames,
043: HolderInstantiator holderInstantiator)
044: throws HibernateException, SQLException {
045:
046: this .rs = rs;
047: this .ps = ps;
048: this .session = sess;
049: this .types = types;
050: this .names = columnNames;
051: this .holderInstantiator = holderInstantiator;
052:
053: single = types.length == 1;
054:
055: postNext();
056: }
057:
058: public void close() throws JDBCException {
059: if (ps != null) {
060: try {
061: log.debug("closing iterator");
062: nextResult = null;
063: session.getBatcher().closeQueryStatement(ps, rs);
064: ps = null;
065: rs = null;
066: hasNext = false;
067: } catch (SQLException e) {
068: log.info("Unable to close iterator", e);
069: throw JDBCExceptionHelper.convert(session.getFactory()
070: .getSQLExceptionConverter(), e,
071: "Unable to close iterator");
072: }
073: }
074: }
075:
076: private void postNext() throws HibernateException, SQLException {
077: this .hasNext = rs.next();
078: if (!hasNext) {
079: log.debug("exhausted results");
080: close();
081: } else {
082: log.debug("retrieving next results");
083: boolean isHolder = holderInstantiator.isRequired();
084:
085: if (single && !isHolder) {
086: nextResult = types[0].nullSafeGet(rs, names[0],
087: session, null);
088: } else {
089: Object[] nextResults = new Object[types.length];
090: for (int i = 0; i < types.length; i++) {
091: nextResults[i] = types[i].nullSafeGet(rs, names[i],
092: session, null);
093: }
094:
095: if (isHolder) {
096: nextResult = holderInstantiator
097: .instantiate(nextResults);
098: } else {
099: nextResult = nextResults;
100: }
101: }
102:
103: }
104: }
105:
106: public boolean hasNext() {
107: return hasNext;
108: }
109:
110: public Object next() {
111: if (!hasNext)
112: throw new NoSuchElementException("No more results");
113: try {
114: currentResult = nextResult;
115: postNext();
116: log.debug("returning current results");
117: return currentResult;
118: } catch (SQLException sqle) {
119: throw JDBCExceptionHelper.convert(session.getFactory()
120: .getSQLExceptionConverter(), sqle,
121: "could not get next iterator result");
122: }
123: }
124:
125: public void remove() {
126: if (!single) {
127: throw new UnsupportedOperationException(
128: "Not a single column hibernate query result set");
129: }
130: if (currentResult == null) {
131: throw new IllegalStateException(
132: "Called Iterator.remove() before next()");
133: }
134: if (!(types[0] instanceof EntityType)) {
135: throw new UnsupportedOperationException("Not an entity");
136: }
137:
138: session.delete(((EntityType) types[0])
139: .getAssociatedEntityName(), currentResult, false, null);
140: }
141:
142: }
|