EMMA Coverage Report (generated Tue Jul 25 07:27:46 CDT 2006)
[all classes][com.mysql.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [CursorRowProvider.java]

nameclass, %method, %block, %line, %
CursorRowProvider.java100% (1/1)40%  (10/25)63%  (192/305)58%  (46/80)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CursorRowProvider100% (1/1)40%  (10/25)63%  (192/305)58%  (46/80)
addRow (byte [][]): void 0%   (0/1)0%   (0/3)0%   (0/2)
afterLast (): void 0%   (0/1)0%   (0/3)0%   (0/2)
beforeFirst (): void 0%   (0/1)0%   (0/3)0%   (0/2)
beforeLast (): void 0%   (0/1)0%   (0/3)0%   (0/2)
getAt (int): Object [] 0%   (0/1)0%   (0/4)0%   (0/2)
getCurrentRowNumber (): int 0%   (0/1)0%   (0/5)0%   (0/1)
getOwner (): ResultSet 0%   (0/1)0%   (0/3)0%   (0/1)
isEmpty (): boolean 0%   (0/1)0%   (0/10)0%   (0/1)
isFirst (): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
isLast (): boolean 0%   (0/1)0%   (0/15)0%   (0/1)
moveRowRelative (int): void 0%   (0/1)0%   (0/3)0%   (0/2)
nextRecord (): void 0%   (0/1)0%   (0/1)0%   (0/1)
notSupported (): void 0%   (0/1)0%   (0/4)0%   (0/1)
removeRow (int): void 0%   (0/1)0%   (0/3)0%   (0/2)
setCurrentRow (int): void 0%   (0/1)0%   (0/3)0%   (0/2)
isAfterLast (): boolean 100% (1/1)38%  (5/13)38%  (0.4/1)
isBeforeFirst (): boolean 100% (1/1)71%  (5/7)71%  (0.7/1)
fetchMoreRows (): void 100% (1/1)75%  (53/71)73%  (12.4/17)
hasNext (): boolean 100% (1/1)81%  (44/54)69%  (7.6/11)
next (): Object [] 100% (1/1)89%  (39/44)78%  (7/9)
CursorRowProvider (MysqlIO, ServerPreparedStatement, Field []): void 100% (1/1)100% (31/31)100% (11/11)
close (): void 100% (1/1)100% (7/7)100% (3/3)
isDynamic (): boolean 100% (1/1)100% (2/2)100% (1/1)
setOwner (ResultSet): void 100% (1/1)100% (4/4)100% (2/2)
size (): int 100% (1/1)100% (2/2)100% (1/1)

1/*
2 Copyright (C) 2002-2004 MySQL AB
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of version 2 of the GNU General Public License as 
6 published by the Free Software Foundation.
7 
8 There are special exceptions to the terms and conditions of the GPL 
9 as it is applied to this software. View the full text of the 
10 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
11 software distribution.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 */
22 
23package com.mysql.jdbc;
24 
25import java.sql.SQLException;
26import java.util.ArrayList;
27import java.util.List;
28 
29/**
30 * Model for result set data backed by a cursor. Only works for forward-only
31 * result sets (but still works with updatable concurrency).
32 * 
33 * @version $Id: CursorRowProvider.java,v 1.1.2.1 2005/05/19 18:31:49 mmatthews
34 *          Exp $
35 */
36public class CursorRowProvider implements RowData {
37 
38        private final static int BEFORE_START_OF_ROWS = -1;
39 
40        /**
41         * The cache of rows we have retrieved from the server.
42         */
43        private List fetchedRows;
44 
45        /**
46         * Where we are positionaly in the entire result set, used mostly to
47         * facilitate easy 'isBeforeFirst()' and 'isFirst()' methods.
48         */
49        private int currentPositionInEntireResult = BEFORE_START_OF_ROWS;
50 
51        /**
52         * Position in cache of rows, used to determine if we need to fetch more
53         * rows from the server to satisfy a request for the next row.
54         */
55        private int currentPositionInFetchedRows = BEFORE_START_OF_ROWS;
56 
57        /**
58         * The result set that we 'belong' to.
59         */
60        private ResultSet owner;
61 
62        /**
63         * Have we been told from the server that we have seen the last row?
64         */
65        private boolean lastRowFetched = false;
66 
67        /**
68         * Field-level metadata from the server. We need this, because it is not
69         * sent for each batch of rows, but we need the metadata to unpack the
70         * results for each field.
71         */
72        private Field[] fields;
73 
74        /**
75         * Communications channel to the server
76         */
77        private MysqlIO mysql;
78 
79        /**
80         * Identifier for the statement that created this cursor.
81         */
82        private long statementIdOnServer;
83 
84        /**
85         * The prepared statement that created this cursor.
86         */
87        private ServerPreparedStatement prepStmt;
88 
89        /**
90         * The server status for 'last-row-sent'...This might belong in mysqldefs,
91         * but it it only ever referenced from here.
92         */
93        private static final int SERVER_STATUS_LAST_ROW_SENT = 128;
94 
95        /**
96         * Have we attempted to fetch any rows yet?
97         */
98        private boolean firstFetchCompleted = false;
99 
100        /**
101         * Creates a new cursor-backed row provider.
102         * 
103         * @param ioChannel
104         *            connection to the server.
105         * @param creatingStatement
106         *            statement that opened the cursor.
107         * @param metadata
108         *            field-level metadata for the results that this cursor covers.
109         */
110        public CursorRowProvider(MysqlIO ioChannel,
111                        ServerPreparedStatement creatingStatement, Field[] metadata) {
112                this.currentPositionInEntireResult = BEFORE_START_OF_ROWS;
113                this.fields = metadata;
114                this.mysql = ioChannel;
115                this.statementIdOnServer = creatingStatement.getServerStatementId();
116                this.prepStmt = creatingStatement;
117        }
118 
119        /**
120         * Returns true if we got the last element.
121         * 
122         * @return DOCUMENT ME!
123         */
124        public boolean isAfterLast() {
125                return lastRowFetched
126                                && this.currentPositionInFetchedRows > this.fetchedRows.size();
127        }
128 
129        /**
130         * Only works on non dynamic result sets.
131         * 
132         * @param index
133         *            row number to get at
134         * @return row data at index
135         * @throws SQLException
136         *             if a database error occurs
137         */
138        public Object[] getAt(int ind) throws SQLException {
139                notSupported();
140 
141                return null;
142        }
143 
144        /**
145         * Returns if iteration has not occured yet.
146         * 
147         * @return true if before first row
148         * @throws SQLException
149         *             if a database error occurs
150         */
151        public boolean isBeforeFirst() throws SQLException {
152                return this.currentPositionInEntireResult < 0;
153        }
154 
155        /**
156         * Moves the current position in the result set to the given row number.
157         * 
158         * @param rowNumber
159         *            row to move to
160         * @throws SQLException
161         *             if a database error occurs
162         */
163        public void setCurrentRow(int rowNumber) throws SQLException {
164                notSupported();
165        }
166 
167        /**
168         * Returns the current position in the result set as a row number.
169         * 
170         * @return the current row number
171         * @throws SQLException
172         *             if a database error occurs
173         */
174        public int getCurrentRowNumber() throws SQLException {
175                return this.currentPositionInEntireResult + 1;
176        }
177 
178        /**
179         * Returns true if the result set is dynamic.
180         * 
181         * This means that move back and move forward won't work because we do not
182         * hold on to the records.
183         * 
184         * @return true if this result set is streaming from the server
185         */
186        public boolean isDynamic() {
187                return true;
188        }
189 
190        /**
191         * Has no records.
192         * 
193         * @return true if no records
194         * @throws SQLException
195         *             if a database error occurs
196         */
197        public boolean isEmpty() throws SQLException {
198                return this.isBeforeFirst() && this.isAfterLast();
199        }
200 
201        /**
202         * Are we on the first row of the result set?
203         * 
204         * @return true if on first row
205         * @throws SQLException
206         *             if a database error occurs
207         */
208        public boolean isFirst() throws SQLException {
209                return this.currentPositionInEntireResult == 0;
210        }
211 
212        /**
213         * Are we on the last row of the result set?
214         * 
215         * @return true if on last row
216         * @throws SQLException
217         *             if a database error occurs
218         */
219        public boolean isLast() throws SQLException {
220                return this.lastRowFetched
221                                && this.currentPositionInFetchedRows == (this.fetchedRows
222                                                .size() - 1);
223        }
224 
225        /**
226         * Adds a row to this row data.
227         * 
228         * @param row
229         *            the row to add
230         * @throws SQLException
231         *             if a database error occurs
232         */
233        public void addRow(byte[][] row) throws SQLException {
234                notSupported();
235        }
236 
237        /**
238         * Moves to after last.
239         * 
240         * @throws SQLException
241         *             if a database error occurs
242         */
243        public void afterLast() throws SQLException {
244                notSupported();
245        }
246 
247        /**
248         * Moves to before first.
249         * 
250         * @throws SQLException
251         *             if a database error occurs
252         */
253        public void beforeFirst() throws SQLException {
254                notSupported();
255        }
256 
257        /**
258         * Moves to before last so next el is the last el.
259         * 
260         * @throws SQLException
261         *             if a database error occurs
262         */
263        public void beforeLast() throws SQLException {
264                notSupported();
265        }
266 
267        /**
268         * We're done.
269         * 
270         * @throws SQLException
271         *             if a database error occurs
272         */
273        public void close() throws SQLException {
274 
275                this.fields = null;
276                this.owner = null;
277        }
278 
279        /**
280         * Returns true if another row exists.
281         * 
282         * @return true if more rows
283         * @throws SQLException
284         *             if a database error occurs
285         */
286        public boolean hasNext() throws SQLException {
287 
288                if (this.fetchedRows != null && this.fetchedRows.size() == 0) {
289                        return false;
290                }
291 
292                if (this.currentPositionInEntireResult != BEFORE_START_OF_ROWS) {
293                        // Case, we've fetched some rows, but are not at end of fetched
294                        // block
295                        if (this.currentPositionInFetchedRows < (this.fetchedRows.size() - 1)) {
296                                return true;
297                        } else if (this.currentPositionInFetchedRows == this.fetchedRows
298                                        .size()
299                                        && this.lastRowFetched) {
300                                return false;
301                        } else {
302                                // need to fetch to determine
303                                fetchMoreRows();
304 
305                                return (this.fetchedRows.size() > 0);
306                        }
307                }
308 
309                // Okay, no rows _yet_, so fetch 'em
310 
311                fetchMoreRows();
312 
313                return this.fetchedRows.size() > 0;
314        }
315 
316        /**
317         * Moves the current position relative 'rows' from the current position.
318         * 
319         * @param rows
320         *            the relative number of rows to move
321         * @throws SQLException
322         *             if a database error occurs
323         */
324        public void moveRowRelative(int rows) throws SQLException {
325                notSupported();
326        }
327 
328        /**
329         * Returns the next row.
330         * 
331         * @return the next row value
332         * @throws SQLException
333         *             if a database error occurs
334         */
335        public Object[] next() throws SQLException {
336 
337                this.currentPositionInEntireResult++;
338                this.currentPositionInFetchedRows++;
339 
340                // Catch the forced scroll-passed-end
341                if (this.fetchedRows != null && this.fetchedRows.size() == 0) {
342                        return null;
343                }
344 
345                if (this.currentPositionInFetchedRows > (this.fetchedRows.size() - 1)) {
346                        fetchMoreRows();
347                        this.currentPositionInFetchedRows = 0;
348                }
349 
350                Object[] row = (Object[]) this.fetchedRows
351                                .get(this.currentPositionInFetchedRows);
352 
353                return row;
354        }
355 
356        /**
357         * 
358         */
359        private void fetchMoreRows() throws SQLException {
360                if (this.lastRowFetched) {
361                        this.fetchedRows = new ArrayList(0);
362                        return;
363                }
364 
365                synchronized (this.owner.connection.getMutex()) {
366                        if (!this.firstFetchCompleted) {
367                                this.firstFetchCompleted = true;
368                        }
369 
370                        int numRowsToFetch = this.owner.getFetchSize();
371 
372                        if (numRowsToFetch == 0) {
373                                numRowsToFetch = this.prepStmt.getFetchSize();
374                        }
375                        
376                        if (numRowsToFetch == Integer.MIN_VALUE) {
377                                // Handle the case where the user used 'old'
378                                // streaming result sets
379 
380                                numRowsToFetch = 1;
381                        }
382 
383                        this.fetchedRows = this.mysql.fetchRowsViaCursor(this.fetchedRows,
384                                        this.statementIdOnServer, this.fields, numRowsToFetch);
385                        this.currentPositionInFetchedRows = BEFORE_START_OF_ROWS;
386 
387                        if ((this.mysql.getServerStatus() & SERVER_STATUS_LAST_ROW_SENT) != 0) {
388                                this.lastRowFetched = true;
389                        }
390                }
391        }
392 
393        /**
394         * Removes the row at the given index.
395         * 
396         * @param index
397         *            the row to move to
398         * @throws SQLException
399         *             if a database error occurs
400         */
401        public void removeRow(int ind) throws SQLException {
402                notSupported();
403        }
404 
405        /**
406         * Only works on non dynamic result sets.
407         * 
408         * @return the size of this row data
409         */
410        public int size() {
411                return RESULT_SET_SIZE_UNKNOWN;
412        }
413 
414        private void nextRecord() throws SQLException {
415 
416        }
417 
418        private void notSupported() throws SQLException {
419                throw new OperationNotSupportedException();
420        }
421 
422        /*
423         * (non-Javadoc)
424         * 
425         * @see com.mysql.jdbc.RowProvider#setOwner(com.mysql.jdbc.ResultSet)
426         */
427        public void setOwner(ResultSet rs) {
428                this.owner = rs;
429        }
430 
431        /*
432         * (non-Javadoc)
433         * 
434         * @see com.mysql.jdbc.RowProvider#getOwner()
435         */
436        public ResultSet getOwner() {
437                return this.owner;
438        }
439 
440}

[all classes][com.mysql.jdbc]
EMMA 2.0.4217 (C) Vladimir Roubtsov