ResultSet.java
上传用户:sxlinghang
上传日期:2022-07-20
资源大小:1405k
文件大小:140k
源码类别:

数据库编程

开发平台:

Java

  1. /*
  2.    Copyright (C) 2002 MySQL AB
  3.       This program is free software; you can redistribute it and/or modify
  4.       it under the terms of the GNU General Public License as published by
  5.       the Free Software Foundation; either version 2 of the License, or
  6.       (at your option) any later version.
  7.       This program is distributed in the hope that it will be useful,
  8.       but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.       GNU General Public License for more details.
  11.       You should have received a copy of the GNU General Public License
  12.       along with this program; if not, write to the Free Software
  13.       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14.  */
  15. package com.mysql.jdbc;
  16. import java.io.ByteArrayInputStream;
  17. import java.io.IOException;
  18. import java.io.InputStream;
  19. import java.io.ObjectInputStream;
  20. import java.io.StringReader;
  21. import java.math.BigDecimal;
  22. import java.net.MalformedURLException;
  23. import java.net.URL;
  24. import java.sql.Array;
  25. import java.sql.Date;
  26. import java.sql.Ref;
  27. import java.sql.SQLException;
  28. import java.sql.SQLWarning;
  29. import java.sql.Time;
  30. import java.sql.Timestamp;
  31. import java.sql.Types;
  32. import java.util.Calendar;
  33. import java.util.GregorianCalendar;
  34. import java.util.HashMap;
  35. import java.util.Map;
  36. import java.util.TimeZone;
  37. /**
  38.  * A ResultSet provides access to a table of data generated by executing a
  39.  * Statement.  The table rows are retrieved in sequence.  Within a row its
  40.  * column values can be accessed in any order.
  41.  * 
  42.  * <P>
  43.  * A ResultSet maintains a cursor pointing to its current row of data.
  44.  * Initially the cursor is positioned before the first row.  The 'next' method
  45.  * moves the cursor to the next row.
  46.  * </p>
  47.  * 
  48.  * <P>
  49.  * The getXXX methods retrieve column values for the current row.  You can
  50.  * retrieve values either using the index number of the column, or by using
  51.  * the name of the column.  In general using the column index will be more
  52.  * efficient.  Columns are numbered from 1.
  53.  * </p>
  54.  * 
  55.  * <P>
  56.  * For maximum portability, ResultSet columns within each row should be read in
  57.  * left-to-right order and each column should be read only once.
  58.  * </p>
  59.  * 
  60.  * <P>
  61.  * For the getXXX methods, the JDBC driver attempts to convert the underlying
  62.  * data to the specified Java type and returns a suitable Java value.  See the
  63.  * JDBC specification for allowable mappings from SQL types to Java types with
  64.  * the ResultSet getXXX methods.
  65.  * </p>
  66.  * 
  67.  * <P>
  68.  * Column names used as input to getXXX methods are case insenstive.  When
  69.  * performing a getXXX using a column name, if several columns have the same
  70.  * name, then the value of the first matching column will be returned.  The
  71.  * column name option is designed to be used when column names are used in the
  72.  * SQL Query.  For columns that are NOT explicitly named in the query, it is
  73.  * best to use column numbers.  If column names were used there is no way for
  74.  * the programmer to guarentee that they actually refer to the intended
  75.  * columns.
  76.  * </p>
  77.  * 
  78.  * <P>
  79.  * A ResultSet is automatically closed by the Statement that generated it when
  80.  * that Statement is closed, re-executed, or is used to retrieve the next
  81.  * result from a sequence of multiple results.
  82.  * </p>
  83.  * 
  84.  * <P>
  85.  * The number, types and properties of a ResultSet's columns are provided by
  86.  * the ResultSetMetaData object returned by the getMetaData method.
  87.  * </p>
  88.  *
  89.  * @author Mark Matthews
  90.  * @version $Id: ResultSet.java,v 1.18.2.25 2004/02/06 00:55:37 mmatthew Exp $
  91.  *
  92.  * @see ResultSetMetaData
  93.  * @see java.sql.ResultSet
  94.  */
  95. public class ResultSet implements java.sql.ResultSet {
  96.     /**
  97.      * This method ends up being staticly synchronized, so just store our own
  98.      * copy....
  99.      */
  100.     private TimeZone defaultTimeZone;
  101.     /** The Connection instance that created us */
  102.     protected com.mysql.jdbc.Connection connection; // The connection that created us
  103.     /** Map column names (and all of their permutations) to column indices */
  104.     protected Map columnNameToIndex = null;
  105.     /** Map of fully-specified column names to column indices */
  106.     protected Map fullColumnNameToIndex = null;
  107.     /** The actual rows */
  108.     protected RowData rowData; // The results
  109.     /** The warning chain */
  110.     protected java.sql.SQLWarning warningChain = null;
  111.     /** The statement that created us */
  112.     protected com.mysql.jdbc.Statement owningStatement;
  113.     /** The catalog that was in use when we were created */
  114.     protected String catalog = null;
  115.     /**
  116.      * Any info message from the server that was created while generating this
  117.      * result set (if 'info parsing'  is enabled for the connection).
  118.      */
  119.     protected String serverInfo = null;
  120.     /** The fields for this result set */
  121.     protected Field[] fields; // The fields
  122.     /** Pointer to current row data */
  123.     protected byte[][] thisRow; // Values for current row
  124.     /** Are we in the middle of doing updates to the current row? */
  125.     protected boolean doingUpdates = false;
  126.     /** Has this result set been closed? */
  127.     protected boolean isClosed = false;
  128.     /** Are we on the insert row? */
  129.     protected boolean onInsertRow = false;
  130.     /**
  131.      * Do we actually contain rows, or just information about
  132.      * UPDATE/INSERT/DELETE?
  133.      */
  134.     protected boolean reallyResult = false;
  135.     /** Did the previous value retrieval find a NULL? */
  136.     protected boolean wasNullFlag = false;
  137.     /**
  138.      * First character of the query that created this result set...Used to
  139.      * determine whether or not to parse server info messages in certain
  140.      * circumstances.
  141.      */
  142.     protected char firstCharOfQuery;
  143.     /** The current row #, -1 == before start of result set */
  144.     protected int currentRow = -1; // Cursor to current row;
  145.     /** The direction to fetch rows (always FETCH_FORWARD) */
  146.     protected int fetchDirection = FETCH_FORWARD;
  147.     /** The number of rows to fetch in one go... */
  148.     protected int fetchSize = 0;
  149.     /** Are we read-only or updatable? */
  150.     protected int resultSetConcurrency = 0;
  151.     /** Are we scroll-sensitive/insensitive? */
  152.     protected int resultSetType = 0;
  153.     /** How many rows were affected by UPDATE/INSERT/DELETE? */
  154.     protected long updateCount;
  155.     // These are longs for
  156.     // recent versions of the MySQL server.
  157.     //
  158.     // They get reduced to ints via the JDBC API,
  159.     // but can be retrieved through a MySQLStatement
  160.     // in their entirety.
  161.     //
  162.     /** Value generated for AUTO_INCREMENT columns */
  163.     protected long updateId = -1;
  164.     private Calendar fastDateCal = null;
  165.     private boolean hasBuiltIndexMapping = false;
  166.     private boolean useStrictFloatingPoint = false;
  167.     /**
  168.      * Create a result set for an executeUpdate statement.
  169.      *
  170.      * @param updateCount the number of rows affected by the update
  171.      * @param updateID the autoincrement value (if any)
  172.      */
  173.     public ResultSet(long updateCount, long updateID) {
  174.         this.updateCount = updateCount;
  175.         this.updateId = updateID;
  176.         reallyResult = false;
  177.         fields = new Field[0];
  178.     }
  179.     /**
  180.      * Create a new ResultSet
  181.      *
  182.      * @param catalog the database in use when we were created
  183.      * @param fields an array of Field objects (basically, the ResultSet
  184.      *        MetaData)
  185.      * @param tuples actual row data
  186.      * @param conn the Connection that created us.
  187.      *
  188.      * @throws SQLException if an error occurs
  189.      */
  190.     public ResultSet(String catalog, Field[] fields, RowData tuples,
  191.         com.mysql.jdbc.Connection conn) throws SQLException {
  192.         this(fields, tuples);
  193.         setConnection(conn);
  194.         this.catalog = catalog;
  195.         
  196.     }
  197.     /**
  198.      * Creates a new ResultSet object.
  199.      *
  200.      * @param fields DOCUMENT ME!
  201.      * @param tuples DOCUMENT ME!
  202.      *
  203.      * @throws SQLException DOCUMENT ME!
  204.      */
  205.     public ResultSet(Field[] fields, RowData tuples) throws SQLException {
  206.         //_currentRow   = -1;
  207.         this.fields = fields;
  208.         this.rowData = tuples;
  209.         this.updateCount = (long) rowData.size();
  210.         if (Driver.DEBUG) {
  211.             System.out.println("Retrieved " + updateCount + " rows");
  212.         }
  213.         this.reallyResult = true;
  214.         // Check for no results
  215.         if (this.rowData.size() > 0) {
  216.             //_thisRow = _rows.next();
  217.             if (this.updateCount == 1) {
  218.                 if (this.thisRow == null) {
  219.                     //_currentRow = -1;
  220.                     this.rowData.close(); // empty result set
  221.                     this.updateCount = -1;
  222.                 }
  223.             }
  224.         } else {
  225.             this.thisRow = null;
  226.         }
  227.         this.rowData.setOwner(this);
  228.     }
  229.     /**
  230.      * JDBC 2.0
  231.      * 
  232.      * <p>
  233.      * Determine if the cursor is after the last row in the result set.
  234.      * </p>
  235.      *
  236.      * @return true if after the last row, false otherwise.  Returns false when
  237.      *         the result set contains no rows.
  238.      *
  239.      * @exception SQLException if a database-access error occurs.
  240.      */
  241.     public boolean isAfterLast() throws SQLException {
  242.         if (Driver.TRACE) {
  243.             Object[] args = {  };
  244.             Debug.methodCall(this, "isAfterLast", args);
  245.         }
  246.         boolean b = rowData.isAfterLast();
  247.         if (Driver.TRACE) {
  248.             Debug.returnValue(this, "isAfterLast", new Boolean(b));
  249.         }
  250.         return b;
  251.     }
  252.     /**
  253.      * JDBC 2.0 Get an array column.
  254.      *
  255.      * @param i the first column is 1, the second is 2, ...
  256.      *
  257.      * @return an object representing an SQL array
  258.      *
  259.      * @throws SQLException if a database error occurs
  260.      * @throws NotImplemented DOCUMENT ME!
  261.      */
  262.     public java.sql.Array getArray(int i) throws SQLException {
  263.         throw new NotImplemented();
  264.     }
  265.     /**
  266.      * JDBC 2.0 Get an array column.
  267.      *
  268.      * @param colName the column name
  269.      *
  270.      * @return an object representing an SQL array
  271.      *
  272.      * @throws SQLException if a database error occurs
  273.      * @throws NotImplemented DOCUMENT ME!
  274.      */
  275.     public java.sql.Array getArray(String colName) throws SQLException {
  276.         throw new NotImplemented();
  277.     }
  278.     /**
  279.      * A column value can be retrieved as a stream of ASCII characters and then
  280.      * read in chunks from the stream.  This method is particulary suitable
  281.      * for retrieving large LONGVARCHAR values. The JDBC driver will do any
  282.      * necessary conversion from the database format into ASCII.
  283.      * 
  284.      * <p>
  285.      * <B>Note:</B> All the data in the returned stream must be read prior to
  286.      * getting the value of any other column.  The next call to a get method
  287.      * implicitly closes the stream.  Also, a stream may return 0 for
  288.      * available() whether there is data available or not.
  289.      * </p>
  290.      *
  291.      * @param columnIndex the first column is 1, the second is 2, ...
  292.      *
  293.      * @return a Java InputStream that delivers the database column value as a
  294.      *         stream of one byte ASCII characters.  If the value is SQL NULL
  295.      *         then the result is null
  296.      *
  297.      * @exception java.sql.SQLException if a database access error occurs
  298.      *
  299.      * @see getBinaryStream
  300.      */
  301.     public InputStream getAsciiStream(int columnIndex)
  302.         throws java.sql.SQLException {
  303.         checkRowPos();
  304.         return getBinaryStream(columnIndex);
  305.     }
  306.     /**
  307.      * DOCUMENT ME!
  308.      *
  309.      * @param columnName DOCUMENT ME!
  310.      *
  311.      * @return DOCUMENT ME!
  312.      *
  313.      * @throws java.sql.SQLException DOCUMENT ME!
  314.      */
  315.     public InputStream getAsciiStream(String columnName)
  316.         throws java.sql.SQLException {
  317.         return getAsciiStream(findColumn(columnName));
  318.     }
  319.     //---------------------------------------------------------------------
  320.     // Traversal/Positioning
  321.     //---------------------------------------------------------------------
  322.     /**
  323.      * JDBC 2.0
  324.      * 
  325.      * <p>
  326.      * Determine if the cursor is before the first row in the result set.
  327.      * </p>
  328.      *
  329.      * @return true if before the first row, false otherwise. Returns false
  330.      *         when the result set contains no rows.
  331.      *
  332.      * @exception SQLException if a database-access error occurs.
  333.      */
  334.     public boolean isBeforeFirst() throws SQLException {
  335.         if (Driver.TRACE) {
  336.             Object[] args = {  };
  337.             Debug.methodCall(this, "isBeforeFirst", args);
  338.         }
  339.         boolean b = rowData.isBeforeFirst();
  340.         if (Driver.TRACE) {
  341.             Debug.returnValue(this, "isBeforeFirst", new Boolean(b));
  342.         }
  343.         return b;
  344.     }
  345.     /**
  346.      * Get the value of a column in the current row as a java.math.BigDecimal
  347.      * object
  348.      *
  349.      * @param columnIndex the first column is 1, the second is 2...
  350.      * @param scale the number of digits to the right of the decimal
  351.      *
  352.      * @return the column value; if the value is SQL NULL, null
  353.      *
  354.      * @exception java.sql.SQLException if a database access error occurs
  355.      */
  356.     public BigDecimal getBigDecimal(int columnIndex, int scale)
  357.         throws java.sql.SQLException {
  358.         String stringVal = getString(columnIndex);
  359.         BigDecimal val;
  360.         if (stringVal != null) {
  361.             if (stringVal.length() == 0) {
  362.                 val = new BigDecimal(0);
  363.                 return val.setScale(scale);
  364.             }
  365.             try {
  366.                 val = new BigDecimal(stringVal);
  367.             } catch (NumberFormatException ex) {
  368.                 throw new java.sql.SQLException("Bad format for BigDecimal '"
  369.                     + stringVal + "' in column " + columnIndex + "("
  370.                     + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  371.             }
  372.             try {
  373.                 return val.setScale(scale);
  374.             } catch (ArithmeticException ex) {
  375.                 throw new java.sql.SQLException("Bad format for BigDecimal '"
  376.                     + stringVal + "' in column " + columnIndex + "("
  377.                     + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  378.             }
  379.         }
  380.         return null;
  381.     }
  382.     /**
  383.      * DOCUMENT ME!
  384.      *
  385.      * @param columnName DOCUMENT ME!
  386.      * @param scale DOCUMENT ME!
  387.      *
  388.      * @return DOCUMENT ME!
  389.      *
  390.      * @throws java.sql.SQLException DOCUMENT ME!
  391.      */
  392.     public BigDecimal getBigDecimal(String columnName, int scale)
  393.         throws java.sql.SQLException {
  394.         return getBigDecimal(findColumn(columnName), scale);
  395.     }
  396.     /**
  397.      * JDBC 2.0 Get the value of a column in the current row as a
  398.      * java.math.BigDecimal object.
  399.      *
  400.      * @param columnIndex the first column is 1, the second is 2, ...
  401.      *
  402.      * @return the column value (full precision); if the value is SQL NULL, the
  403.      *         result is null
  404.      *
  405.      * @exception SQLException if a database-access error occurs.
  406.      * @throws java.sql.SQLException DOCUMENT ME!
  407.      */
  408.     public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
  409.         String stringVal = getString(columnIndex);
  410.         BigDecimal val;
  411.         if (stringVal != null) {
  412.             if (stringVal.length() == 0) {
  413.                 val = new BigDecimal(0);
  414.                 return val;
  415.             }
  416.             try {
  417.                 val = new BigDecimal(stringVal);
  418.                 return val;
  419.             } catch (NumberFormatException ex) {
  420.                 throw new java.sql.SQLException("Bad format for BigDecimal '"
  421.                     + stringVal + "' in column " + columnIndex + "("
  422.                     + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  423.             }
  424.         }
  425.         return null;
  426.     }
  427.     /**
  428.      * JDBC 2.0 Get the value of a column in the current row as a
  429.      * java.math.BigDecimal object.
  430.      *
  431.      * @param columnName the name of the column to retrieve the value from
  432.      *
  433.      * @return the BigDecimal value in the column
  434.      *
  435.      * @throws SQLException if an error occurs
  436.      */
  437.     public BigDecimal getBigDecimal(String columnName)
  438.         throws SQLException {
  439.         return getBigDecimal(findColumn(columnName));
  440.     }
  441.     /**
  442.      * A column value can also be retrieved as a binary strea.  This method is
  443.      * suitable for retrieving LONGVARBINARY values.
  444.      *
  445.      * @param columnIndex the first column is 1, the second is 2...
  446.      *
  447.      * @return a Java InputStream that delivers the database column value as a
  448.      *         stream of bytes.  If the value is SQL NULL, then the result is
  449.      *         null
  450.      *
  451.      * @exception java.sql.SQLException if a database access error occurs
  452.      *
  453.      * @see getAsciiStream
  454.      * @see getUnicodeStream
  455.      */
  456.     public InputStream getBinaryStream(int columnIndex)
  457.         throws java.sql.SQLException {
  458.         checkRowPos();
  459.         byte[] b = getBytes(columnIndex);
  460.         if (b != null) {
  461.             return new ByteArrayInputStream(b);
  462.         }
  463.         return null;
  464.     }
  465.     /**
  466.      * DOCUMENT ME!
  467.      *
  468.      * @param columnName DOCUMENT ME!
  469.      *
  470.      * @return DOCUMENT ME!
  471.      *
  472.      * @throws java.sql.SQLException DOCUMENT ME!
  473.      */
  474.     public InputStream getBinaryStream(String columnName)
  475.         throws java.sql.SQLException {
  476.         return getBinaryStream(findColumn(columnName));
  477.     }
  478.     /**
  479.      * JDBC 2.0 Get a BLOB column.
  480.      *
  481.      * @param columnIndex the first column is 1, the second is 2, ...
  482.      *
  483.      * @return an object representing a BLOB
  484.      *
  485.      * @throws SQLException if an error occurs.
  486.      * @throws java.sql.SQLException DOCUMENT ME!
  487.      */
  488.     public java.sql.Blob getBlob(int columnIndex) throws SQLException {
  489.         checkRowPos();
  490.         if ((columnIndex < 1) || (columnIndex > fields.length)) {
  491.             throw new java.sql.SQLException("Column Index out of range ( "
  492.                 + columnIndex + " > " + fields.length + ").", SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
  493.         }
  494.         try {
  495.             if (thisRow[columnIndex - 1] == null) {
  496.                 wasNullFlag = true;
  497.             } else {
  498.                 wasNullFlag = false;
  499.             }
  500.         } catch (NullPointerException ex) {
  501.             wasNullFlag = true;
  502.         }
  503.         if (wasNullFlag) {
  504.             return null;
  505.         }
  506.         return new Blob(thisRow[columnIndex - 1]);
  507.     }
  508.     /**
  509.      * JDBC 2.0 Get a BLOB column.
  510.      *
  511.      * @param colName the column name
  512.      *
  513.      * @return an object representing a BLOB
  514.      *
  515.      * @throws SQLException if an error occurs.
  516.      */
  517.     public java.sql.Blob getBlob(String colName) throws SQLException {
  518.         return getBlob(findColumn(colName));
  519.     }
  520.     /**
  521.      * Get the value of a column in the current row as a Java boolean
  522.      *
  523.      * @param columnIndex the first column is 1, the second is 2...
  524.      *
  525.      * @return the column value, false for SQL NULL
  526.      *
  527.      * @exception java.sql.SQLException if a database access error occurs
  528.      */
  529.     public boolean getBoolean(int columnIndex) throws java.sql.SQLException {
  530.         String stringVal = getString(columnIndex);
  531.         if ((stringVal != null) && (stringVal.length() > 0)) {
  532.             int c = Character.toLowerCase(stringVal.charAt(0));
  533.             return ((c == 't') || (c == 'y') || (c == '1')
  534.             || stringVal.equals("-1"));
  535.         }
  536.         return false;
  537.     }
  538.     /**
  539.      * DOCUMENT ME!
  540.      *
  541.      * @param columnName DOCUMENT ME!
  542.      *
  543.      * @return DOCUMENT ME!
  544.      *
  545.      * @throws java.sql.SQLException DOCUMENT ME!
  546.      */
  547.     public boolean getBoolean(String columnName) throws java.sql.SQLException {
  548.         return getBoolean(findColumn(columnName));
  549.     }
  550.     /**
  551.      * Get the value of a column in the current row as a Java byte.
  552.      *
  553.      * @param columnIndex the first column is 1, the second is 2,...
  554.      *
  555.      * @return the column value; 0 if SQL NULL
  556.      *
  557.      * @exception java.sql.SQLException if a database access error occurs
  558.      * @throws SQLException DOCUMENT ME!
  559.      */
  560.     public byte getByte(int columnIndex) throws java.sql.SQLException {
  561.         checkRowPos();
  562.         try {
  563.             if (thisRow[columnIndex - 1] == null) {
  564.                 wasNullFlag = true;
  565.             } else {
  566.                 wasNullFlag = false;
  567.             }
  568.         } catch (NullPointerException E) {
  569.             wasNullFlag = true;
  570.         }
  571.         if (wasNullFlag) {
  572.             return 0;
  573.         }
  574.         Field field = fields[columnIndex - 1];
  575.         switch (field.getMysqlType()) {
  576.         case MysqlDefs.FIELD_TYPE_DECIMAL:
  577.         case MysqlDefs.FIELD_TYPE_TINY:
  578.         case MysqlDefs.FIELD_TYPE_SHORT:
  579.         case MysqlDefs.FIELD_TYPE_LONG:
  580.         case MysqlDefs.FIELD_TYPE_FLOAT:
  581.         case MysqlDefs.FIELD_TYPE_DOUBLE:
  582.         case MysqlDefs.FIELD_TYPE_LONGLONG:
  583.         case MysqlDefs.FIELD_TYPE_INT24:
  584.             try {
  585.                 String stringVal = getString(columnIndex);
  586.                 int decimalIndex = stringVal.indexOf(".");
  587.                 // Strip off the decimals
  588.                 if (decimalIndex != -1) {
  589.                     stringVal = stringVal.substring(0, decimalIndex);
  590.                 }
  591.                 return Byte.parseByte(stringVal);
  592.             } catch (NumberFormatException NFE) {
  593.                 throw new SQLException("Value '" + getString(columnIndex)
  594.                     + "' is out of range [-127,127]", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  595.             }
  596.         default:
  597.             try {
  598.                 String stringVal = getString(columnIndex);
  599.                 int decimalIndex = stringVal.indexOf(".");
  600.                 // Strip off the decimals
  601.                 if (decimalIndex != -1) {
  602.                     stringVal = stringVal.substring(0, decimalIndex);
  603.                 }
  604.                 return Byte.parseByte(stringVal);
  605.             } catch (NumberFormatException NFE) {
  606.                 throw new SQLException("Value '" + getString(columnIndex)
  607.                     + "' is out of range [-127,127]", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  608.             }
  609.             // FIXME: JDBC-Compliance test is broken, wants to convert string->byte(num)
  610.             //return _thisRow[columnIndex - 1][0];
  611.         }
  612.     }
  613.     /**
  614.      * DOCUMENT ME!
  615.      *
  616.      * @param columnName DOCUMENT ME!
  617.      *
  618.      * @return DOCUMENT ME!
  619.      *
  620.      * @throws java.sql.SQLException DOCUMENT ME!
  621.      */
  622.     public byte getByte(String columnName) throws java.sql.SQLException {
  623.         return getByte(findColumn(columnName));
  624.     }
  625.     /**
  626.      * Get the value of a column in the current row as a Java byte array.
  627.      * 
  628.      * <p>
  629.      * <b>Be warned</b> If the blob is huge, then you may run out of memory.
  630.      * </p>
  631.      *
  632.      * @param columnIndex the first column is 1, the second is 2, ...
  633.      *
  634.      * @return the column value; if the value is SQL NULL, the result is null
  635.      *
  636.      * @exception java.sql.SQLException if a database access error occurs
  637.      */
  638.     public byte[] getBytes(int columnIndex) throws java.sql.SQLException {
  639.         checkRowPos();
  640.         try {
  641.             if (thisRow[columnIndex - 1] == null) {
  642.                 wasNullFlag = true;
  643.             } else {
  644.                 wasNullFlag = false;
  645.             }
  646.         } catch (NullPointerException E) {
  647.             wasNullFlag = true;
  648.         } catch (ArrayIndexOutOfBoundsException aioobEx) {
  649.             throw new java.sql.SQLException("Column Index out of range ( "
  650.                 + columnIndex + " > " + fields.length + ").", SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
  651.         }
  652.         if (wasNullFlag) {
  653.             return null;
  654.         } else {
  655.             return thisRow[columnIndex - 1];
  656.         }
  657.     }
  658.     /**
  659.      * DOCUMENT ME!
  660.      *
  661.      * @param columnName DOCUMENT ME!
  662.      *
  663.      * @return DOCUMENT ME!
  664.      *
  665.      * @throws java.sql.SQLException DOCUMENT ME!
  666.      */
  667.     public byte[] getBytes(String columnName) throws java.sql.SQLException {
  668.         return getBytes(findColumn(columnName));
  669.     }
  670.     //--------------------------JDBC 2.0-----------------------------------
  671.     //---------------------------------------------------------------------
  672.     // Getter's and Setter's
  673.     //---------------------------------------------------------------------
  674.     /**
  675.      * JDBC 2.0
  676.      * 
  677.      * <p>
  678.      * Get the value of a column in the current row as a java.io.Reader.
  679.      * </p>
  680.      *
  681.      * @param columnIndex the column to get the value from
  682.      *
  683.      * @return the value in the column as a java.io.Reader.
  684.      *
  685.      * @throws SQLException if an error occurs
  686.      */
  687.     public java.io.Reader getCharacterStream(int columnIndex)
  688.         throws SQLException {
  689.         String stringVal = getString(columnIndex);
  690.         if (stringVal != null) {
  691.             return new StringReader(stringVal);
  692.         } else {
  693.             return null;
  694.         }
  695.     }
  696.     /**
  697.      * JDBC 2.0
  698.      * 
  699.      * <p>
  700.      * Get the value of a column in the current row as a java.io.Reader.
  701.      * </p>
  702.      *
  703.      * @param columnName the column name to retrieve the value from
  704.      *
  705.      * @return the value as a java.io.Reader
  706.      *
  707.      * @throws SQLException if an error occurs
  708.      */
  709.     public java.io.Reader getCharacterStream(String columnName)
  710.         throws SQLException {
  711.         return getCharacterStream(findColumn(columnName));
  712.     }
  713.     /**
  714.      * JDBC 2.0 Get a CLOB column.
  715.      *
  716.      * @param i the first column is 1, the second is 2, ...
  717.      *
  718.      * @return an object representing a CLOB
  719.      *
  720.      * @throws SQLException if an error occurs
  721.      */
  722.     public java.sql.Clob getClob(int i) throws SQLException {
  723.         return new com.mysql.jdbc.Clob(getString(i));
  724.     }
  725.     /**
  726.      * JDBC 2.0 Get a CLOB column.
  727.      *
  728.      * @param colName the column name
  729.      *
  730.      * @return an object representing a CLOB
  731.      *
  732.      * @throws SQLException if an error occurs
  733.      */
  734.     public java.sql.Clob getClob(String colName) throws SQLException {
  735.         return getClob(findColumn(colName));
  736.     }
  737.     /**
  738.      * JDBC 2.0 Return the concurrency of this result set.  The concurrency
  739.      * used is determined by the statement that created the result set.
  740.      *
  741.      * @return the concurrency type, CONCUR_READ_ONLY, etc.
  742.      *
  743.      * @throws SQLException if a database-access error occurs
  744.      */
  745.     public int getConcurrency() throws SQLException {
  746.         return (CONCUR_READ_ONLY);
  747.     }
  748.     /**
  749.      * DOCUMENT ME!
  750.      *
  751.      * @param conn the connection that created this result set.
  752.      */
  753.     public void setConnection(com.mysql.jdbc.Connection conn) {
  754.         this.connection = conn;
  755. if (this.connection != null) {
  756. this.useStrictFloatingPoint = this.connection.useStrictFloatingPoint();
  757. this.defaultTimeZone = this.connection.getDefaultTimeZone();
  758. } else {
  759. this.defaultTimeZone = TimeZone.getDefault();
  760. }
  761.     }
  762.     /**
  763.      * Get the name of the SQL cursor used by this ResultSet
  764.      * 
  765.      * <p>
  766.      * In SQL, a result table is retrieved though a cursor that is named.  The
  767.      * current row of a result can be updated or deleted using a positioned
  768.      * update/delete statement that references the cursor name.
  769.      * </p>
  770.      * 
  771.      * <p>
  772.      * JDBC supports this SQL feature by providing the name of the SQL cursor
  773.      * used by a ResultSet.  The current row of a ResulSet is also the current
  774.      * row of this SQL cursor.
  775.      * </p>
  776.      * 
  777.      * <p>
  778.      * <B>Note:</B> If positioned update is not supported, a
  779.      * java.sql.SQLException is thrown.
  780.      * </p>
  781.      *
  782.      * @return the ResultSet's SQL cursor name.
  783.      *
  784.      * @exception java.sql.SQLException if a database access error occurs
  785.      */
  786.     public String getCursorName() throws java.sql.SQLException {
  787.         throw new java.sql.SQLException("Positioned Update not supported.",
  788.             "S1C00");
  789.     }
  790.     /**
  791.      * Get the value of a column in the current row as a java.sql.Date object
  792.      *
  793.      * @param columnIndex the first column is 1, the second is 2...
  794.      *
  795.      * @return the column value; null if SQL NULL
  796.      *
  797.      * @exception java.sql.SQLException if a database access error occurs
  798.      */
  799.     public java.sql.Date getDate(int columnIndex) throws java.sql.SQLException {
  800.         return getDate(columnIndex, null);
  801.     }
  802.     /**
  803.      * DOCUMENT ME!
  804.      *
  805.      * @param columnName DOCUMENT ME!
  806.      *
  807.      * @return DOCUMENT ME!
  808.      *
  809.      * @throws java.sql.SQLException DOCUMENT ME!
  810.      */
  811.     public java.sql.Date getDate(String columnName)
  812.         throws java.sql.SQLException {
  813.         return getDate(findColumn(columnName));
  814.     }
  815.     /**
  816.      * JDBC 2.0 Get the value of a column in the current row as a java.sql.Date
  817.      * object.  Use the calendar to construct an appropriate millisecond value
  818.      * for the Date, if the underlying database doesn't store timezone
  819.      * information.
  820.      *
  821.      * @param columnIndex the first column is 1, the second is 2, ...
  822.      * @param cal the calendar to use in constructing the date
  823.      *
  824.      * @return the column value; if the value is SQL NULL, the result is null
  825.      *
  826.      * @exception SQLException if a database-access error occurs.
  827.      * @throws java.sql.SQLException DOCUMENT ME!
  828.      */
  829.     public java.sql.Date getDate(int columnIndex, Calendar cal)
  830.         throws SQLException {
  831.         Integer year = null;
  832.         Integer month = null;
  833.         Integer day = null;
  834.         String stringVal = "";
  835.         try {
  836.             stringVal = getString(columnIndex);
  837.             if (stringVal == null) {
  838.                 return null;
  839.             } else {
  840.                 int length = stringVal.length();
  841.                 if ((length > 0) && (stringVal.charAt(0) == '0')
  842.                         && (stringVal.equals("0000-00-00")
  843.                         || stringVal.equals("0000-00-00 00:00:00")
  844.                         || stringVal.equals("00000000000000")
  845.                         || stringVal.equals("0"))) {
  846.                     wasNullFlag = true;
  847.                     return null;
  848.                 } else if (fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_TIMESTAMP) {
  849.                     // Convert from TIMESTAMP
  850.                     switch (length) {
  851.                     case 14:
  852.                     case 8: {
  853.                         year = new Integer(stringVal.substring(0, 4));
  854.                         month = new Integer(stringVal.substring(4, 6));
  855.                         day = new Integer(stringVal.substring(6, 8));
  856.                         return fastDateCreate(cal, year.intValue() - 1900,
  857.                             month.intValue() - 1, day.intValue());
  858.                     }
  859.                     case 12:
  860.                     case 10:
  861.                     case 6: {
  862.                         year = new Integer(stringVal.substring(0, 2));
  863.                         if (year.intValue() <= 69) {
  864.                             year = new Integer(year.intValue() + 100);
  865.                         }
  866.                         month = new Integer(stringVal.substring(2, 4));
  867.                         day = new Integer(stringVal.substring(4, 6));
  868.                         return fastDateCreate(cal, year.intValue(),
  869.                             month.intValue() - 1, day.intValue());
  870.                     }
  871.                     case 4: {
  872.                         year = new Integer(stringVal.substring(0, 4));
  873.                         if (year.intValue() <= 69) {
  874.                             year = new Integer(year.intValue() + 100);
  875.                         }
  876.                         month = new Integer(stringVal.substring(2, 4));
  877.                         return fastDateCreate(cal, year.intValue(),
  878.                             month.intValue() - 1, 1);
  879.                     }
  880.                     case 2: {
  881.                         year = new Integer(stringVal.substring(0, 2));
  882.                         if (year.intValue() <= 69) {
  883.                             year = new Integer(year.intValue() + 100);
  884.                         }
  885.                         return fastDateCreate(cal, year.intValue(), 0, 1);
  886.                     }
  887.                     default:
  888.                         throw new SQLException("Bad format for Date '"
  889.                             + stringVal + "' in column " + columnIndex + "("
  890.                             + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  891.                     } /* endswitch */
  892.                 } else if (fields[columnIndex - 1].getMysqlType() == MysqlDefs.FIELD_TYPE_YEAR) {
  893.                     year = new Integer(stringVal.substring(0, 4));
  894.                     return fastDateCreate(cal, year.intValue() - 1900, 0, 1);
  895.                 } else {
  896.                     if (length < 10) {
  897.                         throw new SQLException("Bad format for Date '"
  898.                             + stringVal + "' in column " + columnIndex + "("
  899.                             + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  900.                     }
  901.                     year = new Integer(stringVal.substring(0, 4));
  902.                     month = new Integer(stringVal.substring(5, 7));
  903.                     day = new Integer(stringVal.substring(8, 10));
  904.                 }
  905.                 return fastDateCreate(cal, year.intValue() - 1900,
  906.                     month.intValue() - 1, day.intValue());
  907.             }
  908.         } catch (Exception e) {
  909.             throw new java.sql.SQLException("Cannot convert value '"
  910.                 + stringVal + "' from column " + columnIndex + "(" + stringVal
  911.                 + " ) to DATE.", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  912.         }
  913.     }
  914.     /**
  915.      * Get the value of a column in the current row as a java.sql.Date object.
  916.      * Use the calendar to construct an appropriate millisecond value for the
  917.      * Date, if the underlying database doesn't store timezone information.
  918.      *
  919.      * @param columnName is the SQL name of the column
  920.      * @param cal the calendar to use in constructing the date
  921.      *
  922.      * @return the column value; if the value is SQL NULL, the result is null
  923.      *
  924.      * @exception SQLException if a database-access error occurs.
  925.      */
  926.     public java.sql.Date getDate(String columnName, Calendar cal)
  927.         throws SQLException {
  928.         return getDate(columnName);
  929.     }
  930.     /**
  931.      * Get the value of a column in the current row as a Java double.
  932.      *
  933.      * @param columnIndex the first column is 1, the second is 2,...
  934.      *
  935.      * @return the column value; 0 if SQL NULL
  936.      *
  937.      * @exception java.sql.SQLException if a database access error occurs
  938.      */
  939.     public double getDouble(int columnIndex) throws java.sql.SQLException {
  940.         try {
  941.             return getDoubleInternal(columnIndex);
  942.         } catch (NumberFormatException E) {
  943.             throw new java.sql.SQLException("Bad format for number '"
  944.                 + new String(thisRow[columnIndex - 1]) + "' in column "
  945.                 + columnIndex + "(" + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  946.         }
  947.     }
  948.     /**
  949.      * DOCUMENT ME!
  950.      *
  951.      * @param columnName DOCUMENT ME!
  952.      *
  953.      * @return DOCUMENT ME!
  954.      *
  955.      * @throws java.sql.SQLException DOCUMENT ME!
  956.      */
  957.     public double getDouble(String columnName) throws java.sql.SQLException {
  958.         return getDouble(findColumn(columnName));
  959.     }
  960.     /**
  961.      * JDBC 2.0 Give a hint as to the direction in which the rows in this
  962.      * result set will be processed.  The initial value is determined by the
  963.      * statement that produced the result set.  The fetch direction may be
  964.      * changed at any time.
  965.      *
  966.      * @param direction the direction to fetch rows in.
  967.      *
  968.      * @exception SQLException if a database-access error occurs, or the result
  969.      *            set type is TYPE_FORWARD_ONLY and direction is not
  970.      *            FETCH_FORWARD. MM.MySQL actually ignores this, because it
  971.      *            has the whole result set anyway, so the direction is
  972.      *            immaterial.
  973.      */
  974.     public void setFetchDirection(int direction) throws SQLException {
  975.         if ((direction != FETCH_FORWARD) && (direction != FETCH_REVERSE)
  976.                 && (direction != FETCH_UNKNOWN)) {
  977.             throw new SQLException("Illegal value for fetch direction", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  978.         } else {
  979.             fetchDirection = direction;
  980.         }
  981.     }
  982.     /**
  983.      * JDBC 2.0 Returns the fetch direction for this result set.
  984.      *
  985.      * @return the fetch direction for this result set.
  986.      *
  987.      * @exception SQLException if a database-access error occurs
  988.      */
  989.     public int getFetchDirection() throws SQLException {
  990.         return fetchDirection;
  991.     }
  992.     /**
  993.      * JDBC 2.0 Give the JDBC driver a hint as to the number of rows that
  994.      * should be fetched from the database when more rows are needed for this
  995.      * result set.  If the fetch size specified is zero, then the JDBC driver
  996.      * ignores the value, and is free to make its own best guess as to what
  997.      * the fetch size should be.  The default value is set by the statement
  998.      * that creates the result set.  The fetch size may be changed at any
  999.      * time.
  1000.      *
  1001.      * @param rows the number of rows to fetch
  1002.      *
  1003.      * @exception SQLException if a database-access error occurs, or the
  1004.      *            condition 0 &lt;= rows &lt;= this.getMaxRows() is not
  1005.      *            satisfied. Currently ignored by this driver.
  1006.      */
  1007.     public void setFetchSize(int rows) throws SQLException {
  1008.         if (rows < 0) { /* || rows > getMaxRows()*/
  1009.             throw new SQLException("Value must be between 0 and getMaxRows()",
  1010.                 SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1011.         }
  1012.         fetchSize = rows;
  1013.     }
  1014.     /**
  1015.      * JDBC 2.0 Return the fetch size for this result set.
  1016.      *
  1017.      * @return the fetch size for this result set.
  1018.      *
  1019.      * @exception SQLException if a database-access error occurs
  1020.      */
  1021.     public int getFetchSize() throws SQLException {
  1022.         return fetchSize;
  1023.     }
  1024.     /**
  1025.      * JDBC 2.0
  1026.      * 
  1027.      * <p>
  1028.      * Determine if the cursor is on the first row of the result set.
  1029.      * </p>
  1030.      *
  1031.      * @return true if on the first row, false otherwise.
  1032.      *
  1033.      * @exception SQLException if a database-access error occurs.
  1034.      */
  1035.     public boolean isFirst() throws SQLException {
  1036.         if (Driver.TRACE) {
  1037.             Object[] args = {  };
  1038.             Debug.methodCall(this, "isFirst", args);
  1039.         }
  1040.         boolean b = rowData.isFirst();
  1041.         if (Driver.TRACE) {
  1042.             Debug.returnValue(this, "isFirst", new Boolean(b));
  1043.         }
  1044.         return b;
  1045.     }
  1046.     /**
  1047.      * Get the value of a column in the current row as a Java float.
  1048.      *
  1049.      * @param columnIndex the first column is 1, the second is 2,...
  1050.      *
  1051.      * @return the column value; 0 if SQL NULL
  1052.      *
  1053.      * @exception java.sql.SQLException if a database access error occurs
  1054.      * @throws SQLException DOCUMENT ME!
  1055.      */
  1056.     public float getFloat(int columnIndex) throws java.sql.SQLException {
  1057.         checkRowPos();
  1058.         String val = null;
  1059.         try {
  1060.             val = getString(columnIndex);
  1061.             if ((val != null) && (val.length() != 0)) {
  1062.                 float f = Float.parseFloat(val);
  1063.                 return f;
  1064.             } else {
  1065.                 return 0;
  1066.             }
  1067.         } catch (NumberFormatException nfe) {
  1068.             try {
  1069.                 // To do: warn on under/overflow?
  1070.                 return (float) Double.parseDouble(val);
  1071.             } catch (NumberFormatException newNfe) {
  1072.                 ; // ignore, it's not a number
  1073.             }
  1074.             throw new SQLException("Invalid value for getFloat() - '" + val
  1075.                 + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1076.         }
  1077.     }
  1078.     /**
  1079.      * DOCUMENT ME!
  1080.      *
  1081.      * @param columnName DOCUMENT ME!
  1082.      *
  1083.      * @return DOCUMENT ME!
  1084.      *
  1085.      * @throws java.sql.SQLException DOCUMENT ME!
  1086.      */
  1087.     public float getFloat(String columnName) throws java.sql.SQLException {
  1088.         return getFloat(findColumn(columnName));
  1089.     }
  1090.     /**
  1091.      * Get the value of a column in the current row as a Java int.
  1092.      *
  1093.      * @param columnIndex the first column is 1, the second is 2,...
  1094.      *
  1095.      * @return the column value; 0 if SQL NULL
  1096.      *
  1097.      * @exception java.sql.SQLException if a database access error occurs
  1098.      * @throws SQLException DOCUMENT ME!
  1099.      */
  1100.     public int getInt(int columnIndex) throws java.sql.SQLException {
  1101.         String val = null;
  1102.         try {
  1103.             val = getString(columnIndex);
  1104.             if ((val != null) && (val.length() != 0)) {
  1105.                 if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
  1106.                         && (val.indexOf(".") == -1)) {
  1107.                     return Integer.parseInt(val);
  1108.                 } else {
  1109.                     // Convert floating point
  1110.                     return (int) (Double.parseDouble(val));
  1111.                 }
  1112.             } else {
  1113.                 return 0;
  1114.             }
  1115.         } catch (NumberFormatException nfe) {
  1116.             try {
  1117.                 // To do: warn on under/overflow?
  1118.                 return (int) Double.parseDouble(val);
  1119.             } catch (NumberFormatException newNfe) {
  1120.                 ; // ignore, it's not a number
  1121.             }
  1122.             throw new SQLException("Invalid value for getInt() - '" + val + "'",
  1123.                 SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1124.         }
  1125.     }
  1126.     /**
  1127.      * DOCUMENT ME!
  1128.      *
  1129.      * @param columnName DOCUMENT ME!
  1130.      *
  1131.      * @return DOCUMENT ME!
  1132.      *
  1133.      * @throws java.sql.SQLException DOCUMENT ME!
  1134.      */
  1135.     public int getInt(String columnName) throws java.sql.SQLException {
  1136.         return getInt(findColumn(columnName));
  1137.     }
  1138.     /**
  1139.      * JDBC 2.0
  1140.      * 
  1141.      * <p>
  1142.      * Determine if the cursor is on the last row of the result set. Note:
  1143.      * Calling isLast() may be expensive since the JDBC driver might need to
  1144.      * fetch ahead one row in order to determine whether the current row is
  1145.      * the last row in the result set.
  1146.      * </p>
  1147.      *
  1148.      * @return true if on the last row, false otherwise.
  1149.      *
  1150.      * @exception SQLException if a database-access error occurs.
  1151.      */
  1152.     public boolean isLast() throws SQLException {
  1153.         if (Driver.TRACE) {
  1154.             Object[] args = {  };
  1155.             Debug.methodCall(this, "isLast", args);
  1156.         }
  1157.         boolean b = rowData.isLast();
  1158.         if (Driver.TRACE) {
  1159.             Debug.returnValue(this, "relative", new Boolean(b));
  1160.         }
  1161.         return b;
  1162.     }
  1163.     /**
  1164.      * Get the value of a column in the current row as a Java long.
  1165.      *
  1166.      * @param columnIndex the first column is 1, the second is 2,...
  1167.      *
  1168.      * @return the column value; 0 if SQL NULL
  1169.      *
  1170.      * @exception java.sql.SQLException if a database access error occurs
  1171.      * @throws SQLException DOCUMENT ME!
  1172.      */
  1173.     public long getLong(int columnIndex) throws java.sql.SQLException {
  1174.         checkRowPos();
  1175.         String val = null;
  1176.         try {
  1177.             val = getString(columnIndex);
  1178.             if ((val != null) && (val.length() != 0)) {
  1179.                 if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)) {
  1180.                     return Long.parseLong(val);
  1181.                 } else {
  1182.                     // Convert floating point
  1183.                     return Double.doubleToLongBits(Double.parseDouble(val));
  1184.                 }
  1185.             } else {
  1186.                 return 0;
  1187.             }
  1188.         } catch (NumberFormatException nfe) {
  1189.             try {
  1190.                 // To do: warn on under/overflow?
  1191.                 return (long) Double.parseDouble(val);
  1192.             } catch (NumberFormatException newNfe) {
  1193.                 ; // ignore, it's not a number
  1194.             }
  1195.             throw new SQLException("Invalid value for getLong() - '" + val
  1196.                 + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1197.         }
  1198.     }
  1199.     /**
  1200.      * DOCUMENT ME!
  1201.      *
  1202.      * @param columnName DOCUMENT ME!
  1203.      *
  1204.      * @return DOCUMENT ME!
  1205.      *
  1206.      * @throws java.sql.SQLException DOCUMENT ME!
  1207.      */
  1208.     public long getLong(String columnName) throws java.sql.SQLException {
  1209.         return getLong(findColumn(columnName));
  1210.     }
  1211.     /**
  1212.      * The numbers, types and properties of a ResultSet's columns are provided
  1213.      * by the getMetaData method
  1214.      *
  1215.      * @return a description of the ResultSet's columns
  1216.      *
  1217.      * @exception java.sql.SQLException if a database access error occurs
  1218.      */
  1219.     public java.sql.ResultSetMetaData getMetaData()
  1220.         throws java.sql.SQLException {
  1221.         return new com.mysql.jdbc.ResultSetMetaData(fields);
  1222.     }
  1223.     /**
  1224.      * Get the value of a column in the current row as a Java object
  1225.      * 
  1226.      * <p>
  1227.      * This method will return the value of the given column as a Java object.
  1228.      * The type of the Java object will be the default Java Object type
  1229.      * corresponding to the column's SQL type, following the mapping specified
  1230.      * in the JDBC specification.
  1231.      * </p>
  1232.      * 
  1233.      * <p>
  1234.      * This method may also be used to read database specific abstract data
  1235.      * types.
  1236.      * </p>
  1237.      *
  1238.      * @param columnIndex the first column is 1, the second is 2...
  1239.      *
  1240.      * @return a Object holding the column value
  1241.      *
  1242.      * @exception java.sql.SQLException if a database access error occurs
  1243.      * @throws SQLException DOCUMENT ME!
  1244.      */
  1245.     public Object getObject(int columnIndex) throws java.sql.SQLException {
  1246.         checkRowPos();
  1247.         if (Driver.TRACE) {
  1248.             Object[] args = { new Integer(columnIndex) };
  1249.             Debug.methodCall(this, "getObject", args);
  1250.         }
  1251.         try {
  1252.             if (thisRow[columnIndex - 1] == null) {
  1253.                 wasNullFlag = true;
  1254.                 return null;
  1255.             }
  1256.         } catch (ArrayIndexOutOfBoundsException aioobEx) {
  1257.             throw new java.sql.SQLException("Column Index out of range ( "
  1258.                 + columnIndex + " > " + fields.length + ").", SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
  1259.         }
  1260.         wasNullFlag = false;
  1261.         Field field;
  1262.         field = fields[columnIndex - 1];
  1263.         switch (field.getSQLType()) {
  1264.         case Types.BIT:
  1265.             return new Boolean(getBoolean(columnIndex));
  1266.         case Types.TINYINT:
  1267.             return new Integer(getInt(columnIndex));
  1268.            
  1269.         case Types.SMALLINT:
  1270.         
  1271.             return new Integer(getInt(columnIndex));
  1272.            
  1273.         case Types.INTEGER:
  1274.             if (field.isUnsigned()) {
  1275.                 return new Long(getLong(columnIndex));
  1276.             } else {
  1277.                 return new Integer(getInt(columnIndex));
  1278.             }
  1279.         case Types.BIGINT:
  1280.             if (field.isUnsigned()) {
  1281.                 return getBigDecimal(columnIndex);
  1282.             } else {
  1283.                 return new Long(getLong(columnIndex));
  1284.             }
  1285.         case Types.DECIMAL:
  1286.         case Types.NUMERIC:
  1287.             String stringVal = getString(columnIndex);
  1288.             BigDecimal val;
  1289.             if (stringVal != null) {
  1290.                 if (stringVal.length() == 0) {
  1291.                     val = new BigDecimal(0);
  1292.                     return val;
  1293.                 }
  1294.                 try {
  1295.                     val = new BigDecimal(stringVal);
  1296.                 } catch (NumberFormatException ex) {
  1297.                     throw new java.sql.SQLException(
  1298.                         "Bad format for BigDecimal '" + stringVal
  1299.                         + "' in column " + columnIndex + "("
  1300.                         + fields[columnIndex - 1] + ").", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1301.                 }
  1302.                 return val;
  1303.             } else {
  1304.                 return null;
  1305.             }
  1306.         case Types.REAL:
  1307.             return new Float(getFloat(columnIndex));
  1308.         case Types.FLOAT:
  1309.         case Types.DOUBLE:
  1310.             return new Double(getDouble(columnIndex));
  1311.         case Types.CHAR:
  1312.         case Types.VARCHAR:
  1313.         case Types.LONGVARCHAR:
  1314.             return getString(columnIndex);
  1315.         case Types.BINARY:
  1316.         case Types.VARBINARY:
  1317.         case Types.LONGVARBINARY:
  1318.             if (!field.isBlob()) {
  1319.                 return getString(columnIndex);
  1320.             } else if (!field.isBinary()) {
  1321.                 return getString(columnIndex);
  1322.             } else {
  1323.                 byte[] data = getBytes(columnIndex);
  1324.                 Object obj = data;
  1325.                 if ((data != null) && (data.length >= 2)) {
  1326.                     if ((data[0] == -84) && (data[1] == -19)) {
  1327.                         // Serialized object?
  1328.                         try {
  1329.                             ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
  1330.                             ObjectInputStream objIn = new ObjectInputStream(bytesIn);
  1331.                             obj = objIn.readObject();
  1332.                             objIn.close();
  1333.                             bytesIn.close();
  1334.                         } catch (ClassNotFoundException cnfe) {
  1335.                             throw new SQLException("Class not found: "
  1336.                                 + cnfe.toString()
  1337.                                 + " while reading serialized object");
  1338.                         } catch (IOException ex) {
  1339.                             obj = data; // not serialized?
  1340.                         }
  1341.                     }
  1342.                 }
  1343.                 return obj;
  1344.             }
  1345.         case Types.DATE:
  1346.             return getDate(columnIndex);
  1347.         case Types.TIME:
  1348.             return getTime(columnIndex);
  1349.         case Types.TIMESTAMP:
  1350.             return getTimestamp(columnIndex);
  1351.         default:
  1352.             return getString(columnIndex);
  1353.         }
  1354.     }
  1355.     /**
  1356.      * Get the value of a column in the current row as a Java object
  1357.      * 
  1358.      * <p>
  1359.      * This method will return the value of the given column as a Java object.
  1360.      * The type of the Java object will be the default Java Object type
  1361.      * corresponding to the column's SQL type, following the mapping specified
  1362.      * in the JDBC specification.
  1363.      * </p>
  1364.      * 
  1365.      * <p>
  1366.      * This method may also be used to read database specific abstract data
  1367.      * types.
  1368.      * </p>
  1369.      *
  1370.      * @param columnName is the SQL name of the column
  1371.      *
  1372.      * @return a Object holding the column value
  1373.      *
  1374.      * @exception java.sql.SQLException if a database access error occurs
  1375.      */
  1376.     public Object getObject(String columnName) throws java.sql.SQLException {
  1377.         return getObject(findColumn(columnName));
  1378.     }
  1379.     /**
  1380.      * JDBC 2.0 Returns the value of column i as a Java object.  Use the map to
  1381.      * determine the class from which to construct data of SQL structured and
  1382.      * distinct types.
  1383.      *
  1384.      * @param i the first column is 1, the second is 2, ...
  1385.      * @param map the mapping from SQL type names to Java classes
  1386.      *
  1387.      * @return an object representing the SQL value
  1388.      *
  1389.      * @throws SQLException because this is not implemented
  1390.      */
  1391.     public Object getObject(int i, java.util.Map map) throws SQLException {
  1392.         return getObject(i);
  1393.     }
  1394.     /**
  1395.      * JDBC 2.0 Returns the value of column i as a Java object.  Use the map to
  1396.      * determine the class from which to construct data of SQL structured and
  1397.      * distinct types.
  1398.      *
  1399.      * @param colName the column name
  1400.      * @param map the mapping from SQL type names to Java classes
  1401.      *
  1402.      * @return an object representing the SQL value
  1403.      *
  1404.      * @throws SQLException as this is not implemented
  1405.      */
  1406.     public Object getObject(String colName, java.util.Map map)
  1407.         throws SQLException {
  1408.         return getObject(findColumn(colName), map);
  1409.     }
  1410.     /**
  1411.      * JDBC 2.0 Get a REF(&lt;structured-type&gt;) column.
  1412.      *
  1413.      * @param i the first column is 1, the second is 2, ...
  1414.      *
  1415.      * @return an object representing data of an SQL REF type
  1416.      *
  1417.      * @throws SQLException as this is not implemented
  1418.      * @throws NotImplemented DOCUMENT ME!
  1419.      */
  1420.     public java.sql.Ref getRef(int i) throws SQLException {
  1421.         throw new NotImplemented();
  1422.     }
  1423.     /**
  1424.      * JDBC 2.0 Get a REF(&lt;structured-type&gt;) column.
  1425.      *
  1426.      * @param colName the column name
  1427.      *
  1428.      * @return an object representing data of an SQL REF type
  1429.      *
  1430.      * @throws SQLException as this method is not implemented.
  1431.      * @throws NotImplemented DOCUMENT ME!
  1432.      */
  1433.     public java.sql.Ref getRef(String colName) throws SQLException {
  1434.         throw new NotImplemented();
  1435.     }
  1436.     /**
  1437.      * JDBC 2.0
  1438.      * 
  1439.      * <p>
  1440.      * Determine the current row number.  The first row is number 1, the second
  1441.      * number 2, etc.
  1442.      * </p>
  1443.      *
  1444.      * @return the current row number, else return 0 if there is no current row
  1445.      *
  1446.      * @exception SQLException if a database-access error occurs.
  1447.      */
  1448.     public int getRow() throws SQLException {
  1449.         if (Driver.TRACE) {
  1450.             Object[] args = {  };
  1451.             Debug.methodCall(this, "getRow", args);
  1452.         }
  1453.         int currentRow = rowData.getCurrentRowNumber();
  1454.         int row = 0;
  1455.         // Non-dynamic result sets can be interrogated
  1456.         // for this information
  1457.         if (!rowData.isDynamic()) {
  1458.             if ((currentRow < 0) || rowData.isAfterLast() || rowData.isEmpty()) {
  1459.                 row = 0;
  1460.             } else {
  1461.                 row = currentRow + 1;
  1462.             }
  1463.         } else {
  1464.             // dynamic (streaming) can not
  1465.             row = currentRow + 1;
  1466.         }
  1467.         if (Driver.TRACE) {
  1468.             Debug.returnValue(this, "getRow", new Integer(row));
  1469.         }
  1470.         if (Driver.TRACE) {
  1471.             Debug.returnValue(this, "getRow", new Integer(row));
  1472.         }
  1473.         return row;
  1474.     }
  1475.     /**
  1476.      * Get the value of a column in the current row as a Java short.
  1477.      *
  1478.      * @param columnIndex the first column is 1, the second is 2,...
  1479.      *
  1480.      * @return the column value; 0 if SQL NULL
  1481.      *
  1482.      * @exception java.sql.SQLException if a database access error occurs
  1483.      * @throws SQLException DOCUMENT ME!
  1484.      */
  1485.     public short getShort(int columnIndex) throws java.sql.SQLException {
  1486.         checkRowPos();
  1487.         String val = null;
  1488.         try {
  1489.             val = getString(columnIndex);
  1490.             if ((val != null) && (val.length() != 0)) {
  1491.                 if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
  1492.                         && (val.indexOf(".") == -1)) {
  1493.                     return Short.parseShort(val);
  1494.                 } else {
  1495.                     // Convert floating point
  1496.                     return (short) (Double.parseDouble(val));
  1497.                 }
  1498.             } else {
  1499.                 return 0;
  1500.             }
  1501.         } catch (NumberFormatException nfe) {
  1502.             try {
  1503.                 // To do: warn on under/overflow?
  1504.                 return (short) Double.parseDouble(val);
  1505.             } catch (NumberFormatException newNfe) {
  1506.                 ; // ignore, it's not a number
  1507.             }
  1508.             throw new SQLException("Invalid value for getShort() - '" + val
  1509.                 + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1510.         }
  1511.     }
  1512.     /**
  1513.      * DOCUMENT ME!
  1514.      *
  1515.      * @param columnName DOCUMENT ME!
  1516.      *
  1517.      * @return DOCUMENT ME!
  1518.      *
  1519.      * @throws java.sql.SQLException DOCUMENT ME!
  1520.      */
  1521.     public short getShort(String columnName) throws java.sql.SQLException {
  1522.         return getShort(findColumn(columnName));
  1523.     }
  1524.     /**
  1525.      * JDBC 2.0 Return the Statement that produced the ResultSet.
  1526.      *
  1527.      * @return the Statment that produced the result set, or null if the result
  1528.      *         was produced some other way.
  1529.      *
  1530.      * @exception SQLException if a database-access error occurs
  1531.      */
  1532.     public java.sql.Statement getStatement() throws SQLException {
  1533.         return (java.sql.Statement) owningStatement;
  1534.     }
  1535.     /**
  1536.      * Get the value of a column in the current row as a Java String
  1537.      *
  1538.      * @param columnIndex the first column is 1, the second is 2...
  1539.      *
  1540.      * @return the column value, null for SQL NULL
  1541.      *
  1542.      * @exception java.sql.SQLException if a database access error occurs
  1543.      * @throws SQLException DOCUMENT ME!
  1544.      */
  1545.     public String getString(int columnIndex) throws java.sql.SQLException {
  1546.         checkRowPos();
  1547.         if (fields == null) {
  1548.             throw new java.sql.SQLException("Query generated no fields for ResultSet",
  1549.                 SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
  1550.         }
  1551.         try {
  1552.             if (thisRow[columnIndex - 1] == null) {
  1553.                 wasNullFlag = true;
  1554.                 return null;
  1555.             } else {
  1556.                 wasNullFlag = false;
  1557.             }
  1558.         } catch (NullPointerException E) {
  1559.             wasNullFlag = true;
  1560.             return null;
  1561.         } catch (ArrayIndexOutOfBoundsException aioobEx) {
  1562.             throw new java.sql.SQLException("Column Index out of range ( "
  1563.                 + columnIndex + " > " + fields.length + ").", SQLError.SQL_STATE_INVALID_COLUMN_NUMBER);
  1564.         }
  1565.         String stringVal = null;
  1566.         columnIndex--; // JDBC is 1-based, Java is not !?
  1567.         if ((connection != null) && connection.useUnicode()) {
  1568.             try {
  1569.                 String encoding = this.fields[columnIndex].getCharacterSet();
  1570.                 if (encoding == null) {
  1571.                     stringVal = new String(thisRow[columnIndex]);
  1572.                 } else {
  1573.                     SingleByteCharsetConverter converter = this.connection.getCharsetConverter(encoding);
  1574.                     if (converter != null) {
  1575.                         stringVal = converter.toString(thisRow[columnIndex]);
  1576.                     } else {
  1577.                         stringVal = new String(thisRow[columnIndex], encoding);
  1578.                     }
  1579.                 }
  1580.             } catch (java.io.UnsupportedEncodingException E) {
  1581.                 throw new SQLException("Unsupported character encoding '"
  1582.                     + connection.getEncoding() + "'.", SQLError.SQL_STATE_GENERAL_ERROR);
  1583.             }
  1584.         } else {
  1585.             stringVal = StringUtils.toAsciiString(thisRow[columnIndex]);
  1586.         }
  1587.         return stringVal;
  1588.     }
  1589.     /**
  1590.      * The following routines simply convert the columnName into a columnIndex
  1591.      * and then call the appropriate routine above.
  1592.      *
  1593.      * @param columnName is the SQL name of the column
  1594.      *
  1595.      * @return the column value
  1596.      *
  1597.      * @exception java.sql.SQLException if a database access error occurs
  1598.      */
  1599.     public String getString(String columnName) throws java.sql.SQLException {
  1600.         return getString(findColumn(columnName));
  1601.     }
  1602.     /**
  1603.      * Get the value of a column in the current row as a java.sql.Time object
  1604.      *
  1605.      * @param columnIndex the first column is 1, the second is 2...
  1606.      *
  1607.      * @return the column value; null if SQL NULL
  1608.      *
  1609.      * @throws java.sql.SQLException if a database access error occurs
  1610.      */
  1611.     public synchronized Time getTime(int columnIndex) throws java.sql.SQLException {
  1612.         return getTimeInternal(columnIndex, this.defaultTimeZone);
  1613.     }
  1614.     /**
  1615.      * Get the value of a column in the current row as a java.sql.Time object.
  1616.      *
  1617.      * @param columnName is the SQL name of the column
  1618.      *
  1619.      * @return the column value; if the value is SQL NULL, the result is null
  1620.      *
  1621.      * @throws java.sql.SQLException if a database-access error occurs.
  1622.      */
  1623.     public Time getTime(String columnName) throws java.sql.SQLException {
  1624.         return getTime(findColumn(columnName));
  1625.     }
  1626.     /**
  1627.      * Get the value of a column in the current row as a java.sql.Time object.
  1628.      * Use the calendar to construct an appropriate millisecond value for the
  1629.      * Time, if the underlying database doesn't store timezone information.
  1630.      *
  1631.      * @param columnIndex the first column is 1, the second is 2, ...
  1632.      * @param cal the calendar to use in constructing the time
  1633.      *
  1634.      * @return the column value; if the value is SQL NULL, the result is null
  1635.      *
  1636.      * @exception SQLException if a database-access error occurs.
  1637.      */
  1638.     public java.sql.Time getTime(int columnIndex, Calendar cal)
  1639.         throws SQLException {
  1640.         return getTimeInternal(columnIndex, cal.getTimeZone());
  1641.     }
  1642.     /**
  1643.      * Get the value of a column in the current row as a java.sql.Time object.
  1644.      * Use the calendar to construct an appropriate millisecond value for the
  1645.      * Time, if the underlying database doesn't store timezone information.
  1646.      *
  1647.      * @param columnName is the SQL name of the column
  1648.      * @param cal the calendar to use in constructing the time
  1649.      *
  1650.      * @return the column value; if the value is SQL NULL, the result is null
  1651.      *
  1652.      * @exception SQLException if a database-access error occurs.
  1653.      */
  1654.     public java.sql.Time getTime(String columnName, Calendar cal)
  1655.         throws SQLException {
  1656.         return getTime(findColumn(columnName), cal);
  1657.     }
  1658.     /**
  1659.      * Get the value of a column in the current row as a java.sql.Timestamp
  1660.      * object
  1661.      *
  1662.      * @param columnIndex the first column is 1, the second is 2...
  1663.      *
  1664.      * @return the column value; null if SQL NULL
  1665.      *
  1666.      * @exception java.sql.SQLException if a database access error occurs
  1667.      */
  1668.     public synchronized Timestamp getTimestamp(int columnIndex) throws java.sql.SQLException {
  1669.         return getTimestampInternal(columnIndex, this.defaultTimeZone);
  1670.     }
  1671.     /**
  1672.      * DOCUMENT ME!
  1673.      *
  1674.      * @param columnName DOCUMENT ME!
  1675.      *
  1676.      * @return DOCUMENT ME!
  1677.      *
  1678.      * @throws java.sql.SQLException DOCUMENT ME!
  1679.      */
  1680.     public Timestamp getTimestamp(String columnName)
  1681.         throws java.sql.SQLException {
  1682.         return getTimestamp(findColumn(columnName));
  1683.     }
  1684.     /**
  1685.      * Get the value of a column in the current row as a java.sql.Timestamp
  1686.      * object. Use the calendar to construct an appropriate millisecond value
  1687.      * for the Timestamp, if the underlying database doesn't store timezone
  1688.      * information.
  1689.      *
  1690.      * @param columnIndex the first column is 1, the second is 2, ...
  1691.      * @param cal the calendar to use in constructing the timestamp
  1692.      *
  1693.      * @return the column value; if the value is SQL NULL, the result is null
  1694.      *
  1695.      * @exception SQLException if a database-access error occurs.
  1696.      */
  1697.     public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal)
  1698.         throws SQLException {
  1699.         return getTimestampInternal(columnIndex, cal.getTimeZone());
  1700.     }
  1701.     /**
  1702.      * Get the value of a column in the current row as a java.sql.Timestamp
  1703.      * object. Use the calendar to construct an appropriate millisecond value
  1704.      * for the Timestamp, if the underlying database doesn't store timezone
  1705.      * information.
  1706.      *
  1707.      * @param columnName is the SQL name of the column
  1708.      * @param cal the calendar to use in constructing the timestamp
  1709.      *
  1710.      * @return the column value; if the value is SQL NULL, the result is null
  1711.      *
  1712.      * @exception SQLException if a database-access error occurs.
  1713.      */
  1714.     public java.sql.Timestamp getTimestamp(String columnName, Calendar cal)
  1715.         throws SQLException {
  1716.         return getTimestamp(findColumn(columnName), cal);
  1717.     }
  1718.     /**
  1719.      * JDBC 2.0 Return the type of this result set.  The type is determined
  1720.      * based on the statement that created the result set.
  1721.      *
  1722.      * @return TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, or
  1723.      *         TYPE_SCROLL_SENSITIVE
  1724.      *
  1725.      * @exception SQLException if a database-access error occurs
  1726.      */
  1727.     public int getType() throws SQLException {
  1728.         return resultSetType;
  1729.     }
  1730.     /**
  1731.      * @see ResultSet#getURL(int)
  1732.      */
  1733.     public URL getURL(int colIndex) throws SQLException {
  1734.         String val = getString(colIndex);
  1735.         if (val == null) {
  1736.             return null;
  1737.         } else {
  1738.             try {
  1739.                 return new URL(val);
  1740.             } catch (MalformedURLException mfe) {
  1741.                 throw new SQLException("Malformed URL '" + val + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1742.             }
  1743.         }
  1744.     }
  1745.     /**
  1746.      * @see ResultSet#getURL(String)
  1747.      */
  1748.     public URL getURL(String colName) throws SQLException {
  1749.         String val = getString(colName);
  1750.         if (val == null) {
  1751.             return null;
  1752.         } else {
  1753.             try {
  1754.                 return new URL(val);
  1755.             } catch (MalformedURLException mfe) {
  1756.                 throw new SQLException("Malformed URL '" + val + "'", SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
  1757.             }
  1758.         }
  1759.     }
  1760.     /**
  1761.      * A column value can also be retrieved as a stream of Unicode characters.
  1762.      * We implement this as a binary stream.
  1763.      *
  1764.      * @param columnIndex the first column is 1, the second is 2...
  1765.      *
  1766.      * @return a Java InputStream that delivers the database column value as a
  1767.      *         stream of two byte Unicode characters.  If the value is SQL
  1768.      *         NULL, then the result is null
  1769.      *
  1770.      * @exception java.sql.SQLException if a database access error occurs
  1771.      *
  1772.      * @see getAsciiStream
  1773.      * @see getBinaryStream
  1774.      */
  1775.     public InputStream getUnicodeStream(int columnIndex)
  1776.         throws java.sql.SQLException {
  1777.         checkRowPos();
  1778.         return getBinaryStream(columnIndex);
  1779.     }
  1780.     /**
  1781.      * DOCUMENT ME!
  1782.      *
  1783.      * @param columnName DOCUMENT ME!
  1784.      *
  1785.      * @return DOCUMENT ME!
  1786.      *
  1787.      * @throws java.sql.SQLException DOCUMENT ME!
  1788.      */
  1789.     public InputStream getUnicodeStream(String columnName)
  1790.         throws java.sql.SQLException {
  1791.         return getUnicodeStream(findColumn(columnName));
  1792.     }