~pbms-core/pbms/async_read

« back to all changes in this revision

Viewing changes to mybs/java/src/com/mysql/jdbc/RowDataDynamic.java

  • Committer: paul-mccullagh
  • Date: 2008-03-26 11:35:17 UTC
  • Revision ID: paul-mccullagh-afb1610c21464a577ae428d72fc725eb986c05a5
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 2002-2006 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
 
 
23
 
 
24
 */
 
25
package com.mysql.jdbc;
 
26
 
 
27
import java.sql.SQLException;
 
28
 
 
29
import com.mysql.jdbc.profiler.ProfileEventSink;
 
30
import com.mysql.jdbc.profiler.ProfilerEvent;
 
31
 
 
32
/**
 
33
 * Allows streaming of MySQL data.
 
34
 * 
 
35
 * @author dgan
 
36
 * @version $Id: RowDataDynamic.java 6433 2007-05-18 18:38:56Z mmatthews $
 
37
 */
 
38
public class RowDataDynamic implements RowData {
 
39
        // ~ Instance fields
 
40
        // --------------------------------------------------------
 
41
 
 
42
        class OperationNotSupportedException extends SQLException {
 
43
                OperationNotSupportedException() {
 
44
                        super(
 
45
                                        Messages.getString("RowDataDynamic.10"), SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$
 
46
                }
 
47
        }
 
48
 
 
49
        private int columnCount;
 
50
 
 
51
        private Field[] fields;
 
52
 
 
53
        private int index = -1;
 
54
 
 
55
        private MysqlIO io;
 
56
 
 
57
        private boolean isAfterEnd = false;
 
58
 
 
59
        private boolean isAtEnd = false;
 
60
 
 
61
        private boolean isBinaryEncoded = false;
 
62
 
 
63
        private Object[] nextRow;
 
64
 
 
65
        private ResultSet owner;
 
66
 
 
67
        private boolean streamerClosed = false;
 
68
        
 
69
        private boolean wasEmpty = false; // we don't know until we attempt to traverse
 
70
 
 
71
        // ~ Methods
 
72
        // ----------------------------------------------------------------
 
73
 
 
74
        /**
 
75
         * Creates a new RowDataDynamic object.
 
76
         * 
 
77
         * @param io
 
78
         *            the connection to MySQL that this data is coming from
 
79
         * @param fields
 
80
         *            the fields that describe this data
 
81
         * @param isBinaryEncoded
 
82
         *            is this data in native format?
 
83
         * @param colCount
 
84
         *            the number of columns
 
85
         * @throws SQLException
 
86
         *             if the next record can not be found
 
87
         */
 
88
        public RowDataDynamic(MysqlIO io, int colCount, Field[] fields,
 
89
                        boolean isBinaryEncoded) throws SQLException {
 
90
                this.io = io;
 
91
                this.columnCount = colCount;
 
92
                this.isBinaryEncoded = isBinaryEncoded;
 
93
                this.fields = fields;
 
94
                nextRecord();
 
95
        }
 
96
 
 
97
        /**
 
98
         * Adds a row to this row data.
 
99
         * 
 
100
         * @param row
 
101
         *            the row to add
 
102
         * @throws SQLException
 
103
         *             if a database error occurs
 
104
         */
 
105
        public void addRow(byte[][] row) throws SQLException {
 
106
                notSupported();
 
107
        }
 
108
 
 
109
        /**
 
110
         * Moves to after last.
 
111
         * 
 
112
         * @throws SQLException
 
113
         *             if a database error occurs
 
114
         */
 
115
        public void afterLast() throws SQLException {
 
116
                notSupported();
 
117
        }
 
118
 
 
119
        /**
 
120
         * Moves to before first.
 
121
         * 
 
122
         * @throws SQLException
 
123
         *             if a database error occurs
 
124
         */
 
125
        public void beforeFirst() throws SQLException {
 
126
                notSupported();
 
127
        }
 
128
 
 
129
        /**
 
130
         * Moves to before last so next el is the last el.
 
131
         * 
 
132
         * @throws SQLException
 
133
         *             if a database error occurs
 
134
         */
 
135
        public void beforeLast() throws SQLException {
 
136
                notSupported();
 
137
        }
 
138
 
 
139
        /**
 
140
         * We're done.
 
141
         * 
 
142
         * @throws SQLException
 
143
         *             if a database error occurs
 
144
         */
 
145
        public void close() throws SQLException {
 
146
 
 
147
                boolean hadMore = false;
 
148
                int howMuchMore = 0;
 
149
 
 
150
                // drain the rest of the records.
 
151
                while (this.hasNext()) {
 
152
                        this.next();
 
153
                        hadMore = true;
 
154
                        howMuchMore++;
 
155
 
 
156
                        if (howMuchMore % 100 == 0) {
 
157
                                Thread.yield();
 
158
                        }
 
159
                }
 
160
 
 
161
                if (this.owner != null) {
 
162
                        Connection conn = this.owner.connection;
 
163
 
 
164
                        if (conn != null && conn.getUseUsageAdvisor()) {
 
165
                                if (hadMore) {
 
166
 
 
167
                                        ProfileEventSink eventSink = ProfileEventSink
 
168
                                                        .getInstance(conn);
 
169
 
 
170
                                        eventSink
 
171
                                                        .consumeEvent(new ProfilerEvent(
 
172
                                                                        ProfilerEvent.TYPE_WARN,
 
173
                                                                        "", //$NON-NLS-1$
 
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
 
178
                                                                                                        .getId(),
 
179
                                                                        -1,
 
180
                                                                        System.currentTimeMillis(),
 
181
                                                                        0,
 
182
                                                                        Constants.MILLIS_I18N,
 
183
                                                                        null,
 
184
                                                                        null,
 
185
                                                                        Messages.getString("RowDataDynamic.2") //$NON-NLS-1$
 
186
                                                                                        + howMuchMore
 
187
                                                                                        + Messages
 
188
                                                                                                        .getString("RowDataDynamic.3") //$NON-NLS-1$
 
189
                                                                                        + Messages
 
190
                                                                                                        .getString("RowDataDynamic.4") //$NON-NLS-1$
 
191
                                                                                        + Messages
 
192
                                                                                                        .getString("RowDataDynamic.5") //$NON-NLS-1$
 
193
                                                                                        + Messages
 
194
                                                                                                        .getString("RowDataDynamic.6") //$NON-NLS-1$
 
195
                                                                                        + this.owner.pointOfOrigin));
 
196
                                }
 
197
                        }
 
198
                }
 
199
 
 
200
                this.fields = null;
 
201
                this.owner = null;
 
202
        }
 
203
 
 
204
        /**
 
205
         * Only works on non dynamic result sets.
 
206
         * 
 
207
         * @param index
 
208
         *            row number to get at
 
209
         * @return row data at index
 
210
         * @throws SQLException
 
211
         *             if a database error occurs
 
212
         */
 
213
        public Object[] getAt(int ind) throws SQLException {
 
214
                notSupported();
 
215
 
 
216
                return null;
 
217
        }
 
218
 
 
219
        /**
 
220
         * Returns the current position in the result set as a row number.
 
221
         * 
 
222
         * @return the current row number
 
223
         * @throws SQLException
 
224
         *             if a database error occurs
 
225
         */
 
226
        public int getCurrentRowNumber() throws SQLException {
 
227
                notSupported();
 
228
 
 
229
                return -1;
 
230
        }
 
231
 
 
232
        /**
 
233
         * @see com.mysql.jdbc.RowData#getOwner()
 
234
         */
 
235
        public ResultSet getOwner() {
 
236
                return this.owner;
 
237
        }
 
238
 
 
239
        /**
 
240
         * Returns true if another row exsists.
 
241
         * 
 
242
         * @return true if more rows
 
243
         * @throws SQLException
 
244
         *             if a database error occurs
 
245
         */
 
246
        public boolean hasNext() throws SQLException {
 
247
                boolean hasNext = (this.nextRow != null);
 
248
 
 
249
                if (!hasNext && !this.streamerClosed) {
 
250
                        this.io.closeStreamer(this);
 
251
                        this.streamerClosed = true;
 
252
                }
 
253
 
 
254
                return hasNext;
 
255
        }
 
256
 
 
257
        /**
 
258
         * Returns true if we got the last element.
 
259
         * 
 
260
         * @return true if after last row
 
261
         * @throws SQLException
 
262
         *             if a database error occurs
 
263
         */
 
264
        public boolean isAfterLast() throws SQLException {
 
265
                return this.isAfterEnd;
 
266
        }
 
267
 
 
268
        /**
 
269
         * Returns if iteration has not occured yet.
 
270
         * 
 
271
         * @return true if before first row
 
272
         * @throws SQLException
 
273
         *             if a database error occurs
 
274
         */
 
275
        public boolean isBeforeFirst() throws SQLException {
 
276
                return this.index < 0;
 
277
        }
 
278
 
 
279
        /**
 
280
         * Returns true if the result set is dynamic.
 
281
         * 
 
282
         * This means that move back and move forward won't work because we do not
 
283
         * hold on to the records.
 
284
         * 
 
285
         * @return true if this result set is streaming from the server
 
286
         */
 
287
        public boolean isDynamic() {
 
288
                return true;
 
289
        }
 
290
 
 
291
        /**
 
292
         * Has no records.
 
293
         * 
 
294
         * @return true if no records
 
295
         * @throws SQLException
 
296
         *             if a database error occurs
 
297
         */
 
298
        public boolean isEmpty() throws SQLException {
 
299
                notSupported();
 
300
 
 
301
                return false;
 
302
        }
 
303
 
 
304
        /**
 
305
         * Are we on the first row of the result set?
 
306
         * 
 
307
         * @return true if on first row
 
308
         * @throws SQLException
 
309
         *             if a database error occurs
 
310
         */
 
311
        public boolean isFirst() throws SQLException {
 
312
                notSupported();
 
313
 
 
314
                return false;
 
315
        }
 
316
 
 
317
        /**
 
318
         * Are we on the last row of the result set?
 
319
         * 
 
320
         * @return true if on last row
 
321
         * @throws SQLException
 
322
         *             if a database error occurs
 
323
         */
 
324
        public boolean isLast() throws SQLException {
 
325
                notSupported();
 
326
 
 
327
                return false;
 
328
        }
 
329
 
 
330
        /**
 
331
         * Moves the current position relative 'rows' from the current position.
 
332
         * 
 
333
         * @param rows
 
334
         *            the relative number of rows to move
 
335
         * @throws SQLException
 
336
         *             if a database error occurs
 
337
         */
 
338
        public void moveRowRelative(int rows) throws SQLException {
 
339
                notSupported();
 
340
        }
 
341
 
 
342
        /**
 
343
         * Returns the next row.
 
344
         * 
 
345
         * @return the next row value
 
346
         * @throws SQLException
 
347
         *             if a database error occurs
 
348
         */
 
349
        public Object[] next() throws SQLException {
 
350
                if (this.index != Integer.MAX_VALUE) {
 
351
                        this.index++;
 
352
                }
 
353
 
 
354
                Object[] ret = this.nextRow;
 
355
                nextRecord();
 
356
 
 
357
                return ret;
 
358
        }
 
359
 
 
360
 
 
361
        private void nextRecord() throws SQLException {
 
362
 
 
363
                try {
 
364
                        if (!this.isAtEnd) {
 
365
 
 
366
                                this.nextRow = this.io.nextRow(this.fields, this.columnCount,
 
367
                                                this.isBinaryEncoded,
 
368
                                                java.sql.ResultSet.CONCUR_READ_ONLY);
 
369
 
 
370
                                if (this.nextRow == null) {
 
371
                                        this.isAtEnd = true;
 
372
                                        
 
373
                                        if (this.index == -1) {
 
374
                                                this.wasEmpty = true;
 
375
                                        }
 
376
                                }
 
377
                        } else {
 
378
                                this.isAfterEnd = true;
 
379
                        }
 
380
                } catch (CommunicationsException comEx) {
 
381
                        // Give a better error message
 
382
                        comEx.setWasStreamingResults();
 
383
                        
 
384
                        throw comEx;
 
385
                } catch (SQLException sqlEx) {
 
386
                        // don't wrap SQLExceptions
 
387
                        throw sqlEx;
 
388
                } catch (Exception ex) {
 
389
                        String exceptionType = ex.getClass().getName();
 
390
                        String exceptionMessage = ex.getMessage();
 
391
 
 
392
                        exceptionMessage += Messages.getString("RowDataDynamic.7"); //$NON-NLS-1$
 
393
                        exceptionMessage += Util.stackTraceToString(ex);
 
394
 
 
395
                        throw new java.sql.SQLException(
 
396
                                        Messages.getString("RowDataDynamic.8") //$NON-NLS-1$
 
397
                                                        + exceptionType
 
398
                                                        + Messages.getString("RowDataDynamic.9") + exceptionMessage, SQLError.SQL_STATE_GENERAL_ERROR); //$NON-NLS-1$
 
399
                }
 
400
        }
 
401
 
 
402
        private void notSupported() throws SQLException {
 
403
                throw new OperationNotSupportedException();
 
404
        }
 
405
 
 
406
        /**
 
407
         * Removes the row at the given index.
 
408
         * 
 
409
         * @param index
 
410
         *            the row to move to
 
411
         * @throws SQLException
 
412
         *             if a database error occurs
 
413
         */
 
414
        public void removeRow(int ind) throws SQLException {
 
415
                notSupported();
 
416
        }
 
417
 
 
418
        // ~ Inner Classes
 
419
        // ----------------------------------------------------------
 
420
 
 
421
        /**
 
422
         * Moves the current position in the result set to the given row number.
 
423
         * 
 
424
         * @param rowNumber
 
425
         *            row to move to
 
426
         * @throws SQLException
 
427
         *             if a database error occurs
 
428
         */
 
429
        public void setCurrentRow(int rowNumber) throws SQLException {
 
430
                notSupported();
 
431
        }
 
432
 
 
433
        /**
 
434
         * @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSet)
 
435
         */
 
436
        public void setOwner(ResultSet rs) {
 
437
                this.owner = rs;
 
438
        }
 
439
 
 
440
        /**
 
441
         * Only works on non dynamic result sets.
 
442
         * 
 
443
         * @return the size of this row data
 
444
         */
 
445
        public int size() {
 
446
                return RESULT_SET_SIZE_UNKNOWN;
 
447
        }
 
448
 
 
449
        public boolean wasEmpty() {
 
450
                return this.wasEmpty;
 
451
        }
 
452
        
 
453
        
 
454
 
 
455
}