~ubuntu-branches/ubuntu/karmic/mysql-connector-java/karmic

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Takashi Okamoto
  • Date: 2003-12-30 22:37:53 UTC
  • Revision ID: james.westby@ubuntu.com-20031230223753-5d9n2b0w2ms6puqa
Tags: upstream-3.0.9
ImportĀ upstreamĀ versionĀ 3.0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) 2002 MySQL AB
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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
 
17
 
 
18
 */
 
19
package com.mysql.jdbc;
 
20
 
 
21
import java.io.IOException;
 
22
 
 
23
import java.sql.SQLException;
 
24
 
 
25
 
 
26
/**
 
27
 * Allows streaming of MySQL data.
 
28
 *
 
29
 * @author dgan
 
30
 * @version $Id: RowDataDynamic.java,v 1.8.2.5 2003/10/03 16:29:44 mmatthew Exp $
 
31
 */
 
32
public class RowDataDynamic implements RowData {
 
33
    private MysqlIO io;
 
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;
 
43
 
 
44
    /**
 
45
     * Creates a new RowDataDynamic object.
 
46
     *
 
47
     * @param io DOCUMENT ME!
 
48
     * @param colCount DOCUMENT ME!
 
49
     *
 
50
     * @throws SQLException DOCUMENT ME!
 
51
     */
 
52
    public RowDataDynamic(MysqlIO io, int colCount) throws SQLException {
 
53
        this.io = io;
 
54
        this.columnCount = colCount;
 
55
        nextRecord();
 
56
    }
 
57
 
 
58
    /**
 
59
     * Returns true if we got the last element.
 
60
     *
 
61
     * @return true if after last row
 
62
     *
 
63
     * @throws SQLException if a database error occurs
 
64
     */
 
65
    public boolean isAfterLast() throws SQLException {
 
66
        return isAfterEnd;
 
67
    }
 
68
 
 
69
    /**
 
70
     * Only works on non dynamic result sets.
 
71
     *
 
72
     * @param index row number to get at
 
73
     *
 
74
     * @return row data at index
 
75
     *
 
76
     * @throws SQLException if a database error occurs
 
77
     */
 
78
    public byte[][] getAt(int index) throws SQLException {
 
79
        notSupported();
 
80
 
 
81
        return null;
 
82
    }
 
83
 
 
84
    /**
 
85
     * Returns if iteration has not occured yet.
 
86
     *
 
87
     * @return true if before first row
 
88
     *
 
89
     * @throws SQLException if a database error occurs
 
90
     */
 
91
    public boolean isBeforeFirst() throws SQLException {
 
92
        return index < 0;
 
93
    }
 
94
 
 
95
    /**
 
96
     * Moves the current position in the result set to the given row number.
 
97
     *
 
98
     * @param rowNumber row to move to
 
99
     *
 
100
     * @throws SQLException if a database error occurs
 
101
     */
 
102
    public void setCurrentRow(int rowNumber) throws SQLException {
 
103
        notSupported();
 
104
    }
 
105
    
 
106
        /**
 
107
         * @see com.mysql.jdbc.RowData#setOwner(com.mysql.jdbc.ResultSet)
 
108
         */
 
109
        public void setOwner(ResultSet rs) {
 
110
                this.owner = rs;
 
111
        }
 
112
        
 
113
        /**
 
114
         * @see com.mysql.jdbc.RowData#getOwner()
 
115
         */
 
116
        public ResultSet getOwner() {
 
117
                return this.owner;
 
118
        }
 
119
 
 
120
    /**
 
121
     * Returns the current position in the result set as a row number.
 
122
     *
 
123
     * @return the current row number
 
124
     *
 
125
     * @throws SQLException if a database error occurs
 
126
     */
 
127
    public int getCurrentRowNumber() throws SQLException {
 
128
        notSupported();
 
129
 
 
130
        return -1;
 
131
    }
 
132
 
 
133
    /**
 
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.
 
136
     *
 
137
     * @return true if this result set is streaming from the server
 
138
     */
 
139
    public boolean isDynamic() {
 
140
        return true;
 
141
    }
 
142
 
 
143
    /**
 
144
     * Has no records.
 
145
     *
 
146
     * @return true if no records
 
147
     *
 
148
     * @throws SQLException if a database error occurs
 
149
     */
 
150
    public boolean isEmpty() throws SQLException {
 
151
        notSupported();
 
152
 
 
153
        return false;
 
154
    }
 
155
 
 
156
    /**
 
157
     * Are we on the first row of the result set?
 
158
     *
 
159
     * @return true if on first row
 
160
     *
 
161
     * @throws SQLException if a database error occurs
 
162
     */
 
163
    public boolean isFirst() throws SQLException {
 
164
        notSupported();
 
165
 
 
166
        return false;
 
167
    }
 
168
 
 
169
    /**
 
170
     * Are we on the last row of the result set?
 
171
     *
 
172
     * @return true if on last row
 
173
     *
 
174
     * @throws SQLException if a database error occurs
 
175
     */
 
176
    public boolean isLast() throws SQLException {
 
177
        notSupported();
 
178
 
 
179
        return false;
 
180
    }
 
181
 
 
182
    /**
 
183
     * Adds a row to this row data.
 
184
     *
 
185
     * @param row the row to add
 
186
     *
 
187
     * @throws SQLException if a database error occurs
 
188
     */
 
189
    public void addRow(byte[][] row) throws SQLException {
 
190
        notSupported();
 
191
    }
 
192
 
 
193
    /**
 
194
     * Moves to after last.
 
195
     *
 
196
     * @throws SQLException if a database error occurs
 
197
     */
 
198
    public void afterLast() throws SQLException {
 
199
        notSupported();
 
200
    }
 
201
 
 
202
    /**
 
203
     * Moves to before first.
 
204
     *
 
205
     * @throws SQLException if a database error occurs
 
206
     */
 
207
    public void beforeFirst() throws SQLException {
 
208
        notSupported();
 
209
    }
 
210
 
 
211
    /**
 
212
     * Moves to before last so next el is the last el.
 
213
     *
 
214
     * @throws SQLException if a database error occurs
 
215
     */
 
216
    public void beforeLast() throws SQLException {
 
217
        notSupported();
 
218
    }
 
219
 
 
220
    /**
 
221
     * We're done.
 
222
     *
 
223
     * @throws SQLException if a database error occurs
 
224
     */
 
225
    public void close() throws SQLException {
 
226
        //drain the rest of the records.
 
227
        int count = 0;
 
228
        
 
229
        while (this.hasNext()) {
 
230
            this.next();
 
231
            
 
232
            count++;
 
233
            
 
234
            if (count == 100) {
 
235
                Thread.yield();
 
236
                count = 0;
 
237
            }
 
238
        }
 
239
    }
 
240
 
 
241
    /**
 
242
     * Returns true if another row exsists.
 
243
     *
 
244
     * @return true if more rows
 
245
     *
 
246
     * @throws SQLException if a database error occurs
 
247
     */
 
248
    public boolean hasNext() throws SQLException {
 
249
        boolean hasNext = (nextRow != null);
 
250
 
 
251
        if (!hasNext && !streamerClosed) {
 
252
            io.closeStreamer(this);
 
253
            streamerClosed = true;
 
254
        }
 
255
 
 
256
        return hasNext;
 
257
    }
 
258
 
 
259
    /**
 
260
     * Moves the current position relative 'rows' from the current position.
 
261
     *
 
262
     * @param rows the relative number of rows to move
 
263
     *
 
264
     * @throws SQLException if a database error occurs
 
265
     */
 
266
    public void moveRowRelative(int rows) throws SQLException {
 
267
        notSupported();
 
268
    }
 
269
 
 
270
    /**
 
271
     * Returns the next row.
 
272
     *
 
273
     * @return the next row value
 
274
     *
 
275
     * @throws SQLException if a database error occurs
 
276
     */
 
277
    public byte[][] next() throws SQLException {
 
278
        index++;
 
279
 
 
280
        byte[][] ret = nextRow;
 
281
        nextRecord();
 
282
 
 
283
        return ret;
 
284
    }
 
285
 
 
286
    /**
 
287
     * Removes the row at the given index.
 
288
     *
 
289
     * @param index the row to move to
 
290
     *
 
291
     * @throws SQLException if a database error occurs
 
292
     */
 
293
    public void removeRow(int index) throws SQLException {
 
294
        notSupported();
 
295
    }
 
296
 
 
297
    /**
 
298
     * Only works on non dynamic result sets.
 
299
     *
 
300
     * @return the size of this row data
 
301
     */
 
302
    public int size() {
 
303
        return RESULT_SET_SIZE_UNKNOWN;
 
304
    }
 
305
 
 
306
    private void nextRecord() throws SQLException {
 
307
        try {
 
308
            if (!isAtEnd) {
 
309
                nextRow = io.nextRow((int) columnCount);
 
310
 
 
311
                if (nextRow == null) {
 
312
                    isAtEnd = true;
 
313
                }
 
314
                
 
315
                this.lastSuccessfulReadTimeMs = System.currentTimeMillis();
 
316
            } else {
 
317
                isAfterEnd = true;
 
318
            }
 
319
        } catch (SQLException sqlEx) {
 
320
            // don't wrap SQLExceptions
 
321
            throw sqlEx;
 
322
        } catch (IOException ioEx) {
 
323
                long timeSinceLastReadMs = System.currentTimeMillis() - this.lastSuccessfulReadTimeMs;
 
324
                
 
325
            String exceptionType = ioEx.getClass().getName();
 
326
            String exceptionMessage = ioEx.getMessage();
 
327
 
 
328
            exceptionMessage += "\n\nNested Stack Trace:\n";
 
329
            exceptionMessage += Util.stackTraceToString(ioEx);
 
330
 
 
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 
 
337
                + " ms.) : "
 
338
                + exceptionType + " message given: " + exceptionMessage, "S1000");
 
339
        } catch (Exception ex) {
 
340
            String exceptionType = ex.getClass().getName();
 
341
            String exceptionMessage = ex.getMessage();
 
342
 
 
343
            exceptionMessage += "\n\nNested Stack Trace:\n";
 
344
            exceptionMessage += Util.stackTraceToString(ex);
 
345
 
 
346
            throw new java.sql.SQLException(
 
347
                "Error retrieving record: Unexpected Exception: "
 
348
                + exceptionType + " message given: " + exceptionMessage, "S1000");
 
349
        }
 
350
    }
 
351
 
 
352
    private void notSupported() throws SQLException {
 
353
        throw new OperationNotSupportedException();
 
354
    }
 
355
 
 
356
    class OperationNotSupportedException extends SQLException {
 
357
        OperationNotSupportedException() {
 
358
            super("Operation not supported for streaming result sets", "S1009");
 
359
        }
 
360
    }
 
361
}