KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > internetcds > jdbc > tds > ResultSet_base


1 //
2
// Copyright 1998, 1999 CDS Networks, Inc., Medford Oregon
3
//
4
// All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are met:
8
// 1. Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
// 2. Redistributions in binary form must reproduce the above copyright
11
// notice, this list of conditions and the following disclaimer in the
12
// documentation and/or other materials provided with the distribution.
13
// 3. All advertising materials mentioning features or use of this software
14
// must display the following acknowledgement:
15
// This product includes software developed by CDS Networks, Inc.
16
// 4. The name of CDS Networks, Inc. may not be used to endorse or promote
17
// products derived from this software without specific prior
18
// written permission.
19
//
20
// THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND
21
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
// ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE
24
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
// SUCH DAMAGE.
31
//
32

33
34 package com.internetcds.jdbc.tds;
35
36 import java.sql.*;
37 import java.math.BigDecimal JavaDoc;
38 import java.util.Vector JavaDoc;
39 // import java.util.Calendar;
40
import java.util.GregorianCalendar JavaDoc;
41 import java.util.Calendar JavaDoc;
42 import java.io.*;
43
44 /**
45  * <P>A ResultSet provides access to a table of data generated by
46  * executing a Statement. The table rows are retrieved in
47  * sequence. Within a row its column values can be accessed in any
48  * order.
49  *
50  * <P>A ResultSet maintains a cursor pointing to its current row of
51  * data. Initially the cursor is positioned before the first row.
52  * The 'next' method moves the cursor to the next row.
53  *
54  * <P>The getXXX methods retrieve column values for the current
55  * row. You can retrieve values either using the index number of the
56  * column, or by using the name of the column. In general using the
57  * column index will be more efficient. Columns are numbered from 1.
58  *
59  * <P>For maximum portability, ResultSet columns within each row should be
60  * read in left-to-right order and each column should be read only once.
61  *
62  * <P>For the getXXX methods, the JDBC driver attempts to convert the
63  * underlying data to the specified Java type and returns a suitable
64  * Java value. See the JDBC specification for allowable mappings
65  * from SQL types to Java types with the ResultSet.getXXX methods.
66  *
67  * <P>Column names used as input to getXXX methods are case
68  * insensitive. When performing a getXXX using a column name, if
69  * several columns have the same name, then the value of the first
70  * matching column will be returned. The column name option is
71  * designed to be used when column names are used in the SQL
72  * query. For columns that are NOT explicitly named in the query, it
73  * is best to use column numbers. If column names were used there is
74  * no way for the programmer to guarantee that they actually refer to
75  * the intended columns.
76  *
77  * <P>A ResultSet is automatically closed by the Statement that
78  * generated it when that Statement is closed, re-executed, or is used
79  * to retrieve the next result from a sequence of multiple results.
80  *
81  * <P>The number, types and properties of a ResultSet's columns are
82  * provided by the ResulSetMetaData object returned by the getMetaData
83  * method.
84  *
85  * @author Craig Spannring
86  * @author The FreeTDS project
87  * @version $Id: ResultSet_base.java,v 1.1 2006/06/23 10:39:30 sinisa Exp $
88  *
89  * @see Statement#executeQuery
90  * @see Statement#getResultSet
91  * @see ResultSetMetaData
92  @ @see Tds#getRow
93  */

