Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/mysql/jdbc/RowDataDynamic.java


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