KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > db > impl > ResultSetIterator


1 /*
2  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
3  * All rights reserved.
4  *
5  *
6  */

7
8 //=======================================================================
9
// Package
10
package com.hp.hpl.jena.db.impl;
11
12 //=======================================================================
13
// Imports
14
import java.sql.*;
15 import java.util.*;
16 import com.hp.hpl.jena.util.iterator.*;
17 import com.hp.hpl.jena.shared.*;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22 //=======================================================================
23
/**
24 * Iterates over an SQL result set returning each row as an ArrayList of
25 * objects. The returned array is shared at each iteration so calling next() or even hasNext()
26 * changes the array contents. When the iterator terminates the resources
27 * are cleaned up and the underlying SQL PreparedStatement is returned to
28 * the SQLCache pool from whence it came.
29 *
30 * <p>Override the extractRow, getRow, and remove methods in subclasses
31 * to return an object collection derived from the row contents instead
32 * of the raw row contents.
33 *
34 * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
35 * @version $Revision: 1.10 $ on $Date: 2005/02/21 12:03:09 $
36 */

37
38 public class ResultSetIterator implements ExtendedIterator {
39
40     /** The ResultSet being iterated over */
41     protected ResultSet m_resultSet;
42
43     /** The originating SQLcache to return the statement to, can be null */
44     protected SQLCache m_sqlCache;
45
46     /** The source Statement to be cleaned up when the iterator finishes - return it to cache or close it if no cache */
47     protected PreparedStatement m_statement;
48
49     /** The name of the original operation that lead to this statement, can be null if SQLCache is null */
50     protected String JavaDoc m_opname;
51
52     /** The contents of the current row */
53     protected ArrayList m_row;
54
55     /** The number of columns in this result set */
56     protected int m_nCols;
57
58     /** Flag that the iteration has finished */
59     protected boolean m_finished = false;
60
61     /** Flag if we have prefeteched the next row but not yet returned it */
62     protected boolean m_prefetched = false;
63
64     protected static Log logger = LogFactory.getLog( ResultSetIterator.class );
65     /**
66      * Create an empty iterator.
67      * Needs to be initialized by reset
68      * before it can be accessed. Useful to allow generic functions like
69      * {@link SQLCache#runSQLQuery runSQLQuery}
70      * to return different iterator types to the client.
71      */

72     public ResultSetIterator() {
73         m_finished = true; // Prevent reading until reset
74
}
75
76     /**
77      * Iterate over the results of a PreparedStatement generated by an SQLCache
78      * @param resultSet the result set being iterated over
79      * @param sourceStatement The source Statement to be cleaned up when the iterator finishes - return it to cache or close it if no cache
80      * @param cache The originating SQLcache to return the statement to, can be null
81      * @param opname The name of the original operation that lead to this statement, can be null if SQLCache is null
82      */

83     public ResultSetIterator(ResultSet resultSet, PreparedStatement sourceStatement, SQLCache cache, String JavaDoc opname) {
84         m_resultSet = resultSet;
85         m_sqlCache = cache;
86         m_statement = sourceStatement;
87         m_opname = opname;
88     }
89
90     /**
91      * Iterate over the results of a PreparedStatement, close the statement when finished.
92      * @param resultSet the result set being iterated over
93      * @param sourceStatement The source Statement to be closed when the iterator finishes
94      */

95     public ResultSetIterator(ResultSet resultSet, PreparedStatement sourceStatement) {
96         m_resultSet = resultSet;
97         m_statement = sourceStatement;
98     }
99
100     /**
101      * Reset an existing iterator to scan a new result set.
102      * @param resultSet the result set being iterated over
103      * @param sourceStatement The source Statement to be cleaned up when the iterator finishes - return it to cache or close it if no cache
104      * @param cache The originating SQLcache to return the statement to, can be null
105      * @param opname The name of the original operation that lead to this statement, can be null if SQLCache is null
106      */

107     public void reset(ResultSet resultSet, PreparedStatement sourceStatement, SQLCache cache, String JavaDoc opname) {
108         m_resultSet = resultSet;
109         m_sqlCache = cache;
110         m_statement = sourceStatement;
111         m_opname = opname;
112         m_finished = false;
113         m_prefetched = false;
114         m_row = null;
115     }
116
117     /**
118      * Test if there is a next result to return
119      */

120     public boolean hasNext() {
121         if (!m_finished && !m_prefetched) moveForward();
122         return !m_finished;
123     }
124     
125     public Object JavaDoc removeNext()
126         { cantRemove(); return null; }
127
128     /**
129      * Return the current row
130      */

131     public Object JavaDoc next() {
132         if (!m_finished && !m_prefetched) moveForward();
133         m_prefetched = false;
134         if (m_finished) {
135             throw new NoSuchElementException();
136         }
137         return getRow();
138     }
139
140     /**
141      * Delete the current row entry
142      */

143     public void remove() {
144         cantRemove();
145     }
146     
147     protected void cantRemove() {
148         throw new UnsupportedOperationException JavaDoc("ResultSetIterator can't remove database rows");
149     }
150
151     /**
152      * More forward one row. Sets the m_finished flag if there is no more to fetch
153      */

154     protected void moveForward() {
155         try {
156             if (!m_finished && m_resultSet.next()) {
157                 extractRow();
158                 m_prefetched = true;
159             } else {
160                 close();
161             }
162         } catch (Exception JavaDoc e) {
163             // TODO do we need this catch at all?
164
logger.warn("Problem in iterator over db result set, op = " + m_opname, e);
165             // Added by kers for debugging
166
throw new JenaException( e );
167         }
168     }
169
170     /**
171      * Extract the current row
172      * Override in subclasses.
173      */

174     protected void extractRow() throws Exception JavaDoc {
175         if (m_row == null) {
176             m_nCols = m_resultSet.getMetaData().getColumnCount();
177             m_row = new ArrayList(m_nCols);
178             for (int i = 0; i < m_nCols; i++) m_row.add(null);
179         }
180         for (int i = 0; i < m_nCols; i++) {
181             m_row.set(i, m_resultSet.getObject(i+1));
182         }
183     }
184
185     /**
186      * Return the current row,should have already been extracted.
187      * Override in subclasses.
188      */

189     protected Object JavaDoc getRow() {
190         return m_row;
191     }
192
193     /**
194      * Clean up the allocated resources - result set and statement.
195      * If we know of an SQLCache return the statement there, otherwise close it.
196      */

197     public void close() {
198         if (!m_finished) {
199             if (m_resultSet != null) {
200                 try {
201                     m_resultSet.close();
202                     m_resultSet = null;
203                 } catch (SQLException e) {
204                     logger.warn("Error while finalizing result set iterator", e);
205                 }
206             }
207             if (m_sqlCache != null && m_opname != null) {
208                 m_sqlCache.returnPreparedSQLStatement(m_statement);
209             } else {
210                 try {
211                     m_statement.close();
212                 } catch (SQLException e) {
213                     logger.warn("Error while finalizing result set iterator", e);
214                 }
215             }
216         }
217         m_finished = true;
218     }
219
220     /**
221      * Get a singleton result (single column from single row) and close the iterator.
222      * This may be too specialized but seems to come up a lot - rethink.
223      */

224     public Object JavaDoc getSingleton() throws SQLException {
225         List row = (List) next();
226         close();
227         return row.get(0);
228     }
229
230     /**
231      * Clean up the database cursor. Noramlly the client should read to the end
232      * or explicity close but....
233      */

234     protected void finalize() throws SQLException {
235         if (!m_finished && m_resultSet != null) close();
236     }
237
238     /**
239          return a new iterator which delivers all the elements of this iterator and
240          then all the elements of the other iterator. Does not copy either iterator;
241          they are consumed as the result iterator is consumed.
242      */

243     public ExtendedIterator andThen(ClosableIterator other) {
244         return NiceIterator.andThen(this, other);
245     }
246
247     /* (non-Javadoc)
248      * @see com.hp.hpl.jena.util.iterator.ExtendedIterator#filterKeep(com.hp.hpl.jena.util.iterator.Filter)
249      */

250     public ExtendedIterator filterKeep(Filter f) {
251         return new FilterIterator( f, this );
252     }
253
254     /* (non-Javadoc)
255      * @see com.hp.hpl.jena.util.iterator.ExtendedIterator#filterDrop(com.hp.hpl.jena.util.iterator.Filter)
256      */

257     public ExtendedIterator filterDrop(final Filter f) {
258         Filter notF = new Filter() { public boolean accept( Object JavaDoc x ) { return !f.accept( x ); } };
259         return new FilterIterator( notF, this );
260     }
261
262     /* (non-Javadoc)
263      * @see com.hp.hpl.jena.util.iterator.ExtendedIterator#mapWith(com.hp.hpl.jena.util.iterator.Map1)
264      */

265     public ExtendedIterator mapWith(Map1 map1) {
266         return new Map1Iterator( map1, this );
267     }
268
269 } // End class
270

271 /*
272  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
273  * All rights reserved.
274  *
275  * Redistribution and use in source and binary forms, with or without
276  * modification, are permitted provided that the following conditions
277  * are met:
278  * 1. Redistributions of source code must retain the above copyright
279  * notice, this list of conditions and the following disclaimer.
280  * 2. Redistributions in binary form must reproduce the above copyright
281  * notice, this list of conditions and the following disclaimer in the
282  * documentation and/or other materials provided with the distribution.
283  * 3. The name of the author may not be used to endorse or promote products
284  * derived from this software without specific prior written permission.
285
286  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
287  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
288  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
289  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
290  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
291  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
292  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
293  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
294  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
295  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
296  */

297
Popular Tags