001/*
002        $Id: DynamicResultIterator.java 3207 2009-04-09 06:48:11Z gregory $
003
004        Copyright (C) 2006 Gregory Vincic, Olle Mansson
005        Copyright (C) 2007 Gregory Vincic
006
007        This file is part of Proteios.
008        Available at http://www.proteios.org/
009
010        Proteios is free software; you can redistribute it and/or modify it
011        under the terms of the GNU General Public License as published by
012        the Free Software Foundation; either version 2 of the License, or
013        (at your option) any later version.
014
015        Proteios is distributed in the hope that it will be useful, but
016        WITHOUT ANY WARRANTY; without even the implied warranty of
017        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
018        General Public License for more details.
019
020        You should have received a copy of the GNU General Public License
021        along with this program; if not, write to the Free Software
022        Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
023        02111-1307, USA.
024*/
025package org.proteios.core;
026
027import org.proteios.core.query.SqlResult;
028import org.proteios.core.query.SqlResultIterator;
029import java.sql.ResultSet;
030import java.sql.SQLException;
031import java.util.NoSuchElementException;
032
033/**
034        An iterator view of the result of an AbstractSqlQuery.
035        
036        
037        @author Nicklas
038        @version 2.0
039        @base.modified $Date: 2009-04-09 08:48:11 +0200 (Thu, 09 Apr 2009) $
040*/
041public class DynamicResultIterator
042        implements SqlResultIterator
043{
044
045        /**
046                The results of the query.
047        */
048        private final ResultSet results;
049
050        /**
051                The total number of items.
052        */
053        private final int totalCount;
054
055        private final int limit;
056        
057        private int returnedRows;
058        
059        private final SqlResult sqlResult;
060        
061        private boolean hasNext;
062        private boolean checkNext;
063        private boolean isClosed;
064
065        /**
066                Create a new result iterator.
067                @param results The <code>ResultSet</code> object containing the
068                        results
069                @param totalCount The total number of rows
070                @param limit The maximum numbre of rows that was specified for the
071                        query
072        */
073        DynamicResultIterator(ResultSet results, int totalCount, int limit)
074        {
075                this.results = results;
076                this.totalCount = totalCount;
077                this.limit = limit;
078                this.returnedRows = 0;
079                this.sqlResult = new SqlResultImpl();
080                this.checkNext = true;
081        }
082
083        /**
084                From the QueryResult interface
085                ---------------------------------
086        */
087        public int getTotalCount()
088        {
089                return totalCount;
090        }
091        // ---------------------------------
092        /**
093                From the ResultIterator interface
094                ---------------------------------
095        */
096        public void close()
097        {
098                if (!isClosed()) 
099                {
100                        isClosed = true;
101                        hasNext = false;
102                        checkNext = false;
103                        try
104                        {
105                                results.close();
106                                results.getStatement().close();
107                        }
108                        catch (SQLException ex)
109                        {
110                                throw new DatabaseException(ex);
111                        }
112                }
113        }
114        public boolean isClosed()
115        {
116                return isClosed;
117        }
118        // ---------------------------------
119        /*
120                From the Iterator interface
121                ---------------------------
122        */
123        public boolean hasNext()
124        {
125                if (checkNext && !isClosed())
126                {
127                        try
128                        {
129                                hasNext = results.next();
130                                returnedRows++;
131                        }
132                        catch (SQLException ex)
133                        {
134                                throw new DatabaseException(ex);
135                        }
136                        if (!hasNext || (returnedRows > limit && limit > 0))
137                        {
138                                close();
139                                hasNext = false;
140                        }
141                        checkNext = false;
142                }
143                return hasNext;
144        }
145        /**
146                Get the results in the next row. The actual {@link SqlResult} object
147                is always the same object. It just changes the underlying pointer to
148                the next row in the result set. If you need to store data from
149                a previous row you must copy the values to another place.
150                @return A <code>SqlResult</code> object
151                @throws NoSuchElementException If there are no more results
152        */
153        public SqlResult next()
154        {
155                if (!hasNext()) throw new NoSuchElementException();
156                checkNext = true;
157                return sqlResult;
158        }
159        /**
160                Not supported.
161                @throws UnsupportedOperationException Always
162        */
163        public void remove()
164        {
165                throw new UnsupportedOperationException();
166        }
167        // ---------------------------------
168
169        /*
170                From the SqlResultIterator interface
171                ---------------------------------
172        */
173        public int getIndex(String name)
174                throws SQLException
175        {
176                return results.findColumn(name);
177        }
178        // ---------------------------------
179
180        /**
181                Implements the SqlResult interface.
182        */
183        private class SqlResultImpl 
184                implements SqlResult
185        {
186                /*
187                        From the SqlResult interface
188                        ---------------------------
189                */
190                public short getShort(int index)
191                        throws SQLException
192                {
193                        return results.getShort(index);
194                }
195                public int getInt(int index)
196                        throws SQLException
197                {
198                        return results.getInt(index);
199                }
200                public float getFloat(int index)
201                        throws SQLException
202                {
203                        return results.getFloat(index);
204                }
205                public String getString(int index)
206                        throws SQLException
207                {
208                        return results.getString(index);
209                }
210                public Object getObject(int index)
211                        throws SQLException
212                {
213                        return results.getObject(index);
214                }
215                // ---------------------------------
216        }
217
218}