KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mysql > jdbc > ResultSet


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.ByteArrayInputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.ObjectInputStream JavaDoc;
25 import java.io.StringReader JavaDoc;
26
27 import java.math.BigDecimal JavaDoc;
28
29 import java.net.MalformedURLException JavaDoc;
30 import java.net.URL JavaDoc;
31
32 import java.sql.Array JavaDoc;
33 import java.sql.Date JavaDoc;
34 import java.sql.Ref JavaDoc;
35 import java.sql.SQLException JavaDoc;
36 import java.sql.SQLWarning JavaDoc;
37 import java.sql.Time JavaDoc;
38 import java.sql.Timestamp JavaDoc;
39 import java.sql.Types JavaDoc;
40
41 import java.util.Calendar JavaDoc;
42 import java.util.GregorianCalendar JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.util.TimeZone JavaDoc;
46
47
48 /**
49  * A ResultSet provides access to a table of data generated by executing a
50  * Statement. The table rows are retrieved in sequence. Within a row its
51  * column values can be accessed in any order.
52  *
53  * <P>
54  * A ResultSet maintains a cursor pointing to its current row of data.
55  * Initially the cursor is positioned before the first row. The 'next' method
56  * moves the cursor to the next row.
57  * </p>
58  *
59  * <P>
60  * The getXXX methods retrieve column values for the current row. You can
61  * retrieve values either using the index number of the column, or by using
62  * the name of the column. In general using the column index will be more
63  * efficient. Columns are numbered from 1.
64  * </p>
65  *
66  * <P>
67  * For maximum portability, ResultSet columns within each row should be read in
68  * left-to-right order and each column should be read only once.
69  * </p>
70  *
71  * <P>
72  * For the getXXX methods, the JDBC driver attempts to convert the underlying
73  * data to the specified Java type and returns a suitable Java value. See the
74  * JDBC specification for allowable mappings from SQL types to Java types with
75  * the ResultSet getXXX methods.
76  * </p>
77  *
78  * <P>
79  * Column names used as input to getXXX methods are case insenstive. When
80  * performing a getXXX using a column name, if several columns have the same
81  * name, then the value of the first matching column will be returned. The
82  * column name option is designed to be used when column names are used in the
83  * SQL Query. For columns that are NOT explicitly named in the query, it is
84  * best to use column numbers. If column names were used there is no way for
85  * the programmer to guarentee that they actually refer to the intended
86  * columns.
87  * </p>
88  *
89  * <P>
90  * A ResultSet is automatically closed by the Statement that generated it when
91  * that Statement is closed, re-executed, or is used to retrieve the next
92  * result from a sequence of multiple results.
93  * </p>
94  *
95  * <P>
96  * The number, types and properties of a ResultSet's columns are provided by
97  * the ResultSetMetaData object returned by the getMetaData method.
98  * </p>
99  *
100  * @author Mark Matthews
101  * @version $Id: ResultSet.java,v 1.18.2.25 2004/02/06 00:55:37 mmatthew Exp $
102  *
103  * @see ResultSetMetaData
104  * @see java.sql.ResultSet
105  */

