2
Copyright (C) 2002-2006 MySQL AB
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.
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.
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.
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
25
package com.mysql.jdbc;
27
import java.sql.SQLException;
29
import com.mysql.jdbc.profiler.ProfileEventSink;
30
import com.mysql.jdbc.profiler.ProfilerEvent;
33
* Allows streaming of MySQL data.
36
* @version $Id: RowDataDynamic.java 6433 2007-05-18 18:38:56Z mmatthews $
38
public class RowDataDynamic implements RowData {
40
// --------------------------------------------------------
42
class OperationNotSupportedException extends SQLException {
43
OperationNotSupportedException() {
45
Messages.getString("RowDataDynamic.10"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
49
private int columnCount;
51
private Field[] fields;
53
private int index = -1;
57
private boolean isAfterEnd = false;
59
private boolean isAtEnd = false;
61
private boolean isBinaryEncoded = false;
63
private Object[] nextRow;
65
private ResultSet owner;
67
private boolean streamerClosed = false;
69
private boolean wasEmpty = false; // we don't know until we attempt to traverse
72
// ----------------------------------------------------------------
75
* Creates a new RowDataDynamic object.
78
* the connection to MySQL that this data is coming from
80
* the fields that describe this data
81
* @param isBinaryEncoded
82
* is this data in native format?
84
* the number of columns
85
* @throws SQLException
86
* if the next record can not be found
88
public RowDataDynamic(MysqlIO io, int colCount, Field[] fields,
89
boolean isBinaryEncoded) throws SQLException {
91
this.columnCount = colCount;
92
this.isBinaryEncoded = isBinaryEncoded;
98
* Adds a row to this row data.
102
* @throws SQLException
103
* if a database error occurs
105
public void addRow(byte[][] row) throws SQLException {
110
* Moves to after last.
112
* @throws SQLException
113
* if a database error occurs
115
public void afterLast() throws SQLException {
120
* Moves to before first.
122
* @throws SQLException
123
* if a database error occurs
125
public void beforeFirst() throws SQLException {
130
* Moves to before last so next el is the last el.
132
* @throws SQLException
133
* if a database error occurs
135
public void beforeLast() throws SQLException {
142
* @throws SQLException
143
* if a database error occurs
145
public void close() throws SQLException {
147
boolean hadMore = false;
150
// drain the rest of the records.
151
while (this.hasNext()) {
156
if (howMuchMore % 100 == 0) {
161
if (this.owner != null) {
162
Connection conn = this.owner.connection;
164
if (conn != null && conn.getUseUsageAdvisor()) {
167
ProfileEventSink eventSink = ProfileEventSink
171
.consumeEvent(new ProfilerEvent(
172
ProfilerEvent.TYPE_WARN,
174
this.owner.owningStatement == null ? "N/A" : this.owner.owningStatement.currentCatalog, //$NON-NLS-1$
175
this.owner.connectionId,
176
this.owner.owningStatement == null ? -1
177
: this.owner.owningStatement
180
System.currentTimeMillis(),
182
Constants.MILLIS_I18N,
185
Messages.getString("RowDataDynamic.2") //$NON-NLS-1$
188
.getString("RowDataDynamic.3") //$NON-NLS-1$
190
.getString("RowDataDynamic.4") //$NON-NLS-1$
192
.getString("RowDataDynamic.5") //$NON-NLS-1$
194
.getString("RowDataDynamic.6") //$NON-NLS-1$
195
+ this.owner.pointOfOrigin));
205
* Only works on non dynamic result sets.
208
* row number to get at
209
* @return row data at index
210
* @throws SQLException
211
* if a database error occurs
213
public Object[] getAt(int ind) throws SQLException {
220
* Returns the current position in the result set as a row number.
222
* @return the current row number
223
* @throws SQLException
224
* if a database error occurs
226
public int getCurrentRowNumber() throws SQLException {
233
* @see com.mysql.jdbc.RowData#getOwner()
235
public ResultSet getOwner() {
240
* Returns true if another row exsists.
242
* @return true if more rows
243
* @throws SQLException
244
* if a database error occurs
246
public boolean hasNext() throws SQLException {
247
boolean hasNext = (this.nextRow != null);
249
if (!hasNext && !this.streamerClosed) {
250
this.io.closeStreamer(this);
251
this.streamerClosed = true;
258
* Returns true if we got the last element.
260
* @return true if after last row
261
* @throws SQLException
262
* if a database error occurs
264
public boolean isAfterLast() throws SQLException {
265
return this.isAfterEnd;
269
* Returns if iteration has not occured yet.
271
* @return true if before first row
272
* @throws SQLException
273
* if a database error occurs
275
public boolean isBeforeFirst() throws SQLException {
276
return this.index < 0;
280
* Returns true if the result set is dynamic.
282
* This means that move back and move forward won't work because we do not
283
* hold on to the records.
285
* @return true if this result set is streaming from the server
287
public boolean isDynamic() {
294
* @return true if no records
295
* @throws SQLException
296
* if a database error occurs
298
public boolean isEmpty() throws SQLException {
305
* Are we on the first row of the result set?
307
* @return true if on first row
308
* @throws SQLException
309
* if a database error occurs
311
public boolean isFirst() throws SQLException {
318
* Are we on the last row of the result set?
320
* @return true if on last row
321
* @throws SQLException
322
* if a database error occurs
324
public boolean isLast() throws SQLException {
331
* Moves the current position relative 'rows' from the current position.
334
* the relative number of rows to move
335
* @throws SQLException
336
* if a database error occurs
338
public void moveRowRelative(int rows) throws SQLException {
343
* Returns the next row.
345
* @return the next row value
346
* @throws SQLException
347
* if a database error occurs
349
public Object[] next() throws SQLException {
350
if (this.index != Integer.MAX_VALUE) {
354
Object[] ret = this.nextRow;
361
private void nextRecord() throws SQLException {
366
this.nextRow = this.io.nextRow(this.fields, this.columnCount,
367
this.isBinaryEncoded,
368
java.sql.ResultSet.CONCUR_READ_ONLY);
370
if (this.nextRow == null) {
373
if (this.index == -1) {
374
this.wasEmpty = true;
378
this.isAfterEnd = true;
380
} catch (CommunicationsException comEx) {
381
// Give a better error message
382
comEx.setWasStreamingResults();
385
} catch (SQLException sqlEx) {
386
// don't wrap SQLExceptions
388
} catch (Exception ex) {
389
String exceptionType = ex.getClass().getName();
390
String exceptionMessage = ex.getMessage();
392
exceptionMessage += Messages.getString("RowDataDynamic.7"); //$NON-NLS-1$
393
exceptionMessage += Util.stackTraceToString(ex);
395
throw new java.sql.SQLException(
396
Messages.getString("RowDataDynamic.8") //$NON-NLS-1$
398
+ Messages.getString("RowDataDynamic.9") + exceptionMessage, SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
402
private void notSupported() throws SQLException {
403
throw new OperationNotSupportedException();
407
* Removes the row at the given index.
411
* @throws SQLException
412
* if a database error occurs
414
public void removeRow(int ind) throws SQLException {
419
// ----------------------------------------------------------
422
* Moves the current position in the result set to the given row number.
426
* @throws SQLException
427
* if a database error occurs
429
public void setCurrentRow(int rowNumber) throws SQLException {
434
* @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSet)
436
public void setOwner(ResultSet rs) {
441
* Only works on non dynamic result sets.
443
* @return the size of this row data
446
return RESULT_SET_SIZE_UNKNOWN;
449
public boolean wasEmpty() {
450
return this.wasEmpty;