KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > impl > FetchingScrollableResultsImpl


1 // $Id: FetchingScrollableResultsImpl.java,v 1.3 2005/07/14 13:12:01 steveebersole Exp $
2
package org.hibernate.impl;
3
4 import org.hibernate.HibernateException;
5 import org.hibernate.MappingException;
6 import org.hibernate.exception.JDBCExceptionHelper;
7 import org.hibernate.hql.HolderInstantiator;
8 import org.hibernate.type.Type;
9 import org.hibernate.loader.Loader;
10 import org.hibernate.engine.SessionImplementor;
11 import org.hibernate.engine.QueryParameters;
12
13 import java.sql.ResultSet JavaDoc;
14 import java.sql.PreparedStatement JavaDoc;
15 import java.sql.SQLException JavaDoc;
16
17 /**
18  * Implementation of ScrollableResults which can handle collection fetches.
19  *
20  * @author Steve Ebersole
21  */

22 public class FetchingScrollableResultsImpl extends AbstractScrollableResults {
23
24     public FetchingScrollableResultsImpl(
25             ResultSet JavaDoc rs,
26             PreparedStatement JavaDoc ps,
27             SessionImplementor sess,
28             Loader loader,
29             QueryParameters queryParameters,
30             Type[] types,
31             HolderInstantiator holderInstantiator) throws MappingException {
32         super( rs, ps, sess, loader, queryParameters, types, holderInstantiator );
33     }
34
35     private Object JavaDoc[] currentRow = null;
36     private int currentPosition = 0;
37     private Integer JavaDoc maxPosition = null;
38
39     protected Object JavaDoc[] getCurrentRow() {
40         return currentRow;
41     }
42
43     /**
44      * Advance to the next result
45      *
46      * @return <tt>true</tt> if there is another result
47      */

48     public boolean next() throws HibernateException {
49         if ( maxPosition != null && maxPosition.intValue() <= currentPosition ) {
50             currentRow = null;
51             currentPosition = maxPosition.intValue() + 1;
52             return false;
53         }
54
55         Object JavaDoc row = getLoader().loadSequentialRowsForward(
56                 getResultSet(),
57                 getSession(),
58                 getQueryParameters(),
59                 false
60         );
61
62
63         boolean afterLast;
64         try {
65             afterLast = getResultSet().isAfterLast();
66         }
67         catch( SQLException JavaDoc e ) {
68             throw JDBCExceptionHelper.convert(
69                     getSession().getFactory().getSQLExceptionConverter(),
70                     e,
71                     "exception calling isAfterLast()"
72                 );
73         }
74
75         currentPosition++;
76         currentRow = new Object JavaDoc[] { row };
77
78         if ( afterLast ) {
79             if ( maxPosition == null ) {
80                 // we just hit the last position
81
maxPosition = new Integer JavaDoc( currentPosition );
82             }
83         }
84
85         afterScrollOperation();
86
87         return true;
88     }
89
90     /**
91      * Retreat to the previous result
92      *
93      * @return <tt>true</tt> if there is a previous result
94      */

95     public boolean previous() throws HibernateException {
96         if ( currentPosition <= 1 ) {
97             currentPosition = 0;
98             currentRow = null;
99             return false;
100         }
101
102         Object JavaDoc loadResult = getLoader().loadSequentialRowsReverse(
103                 getResultSet(),
104                 getSession(),
105                 getQueryParameters(),
106                 false,
107                 ( maxPosition != null && currentPosition > maxPosition.intValue() )
108         );
109
110         currentRow = new Object JavaDoc[] { loadResult };
111         currentPosition--;
112
113         afterScrollOperation();
114
115         return true;
116
117     }
118
119     /**
120      * Scroll an arbitrary number of locations
121      *
122      * @param positions a positive (forward) or negative (backward) number of rows
123      *
124      * @return <tt>true</tt> if there is a result at the new location
125      */

126     public boolean scroll(int positions) throws HibernateException {
127         boolean more = false;
128         if ( positions > 0 ) {
129             // scroll ahead
130
for ( int i = 0; i < positions; i++ ) {
131                 more = next();
132                 if ( !more ) {
133                     break;
134                 }
135             }
136         }
137         else if ( positions < 0 ) {
138             // scroll backward
139
for ( int i = 0; i < ( 0 - positions ); i++ ) {
140                 more = previous();
141                 if ( !more ) {
142                     break;
143                 }
144             }
145         }
146         else {
147             throw new HibernateException( "scroll(0) not valid" );
148         }
149
150         afterScrollOperation();
151
152         return more;
153     }
154
155     /**
156      * Go to the last result
157      *
158      * @return <tt>true</tt> if there are any results
159      */

160     public boolean last() throws HibernateException {
161         boolean more = false;
162         if ( maxPosition != null ) {
163             for ( int i = currentPosition; i < maxPosition.intValue(); i++ ) {
164                 more = next();
165             }
166         }
167         else {
168             try {
169                 if ( getResultSet().isAfterLast() ) {
170                     // should not be able to reach last without maxPosition being set
171
// unless there are no results
172
return false;
173                 }
174
175                 while ( !getResultSet().isAfterLast() ) {
176                     more = next();
177                 }
178             }
179             catch( SQLException JavaDoc e ) {
180                 throw JDBCExceptionHelper.convert(
181                         getSession().getFactory().getSQLExceptionConverter(),
182                         e,
183                         "exception calling isAfterLast()"
184                     );
185             }
186         }
187
188         afterScrollOperation();
189
190         return more;
191     }
192
193     /**
194      * Go to the first result
195      *
196      * @return <tt>true</tt> if there are any results
197      */

198     public boolean first() throws HibernateException {
199         beforeFirst();
200         boolean more = next();
201
202         afterScrollOperation();
203
204         return more;
205     }
206
207     /**
208      * Go to a location just before first result (this is the initial location)
209      */

210     public void beforeFirst() throws HibernateException {
211         try {
212             getResultSet().beforeFirst();
213         }
214         catch( SQLException JavaDoc e ) {
215             throw JDBCExceptionHelper.convert(
216                     getSession().getFactory().getSQLExceptionConverter(),
217                     e,
218                     "exception calling beforeFirst()"
219                 );
220         }
221         currentRow = null;
222         currentPosition = 0;
223     }
224
225     /**
226      * Go to a location just after the last result
227      */

228     public void afterLast() throws HibernateException {
229         // TODO : not sure the best way to handle this.
230
// The non-performant way :
231
last();
232         next();
233         afterScrollOperation();
234     }
235
236     /**
237      * Is this the first result?
238      *
239      * @return <tt>true</tt> if this is the first row of results
240      *
241      * @throws org.hibernate.HibernateException
242      */

243     public boolean isFirst() throws HibernateException {
244         return currentPosition == 1;
245     }
246
247     /**
248      * Is this the last result?
249      *
250      * @return <tt>true</tt> if this is the last row of results
251      *
252      * @throws org.hibernate.HibernateException
253      */

254     public boolean isLast() throws HibernateException {
255         if ( maxPosition == null ) {
256             // we have not yet hit the last result...
257
return false;
258         }
259         else {
260             return currentPosition == maxPosition.intValue();
261         }
262     }
263
264     /**
265      * Get the current location in the result set. The first row is number <tt>0</tt>, contrary to JDBC.
266      *
267      * @return the row number, numbered from <tt>0</tt>, or <tt>-1</tt> if there is no current row
268      */

269     public int getRowNumber() throws HibernateException {
270         return currentPosition;
271     }
272
273     /**
274      * Set the current location in the result set, numbered from either the first row (row number <tt>0</tt>), or the last
275      * row (row number <tt>-1</tt>).
276      *
277      * @param rowNumber the row number, numbered from the last row, in the case of a negative row number
278      *
279      * @return true if there is a row at that row number
280      */

281     public boolean setRowNumber(int rowNumber) throws HibernateException {
282         if ( rowNumber == 1 ) {
283             return first();
284         }
285         else if ( rowNumber == -1 ) {
286             return last();
287         }
288         else if ( maxPosition != null && rowNumber == maxPosition.intValue() ) {
289             return last();
290         }
291         return scroll( rowNumber - currentPosition );
292     }
293 }
294
Popular Tags