001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.dbutils;
018    
019    import java.sql.ResultSet;
020    import java.sql.SQLException;
021    import java.util.Iterator;
022    
023    /**
024     * <p>
025     * Wraps a <code>ResultSet</code> in an <code>Iterator<Object[]></code>.  This is useful
026     * when you want to present a non-database application layer with domain
027     * neutral data.
028     * </p>
029     *
030     * <p>
031     * This implementation requires the <code>ResultSet.isLast()</code> method
032     * to be implemented.
033     * </p>
034     */
035    public class ResultSetIterator implements Iterator<Object[]> {
036    
037        /**
038         * The wrapped <code>ResultSet</code>.
039         */
040        private final ResultSet rs;
041    
042        /**
043         * The processor to use when converting a row into an Object[].
044         */
045        private final RowProcessor convert;
046    
047        /**
048         * Constructor for ResultSetIterator.
049         * @param rs Wrap this <code>ResultSet</code> in an <code>Iterator</code>.
050         */
051        public ResultSetIterator(ResultSet rs) {
052            this(rs, new BasicRowProcessor());
053        }
054    
055        /**
056         * Constructor for ResultSetIterator.
057         * @param rs Wrap this <code>ResultSet</code> in an <code>Iterator</code>.
058         * @param convert The processor to use when converting a row into an
059         * <code>Object[]</code>.  Defaults to a
060         * <code>BasicRowProcessor</code>.
061         */
062        public ResultSetIterator(ResultSet rs, RowProcessor convert) {
063            this.rs = rs;
064            this.convert = convert;
065        }
066    
067        /**
068         * Returns true if there are more rows in the ResultSet.
069         * @return boolean <code>true</code> if there are more rows
070         * @throws RuntimeException if an SQLException occurs.
071         */
072        public boolean hasNext() {
073            try {
074                return !rs.isLast();
075            } catch (SQLException e) {
076                rethrow(e);
077                return false;
078            }
079        }
080    
081        /**
082         * Returns the next row as an <code>Object[]</code>.
083         * @return An <code>Object[]</code> with the same number of elements as
084         * columns in the <code>ResultSet</code>.
085         * @see java.util.Iterator#next()
086         * @throws RuntimeException if an SQLException occurs.
087         */
088        public Object[] next() {
089            try {
090                rs.next();
091                return this.convert.toArray(rs);
092            } catch (SQLException e) {
093                rethrow(e);
094                return null;
095            }
096        }
097    
098        /**
099         * Deletes the current row from the <code>ResultSet</code>.
100         * @see java.util.Iterator#remove()
101         * @throws RuntimeException if an SQLException occurs.
102         */
103        public void remove() {
104            try {
105                this.rs.deleteRow();
106            } catch (SQLException e) {
107                rethrow(e);
108            }
109        }
110    
111        /**
112         * Rethrow the SQLException as a RuntimeException.  This implementation
113         * creates a new RuntimeException with the SQLException's error message.
114         * @param e SQLException to rethrow
115         * @since DbUtils 1.1
116         */
117        protected void rethrow(SQLException e) {
118            throw new RuntimeException(e.getMessage());
119        }
120    
121        /**
122         * Generates an <code>Iterable</code>, suitable for use in for-each loops.
123         *
124         * @param rs Wrap this <code>ResultSet</code> in an <code>Iterator</code>.
125         * @return an <code>Iterable</code>, suitable for use in for-each loops.
126         */
127        public static Iterable<Object[]> iterable(final ResultSet rs) {
128            return new Iterable<Object[]>() {
129    
130                public Iterator<Object[]> iterator() {
131                    return new ResultSetIterator(rs);
132                }
133    
134            };
135        }
136    
137    }