2
Copyright (C) 2002 MySQL AB
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
package com.mysql.jdbc;
21
import java.io.IOException;
23
import java.sql.SQLException;
27
* Allows streaming of MySQL data.
30
* @version $Id: RowDataDynamic.java,v 1.8.2.5 2003/10/03 16:29:44 mmatthew Exp $
32
public class RowDataDynamic implements RowData {
34
private byte[][] nextRow;
35
private boolean isAfterEnd = false;
36
private boolean isAtEnd = false;
37
private boolean streamerClosed = false;
38
private int columnCount;
39
private int index = -1;
40
private long lastSuccessfulReadTimeMs = 0;
41
private long netWriteTimeoutMs = 0;
42
private ResultSet owner;
45
* Creates a new RowDataDynamic object.
47
* @param io DOCUMENT ME!
48
* @param colCount DOCUMENT ME!
50
* @throws SQLException DOCUMENT ME!
52
public RowDataDynamic(MysqlIO io, int colCount) throws SQLException {
54
this.columnCount = colCount;
59
* Returns true if we got the last element.
61
* @return true if after last row
63
* @throws SQLException if a database error occurs
65
public boolean isAfterLast() throws SQLException {
70
* Only works on non dynamic result sets.
72
* @param index row number to get at
74
* @return row data at index
76
* @throws SQLException if a database error occurs
78
public byte[][] getAt(int index) throws SQLException {
85
* Returns if iteration has not occured yet.
87
* @return true if before first row
89
* @throws SQLException if a database error occurs
91
public boolean isBeforeFirst() throws SQLException {
96
* Moves the current position in the result set to the given row number.
98
* @param rowNumber row to move to
100
* @throws SQLException if a database error occurs
102
public void setCurrentRow(int rowNumber) throws SQLException {
107
* @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSet)
109
public void setOwner(ResultSet rs) {
114
* @see com.mysql.jdbc.RowData#getOwner()
116
public ResultSet getOwner() {
121
* Returns the current position in the result set as a row number.
123
* @return the current row number
125
* @throws SQLException if a database error occurs
127
public int getCurrentRowNumber() throws SQLException {
134
* Returns true if the result set is dynamic. This means that move back and
135
* move forward won't work because we do not hold on to the records.
137
* @return true if this result set is streaming from the server
139
public boolean isDynamic() {
146
* @return true if no records
148
* @throws SQLException if a database error occurs
150
public boolean isEmpty() throws SQLException {
157
* Are we on the first row of the result set?
159
* @return true if on first row
161
* @throws SQLException if a database error occurs
163
public boolean isFirst() throws SQLException {
170
* Are we on the last row of the result set?
172
* @return true if on last row
174
* @throws SQLException if a database error occurs
176
public boolean isLast() throws SQLException {
183
* Adds a row to this row data.
185
* @param row the row to add
187
* @throws SQLException if a database error occurs
189
public void addRow(byte[][] row) throws SQLException {
194
* Moves to after last.
196
* @throws SQLException if a database error occurs
198
public void afterLast() throws SQLException {
203
* Moves to before first.
205
* @throws SQLException if a database error occurs
207
public void beforeFirst() throws SQLException {
212
* Moves to before last so next el is the last el.
214
* @throws SQLException if a database error occurs
216
public void beforeLast() throws SQLException {
223
* @throws SQLException if a database error occurs
225
public void close() throws SQLException {
226
//drain the rest of the records.
229
while (this.hasNext()) {
242
* Returns true if another row exsists.
244
* @return true if more rows
246
* @throws SQLException if a database error occurs
248
public boolean hasNext() throws SQLException {
249
boolean hasNext = (nextRow != null);
251
if (!hasNext && !streamerClosed) {
252
io.closeStreamer(this);
253
streamerClosed = true;
260
* Moves the current position relative 'rows' from the current position.
262
* @param rows the relative number of rows to move
264
* @throws SQLException if a database error occurs
266
public void moveRowRelative(int rows) throws SQLException {
271
* Returns the next row.
273
* @return the next row value
275
* @throws SQLException if a database error occurs
277
public byte[][] next() throws SQLException {
280
byte[][] ret = nextRow;
287
* Removes the row at the given index.
289
* @param index the row to move to
291
* @throws SQLException if a database error occurs
293
public void removeRow(int index) throws SQLException {
298
* Only works on non dynamic result sets.
300
* @return the size of this row data
303
return RESULT_SET_SIZE_UNKNOWN;
306
private void nextRecord() throws SQLException {
309
nextRow = io.nextRow((int) columnCount);
311
if (nextRow == null) {
315
this.lastSuccessfulReadTimeMs = System.currentTimeMillis();
319
} catch (SQLException sqlEx) {
320
// don't wrap SQLExceptions
322
} catch (IOException ioEx) {
323
long timeSinceLastReadMs = System.currentTimeMillis() - this.lastSuccessfulReadTimeMs;
325
String exceptionType = ioEx.getClass().getName();
326
String exceptionMessage = ioEx.getMessage();
328
exceptionMessage += "\n\nNested Stack Trace:\n";
329
exceptionMessage += Util.stackTraceToString(ioEx);
331
throw new java.sql.SQLException(
332
"IOException while retrieving next record in streaming result set."
333
+ "(Check for deadlock "
334
+ " or retrieval exceeding 'net_write_timeout' seconds. Last "
335
+ "successful record read was " + timeSinceLastReadMs + " ms ago, and"
336
+ "'net_write_timeout' is configured in the server as " + this.netWriteTimeoutMs
338
+ exceptionType + " message given: " + exceptionMessage, "S1000");
339
} catch (Exception ex) {
340
String exceptionType = ex.getClass().getName();
341
String exceptionMessage = ex.getMessage();
343
exceptionMessage += "\n\nNested Stack Trace:\n";
344
exceptionMessage += Util.stackTraceToString(ex);
346
throw new java.sql.SQLException(
347
"Error retrieving record: Unexpected Exception: "
348
+ exceptionType + " message given: " + exceptionMessage, "S1000");
352
private void notSupported() throws SQLException {
353
throw new OperationNotSupportedException();
356
class OperationNotSupportedException extends SQLException {
357
OperationNotSupportedException() {
358
super("Operation not supported for streaming result sets", "S1009");