KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > driver > DriverResultSet


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Mark Matthews.
22  * Contributor(s): Emmanuel Cecchet, Andre Austin, Marc Wick, Jean-Bernard
23  * van Zuylen, Marc Herbert.
24  */

25
26 package org.objectweb.cjdbc.driver;
27
28 import java.io.ByteArrayInputStream JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.InputStream JavaDoc;
31 import java.io.NotSerializableException JavaDoc;
32 import java.io.ObjectInputStream JavaDoc;
33 import java.math.BigDecimal JavaDoc;
34 import java.math.BigInteger JavaDoc;
35 import java.net.URL JavaDoc;
36 import java.sql.PreparedStatement JavaDoc;
37 import java.sql.Ref JavaDoc;
38 import java.sql.ResultSet JavaDoc;
39 import java.sql.SQLException JavaDoc;
40 import java.sql.SQLWarning JavaDoc;
41 import java.sql.Time JavaDoc;
42 import java.sql.Timestamp JavaDoc;
43 import java.util.ArrayList JavaDoc;
44 import java.util.Calendar JavaDoc;
45 import java.util.Hashtable JavaDoc;
46 import java.util.Iterator JavaDoc;
47
48 import org.objectweb.cjdbc.common.exceptions.NotImplementedException;
49 import org.objectweb.cjdbc.common.exceptions.ProtocolException;
50 import org.objectweb.cjdbc.common.stream.CJDBCInputStream;
51 import org.objectweb.cjdbc.common.stream.CJDBCOutputStream;
52 import org.objectweb.cjdbc.driver.protocol.SQLDataSerialization;
53 import org.objectweb.cjdbc.driver.protocol.TypeTag;
54
55 /**
56  * A <code>ResultSet</code> provides access to a table of data generated by
57  * executing a Statement. The table rows are retrieved in sequence. Within a row
58  * its column values can be accessed in any order.
59  * <p>
60  * A <code>ResultSet</code> maintains a cursor pointing to its current row of
61  * data. Initially the cursor is positioned before the first row. The 'next'
62  * method moves the cursor to the next row.
63  * <p>
64  * The <code>getXXX</code> methods retrieve column values for the current row.
65  * You can retrieve values either using the index number of the column, or by
66  * using the name of the column. In general using the column index will be more
67  * efficient. Columns are numbered from 1.
68  * <p>
69  * For maximum portability, <code>ResultSet</code> columns within each row
70  * should be read in left-to-right order and each column should be read only
71  * once.
72  * <p>
73  * For the <code>getXXX</code> methods, the JDBC driver attempts to convert
74  * the underlying data to the specified Java type and returns a suitable Java
75  * value. See the JDBC specification for allowable mappings from SQL types to
76  * Java types with the <code>ResultSet</code> <code>getXXX</code> methods.
77  * <p>
78  * Column names used as input to <code>getXXX</code> methods are case
79  * insenstive. When performing a <code>getXXX</code> using a column name, if
80  * several columns have the same name, then the value of the first matching
81  * column will be returned. The column name option is designed to be used when
82  * column names are used in the SQL Query. For columns that are NOT explicitly
83  * named in the query, it is best to use column numbers. If column names were
84  * used there is no way for the programmer to guarentee that they actually refer
85  * to the intended columns.
86  * <P>
87  * A <code>ResultSet</code> is automatically closed by the
88  * <code>Statement</code> that generated it when that <code>Statement</code>
89  * is closed, re-executed, or is used to retrieve the next result from a
90  * sequence of multiple results.
91  * <P>
92  * The number, types and properties of a ResultSet's columns are provided by the
93  * <code>ResultSetMetaData</code> object returned by the
94  * <code>getMetaData</code> method.
95  *
96  * @see java.sql.ResultSetMetaData
97  * @see java.sql.ResultSet
98  * @author Mark Matthews <mmatthew@worldserver.com>
99  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
100  * @author <a HREF="mailto:alexander.laamanen@tecnomen.com">Alexander Laamanen
101  * </a>
102  * @author <a HREF="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk </a>
103  * @author <a HREF="mailto:jbvanzuylen@transwide.com">Jean-Bernard van Zuylen
104  * </a>
105  * @author <a HREF="mailto:Marc.Herbert@emicnetworks.com">Marc Herbert </a>
106  * @version 1.0
107  */