106 public class ResultSet implements java.sql.ResultSet JavaDoc {
107     /**
108      * This method ends up being staticly synchronized, so just store our own
109      * copy....
110      */

111     private TimeZone JavaDoc defaultTimeZone;
112
113     /** The Connection instance that created us */
114     protected com.mysql.jdbc.Connection connection; // The connection that created us
115

116     /** Map column names (and all of their permutations) to column indices */
117     protected Map JavaDoc columnNameToIndex = null;
118
119     /** Map of fully-specified column names to column indices */
120     protected Map JavaDoc fullColumnNameToIndex = null;
121
122     /** The actual rows */
123     protected RowData rowData; // The results
124

125     /** The warning chain */
126     protected java.sql.SQLWarning JavaDoc warningChain = null;
127
128     /** The statement that created us */
129     protected com.mysql.jdbc.Statement owningStatement;
130
131     /** The catalog that was in use when we were created */
132     protected String JavaDoc catalog = null;
133
134     /**
135      * Any info message from the server that was created while generating this
136      * result set (if 'info parsing' is enabled for the connection).
137      */

138     protected String JavaDoc serverInfo = null;
139
140     /** The fields for this result set */
141     protected Field[] fields; // The fields
142

143     /** Pointer to current row data */
144     protected byte[][] thisRow; // Values for current row
145

146     /** Are we in the middle of doing updates to the current row? */
147     protected boolean doingUpdates = false;
148
149     /** Has this result set been closed? */
150     protected boolean isClosed = false;
151
152     /** Are we on the insert row? */
153     protected boolean onInsertRow = false;
154
155     /**
156      * Do we actually contain rows, or just information about
157      * UPDATE/INSERT/DELETE?
158      */

159     protected boolean reallyResult = false;
160
161     /** Did the previous value retrieval find a NULL? */
162     protected boolean wasNullFlag = false;
163
164     /**
165      * First character of the query that created this result set...Used to
166      * determine whether or not to parse server info messages in certain
167      * circumstances.
168      */

169     protected char firstCharOfQuery;
170
171     /** The current row #, -1 == before start of result set */
172     protected int currentRow = -1; // Cursor to current row;
173

174     /** The direction to fetch rows (always FETCH_FORWARD) */
175     protected int fetchDirection = FETCH_FORWARD;
176
177     /** The number of rows to fetch in one go... */
178     protected int fetchSize = 0;
179
180     /** Are we read-only or updatable? */
181     protected int resultSetConcurrency = 0;
182
183     /** Are we scroll-sensitive/insensitive? */
184     protected int resultSetType = 0;
185
186     /** How many rows were affected by UPDATE/INSERT/DELETE? */
187     protected long updateCount;
188
189     // These are longs for
190
// recent versions of the MySQL server.
191
//
192
// They get reduced to ints via the JDBC API,
193
// but can be retrieved through a MySQLStatement
194
// in their entirety.
195
//
196

197     /** Value generated for AUTO_INCREMENT columns */
198     protected long updateId = -1;
199     private Calendar JavaDoc fastDateCal = null;
200     private boolean hasBuiltIndexMapping = false;
201     private boolean useStrictFloatingPoint = false;
202
203     /**
204      * Create a result set for an executeUpdate statement.
205      *
206      * @param updateCount the number of rows affected by the update
207      * @param updateID the autoincrement value (if any)
208      */

209     public ResultSet(long updateCount, long updateID) {
210         this.updateCount = updateCount;
211         this.updateId = updateID;
212         reallyResult = false;
213         fields = new Field[0];
214     }
215
216     /**
217      * Create a new ResultSet
218      *
219      * @param catalog the database in use when we were created
220      * @param fields an array of Field objects (basically, the ResultSet
221      * MetaData)
222      * @param tuples actual row data
223      * @param conn the Connection that created us.
224      *
225      * @throws SQLException if an error occurs
226      */

227     public ResultSet(String JavaDoc catalog, Field[] fields, RowData tuples,
228         com.mysql.jdbc.Connection conn) throws SQLException JavaDoc {
229         this(fields, tuples);
230         setConnection(conn);
231         this.catalog = catalog;
232         
233     }
234
235     /**
236      * Creates a new ResultSet object.
237      *
238      * @param fields DOCUMENT ME!
239      * @param tuples DOCUMENT ME!
240      *
241      * @throws SQLException DOCUMENT ME!
242      */

243     public ResultSet(Field[] fields, RowData tuples) throws SQLException JavaDoc {
244         //_currentRow = -1;
245
this.fields = fields;
246         this.rowData = tuples;
247         this.updateCount = (long) rowData.size();
248
249         if (Driver.DEBUG) {
250             System.out.println("Retrieved " + updateCount + " rows");
251         }
252
253         this.reallyResult = true;
254
255         // Check for no results
256
if (this.rowData.size() > 0) {
257             //_thisRow = _rows.next();
258
if (this.updateCount == 1) {
259                 if (this.thisRow == null) {
260                     //_currentRow = -1;
261
this.rowData.close(); // empty result set
262
this.updateCount = -1;
263                 }
264             }
265         } else {
266             this.thisRow = null;
267         }
268
269         this.rowData.setOwner(this);
270     }
271
272     /**
273      * JDBC 2.0
274      *
275      * <p>
276      * Determine if the cursor is after the last row in the result set.
277      * </p>
278      *
279      * @return true if after the last row, false otherwise. Returns false when
280      * the result set contains no rows.
281      *
282      * @exception SQLException if a database-access error occurs.
283      */

284     public boolean isAfterLast() throws SQLException JavaDoc {
285         if (Driver.TRACE) {
286             Object JavaDoc[] args = { };
287             Debug.methodCall(this, "isAfterLast", args);
288         }
289
290         boolean b = rowData.isAfterLast();
291
292         if (Driver.TRACE) {
293             Debug.returnValue(this, "isAfterLast", new Boolean JavaDoc(b));
294         }
295
296         return b;
297     }
298
299     /**
300      * JDBC 2.0 Get an array column.
301      *
302      * @param i the first column is 1, the second is 2, ...
303      *
304      * @return an object representing an SQL array
305      *
306      * @throws SQLException if a database error occurs
307      * @throws NotImplemented DOCUMENT ME!
308      */

309     public java.sql.Array JavaDoc getArray(int i) throws SQLException JavaDoc {
310         throw new NotImplemented();
311     }
312
313     /**
314      * JDBC 2.0 Get an array column.
315      *
316      * @param colName the column name
317      *
318      * @return an object representing an SQL array
319      *
320      * @throws SQLException if a database error occurs
321      * @throws NotImplemented DOCUMENT ME!
322      */

323     public java.sql.Array JavaDoc getArray(String JavaDoc colName) throws SQLException JavaDoc {
324         throw new NotImplemented();
325     }
326
327     /**
328      * A column value can be retrieved as a stream of ASCII characters and then
329      * read in chunks from the stream. This method is particulary suitable
330      * for retrieving large LONGVARCHAR values. The JDBC driver will do any
331      * necessary conversion from the database format into ASCII.
332      *
333      * <p>
334      * <B>Note:</B> All the data in the returned stream must be read prior to
335      * getting the value of any other column. The next call to a get method
336      * implicitly closes the stream. Also, a stream may return 0 for
337      * available() whether there is data available or not.
338      * </p>
339      *
340      * @param columnIndex the first column is 1, the second is 2, ...
341      *
342      * @return a Java InputStream that delivers the database column value as a
343      * stream of one byte ASCII characters. If the value is SQL NULL
344      * then the result is null
345      *
346      * @exception java.sql.SQLException if a database access error occurs
347      *
348      * @see getBinaryStream
349      */

350     public InputStream JavaDoc getAsciiStream(int columnIndex)
351         throws java.sql.SQLException JavaDoc {
352         checkRowPos();
353
354         return getBinaryStream(columnIndex);
355     }
356
357     /**
358      * DOCUMENT ME!
359      *
360      * @param columnName DOCUMENT ME!
361      *
362      * @return DOCUMENT ME!
363      *
364      * @throws java.sql.SQLException DOCUMENT ME!
365      */

366     public InputStream JavaDoc getAsciiStream(String JavaDoc columnName)
367         throws java.sql.SQLException JavaDoc {
368         return getAsciiStream(findColumn(columnName));
369     }
370
371     //---------------------------------------------------------------------
372
// Traversal/Positioning
373
//---------------------------------------------------------------------
374

375     /**
376      * JDBC 2.0
377      *
378      * <p>
379      * Determine if the cursor is before the first row in the result set.
380      * </p>
381      *
382      * @return true if before the first row, false otherwise. Returns false
383      * when the result set contains no rows.
384      *
385      * @exception SQLException if a database-access error occurs.
386      */

387     public boolean isBeforeFirst() throws SQLException JavaDoc {
388         if (Driver.TRACE) {
389             Object JavaDoc[] args = { };
390             Debug.methodCall(this, "isBeforeFirst", args);
391         }
392
393         boolean b = rowData.isBeforeFirst();
394
395         if (Driver.TRACE) {
396             Debug.returnValue(this, "isBeforeFirst", new Boolean JavaDoc(b));
397         }
398
399         return b;
400     }
401
402     /**
403      * Get the value of a column in the current row as a java.math.BigDecimal
404      * object
405      *
406      * @param columnIndex the first column is 1, the second is 2...
407      * @param scale the number of digits to the right of the decimal
408      *
409      * @return the column value; if the value is SQL NULL, null
410      *
411      * @exception java.sql.SQLException if a database access error occurs
412      */

413     public BigDecimal JavaDoc getBigDecimal(int columnIndex, int scale)
414         throws java.sql.SQLException JavaDoc {
415         String JavaDoc stringVal = getString(columnIndex);
416         BigDecimal JavaDoc val;
417
418         if (stringVal != null) {
419             if (stringVal.length() == 0) {
420                 val = new BigDecimal JavaDoc(0);
421
422                 return val.setScale(scale);
423             }
424
425             try {
426                 val = new BigDecimal JavaDoc(stringVal);
427             } catch (NumberFormatException JavaDoc ex) {
428                 throw new java.sql.SQLException JavaDoc("Bad format for BigDecimal '"
429                     + stringVal + "' in column " + columnIndex + "("
430                     + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
431             }
432
433             try {
434                 return val.setScale(scale);
435             } catch (ArithmeticException JavaDoc ex) {
436                 throw new java.sql.SQLException JavaDoc("Bad format for BigDecimal '"
437                     + stringVal + "' in column " + columnIndex + "("
438                     + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
439             }
440         }
441
442         return null;
443     }
444
445     /**
446      * DOCUMENT ME!
447      *
448      * @param columnName DOCUMENT ME!
449      * @param scale DOCUMENT ME!
450      *
451      * @return DOCUMENT ME!
452      *
453      * @throws java.sql.SQLException DOCUMENT ME!
454      */

455     public BigDecimal JavaDoc getBigDecimal(String JavaDoc columnName, int scale)
456         throws java.sql.SQLException JavaDoc {
457         return getBigDecimal(findColumn(columnName), scale);
458     }
459
460     /**
461      * JDBC 2.0 Get the value of a column in the current row as a
462      * java.math.BigDecimal object.
463      *
464      * @param columnIndex the first column is 1, the second is 2, ...
465      *
466      * @return the column value (full precision); if the value is SQL NULL, the
467      * result is null
468      *
469      * @exception SQLException if a database-access error occurs.
470      * @throws java.sql.SQLException DOCUMENT ME!
471      */

472     public BigDecimal JavaDoc getBigDecimal(int columnIndex) throws SQLException JavaDoc {
473         String JavaDoc stringVal = getString(columnIndex);
474         BigDecimal JavaDoc val;
475
476         if (stringVal != null) {
477             if (stringVal.length() == 0) {
478                 val = new BigDecimal JavaDoc(0);
479
480                 return val;
481             }
482
483             try {
484                 val = new BigDecimal JavaDoc(stringVal);
485
486                 return val;
487             } catch (NumberFormatException JavaDoc ex) {
488                 throw new java.sql.SQLException JavaDoc("Bad format for BigDecimal '"
489                     + stringVal + "' in column " + columnIndex + "("
490                     + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
491             }
492         }
493
494         return null;
495     }
496
497     /**
498      * JDBC 2.0 Get the value of a column in the current row as a
499      * java.math.BigDecimal object.
500      *
501      * @param columnName the name of the column to retrieve the value from
502      *
503      * @return the BigDecimal value in the column
504      *
505      * @throws SQLException if an error occurs
506      */

507     public BigDecimal JavaDoc getBigDecimal(String JavaDoc columnName)
508         throws SQLException JavaDoc {
509         return getBigDecimal(findColumn(columnName));
510     }
511
512     /**
513      * A column value can also be retrieved as a binary strea. This method is
514      * suitable for retrieving LONGVARBINARY values.
515      *
516      * @param columnIndex the first column is 1, the second is 2...
517      *
518      * @return a Java InputStream that delivers the database column value as a
519      * stream of bytes. If the value is SQL NULL, then the result is
520      * null
521      *
522      * @exception java.sql.SQLException if a database access error occurs
523      *
524      * @see getAsciiStream
525      * @see getUnicodeStream
526      */

527     public InputStream JavaDoc getBinaryStream(int columnIndex)
528         throws java.sql.SQLException JavaDoc {
529         checkRowPos();
530
531         byte[] b = getBytes(columnIndex);
532
533         if (b != null) {
534             return new ByteArrayInputStream JavaDoc(b);
535         }
536
537         return null;
538     }
539
540     /**
541      * DOCUMENT ME!
542      *
543      * @param columnName DOCUMENT ME!
544      *
545      * @return DOCUMENT ME!
546      *
547      * @throws java.sql.SQLException DOCUMENT ME!
548      */

549     public InputStream JavaDoc getBinaryStream(String JavaDoc columnName)
550         throws java.sql.SQLException JavaDoc {
551         return getBinaryStream(findColumn(columnName));
552     }
553
554     /**
555      * JDBC 2.0 Get a BLOB column.
556      *
557      * @param columnIndex the first column is 1, the second is 2, ...
558      *
559      * @return an object representing a BLOB
560      *
561      * @throws SQLException if an error occurs.
562      * @throws java.sql.SQLException DOCUMENT ME!
563      */

564     public java.sql.Blob JavaDoc getBlob(int columnIndex) throws SQLException JavaDoc {
565         checkRowPos();
566
567         if ((columnIndex < 1) || (columnIndex > fields.length)) {
568             throw new java.sql.SQLException JavaDoc("Column Index out of range ( "
569                 + columnIndex + " > " + fields.length + ").", SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
570         }
571
572         try {
573             if (thisRow[columnIndex - 1] == null) {
574                 wasNullFlag = true;
575             } else {
576                 wasNullFlag = false;
577             }
578         } catch (NullPointerException JavaDoc ex) {
579             wasNullFlag = true;
580         }
581
582         if (wasNullFlag) {
583             return null;
584         }
585
586         return new Blob(thisRow[columnIndex - 1]);
587     }
588
589     /**
590      * JDBC 2.0 Get a BLOB column.
591      *
592      * @param colName the column name
593      *
594      * @return an object representing a BLOB
595      *
596      * @throws SQLException if an error occurs.
597      */

598     public java.sql.Blob JavaDoc getBlob(String JavaDoc colName) throws SQLException JavaDoc {
599         return getBlob(findColumn(colName));
600     }
601
602     /**
603      * Get the value of a column in the current row as a Java boolean
604      *
605      * @param columnIndex the first column is 1, the second is 2...
606      *
607      * @return the column value, false for SQL NULL
608      *
609      * @exception java.sql.SQLException if a database access error occurs
610      */

611     public boolean getBoolean(int columnIndex) throws java.sql.SQLException JavaDoc {
612         String JavaDoc stringVal = getString(columnIndex);
613
614         if ((stringVal != null) && (stringVal.length() > 0)) {
615             int c = Character.toLowerCase(stringVal.charAt(0));
616
617             return ((c == 't') || (c == 'y') || (c == '1')
618             || stringVal.equals("-1"));
619         }
620
621         return false;
622     }
623
624     /**
625      * DOCUMENT ME!
626      *
627      * @param columnName DOCUMENT ME!
628      *
629      * @return DOCUMENT ME!
630      *
631      * @throws java.sql.SQLException DOCUMENT ME!
632      */

633     public boolean getBoolean(String JavaDoc columnName) throws java.sql.SQLException JavaDoc {
634         return getBoolean(findColumn(columnName));
635     }
636
637     /**
638      * Get the value of a column in the current row as a Java byte.
639      *
640      * @param columnIndex the first column is 1, the second is 2,...
641      *
642      * @return the column value; 0 if SQL NULL
643      *
644      * @exception java.sql.SQLException if a database access error occurs
645      * @throws SQLException DOCUMENT ME!
646      */

647     public byte getByte(int columnIndex) throws java.sql.SQLException JavaDoc {
648         checkRowPos();
649
650         try {
651             if (thisRow[columnIndex - 1] == null) {
652                 wasNullFlag = true;
653             } else {
654                 wasNullFlag = false;
655             }
656         } catch (NullPointerException JavaDoc E) {
657             wasNullFlag = true;
658         }
659
660         if (wasNullFlag) {
661             return 0;
662         }
663
664         Field field = fields[columnIndex - 1];
665
666         switch (field.getMysqlType()) {
667         case MysqlDefs.FIELD_TYPE_DECIMAL:
668         case MysqlDefs.FIELD_TYPE_TINY:
669         case MysqlDefs.FIELD_TYPE_SHORT:
670         case MysqlDefs.FIELD_TYPE_LONG:
671         case MysqlDefs.FIELD_TYPE_FLOAT:
672         case MysqlDefs.FIELD_TYPE_DOUBLE:
673         case MysqlDefs.FIELD_TYPE_LONGLONG:
674         case MysqlDefs.FIELD_TYPE_INT24:
675
676             try {
677                 String JavaDoc stringVal = getString(columnIndex);
678                 int decimalIndex = stringVal.indexOf(".");
679
680                 // Strip off the decimals
681
if (decimalIndex != -1) {
682                     stringVal = stringVal.substring(0, decimalIndex);
683                 }
684
685                 return Byte.parseByte(stringVal);
686             } catch (NumberFormatException JavaDoc NFE) {
687                 throw new SQLException JavaDoc("Value '" + getString(columnIndex)
688                     + "' is out of range [-127,127]", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
689             }
690
691         default:
692
693             try {
694                 String JavaDoc stringVal = getString(columnIndex);
695
696                 int decimalIndex = stringVal.indexOf(".");
697
698                 // Strip off the decimals
699
if (decimalIndex != -1) {
700                     stringVal = stringVal.substring(0, decimalIndex);
701                 }
702
703                 return Byte.parseByte(stringVal);
704             } catch (NumberFormatException JavaDoc NFE) {
705                 throw new SQLException JavaDoc("Value '" + getString(columnIndex)
706                     + "' is out of range [-127,127]", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
707             }
708
709             // FIXME: JDBC-Compliance test is broken, wants to convert string->byte(num)
710
//return _thisRow[columnIndex - 1][0];
711
}
712     }
713
714     /**
715      * DOCUMENT ME!
716      *
717      * @param columnName DOCUMENT ME!
718      *
719      * @return DOCUMENT ME!
720      *
721      * @throws java.sql.SQLException DOCUMENT ME!
722      */

723     public byte getByte(String JavaDoc columnName) throws java.sql.SQLException JavaDoc {
724         return getByte(findColumn(columnName));
725     }
726
727     /**
728      * Get the value of a column in the current row as a Java byte array.
729      *
730      * <p>
731      * <b>Be warned</b> If the blob is huge, then you may run out of memory.
732      * </p>
733      *
734      * @param columnIndex the first column is 1, the second is 2, ...
735      *
736      * @return the column value; if the value is SQL NULL, the result is null
737      *
738      * @exception java.sql.SQLException if a database access error occurs
739      */

740     public byte[] getBytes(int columnIndex) throws java.sql.SQLException JavaDoc {
741         checkRowPos();
742
743         try {
744             if (thisRow[columnIndex - 1] == null) {
745                 wasNullFlag = true;
746             } else {
747                 wasNullFlag = false;
748             }
749         } catch (NullPointerException JavaDoc E) {
750             wasNullFlag = true;
751         } catch (ArrayIndexOutOfBoundsException JavaDoc aioobEx) {
752             throw new java.sql.SQLException JavaDoc("Column Index out of range ( "
753                 + columnIndex + " > " + fields.length + ").", SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
754         }
755
756         if (wasNullFlag) {
757             return null;
758         } else {
759             return thisRow[columnIndex - 1];
760         }
761     }
762
763     /**
764      * DOCUMENT ME!
765      *
766      * @param columnName DOCUMENT ME!
767      *
768      * @return DOCUMENT ME!
769      *
770      * @throws java.sql.SQLException DOCUMENT ME!
771      */

772     public byte[] getBytes(String JavaDoc columnName) throws java.sql.SQLException JavaDoc {
773         return getBytes(findColumn(columnName));
774     }
775
776     //--------------------------JDBC 2.0-----------------------------------
777
//---------------------------------------------------------------------
778
// Getter's and Setter's
779
//---------------------------------------------------------------------
780

781     /**
782      * JDBC 2.0
783      *
784      * <p>
785      * Get the value of a column in the current row as a java.io.Reader.
786      * </p>
787      *
788      * @param columnIndex the column to get the value from
789      *
790      * @return the value in the column as a java.io.Reader.
791      *
792      * @throws SQLException if an error occurs
793      */

794     public java.io.Reader JavaDoc getCharacterStream(int columnIndex)
795         throws SQLException JavaDoc {
796         String JavaDoc stringVal = getString(columnIndex);
797
798         if (stringVal != null) {
799             return new StringReader JavaDoc(stringVal);
800         } else {
801             return null;
802         }
803     }
804
805     /**
806      * JDBC 2.0
807      *
808      * <p>
809      * Get the value of a column in the current row as a java.io.Reader.
810      * </p>
811      *
812      * @param columnName the column name to retrieve the value from
813      *
814      * @return the value as a java.io.Reader
815      *
816      * @throws SQLException if an error occurs
817      */

818     public java.io.Reader JavaDoc getCharacterStream(String JavaDoc columnName)
819         throws SQLException JavaDoc {
820         return getCharacterStream(findColumn(columnName));
821     }
822
823     /**
824      * JDBC 2.0 Get a CLOB column.
825      *
826      * @param i the first column is 1, the second is 2, ...
827      *
828      * @return an object representing a CLOB
829      *
830      * @throws SQLException if an error occurs
831      */

832     public java.sql.Clob JavaDoc getClob(int i) throws SQLException JavaDoc {
833         return new com.mysql.jdbc.Clob(getString(i));
834     }
835
836     /**
837      * JDBC 2.0 Get a CLOB column.
838      *
839      * @param colName the column name
840      *
841      * @return an object representing a CLOB
842      *
843      * @throws SQLException if an error occurs
844      */

845     public java.sql.Clob JavaDoc getClob(String JavaDoc colName) throws SQLException JavaDoc {
846         return getClob(findColumn(colName));
847     }
848
849     /**
850      * JDBC 2.0 Return the concurrency of this result set. The concurrency
851      * used is determined by the statement that created the result set.
852      *
853      * @return the concurrency type, CONCUR_READ_ONLY, etc.
854      *
855      * @throws SQLException if a database-access error occurs
856      */

857     public int getConcurrency() throws SQLException JavaDoc {
858         return (CONCUR_READ_ONLY);
859     }
860
861     /**
862      * DOCUMENT ME!
863      *
864      * @param conn the connection that created this result set.
865      */

866     public void setConnection(com.mysql.jdbc.Connection conn) {
867         this.connection = conn;
868
869         if (this.connection != null) {
870             this.useStrictFloatingPoint = this.connection.useStrictFloatingPoint();
871             this.defaultTimeZone = this.connection.getDefaultTimeZone();
872         } else {
873             this.defaultTimeZone = TimeZone.getDefault();
874         }
875     }
876
877     /**
878      * Get the name of the SQL cursor used by this ResultSet
879      *
880      * <p>
881      * In SQL, a result table is retrieved though a cursor that is named. The
882      * current row of a result can be updated or deleted using a positioned
883      * update/delete statement that references the cursor name.
884      * </p>
885      *
886      * <p>
887      * JDBC supports this SQL feature by providing the name of the SQL cursor
888      * used by a ResultSet. The current row of a ResulSet is also the current
889      * row of this SQL cursor.
890      * </p>
891      *
892      * <p>
893      * <B>Note:</B> If positioned update is not supported, a
894      * java.sql.SQLException is thrown.
895      * </p>
896      *
897      * @return the ResultSet's SQL cursor name.
898      *
899      * @exception java.sql.SQLException if a database access error occurs
900      */

901     public String JavaDoc getCursorName() throws java.sql.SQLException JavaDoc {
902         throw new java.sql.SQLException JavaDoc("Positioned Update not supported.",
903             "S1C00");
904     }
905
906     /**
907      * Get the value of a column in the current row as a java.sql.Date object
908      *
909      * @param columnIndex the first column is 1, the second is 2...
910      *
911      * @return the column value; null if SQL NULL
912      *
913      * @exception java.sql.SQLException if a database access error occurs
914      */

915     public java.sql.Date JavaDoc getDate(int columnIndex) throws java.sql.SQLException JavaDoc {
916         return getDate(columnIndex, null);
917     }
918
919     /**
920      * DOCUMENT ME!
921