94
95 public class ResultSet_base
96 {
97    public static final String JavaDoc cvsVersion = "$Id: ResultSet_base.java,v 1.1 2006/06/23 10:39:30 sinisa Exp $";
98
99
100    Tds tds = null;
101    Statement stmt = null;
102    Columns columnsInfo = null;
103    ResultSetMetaData metaData = null;
104    PacketRowResult currentRow = null;
105    boolean lastGetWasNull = false;
106
107    boolean hitEndOfData = false;
108    boolean isClosed = false;
109
110    private SQLWarningChain warningChain = null; // The warnings chain.
111

112    public ResultSet_base(Tds tds_, Statement stmt_, Columns columns_)
113    {
114       tds = tds_;
115       stmt = stmt_;
116       columnsInfo = columns_;
117
118       hitEndOfData = false;
119       warningChain = new SQLWarningChain();
120    }
121
122
123    protected void NotImplemented() throws java.sql.SQLException JavaDoc
124       {
125          throw new SQLException("Not implemented");
126       }
127
128
129    /**
130     * After this call getWarnings returns null until a new warning is
131     * reported for this ResultSet.
132     *
133     * @exception SQLException if a database-access error occurs.
134     */

135    public void clearWarnings() throws SQLException
136    {
137       warningChain.clearWarnings();
138    }
139
140    /**
141     * In some cases, it is desirable to immediately release a
142     * ResultSet's database and JDBC resources instead of waiting for
143     * this to happen when it is automatically closed; the close
144     * method provides this immediate release.
145     *
146     * <P><B>Note:</B> A ResultSet is automatically closed by the
147     * Statement that generated it when that Statement is closed,
148     * re-executed, or is used to retrieve the next result from a
149     * sequence of multiple results. A ResultSet is also automatically
150     * closed when it is garbage collected.
151     *
152     * @exception SQLException if a database-access error occurs.
153     */

154    public void close() throws SQLException
155    {
156       Exception JavaDoc exception = null;
157       
158       if (isClosed)
159       {
160          // nop ???
161
}
162       else
163       {
164          isClosed = true;
165          try
166          {
167             if (!hitEndOfData)
168             {
169                tds.discardResultSet(columnsInfo);
170                hitEndOfData = true;
171             }
172             else
173             {
174                // nop
175
}
176          }
177          catch(com.internetcds.jdbc.tds.TdsException e)
178          {
179              e.printStackTrace();
180             exception = e;
181       }
182          catch(java.io.IOException JavaDoc e)
183          {
184              e.printStackTrace();
185             exception = e;
186          }
187          
188          currentRow = null;
189          metaData = null;
190          columnsInfo = null;
191          stmt = null;
192          
193          if (exception != null)
194          {
195             throw new SQLException(exception.getMessage());
196          }
197       }
198    }
199
200
201    //----------------------------------------------------------------
202

203    /**
204     * Map a Resultset column name to a ResultSet column index.
205     *
206     * @param columnName the name of the column
207     * @return the column index
208     * @exception SQLException if a database-access error occurs.
209     */

210    public int findColumn(String JavaDoc columnName) throws SQLException
211    {
212       int i;
213
214       for(i=1; i<=columnsInfo.getColumnCount(); i++)
215       {
216          if (columnsInfo.getName(i).equalsIgnoreCase(columnName))
217          {
218             return i;
219          }
220          // XXX also need to look at the fully qualified name ie. table.column
221
}
222       throw new SQLException("No such column " + columnName);
223    }
224
225
226    /**
227     * A column value can be retrieved as a stream of ASCII characters
228     * and then read in chunks from the stream. This method is particularly
229     * suitable for retrieving large LONGVARCHAR values. The JDBC driver will
230     * do any necessary conversion from the database format into ASCII.
231     *
232     * <P><B>Note:</B> All the data in the returned stream must be
233     * read prior to getting the value of any other column. The next
234     * call to a get method implicitly closes the stream. . Also, a
235     * stream may return 0 for available() whether there is data
236     * available or not.
237     *
238     * @param columnIndex the first column is 1, the second is 2, ...
239     * @return a Java input stream that delivers the database column value
240     * as a stream of one byte ASCII characters. If the value is SQL NULL
241     * then the result is null.
242     * @exception SQLException if a database-access error occurs.
243     */

244    public java.io.InputStream JavaDoc getAsciiStream(int columnIndex) throws SQLException
245    {
246        String JavaDoc val = getString(columnIndex);
247        if (val == null)
248            return null;
249        try {
250            return new ByteArrayInputStream(val.getBytes("ASCII"));
251        } catch (UnsupportedEncodingException ue) {
252            // plain impossible with encoding ASCII
253
return null;
254        }
255    }
256
257
258    /**
259     * A column value can be retrieved as a stream of ASCII characters
260     * and then read in chunks from the stream. This method is particularly
261     * suitable for retrieving large LONGVARCHAR values. The JDBC driver will
262     * do any necessary conversion from the database format into ASCII.
263     *
264     * <P><B>Note:</B> All the data in the returned stream must
265     * be read prior to getting the value of any other column. The
266     * next call to a get method implicitly closes the stream.
267     *
268     * @param columnName is the SQL name of the column
269     * @return a Java input stream that delivers the database column value
270     * as a stream of one byte ASCII characters. If the value is SQL NULL
271     * then the result is null.
272     * @exception SQLException if a database-access error occurs.
273     */

274    public java.io.InputStream JavaDoc getAsciiStream(String JavaDoc columnName) throws SQLException
275    {
276       return getAsciiStream(findColumn(columnName));
277    }
278
279
280    /**
281     * Get the value of a column in the current row as a
282     * java.lang.BigDecimal object.
283     *
284     * @param columnIndex the first column is 1, the second is 2, ...
285     * @param scale the number of digits to the right of the decimal
286     * @return the column value; if the value is SQL NULL, the result is null
287     * @exception SQLException if a database-access error occurs.
288     */

289    public BigDecimal JavaDoc getBigDecimal(int columnIndex, int scale)
290       throws SQLException
291    {
292       Object JavaDoc tmp = getObject(columnIndex);
293       BigDecimal JavaDoc result = null;
294
295
296       if (tmp == null)
297       {
298          result = null;
299       }
300       else if (tmp instanceof java.lang.Double JavaDoc)
301       {
302          result = new BigDecimal JavaDoc(((Double JavaDoc)tmp).doubleValue());
303          result = result.setScale(scale, BigDecimal.ROUND_HALF_UP);
304       }
305       else if (tmp instanceof java.lang.Float JavaDoc)
306       {
307          result = new BigDecimal JavaDoc(((Float JavaDoc)tmp).doubleValue());
308          result = result.setScale(scale, BigDecimal.ROUND_HALF_UP);
309       }
310       else if (tmp instanceof java.lang.Number JavaDoc)
311       {
312          // This handles Byte, Short, Integer, and Long
313
result = BigDecimal.valueOf(((Number JavaDoc)tmp).longValue(), scale);
314       }
315       else if (tmp instanceof BigDecimal JavaDoc)
316       {
317          result = (BigDecimal JavaDoc)tmp;
318       }
319       else if (tmp instanceof java.lang.String JavaDoc)
320       {
321          try
322          {
323             result = new BigDecimal JavaDoc((String JavaDoc)tmp);
324          }
325          catch (NumberFormatException JavaDoc e)
326          {
327             throw new SQLException(e.getMessage());
328          }
329       }
330       return result;
331    }
332
333    /**
334     * Get the value of a column in the current row as a
335     * java.lang.BigDecimal object.
336     *
337     * @param columnName is the SQL name of the column
338     * @param scale the number of digits to the right of the decimal
339     * @return the column value; if the value is SQL NULL, the result is null
340     * @exception SQLException if a database-access error occurs.
341     */

342    public BigDecimal JavaDoc getBigDecimal(String JavaDoc columnName, int scale) throws SQLException
343    {
344       return getBigDecimal(findColumn(columnName), scale);
345    }
346
347
348    /**
349     * A column value can be retrieved as a stream of uninterpreted bytes
350     * and then read in chunks from the stream. This method is particularly
351     * suitable for retrieving large LONGVARBINARY values.
352     *
353     * <P><B>Note:</B> All the data in the returned stream must be
354     * read prior to getting the value of any other column. The next
355     * call to a get method implicitly closes the stream. Also, a
356     * stream may return 0 for available() whether there is data
357     * available or not.
358     *
359     * @param columnIndex the first column is 1, the second is 2, ...
360     * @return a Java input stream that delivers the database column value
361     * as a stream of uninterpreted bytes. If the value is SQL NULL
362     * then the result is null.
363     * @exception SQLException if a database-access error occurs.
364     */

365    public java.io.InputStream JavaDoc getBinaryStream(int columnIndex)
366       throws SQLException
367    {
368        byte[] bytes = getBytes(columnIndex);
369        if (bytes != null)
370            return new ByteArrayInputStream(bytes);
371        return null;
372    }
373
374
375    /**
376     * A column value can be retrieved as a stream of uninterpreted bytes
377     * and then read in chunks from the stream. This method is particularly
378     * suitable for retrieving large LONGVARBINARY values.
379     *
380     * <P><B>Note:</B> All the data in the returned stream must
381     * be read prior to getting the value of any other column. The
382     * next call to a get method implicitly closes the stream.
383     *
384     * @param columnName is the SQL name of the column
385     * @return a Java input stream that delivers the database column value
386     * as a stream of uninterpreted bytes. If the value is SQL NULL
387     * then the result is null.
388     * @exception SQLException if a database-access error occurs.
389     */

390    public java.io.InputStream JavaDoc getBinaryStream(String JavaDoc columnName)
391       throws SQLException
392    {
393       return getBinaryStream(findColumn(columnName));
394    }
395
396
397    /**
398     * Get the value of a column in the current row as a Java boolean.
399     *
400     * @param columnIndex the first column is 1, the second is 2, ...
401     * @return the column value; if the value is SQL NULL, the result is false
402     * @exception SQLException if a database-access error occurs.
403     */

404    public boolean getBoolean(int columnIndex) throws SQLException
405    {
406       Object JavaDoc obj = getObject(columnIndex);
407       boolean result;
408
409       if (obj == null)
410       {
411          result = false;
412       }
413       else
414       {
415          switch(getMetaData().getColumnType(columnIndex))
416          {
417             case java.sql.Types.TINYINT:
418             case java.sql.Types.SMALLINT:
419             case java.sql.Types.INTEGER:
420             case java.sql.Types.BIGINT:
421             case java.sql.Types.REAL:
422             case java.sql.Types.FLOAT:
423             case java.sql.Types.DOUBLE:
424             case java.sql.Types.DECIMAL:
425             case java.sql.Types.NUMERIC:
426             {
427                if (! (obj instanceof java.lang.Number JavaDoc))
428                {
429                   // Must be out of sync with the implementation of
430
// Tds.getRow() for this to happen.
431
throw new SQLException("Internal error");
432                }
433                // Would somebody like to tell what a true/false has
434
// to do with a double?
435
result = ((java.lang.Number JavaDoc)obj).intValue()!=0;
436                break;
437             }
438             case java.sql.Types.BIT:
439             {
440                if (! (obj instanceof Boolean JavaDoc))
441                {
442                   // Must be out of sync with the implementation of
443
// Tds.getRow() for this to happen.
444
throw new SQLException("Internal error");
445                }
446                result = ((Boolean JavaDoc)obj).booleanValue();
447                break;
448             }
449             case java.sql.Types.CHAR:
450             case java.sql.Types.VARCHAR:
451             case java.sql.Types.LONGVARCHAR:
452             {
453                // Okay, I'm really confused as to what you mean
454
// by a character string being true or false. What
455
// is the boolean value for "Let the wookie win"?
456
// But since the spec says I have to convert from
457
// character to boolean data...
458

459                if (! (obj instanceof String JavaDoc))
460                {
461                   // Must be out of sync with the implementation of
462
// Tds.getRow() for this to happen.
463
throw new SQLException("Internal error");
464                }
465                char ch = (((String JavaDoc)obj) + "n").charAt(0);
466
467                result = (ch=='Y')||(ch=='y')||(ch=='t')||(ch=='T');
468                break;
469             }
470             default:
471             {
472                throw new SQLException("Can't convert column " + columnIndex
473                                       + " from "
474                                       + obj.getClass().getName()
475                                       + " to boolean");
476             }
477          }
478       }
479       return result;
480    } // getBoolean()
481

482
483    /**
484     * Get the value of a column in the current row as a Java boolean.
485     *
486     * @param columnName is the SQL name of the column
487     * @return the column value; if the value is SQL NULL, the result is false
488     * @exception SQLException if a database-access error occurs.
489     */

490    public boolean getBoolean(String JavaDoc columnName) throws SQLException
491    {
492       return getBoolean(findColumn(columnName));
493    } // getBoolean()
494

495
496    /**
497     * Get the value of a column in the current row as a Java byte.
498     *
499     * @param columnIndex the first column is 1, the second is 2, ...
500     * @return the column value; if the value is SQL NULL, the result is 0
501     * @exception SQLException if a database-access error occurs.
502     */

503    public byte getByte(int columnIndex) throws SQLException
504    {
505       return (byte) getLong(columnIndex);
506    }
507
508
509    /**
510     * Get the value of a column in the current row as a Java byte.
511     *
512     * @param columnName is the SQL name of the column
513     * @return the column value; if the value is SQL NULL, the result is 0
514     * @exception SQLException if a database-access error occurs.
515     */

516    public byte getByte(String JavaDoc columnName) throws SQLException
517    {
518       return getByte(findColumn(columnName));
519    }
520
521
522    /**
523     * Get the value of a column in the current row as a Java byte array.
524     * The bytes represent the raw values returned by the driver.
525     *
526     * @param columnIndex the first column is 1, the second is 2, ...
527     * @return the column value; if the value is SQL NULL, the result is null
528     * @exception SQLException if a database-access error occurs.
529     */

530    public byte[] getBytes(int columnIndex) throws SQLException
531    {
532       byte result[];
533
534       try
535       {
536          Object JavaDoc tmp = currentRow.getElementAt(columnIndex);
537          lastGetWasNull = false;
538          if (tmp == null)
539          {
540             lastGetWasNull = true;
541             result = null;
542          }
543          else if (tmp instanceof byte[])
544          {
545             result = (byte[])tmp;
546          }
547          else if (tmp instanceof String JavaDoc)
548          {
549             result = tds.getEncoder().getBytes((String JavaDoc)tmp);
550          }
551          else
552          {
553             throw new SQLException("Can't convert column " + columnIndex
554                                    + " from "
555                                    + tmp.getClass().getName()
556                                    + " to byte[]");
557          }
558       }
559       catch (TdsException e)
560       {
561          e.printStackTrace();
562          throw new SQLException(e.getMessage());
563       }
564       return result;
565    }
566
567
568    /**
569     * Get the value of a column in the current row as a Java byte array.
570     * The bytes represent the raw values returned by the driver.
571     *
572     * @param columnName is the SQL name of the column
573     * @return the column value; if the value is SQL NULL, the result is null
574     * @exception SQLException if a database-access error occurs.
575     */

576    public byte[] getBytes(String JavaDoc columnName) throws SQLException
577    {
578       return getBytes(findColumn(columnName));
579    }
580
581
582    /**
583     * Get the name of the SQL cursor used by this ResultSet.
584     *
585     * <P>In SQL, a result table is retrieved through a cursor that is
586     * named. The current row of a result can be updated or deleted
587     * using a positioned update/delete statement that references the
588     * cursor name.
589     *
590     * <P>JDBC supports this SQL feature by providing the name of the
591     * SQL cursor used by a ResultSet. The current row of a ResultSet
592     * is also the current row of this SQL cursor.
593     *
594     * <P><B>Note:</B> If positioned update is not supported a
595     * SQLException is thrown
596     *
597     * @return the ResultSet's SQL cursor name
598     * @exception SQLException if a database-access error occurs.
599     */

600    public String JavaDoc getCursorName() throws SQLException
601    {
602       throw new SQLException("Not implemented (getCursorName)");
603    }
604
605
606    /**
607     * Get the value of a column in the current row as a java.sql.Date object.
608     *
609     * @param columnIndex the first column is 1, the second is 2, ...
610     * @return the column value; if the value is SQL NULL, the result is null
611     * @exception SQLException if a database-access error occurs.
612     */

613    public java.sql.Date JavaDoc getDate(int columnIndex) throws SQLException
614    {
615       java.sql.Date JavaDoc result = null;
616       java.sql.Timestamp JavaDoc tmp = getTimestamp(columnIndex);
617
618       if (tmp != null)
619       {
620          result = new java.sql.Date JavaDoc(tmp.getTime());
621       }
622       return result;
623    }
624
625
626    /**
627     * Get the value of a column in the current row as a java.sql.Date object.
628     *
629     * @param columnName is the SQL name of the column
630     * @return the column value; if the value is SQL NULL, the result is null
631     * @exception SQLException if a database-access error occurs.
632     */

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

646    public double getDouble(int columnIndex) throws SQLException
647    {
648       double result;
649       Object JavaDoc obj = getObject(columnIndex);
650
651       if (obj == null)
652       {
653          result = 0.0;
654       }
655       else
656       {
657          try
658          {
659             switch(getMetaData().getColumnType(columnIndex))
660             {
661                case java.sql.Types.TINYINT:
662                case java.sql.Types.SMALLINT:
663                case java.sql.Types.INTEGER:
664                {
665                   result = ((Number JavaDoc)obj).doubleValue();
666                   break;
667                }
668                case java.sql.Types.BIGINT:
669                {
670                   result = ((Number JavaDoc)obj).doubleValue();
671                   break;
672                }
673                case java.sql.Types.REAL:
674                {
675                   result = ((Float JavaDoc)obj).doubleValue();
676                   break;
677                }
678                case java.sql.Types.FLOAT:
679                case java.sql.Types.DOUBLE:
680                {
681                   result = ((Number JavaDoc)obj).doubleValue();
682                   break;
683                }
684                case java.sql.Types.CHAR:
685                case java.sql.Types.VARCHAR:
686                case java.sql.Types.LONGVARCHAR:
687                {
688                   try
689                   {
690                      Double JavaDoc d = new Double JavaDoc((String JavaDoc)obj);
691                      result = d.doubleValue();
692                   }
693                   catch (NumberFormatException JavaDoc e)
694                   {
695                      throw new SQLException(e.getMessage());
696                   }
697                   break;
698                }
699                case java.sql.Types.DECIMAL:
700                case java.sql.Types.NUMERIC:
701                {
702                   result = ((BigDecimal JavaDoc)obj).doubleValue();
703                   break;
704                }
705                case java.sql.Types.BIT:
706                {
707                   // XXX according to JDBC spec we need to handle these
708
// for now just fall through
709
}
710                default:
711                {
712                   throw new SQLException("Internal error. "
713                                          + "Don't know how to convert from "
714                                          + "java.sql.Types." +
715                                          TdsUtil.javaSqlTypeToString(getMetaData().getColumnType(columnIndex))
716                                          + " to an Dboule");
717                }
718             }
719          }
720          catch(ClassCastException JavaDoc e)
721          {
722             throw new SQLException("Couldn't convert column " + columnIndex
723                                    + " to an long. "
724                                    + e.getMessage());
725          }
726       }
727       return result;
728    } /* getDouble() */
729
730
731    /**
732     * Get the value of a column in the current row as a Java double.
733     *
734     * @param columnName is the SQL name of the column
735     * @return the column value; if the value is SQL NULL, the result is 0
736     * @exception SQLException if a database-access error occurs.
737     */

738    public double getDouble(String JavaDoc columnName) throws SQLException
739    {
740       return getDouble(findColumn(columnName));
741    }
742
743
744    /**
745     * Get the value of a column in the current row as a Java float.
746     *
747     * @param columnIndex the first column is 1, the second is 2, ...
748     * @return the column value; if the value is SQL NULL, the result is 0
749     * @exception SQLException if a database-access error occurs.
750     */

751    public float getFloat(int columnIndex) throws SQLException
752    {
753       return (float)getDouble(columnIndex);
754    }
755
756
757    /**
758     * Get the value of a column in the current row as a Java float.
759     *
760     * @param columnName is the SQL name of the column
761     * @return the column value; if the value is SQL NULL, the result is 0
762     * @exception SQLException if a database-access error occurs.
763     */

764    public float getFloat(String JavaDoc columnName) throws SQLException
765    {
766       return getFloat(findColumn(columnName));
767    }
768
769
770    /**
771     * Get the value of a column in the current row as a Java int.
772     *
773     * @param columnIndex the first column is 1, the second is 2, ...
774     * @return the column value; if the value is SQL NULL, the result is 0
775     * @exception SQLException if a database-access error occurs.
776     */

777    public int getInt(int columnIndex) throws SQLException
778    {
779       return (int) getLong(columnIndex);
780    }
781
782
783    /**
784     * Get the value of a column in the current row as a Java int.
785     *
786     * @param columnName is the SQL name of the column
787     * @return the column value; if the value is SQL NULL, the result is 0
788     * @exception SQLException if a database-access error occurs.
789     */

790    public int getInt(String JavaDoc columnName) throws SQLException
791    {
792       return getInt(findColumn(columnName));
793    }
794
795
796    /**
797     * Get the value of a column in the current row as a Java long.
798     *
799     * @param columnIndex the first column is 1, the second is 2, ...
800     * @return the column value; if the value is SQL NULL, the result is 0
801     * @exception SQLException if a database-access error occurs.
802     */

803    public long getLong(int columnIndex) throws SQLException
804    {
805       long result = 0;
806       Object JavaDoc obj = getObject(columnIndex);
807
808       if (obj == null)
809       {
810          result = 0;
811       }
812       else
813       {
814          try
815          {
816             switch(getMetaData().getColumnType(columnIndex))
817             {
818                case java.sql.Types.TINYINT:
819                case java.sql.Types.SMALLINT:
820                case java.sql.Types.INTEGER:
821                {
822                   result = ((Number JavaDoc)obj).longValue();
823                   break;
824                }
825                case java.sql.Types.BIGINT:
826                {
827                   result = ((Number JavaDoc)obj).longValue();
828                   break;
829                }
830                case java.sql.Types.REAL:
831                case java.sql.Types.FLOAT:
832                case java.sql.Types.DOUBLE:
833                {
834                   result = ((Number JavaDoc)obj).longValue();
835                   break;
836                }
837                case java.sql.Types.CHAR:
838                case java.sql.Types.VARCHAR:
839                case java.sql.Types.LONGVARCHAR:
840                {
841                   try
842                   {
843                      Long JavaDoc i = new Long JavaDoc((String JavaDoc)obj);
844                      result = i.longValue();
845                   }
846                   catch (NumberFormatException JavaDoc e)
847                   {
848                      throw new SQLException(e.getMessage());
849                   }
850                   break;
851                }
852                case java.sql.Types.NUMERIC:
853                {
854                   result = ((Number JavaDoc)obj).longValue();
855                   break;
856                }
857                case java.sql.Types.DECIMAL:
858                {
859                   result = ((Number JavaDoc)obj).longValue();
860                   break;
861                }
862                case java.sql.Types.BIT:
863                {
864                   // XXX according to JDBC spec we need to handle these
865
// for now just fall through
866
}
867                default:
868                {
869                   throw new SQLException("Internal error. "
870                                          + "Don't know how to convert from "
871                                          + "java.sql.Types " +
872                                          TdsUtil.javaSqlTypeToString(getMetaData().getColumnType(columnIndex))
873                                          + " to an long");
874                }
875             }
876          }
877          catch(ClassCastException JavaDoc e)
878          {
879             throw new SQLException("Couldn't convert column " + columnIndex
880                                    + " to an long. "
881                                    + e.getMessage());
882          }
883       }
884       return result;
885    } /* getLong() */
886
887
888    /**
889     * Get the value of a column in the current row as a Java long.
890     *
891     * @param columnName is the SQL name of the column
892     * @return the column value; if the value is SQL NULL, the result is 0
893     * @exception SQLException if a database-access error occurs.
894     */

895    public long getLong(String JavaDoc columnName) throws SQLException
896    {
897       return getLong(findColumn(columnName));
898    }
899
900
901    /**
902     * The number, types and properties of a ResultSet's columns
903     * are provided by the getMetaData method.
904     *
905     * @return the description of a ResultSet's columns
906     * @exception SQLException if a database-access error occurs.
907     */

908    public java.sql.ResultSetMetaData JavaDoc getMetaData() throws SQLException
909    {
910       if (metaData == null)
911       {
912          metaData = new ResultSetMetaData(columnsInfo);
913       }
914       return metaData;
915    }
916
917
918    /**
919     * <p>Get the value of a column in the current row as a Java object.
920     *
921     * <p>This method will return the value of the given column as a
922     * Java object. The type of the Java object will be the default
923     * Java Object type corresponding to the column's SQL type,
924     * following the mapping specified in the JDBC spec.
925     *
926     * <p>This method may also be used to read datatabase specific abstract
927     * data types.
928     *
929     * JDBC 2.0
930     *
931     * In the JDBC 2.0 API, the behavior of method
932     * <code>getObject</code> is extended to materialize
933     * data of SQL user-defined types. When the a column contains
934     * a structured or distinct value, the behavior of this method is as
935     * if it were a call to: getObject(columnIndex,
936     * this.getStatement().getConnection().getTypeMap()).
937     *
938     * @param columnIndex the first column is 1, the second is 2, ...
939     * @return A java.lang.Object holding the column value.
940     * @exception SQLException if a database-access error occurs.
941     */

942    public Object JavaDoc getObject(int columnIndex) throws SQLException
943    {
944       // This method is implicitly coupled to the getRow() method in the
945
// Tds class. Every type that getRow() could return must
946
// be handled in this method.
947
//
948
// The object type returned by getRow() must correspond with the
949
// jdbc SQL type in the switch statement below.
950
//
951
// Note- The JDBC spec (version 1.20) does not define the type
952
// of the Object returned for LONGVARCHAR data.
953

954       // XXX- Needs modifications for JDBC 2.0
955

956       Object JavaDoc result = null;
957
958       if (currentRow == null)
959       {
960          throw new SQLException("No current row in the result set. " +
961                                 "Did you call ResultSet.next()?");
962       }
963       
964       try
965       {
966          Object JavaDoc tmp = currentRow.getElementAt(columnIndex);
967          lastGetWasNull = false;
968          if (tmp == null)
969          {
970             lastGetWasNull = true;
971
972             result = null;
973          }
974          else
975          {
976             switch(getMetaData().getColumnType(columnIndex))
977             {
978                case java.sql.Types.CHAR:
979                case java.sql.Types.VARCHAR:
980                {
981                   if (tmp instanceof String JavaDoc)
982                   {
983                      result = tmp;
984                   }
985                   else
986                   {
987                      throw new SQLException("Was expecting CHAR data. Got"
988                                             + tmp.getClass().getName());
989                   }
990                   break;
991                }
992                case java.sql.Types.TINYINT:
993                {
994                   if (! (tmp instanceof Long JavaDoc))
995                   {
996                      throw new SQLException("Internal error");
997                   }
998
999                   result = new Byte JavaDoc((byte) ((Long JavaDoc)tmp).intValue());
1000                  break;
1001               }
1002               case java.sql.Types.SMALLINT:
1003               {
1004                  if (! (tmp instanceof Long JavaDoc))
1005                  {
1006                     throw new SQLException("Internal error");
1007                  }
1008
1009                  result = new Short JavaDoc((short) ((Long JavaDoc)tmp).intValue());
1010                  break;
1011               }
1012               case java.sql.Types.INTEGER:
1013               {
1014                  if (! (tmp instanceof Long JavaDoc))
1015                  {
1016                     throw new SQLException("Internal error");
1017                  }
1018
1019                  result = new Integer JavaDoc(((Long JavaDoc)tmp).intValue());
1020                  break;
1021               }
1022               case java.sql.Types.BIGINT:
1023               {
1024                  if (! (tmp instanceof Long JavaDoc))
1025                  {
1026                     throw new SQLException("Internal error");
1027                  }
1028
1029                  result = (Long JavaDoc)tmp;
1030                  break;
1031               }
1032               case java.sql.Types.REAL:
1033               {
1034                  if (! (tmp instanceof Float JavaDoc))
1035                  {
1036                     throw new SQLException("Internal error");
1037                  }
1038
1039                  result = (Float JavaDoc)tmp;
1040                  break;
1041               }
1042               case java.sql.Types.FLOAT:
1043               case java.sql.Types.DOUBLE:
1044               {
1045                  if (tmp instanceof Double JavaDoc)
1046                  {
1047                     result = (Double JavaDoc)tmp;
1048                  }
1049                  else if (tmp instanceof Float JavaDoc)
1050                  {
1051                     result = new Double JavaDoc(((Float JavaDoc)tmp).doubleValue());
1052                  }
1053                  else
1054                  {
1055                     throw new SQLException("Was expecting Double data. Got"
1056                                            + tmp.getClass().getName());
1057                  }
1058
1059                  break;
1060               }
1061               case java.sql.Types.DATE:
1062               {
1063                  // XXX How do the time types hold up with timezones?
1064
if (! (tmp instanceof Timestamp))
1065                  {
1066                     throw new SQLException("Internal error");
1067                  }
1068
1069// java.util.Calendar cal = new java.util.GregorianCalendar();
1070
// cal.setTime(getTimestamp(columnIndex));
1071
// result = cal.getTime();
1072
result = new Date(((Timestamp)tmp).getTime());
1073                  break;
1074               }
1075               case java.sql.Types.TIME:
1076               {
1077                  if (! (tmp instanceof Timestamp))
1078                  {
1079                     throw new SQLException("Internal error");
1080                  }
1081
1082                  result = new Time(((Timestamp)tmp).getTime());
1083                  break;
1084               }
1085               case java.sql.Types.TIMESTAMP:
1086               {
1087                  if (! (tmp instanceof Timestamp))
1088                  {
1089                     throw new SQLException("Internal error");
1090                  }
1091
1092                  result = (Timestamp) tmp;
1093                  break;
1094               }
1095               case java.sql.Types.BINARY:
1096               case java.sql.Types.VARBINARY:
1097               {
1098                  result = getBytes(columnIndex);
1099                  break;
1100               }
1101               case java.sql.Types.DECIMAL:
1102               case java.sql.Types.NUMERIC:
1103               {
1104                  if (tmp instanceof BigDecimal JavaDoc)
1105                  {
1106                     result = ((BigDecimal JavaDoc)tmp);
1107                  }
1108                  else
1109                  {
1110                     throw new SQLException("Was expecting NUMERIC data. Got"
1111                                            + tmp.getClass().getName());
1112                  }
1113                  break;
1114               }
1115               case java.sql.Types.LONGVARCHAR:
1116               {
1117                  if (tmp instanceof TdsAsciiInputStream)
1118                  {
1119                     result = ((TdsAsciiInputStream)tmp).toString();
1120                  }
1121                  else if (tmp instanceof java.lang.String JavaDoc)
1122                  {
1123                     result = tmp;
1124                  }
1125                  else
1126                  {
1127                     throw new SQLException("Was expecting LONGVARCHAR data. "
1128                                            + "Got "
1129                                            + tmp.getClass().getName());
1130                  }
1131                  break;
1132               }
1133               case java.sql.Types.LONGVARBINARY:
1134               {
1135                  throw new SQLException("Not implemented");
1136               }
1137               case java.sql.Types.NULL:
1138               {
1139                  throw new SQLException("Not implemented");
1140               }
1141               case java.sql.Types.OTHER:
1142               {
1143                  throw new SQLException("Not implemented");
1144               }
1145               case java.sql.Types.BIT:
1146               {
1147                  if (tmp instanceof Boolean JavaDoc)
1148                  {
1149                     result = ((Boolean JavaDoc)tmp);
1150                  }
1151                  else
1152                  {
1153                     throw new SQLException("Was expecting BIT data. "
1154                                            + "Got"
1155                                            + tmp.getClass().getName());
1156                  }
1157                  break;
1158               }
1159               default:
1160               {
1161                  String JavaDoc msg = ""
1162                     + "Unknown datatype "
1163                     + getMetaData().getColumnType(columnIndex);
1164                  throw new SQLException(msg);
1165               }
1166            }
1167         }
1168      }
1169      catch (com.internetcds.jdbc.tds.TdsException e)
1170      {
1171         e.printStackTrace();
1172         throw new SQLException(e.getMessage());
1173      }
1174      return result;
1175   } // getObject()
1176

1177
1178   /**
1179    * <p>Get the value of a column in the current row as a Java object.
1180    *
1181    * <p>This method will return the value of the given column as a
1182    * Java object. The type of the Java object will be the default
1183    * Java Object type corresponding to the column's SQL type,
1184    * following the mapping specified in the JDBC spec.
1185    *
1186    * JDBC 2.0
1187    *
1188    *
1189    * In the JDBC 2.0 API, the behavior of method
1190    * <code>getObject</code> is extended to materialize
1191    * data of SQL user-defined types. When the a column contains
1192    * a structured or distinct value, the behavior of this method is as
1193    * if it were a call to: getObject(columnIndex,
1194    * this.getStatement().getConnection().getTypeMap()).
1195    *
1196    * <p>This method may also be used to read datatabase specific abstract
1197    * data types.
1198    *
1199    * @param columnName is the SQL name of the column
1200    * @return A java.lang.Object holding the column value.
1201    * @exception SQLException if a database-access error occurs.
1202    */

1203   public Object JavaDoc getObject(String JavaDoc columnName) throws SQLException
1204   {
1205      return getObject(findColumn(columnName));
1206   }
1207
1208
1209   /**
1210    * Get the value of a column in the current row as a Java short.
1211    *
1212    * @param columnIndex the first column is 1, the second is 2, ...
1213    * @return the column value; if the value is SQL NULL, the result is 0
1214    * @exception SQLException if a database-access error occurs.
1215    */

1216   public short getShort(int columnIndex) throws SQLException
1217   {
1218      return (short) getLong(columnIndex);
1219   }
1220
1221
1222   /**
1223    * Get the value of a column in the current row as a Java short.
1224    *
1225    * @param columnName is the SQL name of the column
1226    * @return the column value; if the value is SQL NULL, the result is 0
1227    * @exception SQLException if a database-access error occurs.
1228    */

1229   public short getShort(String JavaDoc columnName) throws SQLException
1230   {
1231      return getShort(findColumn(columnName));
1232   }
1233
1234
1235   //======================================================================
1236
// Methods for accessing results by column index
1237
//======================================================================
1238

1239   /**
1240    * Get the value of a column in the current row as a Java String.
1241    *
1242    * @param columnIndex the first column is 1, the second is 2, ...
1243    * @return the column value; if the value is SQL NULL, the result is null
1244    * @exception SQLException if a database-access error occurs.
1245    */

1246   public String JavaDoc getString(int columnIndex) throws SQLException
1247   {
1248      Object JavaDoc tmp = getObject(columnIndex);
1249
1250      if (tmp == null)
1251      {
1252         return null;
1253      }
1254      else if (tmp instanceof byte[])
1255      {
1256         return new String JavaDoc((byte[])tmp);
1257      }
1258      else
1259      {
1260         return tmp.toString();
1261      }
1262   }
1263
1264
1265   //======================================================================
1266
// Methods for accessing results by column name
1267
//======================================================================
1268

1269   /**
1270    * Get the value of a column in the current row as a Java String.
1271    *
1272    * @param columnName is the SQL name of the column
1273    * @return the column value; if the value is SQL NULL, the result is null
1274    * @exception SQLException if a database-access error occurs.
1275    */

1276   public String JavaDoc getString(String JavaDoc columnName) throws SQLException
1277   {
1278      return getString(findColumn(columnName));
1279   }
1280
1281
1282   /**
1283    * Get the value of a column in the current row as a java.sql.Time object.
1284    *
1285    * @param columnIndex the first column is 1, the second is 2, ...
1286    * @return the column value; if the value is SQL NULL, the result is null
1287    * @exception SQLException if a database-access error occurs.
1288    */

1289   public java.sql.Time JavaDoc getTime(int columnIndex) throws SQLException
1290   {
1291      java.sql.Time JavaDoc result = null;
1292      java.sql.Timestamp JavaDoc tmp = getTimestamp(columnIndex);
1293      
1294      if (tmp != null)
1295      {
1296         result = new java.sql.Time JavaDoc(tmp.getTime());
1297      }
1298      return result;
1299   }
1300
1301
1302   /**
1303    * Get the value of a column in the current row as a java.sql.Time object.
1304    *
1305    * @param columnName is the SQL name of the column
1306    * @return the column value; if the value is SQL NULL, the result is null
1307    * @exception SQLException if a database-access error occurs.
1308    */

1309   public java.sql.Time JavaDoc getTime(String JavaDoc columnName) throws SQLException
1310   {
1311      return getTime(findColumn(columnName));
1312   }
1313
1314
1315   /**
1316    * Get the value of a column in the current row as a java.sql.Timestamp object.
1317    *
1318    * @param columnIndex the first column is 1, the second is 2, ...
1319    * @return the column value; if the value is SQL NULL, the result is null
1320    * @exception SQLException if a database-access error occurs.
1321    */

1322   public java.sql.Timestamp JavaDoc getTimestamp(int columnIndex) throws SQLException
1323   {
1324      Timestamp result;
1325
1326      try
1327      {
1328         Object JavaDoc tmp = currentRow.getElementAt(columnIndex);
1329
1330         lastGetWasNull = false;
1331         if (tmp == null)
1332         {
1333            lastGetWasNull = true;
1334            result = null;
1335         }
1336         else if (tmp instanceof Timestamp)
1337         {
1338            result = (Timestamp)tmp;
1339         }
1340         else
1341         {
1342            throw new SQLException("Can't convert column " + columnIndex
1343                                   + " from "
1344                                   + tmp.getClass().getName()
1345                                   + " to Timestamp");
1346         }
1347      }
1348      catch (TdsException e)
1349      {
1350         throw new SQLException(e.getMessage());
1351      }
1352      return result;
1353   }
1354
1355
1356   /**
1357    * Get the value of a column in the current row as a java.sql.Timestamp object.
1358    *
1359    * @param columnName is the SQL name of the column
1360    * @return the column value; if the value is SQL NULL, the result is null
1361    * @exception SQLException if a database-access error occurs.
1362    */

1363   public java.sql.Timestamp JavaDoc getTimestamp(String JavaDoc columnName) throws SQLException
1364   {
1365      return getTimestamp(findColumn(columnName));
1366   }
1367
1368
1369   /**
1370    * A column value can be retrieved as a stream of Unicode characters
1371    * and then read in chunks from the stream. This method is particularly
1372    * suitable for retrieving large LONGVARCHAR values. The JDBC driver will
1373    * do any necessary conversion from the database format into Unicode.
1374    *
1375    * <P><B>Note:</B> All the data in the returned stream must be
1376    * read prior to getting the value of any other column. The next
1377    * call to a get method implicitly closes the stream. . Also, a
1378    * stream may return 0 for available() whether there is data
1379    * available or not.
1380    *
1381    * @param columnIndex the first column is 1, the second is 2, ...
1382    * @return a Java input stream that delivers the database column value
1383    * as a stream of two byte Unicode characters. If the value is SQL NULL
1384    * then the result is null.
1385    * @exception SQLException if a database-access error occurs.
1386    */

1387   public java.io.InputStream JavaDoc getUnicodeStream(int columnIndex) throws SQLException
1388   {
1389       String JavaDoc val = getString(columnIndex);
1390       if (val == null)
1391           return null;
1392       try {
1393           return new ByteArrayInputStream(val.getBytes("UTF8"));
1394       } catch (UnsupportedEncodingException e) {
1395           // plain impossible with UTF-8
1396
return null;
1397       }
1398   }
1399
1400   /**
1401    * A column value can be retrieved as a stream of Unicode characters
1402    * and then read in chunks from the stream. This method is particularly
1403    * suitable for retrieving large LONGVARCHAR values. The JDBC driver will
1404    * do any necessary conversion from the database format into Unicode.
1405    *
1406    * <P><B>Note:</B> All the data in the returned stream must
1407    * be read prior to getting the value of any other column. The
1408    * next call to a get method implicitly closes the stream.
1409    *
1410    * @param columnName is the SQL name of the column
1411    * @return a Java input stream that delivers the database column value
1412    * as a stream of two byte Unicode characters. If the value is SQL NULL
1413    * then the result is null.
1414    * @exception SQLException if a database-access error occurs.
1415    */

1416   public java.io.InputStream JavaDoc getUnicodeStream(String JavaDoc columnName) throws SQLException
1417   {
1418      return getUnicodeStream(findColumn(columnName));
1419   }
1420
1421
1422   //=====================================================================
1423
// Advanced features:
1424
//=====================================================================
1425

1426   /**
1427    * <p>The first warning reported by calls on this ResultSet is
1428    * returned. Subsequent ResultSet warnings will be chained to this
1429    * SQLWarning.
1430    *
1431    * <P>The warning chain is automatically cleared each time a new
1432    * row is read.
1433    *
1434    * <P><B>Note:</B> This warning chain only covers warnings caused
1435    * by ResultSet methods. Any warning caused by statement methods
1436    * (such as reading OUT parameters) will be chained on the
1437    * Statement object.
1438    *
1439    * @return the first SQLWarning or null
1440    * @exception SQLException if a database-access error occurs.
1441    */

1442   public SQLWarning getWarnings() throws SQLException
1443   {
1444      return warningChain.getWarnings();
1445   }
1446
1447
1448   /**
1449    * A ResultSet is initially positioned before its first row; the
1450    * first call to next makes the first row the current row; the
1451    * second call makes the second row the current row, etc.
1452    *
1453    * <P>If an input stream from the previous row is open, it is
1454    * implicitly closed. The ResultSet's warning chain is cleared
1455    * when a new row is read.
1456    *
1457    * @return true if the new current row is valid; false if there
1458    * are no more rows
1459    * @exception SQLException if a database-access error occurs.
1460    */

1461   public boolean next() throws SQLException
1462   {
1463      boolean result = false;
1464      SQLException exception = null;
1465      boolean done = false;
1466      boolean wasCanceled = false;
1467
1468      if (isClosed)
1469      {
1470         throw new SQLException("result set is closed");
1471      }
1472   if(!hitEndOfData) {
1473      try
1474      {
1475         clearWarnings();
1476
1477         Context context = new Context();
1478         context.setColumnInfo(columnsInfo);
1479
1480
1481         // Keep eating garbage and warnings until we reach the next result
1482
while (!tds.isResultSet() &&
1483                !tds.isEndOfResults() &&
1484                !tds.isResultRow())
1485         {
1486            // RMK 2000-06-08: don't choke on RET_STAT package.
1487
if (tds.isProcId() || tds.peek() == Tds.TDS_RET_STAT_TOKEN)
1488            {
1489               tds.processSubPacket();
1490            }
1491            else if (tds.isDoneInProc())
1492            {
1493               PacketDoneInProcResult tmp =
1494                  (PacketDoneInProcResult)tds.processSubPacket();
1495            }
1496            else if (tds.isTextUpdate())
1497            {
1498               PacketResult tmp1 =
1499                  (PacketResult)tds.processSubPacket();
1500            }
1501            else if (tds.isMessagePacket() || tds.isErrorPacket())
1502            {
1503               PacketMsgResult tmp = (PacketMsgResult)tds.processSubPacket();
1504               exception = warningChain.addOrReturn(tmp);
1505            }
1506            else
1507            {
1508               throw new SQLException("Protocol confusion. "
1509                                      + "Got a 0x"
1510                                      + Integer.toHexString((tds.peek() & 0xff))
1511                                      + " packet");
1512            }
1513         } // end while
1514

1515         if (exception != null)
1516         {
1517            throw exception;
1518         }
1519         
1520         if (tds.isResultRow())
1521         {
1522            currentRow = (PacketRowResult)tds.processSubPacket(context);
1523            result = true;
1524            done = true;
1525         }
1526         else if (tds.isEndOfResults())
1527         {
1528            PacketResult tmp = tds.processSubPacket(context);
1529            currentRow = null;
1530            done = true;
1531            hitEndOfData = true;
1532            wasCanceled = wasCanceled
1533               || ((PacketEndTokenResult)tmp).wasCanceled();
1534         }
1535         else if (!tds.isResultSet())
1536         {
1537            throw new SQLException("Protocol confusion. "
1538                                   + "Got a 0x"
1539                                   + Integer.toHexString((tds.peek() & 0xff))
1540                                   + " packet");
1541         }
1542
1543
1544         if (exception != null)
1545         {
1546            throw exception;
1547         }
1548      }
1549      catch(java.io.IOException JavaDoc e)
1550      {
1551         throw new SQLException(e.getMessage());
1552      }
1553      catch(TdsException e)
1554      {
1555         e.printStackTrace();
1556         throw new SQLException(e.getMessage());
1557      }
1558      if (wasCanceled)
1559      {
1560         throw new SQLException("Query was canceled or timed out.");
1561      }
1562      }
1563      return result;
1564   }
1565
1566
1567   /**
1568    * A column may have the value of SQL NULL; wasNull reports whether
1569    * the last column read had this special value.
1570    * Note that you must first call getXXX on a column to try to read
1571    * its value and then call wasNull() to find if the value was
1572    * the SQL NULL.
1573    *
1574    * @return true if last column read was SQL NULL
1575    * @exception SQLException if a database-access error occurs.
1576    */

1577   public boolean wasNull() throws SQLException
1578   {
1579      return lastGetWasNull;
1580   }
1581}
1582
Popular Tags