108 public class DriverResultSet
109     implements
110       java.sql.ResultSet JavaDoc,
111       java.io.Serializable JavaDoc,
112       java.lang.Cloneable JavaDoc
113 {
114   private static final long serialVersionUID = 7408879935608629886L;
115
116   /** Cursor to current row */
117   protected int currentRow = -1;
118   /** Number of rows */
119   protected int nbOfRows = -1;
120   /** Number of columns */
121   protected int nbOfColumns = -1;
122   /** The results */
123   protected ArrayList JavaDoc data;
124   /** True if there is more data to fetch from the controller */
125   private boolean hasMoreData;
126   /** The fetch direction (not used yet) */
127   protected int fetchDirection = FETCH_FORWARD;
128   /** The fetch size */
129   protected int fetchSize = 0;
130   /** ResultSet cursor name */
131   private String JavaDoc cursorName;
132
133   /** The fields */
134   protected Field[] fields;
135
136   /** Pointers to column-specific de/serializer */
137   private SQLDataSerialization.Serializer[] serializers;
138
139   /** for wasNull() */
140   protected boolean wasNullFlag = false;
141   /** column name -> index in ResultSet data array */
142   protected transient Hashtable JavaDoc columnNameToIndex = null;
143   /** full column name -> index in ResultSet data array */
144   protected transient Hashtable JavaDoc fullColumnNameToIndex = null;
145
146   /** Type of ResultSet */
147   protected int resultSetType = 0;
148   /** Concurrency for this ResultSet */
149   protected int resultSetConcurrency = 0;
150   /** the warning chain */
151   protected SQLWarning JavaDoc warnings = null;
152   /** Statement corresponding to this ResultSet, if any (not for metadata) */
153   protected transient Statement owningStatement;
154   /** The driver connection we were received from (null on the controller side) */
155   private final Connection connection;
156
157   private boolean isClosed = true;
158
159   /** Statement for deleting rows with Updatable ResultSets * */
160   private transient PreparedStatement deleteStatement = null;
161   /** Statement for inserting rows with Updatable ResultSets * */
162   private transient PreparedStatement insertStatement = null;
163   /** Statement for refreshing rows with Updatable ResultSets * */
164   private transient PreparedStatement refreshStatement = null;
165   /** Statement for updating rows with Updatable ResultSets * */
166   private transient PreparedStatement updateStatement = null;
167   /** Indicates whether cursor is on the insert row * */
168   private transient boolean inserting = false;
169   /** Indicates if the current row is being updated * */
170   private transient boolean updating = false;
171   /** Temporary object for not yet comitted ResultSet updates * */
172   private transient Object JavaDoc[] tempRow = null;
173   /** Cache the columns forming the primary key * */
174   private transient String JavaDoc[] primaryKeyColumns = null;
175
176   private static final String JavaDoc UPDATEABLE_MESSAGE = "ResultSet not updateable. The "
177                                                                       + "query that generated this result set must select only one table, and must "
178                                                                       + "select all primary keys from that table. See the JDBC 2.1 API Specification, "
179                                                                       + "section 5.6 for more details.";
180
181   // ---------------------------------------------------------------------
182
// Traversal/Positioning
183
// ---------------------------------------------------------------------
184

185   /**
186    * A ResultSet is initially positioned before its first row, the first call to
187    * next makes the first row the current row; the second call makes the second
188    * row the current row, etc.
189    * <p>
190    * If an input stream from the previous row is open, it is implicitly closed.
191    * The ResultSet's warning chain is cleared when a new row is read
192    *
193    * @return <code>true</code> if the new current is valid; <code>false</code>
194    * if there are no more rows
195    * @exception java.sql.SQLException if a database access error occurs
196    */

197   public boolean next() throws java.sql.SQLException JavaDoc
198   {
199     checkIfClosed();
200
201     if (inserting)
202     {
203       insertStatement.clearParameters();
204       tempRow = null;
205       inserting = false;
206     }
207
208     if (updating)
209       cancelRowUpdates();
210
211     if (nbOfRows == 0)
212       return false;
213
214     if (currentRow + 1 >= nbOfRows)
215     {
216       if (hasMoreData)
217       {
218         this.connection.fetchNextData(cursorName, fetchSize, this);
219         currentRow = 0;
220         if (data == null)
221         {
222           nbOfRows = 0;
223           return false;
224         }
225         else
226         {
227           nbOfRows = data.size();
228           return true;
229         }
230       }
231
232       // force scroll past end
233
currentRow = nbOfRows;
234       return false;
235     }
236
237     clearWarnings();
238     currentRow++;
239     return true;
240   }
241
242   /**
243    * The prev method is not part of JDBC, but because of the architecture of
244    * this driver it is possible to move both forward and backward within the
245    * result set.
246    * <p>
247    * If an input stream from the previous row is open, it is implicitly closed.
248    * The ResultSet's warning chain is cleared when a new row is read
249    *
250    * @return <code>true</code> if the new current is valid; <code>false</code>
251    * if there are no more rows
252    * @exception SQLException if a database access error occurs
253    */

254   public boolean prev() throws SQLException JavaDoc
255   {
256     checkIfClosed();
257
258     if (inserting)
259     {
260       insertStatement.clearParameters();
261       tempRow = null;
262       inserting = false;
263     }
264
265     if (updating)
266       cancelRowUpdates();
267
268     if (currentRow - 1 >= 0)
269     {
270       currentRow--;
271       return true;
272     }
273
274     return false;
275   }
276
277   /**
278    * JDBC 2.0.
279    * <p>
280    * Determine if the cursor is before the first row in the result set.
281    *
282    * @return <code>true</code> if before the first row, <code>false</code>
283    * otherwise. Returns <code>false</code> when the result set
284    * contains no rows.
285    * @exception SQLException if a database-access error occurs.
286    */

287   public boolean isBeforeFirst() throws SQLException JavaDoc
288   {
289     checkIfClosed();
290     if (nbOfRows == 0)
291       return false;
292     else
293       return (currentRow == -1);
294   }
295
296   /**
297    * JDBC 2.0
298    * <p>
299    * Determine if the cursor is after the last row in the result set.
300    *
301    * @return <code>true</code> if after the last row, <code>false</code>
302    * otherwise. Returns <code>false</code> when the result set
303    * contains no rows.
304    * @exception SQLException if a database-access error occurs.
305    */

306   public boolean isAfterLast() throws SQLException JavaDoc
307   {
308     checkIfClosed();
309     if (nbOfRows == 0)
310       return false;
311     else
312       return (currentRow >= nbOfRows);
313   }
314
315   /**
316    * JDBC 2.0
317    * <p>
318    * Determine if the cursor is on the first row of the result set.
319    *
320    * @return <code>true</code> if on the first row, <code>false</code>
321    * otherwise.
322    * @exception SQLException if a database-access error occurs.
323    */

324   public boolean isFirst() throws SQLException JavaDoc
325   {
326     checkIfClosed();
327     if (nbOfRows == 0)
328       return false;
329     else
330       return (currentRow == 0);
331   }
332
333   /**
334    * JDBC 2.0
335    * <p>
336    * Determine if the cursor is on the last row of the result set. Note: Calling
337    * isLast() may be expensive since the JDBC driver might need to fetch ahead
338    * one row in order to determine whether the current row is the last row in
339    * the result set.
340    *
341    * @return <code>true</code> if on the last row, <code>false</code>
342    * otherwise.
343    * @exception SQLException if a database-access error occurs.
344    */

345   public boolean isLast() throws SQLException JavaDoc
346   {
347     checkIfClosed();
348     if (nbOfRows == 0)
349       return false;
350     else
351       return (currentRow == nbOfRows - 1);
352   }
353
354   /**
355    * JDBC 2.0
356    * <p>
357    * Moves to the front of the result set, just before the first row. Has no
358    * effect if the result set contains no rows.
359    *
360    * @exception SQLException if a database-access error occurs, or result set
361    * type is TYPE_FORWARD_ONLY
362    */

363   public void beforeFirst() throws SQLException JavaDoc
364   {
365     checkIfClosed();
366
367     if (inserting)
368     {
369       insertStatement.clearParameters();
370       tempRow = null;
371       inserting = false;
372     }
373
374     if (updating)
375       cancelRowUpdates();
376
377     currentRow = -1;
378   }
379
380   /**
381    * JDBC 2.0
382    * <p>
383    * Moves to the end of the result set, just after the last row. Has no effect
384    * if the result set contains no rows.
385    *
386    * @exception SQLException if a database-access error occurs, or result set
387    * type is TYPE_FORWARD_ONLY.
388    */

389   public void afterLast() throws SQLException JavaDoc
390   {
391     checkIfClosed();
392
393     if (inserting)
394     {
395       insertStatement.clearParameters();
396       tempRow = null;
397       inserting = false;
398     }
399
400     if (updating)
401       cancelRowUpdates();
402
403     if (nbOfRows != 0)
404       currentRow = nbOfRows;
405   }
406
407   /**
408    * JDBC 2.0
409    * <p>
410    * Moves to the first row in the result set.
411    *
412    * @return <code>true</code> if on a valid row, false if no rows in the
413    * result set.
414    * @exception SQLException if a database-access error occurs, or result set
415    * type is TYPE_FORWARD_ONLY.
416    */

417   public boolean first() throws SQLException JavaDoc
418   {
419     checkIfClosed();
420
421     if (inserting)
422     {
423       insertStatement.clearParameters();
424       tempRow = null;
425       inserting = false;
426     }
427
428     if (updating)
429       cancelRowUpdates();
430
431     if (nbOfRows == 0)
432       return false;
433
434     currentRow = 0;
435     return true;
436   }
437
438   /**
439    * JDBC 2.0
440    * <p>
441    * Moves to the last row in the result set.
442    *
443    * @return <code>true</code> if on a valid row, false if no rows in the
444    * result set.
445    * @exception SQLException if a database-access error occurs, or result set
446    * type is TYPE_FORWARD_ONLY.
447    */

448   public boolean last() throws SQLException JavaDoc
449   {
450     checkIfClosed();
451
452     if (inserting)
453     {
454       insertStatement.clearParameters();
455       tempRow = null;
456       inserting = false;
457     }
458
459     if (updating)
460       cancelRowUpdates();
461
462     if (nbOfRows == 0)
463       return false;
464
465     currentRow = nbOfRows - 1;
466     return true;
467   }
468
469   /**
470    * JDBC 2.0
471    * <p>
472    * Determine the current row number. The first row is number 1, the second
473    * number 2, etc.
474    *
475    * @return the current row number, else return 0 if there is no current row
476    * @exception SQLException if a database-access error occurs.
477    */

478   public int getRow() throws SQLException JavaDoc
479   {
480     checkIfClosed();
481     if (currentRow < 0 || currentRow >= nbOfRows || nbOfRows == 0)
482       return 0;
483     else
484       return currentRow + 1;
485   }
486
487   /**
488    * JDBC 2.0
489    * <p>
490    * Move to an absolute row number in the result set.
491    * <p>
492    * If row is positive, moves to an absolute row with respect to the beginning
493    * of the result set. The first row is row 1, the second is row 2, etc.
494    * <p>
495    * If row is negative, moves to an absolute row position with respect to the
496    * end of result set. For example, calling absolute(-1) positions the cursor
497    * on the last row, absolute(-2) indicates the next-to-last row, etc.
498    * <p>
499    * An attempt to position the cursor beyond the first/last row in the result
500    * set, leaves the cursor before/after the first/last row, respectively.
501    * <p>
502    * Note: Calling absolute(1) is the same as calling first(). Calling
503    * absolute(-1) is the same as calling last().
504    *
505    * @param row the row to move to
506    * @return <code>true</code> if on the result set, false if off.
507    * @exception SQLException if a database-access error occurs, or row is 0, or
508    * result set type is TYPE_FORWARD_ONLY.
509    */

510   public boolean absolute(int row) throws SQLException JavaDoc
511   {
512     checkIfClosed();
513
514     if (inserting)
515     {
516       insertStatement.clearParameters();
517       tempRow = null;
518       inserting = false;
519     }
520
521     if (updating)
522       cancelRowUpdates();
523
524     if (nbOfRows == 0)
525       return false;
526
527     if (row == 0)
528       throw new SQLException JavaDoc("Cannot absolute position to row 0");
529
530     if (row == 1)
531       return first();
532
533     if (row == -1)
534       return last();
535
536     if (row > nbOfRows)
537     {
538       afterLast();
539       return false;
540     }
541
542     if (row < 0)
543     { // adjust to reflect after end of result set
544
int newRowPosition = nbOfRows + row + 1;
545
546       if (newRowPosition <= 0)
547       {
548         beforeFirst();
549         return false;
550       }
551
552       return absolute(newRowPosition);
553     }
554     else
555     {
556       row--; // adjust for index difference
557
currentRow = row;
558       return true;
559     }
560   }
561
562   /**
563    * JDBC 2.0
564    * <p>
565    * Moves a relative number of rows, either positive or negative. Attempting to
566    * move beyond the first/last row in the result set positions the cursor
567    * before/after the the first/last row. Calling relative(0) is valid, but does
568    * not change the cursor position.
569    * <p>
570    * Note: Calling relative(1) is different than calling next() since is makes
571    * sense to call next() when there is no current row, for example, when the
572    * cursor is positioned before the first row or after the last row of the
573    * result set.
574    *
575    * @param rows the number of rows
576    * @return <code>true</code> if on a row, false otherwise.
577    * @exception SQLException if a database-access error occurs, or there is no
578    * current row, or result set type is TYPE_FORWARD_ONLY.
579    */

580   public boolean relative(int rows) throws SQLException JavaDoc
581   {
582     checkIfClosed();
583
584     if (inserting)
585     {
586       insertStatement.clearParameters();
587       tempRow = null;
588       inserting = false;
589     }
590
591     if (updating)
592       cancelRowUpdates();
593
594     if (nbOfRows == 0)
595       return false;
596
597     return absolute(currentRow + rows + 1);
598   }
599
600   /**
601    * JDBC 2.0
602    * <p>
603    * Moves to the previous row in the result set.
604    * <p>
605    * Note: previous() is not the same as relative(-1) since it makes sense to
606    * call previous() when there is no current row.
607    *
608    * @return <code>true</code> if on a valid row, false if off the result set.
609    * @exception SQLException if a database-access error occurs, or result set
610    * type is TYPE_FORWAR_DONLY.
611    */

612   public boolean previous() throws SQLException JavaDoc
613   {
614     return prev();
615   }
616
617   /**
618    * JDBC 2.0 Give a hint as to the direction in which the rows in this result
619    * set will be processed. The initial value is determined by the statement
620    * that produced the result set. The fetch direction may be changed at any
621    * time.
622    *
623    * @param direction the fetch direction
624    * @exception SQLException if a database-access error occurs, or the result
625    * set type is TYPE_FORWARD_ONLY and direction is not
626    * FETCH_FORWARD. MM.MySQL actually ignores this, because it has
627    * the whole result set anyway, so the direction is immaterial.
628    */

629   public void setFetchDirection(int direction) throws SQLException JavaDoc
630   {
631     if (direction != FETCH_FORWARD && direction != FETCH_REVERSE)
632       throw new SQLException JavaDoc("Illegal value for fetch direction");
633     else
634       fetchDirection = direction;
635   }
636
637   /**
638    * JDBC 2.0 Return the fetch direction for this result set.
639    *
640    * @return the fetch direction
641    * @exception SQLException if a database-access error occurs
642    */

643   public int getFetchDirection() throws SQLException JavaDoc
644   {
645     return fetchDirection;
646   }
647
648   /**
649    * JDBC 2.0 Give the JDBC driver a hint as to the number of rows that should
650    * be fetched from the database when more rows are needed for this result set.
651    * If the fetch size specified is zero, then the JDBC driver ignores the
652    * value, and is free to make its own best guess as to what the fetch size
653    * should be. The default value is set by the statement that creates the
654    * result set. The fetch size may be changed at any time.
655    *
656    * @param rows the number of rows to fetch
657    * @exception SQLException if a database-access error occurs, or the condition
658    * 0 <= rows <= statement.getMaxRows() is not satisfied.
659    * Currently ignored by this driver.
660    */

661   public void setFetchSize(int rows) throws SQLException JavaDoc
662   {
663     // This is just a hint afterall, let's not try to throw exceptions for
664
// nothing
665
if (rows < 0)
666       throw new SQLException JavaDoc("Value must be between 0 and getMaxRows()");
667
668     fetchSize = rows;
669   }
670
671   /**
672    * JDBC 2.0 Return the fetch size for this result set.
673    *
674    * @return the fetch size
675    * @exception SQLException if a database-access error occurs
676    */

677   public int getFetchSize() throws SQLException JavaDoc
678   {
679     return fetchSize;
680   }
681
682   //
683
// ---------------------------------------------------------------------
684
// Getter's and Setter's
685
// ---------------------------------------------------------------------
686
//
687

688   /**
689    * Get the value of a column in the current row as a Java String
690    *
691    * @param columnIndex the first column is 1, the second is 2...
692    * @return the column value, null for SQL NULL
693    * @exception SQLException if a database access error occurs
694    */

695   public String JavaDoc getString(int columnIndex) throws SQLException JavaDoc
696   {
697     checkRowAndColPosAndSetNullFlag(columnIndex);
698
699     if (wasNullFlag)
700       return null;
701
702     if (inserting || updating)
703       return tempRow[columnIndex - 1].toString();
704     else
705       return (((Object JavaDoc[]) data.get(currentRow))[columnIndex - 1]).toString();
706   }
707
708   /**
709    * Get the value of a column in the current row as a Java boolean
710    *
711    * @param columnIndex the first column is 1, the second is 2...
712    * @return the column value, false for SQL NULL
713    * @exception SQLException if a database access error occurs
714    */

715   public boolean getBoolean(int columnIndex) throws SQLException JavaDoc
716   {
717     checkRowAndColPosAndSetNullFlag(columnIndex);
718
719     if (wasNullFlag)
720       return false;
721
722     Object JavaDoc object;
723     if (inserting || updating)
724       object = tempRow[columnIndex - 1];
725     else
726       object = (((Object JavaDoc[]) data.get(currentRow))[columnIndex - 1]);
727
728     String JavaDoc stringVal = object.toString();
729     if ((stringVal != null) && (stringVal.length() > 0))
730     {
731       stringVal = stringVal.toLowerCase();
732
733       // first we check the connection values to be consistent
734
if (this.connection.getPreparedStatementBooleanTrue().equals(
735           stringVal))
736       {
737         return true;
738       }
739       else if (this.connection.getPreparedStatementBooleanFalse()
740           .equals(stringVal))
741       {
742         return false;
743       }
744
745       // now we check some other possible string representations of boolean
746
else if ("t".equals(stringVal))
747       {
748         return true;
749       }
750       else if ("f".equals(stringVal))
751       {
752         return false;
753       }
754       else if ("true".equals(stringVal))
755       {
756         return true;
757       }
758       else if ("false".equals(stringVal))
759       {
760         return false;
761       }
762       else if ("1".equals(stringVal))
763       {
764         return true;
765       }
766       else if ("0".equals(stringVal))
767       {
768         return false;
769       }
770       else if ("y".equals(stringVal))
771       {
772         return true;
773       }
774       else if ("n".equals(stringVal))
775       {
776         return false;
777       }
778       else if ("yes".equals(stringVal))
779       {
780         return true;
781       }
782       else if ("no".equals(stringVal))
783       {
784         return false;
785       }
786       else if (object instanceof Number JavaDoc)
787       {
788         int value = ((Number JavaDoc) object).intValue();
789         if (value == 0)
790           return false;
791         else if (value == 1)
792           return true;
793         // else other value throw an exception
794
}
795
796       // we didn't find anything reasonable and throw an exception
797
throw new SQLException JavaDoc("column value " + stringVal
798           + " could not be converted to boolean");
799     }
800     else
801     {
802       return false;
803     }
804   }
805
806   /**
807    * Get the value of a column in the current row as a Java short.
808    *
809    * @param columnIndex the first column is 1, the second is 2,...
810    * @return the column value; 0 if SQL NULL
811    * @exception SQLException if a database access error occurs
812    */

813   public short getShort(int columnIndex) throws SQLException JavaDoc
814   {
815     checkRowAndColPosAndSetNullFlag(columnIndex);
816
817     if (wasNullFlag)
818       return 0;
819
820     Object JavaDoc obj;
821     if (inserting || updating)
822       obj = tempRow[columnIndex - 1];
823     else
824       obj = ((Object JavaDoc[]) data.get(currentRow))[columnIndex - 1];
825
826     if (obj instanceof Number JavaDoc)
827     {
828       return ((Number JavaDoc) obj).shortValue();
829     }
830
831     // the object is not of type number we parse the string representation
832
try
833     {
834       String JavaDoc string = obj.toString();
835       string = string.trim();
836       return Short.parseShort(string);
837     }
838     catch (NumberFormatException JavaDoc e)
839     {
840       throw new SQLException JavaDoc("the value " + obj.toString()
841           + " is not a valid short number");
842     }
843   }
844
845   /**
846    * Get the value of a column in the current row as a Java int.
847    *
848    * @param columnIndex the first column is 1, the second is 2,...
849    * @return the column value; 0 if SQL NULL
850    * @exception SQLException if a database access error occurs
851    */

852   public int getInt(int columnIndex) throws SQLException JavaDoc
853   {
854     checkRowAndColPosAndSetNullFlag(columnIndex);
855
856     if (wasNullFlag)
857       return 0;
858
859     Object JavaDoc obj;
860     if (inserting || updating)
861       obj = tempRow[columnIndex - 1];
862     else
863       obj = ((Object JavaDoc[]) data.get(currentRow))[columnIndex - 1];
864
865     if (obj instanceof Number JavaDoc)
866     {
867       return ((Number JavaDoc) obj).intValue();
868     }
869
870     // the object is not of type number we parse the string representation
871
try
872     {
873       String JavaDoc string = obj.toString();
874       string = string.trim();
875       return Integer.parseInt(string);
876     }
877     catch (NumberFormatException JavaDoc e)
878     {
879       throw new SQLException JavaDoc("the value " + obj.toString()
880           + " is not a valid int number");
881     }
882   }
883
884   /**
885    * Get the value of a column in the current row as a Java long.
886    *
887    * @param columnIndex the first column is 1, the second is 2,...
888    * @return the column value; 0 if SQL NULL
889    * @exception SQLException if a database access error occurs
890    */

891   public long getLong(int columnIndex) throws SQLException JavaDoc
892   {
893     checkRowAndColPosAndSetNullFlag(columnIndex);
894
895     if (wasNullFlag)
896       return 0;
897
898     Object JavaDoc obj;
899     if (inserting || updating)
900       obj = tempRow[columnIndex - 1];
901     else
902       obj = ((Object JavaDoc[]) data.get(currentRow))[columnIndex - 1];
903
904     if (obj instanceof Number JavaDoc)
905     {
906       return ((Number JavaDoc) obj).longValue();
907     }
908
909     // the object is not of type number we parse the string representation
910
try
911     {
912       String JavaDoc string = obj.toString();
913       string = string.trim();
914       return Long.parseLong(string);
915     }
916     catch (NumberFormatException JavaDoc e)
917     {
918       throw new SQLException JavaDoc("the value " + obj.toString()
919           + " is not a valid long number");
920     }
921   }
922
923   /**
924    * Get the value of a column in the current row as a Java float.
925    *
926    * @param columnIndex the first column is 1, the second is 2,...
927    * @return the column value; 0 if SQL NULL
928    * @exception SQLException if a database access error occurs
929    */

930   public float getFloat(int columnIndex) throws SQLException JavaDoc
931   {
932     checkRowAndColPosAndSetNullFlag(columnIndex);
933
934     if (wasNullFlag)
935       return 0;
936
937     Object JavaDoc obj;
938     if (inserting || updating)
939       obj = tempRow[columnIndex - 1];
940     else
941       obj = ((Object JavaDoc[]) data.get(currentRow))[columnIndex - 1];
942
943     if (obj instanceof Number JavaDoc)
944     {
945       return ((Number JavaDoc) obj).floatValue();
946     }
947
948     // the object is not of type number we parse the string representation
949
try
950     {
951       String JavaDoc string = obj.toString();
952       string = string.trim();
953       return Float.parseFloat(string);
954     }
955     catch (NumberFormatException JavaDoc e)
956     {
957       throw new SQLException JavaDoc("the value " + obj.toString()
958           + " is not a valid float number");
959     }
960   }
961
962   /**
963    * Get the value of a column in the current row as a Java double.
964    *
965    * @param columnIndex the first column is 1, the second is 2,...
966    * @return the column value; 0 if SQL NULL
967    * @exception SQLException if a database access error occurs
968    */

969   public double getDouble(int columnIndex) throws SQLException JavaDoc
970   {
971     checkRowAndColPosAndSetNullFlag(columnIndex);
972
973     if (wasNullFlag)
974       return 0;
975
976     Object JavaDoc obj;
977     if (inserting || updating)
978       obj = tempRow[columnIndex - 1];
979     else
980       obj = ((Object JavaDoc[]) data.get(currentRow))[columnIndex - 1];
981
982     if (obj instanceof Number JavaDoc)
983     {
984       return ((Number JavaDoc) obj).doubleValue();
985     }
986
987     // the object is not of type number we parse the string representation
988
try
989     {
990       String JavaDoc string = obj.toString();
991       string = string.trim();
992       return Double.parseDouble(string);
993     }
994     catch (NumberFormatException JavaDoc e)
995     {
996       throw new SQLException JavaDoc("the value " + obj.toString()
997           + " is not a valid double number");
998     }
999   }
1000
1001  /**
1002   * Get the value of a column in the current row as a java.lang.BigDecimal
1003   * object
1004   *
1005   * @param columnIndex the first column is 1, the second is 2...
1006   * @param scale the number of digits to