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 */ 017package org.apache.commons.dbutils; 018 019import java.sql.ResultSet; 020import java.sql.SQLException; 021import java.util.Iterator; 022 023/** 024 * <p> 025 * Wraps a {@code ResultSet} in an {@code Iterator<Object[]>}. 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()} method 032 * to be implemented. 033 * </p> 034 */ 035public class ResultSetIterator implements Iterator<Object[]> { 036 037 /** 038 * The wrapped {@code ResultSet}. 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} in an {@code Iterator}. 050 */ 051 public ResultSetIterator(final ResultSet rs) { 052 this(rs, new BasicRowProcessor()); 053 } 054 055 /** 056 * Constructor for ResultSetIterator. 057 * @param rs Wrap this {@code ResultSet} in an {@code Iterator}. 058 * @param convert The processor to use when converting a row into an 059 * {@code Object[]}. Defaults to a 060 * {@code BasicRowProcessor}. 061 */ 062 public ResultSetIterator(final ResultSet rs, final 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} if there are more rows 070 * @throws RuntimeException if an SQLException occurs. 071 */ 072 @Override 073 public boolean hasNext() { 074 try { 075 return !rs.isLast(); 076 } catch (final SQLException e) { 077 rethrow(e); 078 return false; 079 } 080 } 081 082 /** 083 * Returns the next row as an {@code Object[]}. 084 * @return An {@code Object[]} with the same number of elements as 085 * columns in the {@code ResultSet}. 086 * @see java.util.Iterator#next() 087 * @throws RuntimeException if an SQLException occurs. 088 */ 089 @Override 090 public Object[] next() { 091 try { 092 rs.next(); 093 return this.convert.toArray(rs); 094 } catch (final SQLException e) { 095 rethrow(e); 096 return null; 097 } 098 } 099 100 /** 101 * Deletes the current row from the {@code ResultSet}. 102 * @see java.util.Iterator#remove() 103 * @throws RuntimeException if an SQLException occurs. 104 */ 105 @Override 106 public void remove() { 107 try { 108 this.rs.deleteRow(); 109 } catch (final SQLException e) { 110 rethrow(e); 111 } 112 } 113 114 /** 115 * Rethrow the SQLException as a RuntimeException. This implementation 116 * creates a new RuntimeException with the SQLException's error message. 117 * @param e SQLException to rethrow 118 * @since DbUtils 1.1 119 */ 120 protected void rethrow(final SQLException e) { 121 throw new RuntimeException(e.getMessage()); 122 } 123 124 /** 125 * Generates an {@code Iterable}, suitable for use in for-each loops. 126 * 127 * @param rs Wrap this {@code ResultSet} in an {@code Iterator}. 128 * @return an {@code Iterable}, suitable for use in for-each loops. 129 */ 130 public static Iterable<Object[]> iterable(final ResultSet rs) { 131 return new Iterable<Object[]>() { 132 133 @Override 134 public Iterator<Object[]> iterator() { 135 return new ResultSetIterator(rs); 136 } 137 138 }; 139 } 140 141}