package ModSQL;
import java.sql.*;
import java.math.BigDecimal;
import java.util.Calendar;

/* $Id: ResultSet.java,v 1.7 2003/05/29 07:55:43 cvs Exp $
 *
 * Copyright (c) 2003 Chris Studholme <chris.studholme@utoronto.ca>
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See COPYING for more information.
 */

/**
 * <P>A ResultSet provides access to a table of data.  A ResultSet
 * object is usually generated by executing a Statement. 
 * 
 * <P>A ResultSet maintains a cursor pointing to its current row of
 * data.  Initially the cursor is positioned before the first row.
 * The 'next' method moves the cursor to the next row.
 *
 * <P>The getXXX methods retrieve column values for the current
 * row.  You can retrieve values either using the index number of the
 * column, or by using the name of the column.  In general using the 
 * column index will be more efficient.  Columns are numbered from 1.
 *
 * <P>For maximum portability, ResultSet columns within each row should be
 * read in left-to-right order and each column should be read only once.
 *
 * <P>For the getXXX methods, the JDBC driver attempts to convert the
 * underlying data to the specified Java type and returns a suitable
 * Java value.  See the JDBC specification for allowable mappings
 * from SQL types to Java types with the ResultSet.getXXX methods.
 *
 * <P>Column names used as input to getXXX methods are case
 * insensitive.  When performing a getXXX using a column name, if
 * several columns have the same name, then the value of the first
 * matching column will be returned. The column name option is
 * designed to be used when column names are used in the SQL
 * query. For columns that are NOT explicitly named in the query, it
 * is best to use column numbers. If column names were used there is
 * no way for the programmer to guarantee that they actually refer to
 * the intended columns.
 *
 * <P>A ResultSet is automatically closed by the Statement that
 * generated it when that Statement is closed, re-executed, or is used
 * to retrieve the next result from a sequence of multiple results.
 * 
 * <P>The number, types and properties of a ResultSet's columns are
 * provided by the ResulSetMetaData object returned by the getMetaData
 * method.
 *
 * @see PreparedStatement#executeQuery 
 * @see PreparedStatement#getResultSet 
 * @see ResultSetMetaData 
 * @author chris.studholme@utoronto.ca
 */
public class ResultSet implements java.sql.ResultSet {

  /** Query that generated this result set. */
  protected Select query=null;
  /** Statement that was used to generate this result set. */
  protected PreparedStatement statement=null;

  /** True if last value retrieved was null. */
  protected boolean lastNull=false;
  /** True if we are before the first row. */
  protected boolean beforefirst=true;

  /**
   * Constructor.
   *
   * @param query query to generate result set from
   * @param statement statement used to execute query
   */
  protected ResultSet(Select query, PreparedStatement statement) {
    this.query = query;
    this.statement = statement;
  }


  /**
   * A ResultSet is initially positioned before its first row; the
   * first call to next makes the first row the current row; the
   * second call makes the second row the current row, etc. 
   *
   * <P>If an input stream from the previous row is open, it is
   * implicitly closed. The ResultSet's warning chain is cleared
   * when a new row is read.
   *
   * @return true if the new current row is valid; false if there
   * are no more rows 
   * @throws SQLException if a database-access error occurs.
   */
  public boolean next() throws SQLException {
    try {
      return query.next();
    }
    catch (EndOfTable e) {
      throw new SQLExceptionWithCause("SOFTWARE BUG",e);
    }
  }


  /**
   * In some cases, it is desirable to immediately release a
   * ResultSet's database and JDBC resources instead of waiting for
   * this to happen when it is automatically closed; the close
   * method provides this immediate release.
   *
   * <P><B>Note:</B> A ResultSet is automatically closed by the
   * Statement that generated it when that Statement is closed,
   * re-executed, or is used to retrieve the next result from a
   * sequence of multiple results. A ResultSet is also automatically
   * closed when it is garbage collected.  
   *
   * @throws SQLException if a database-access error occurs.
   */
  public void close() throws SQLException {
    query=null;
    statement=null;
  }

  /**
   * A column may have the value of SQL NULL; wasNull reports whether
   * the last column read had this special value.
   * Note that you must first call getXXX on a column to try to read
   * its value and then call wasNull() to find if the value was
   * the SQL NULL.
   *
   * @return true if last column read was SQL NULL
   * @throws SQLException if a database-access error occurs.
   */
  public boolean wasNull() throws SQLException {
    return lastNull;
  }
    
  //======================================================================
  // Methods for accessing results by column index
  //======================================================================
  
  /**
   * <p>Get the value of a column in the current row as a Java object.
   *
   * <p>This method will return the value of the given column as a
   * Java object.  The type of the Java object will be the default
   * Java Object type corresponding to the column's SQL type,
   * following the mapping specified in the JDBC spec.
   *
   * <p>This method may also be used to read datatabase specific abstract
   * data types.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return A java.lang.Object holding the column value.  
   * @throws SQLException if a database-access error occurs.
   */
  public Object getObject(int columnIndex) throws SQLException {
    Object o = query.getObject(columnIndex-1);
    lastNull=(o==null);
    return o;
  }
  
  /**
   * Get the value of a column in the current row as a Java String.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public String getString(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    return o!=null ? o.toString() : null;
  }

  /**
   * Get the value of a column in the current row as a Java boolean.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is false
   * @throws SQLException if a database-access error occurs.
   */
  public boolean getBoolean(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    if (o==null) return false;
    if (o instanceof Boolean)
      return ((Boolean)o).booleanValue();
    throw new SQLException("type mismatch");
  }

  /**
   * Get the value of a column in the current row as a Java byte.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public byte getByte(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    if (o==null) return 0;
    if (o instanceof Number)
      return ((Number)o).byteValue();
    throw new SQLException("type mismatch");
  }

  /**
   * Get the value of a column in the current row as a Java short.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public short getShort(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    if (o==null) return 0;
    if (o instanceof Number)
      return ((Number)o).shortValue();
    throw new SQLException("type mismatch");
  }
  
  /**
   * Get the value of a column in the current row as a Java int.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public int getInt(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    if (o==null) return 0;
    if (o instanceof Number)
      return ((Number)o).intValue();
    throw new SQLException("type mismatch");
  }
  
  /**
   * Get the value of a column in the current row as a Java long.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public long getLong(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    if (o==null) return 0;
    if (o instanceof Number)
      return ((Number)o).longValue();
    throw new SQLException("type mismatch");
  }
  
  /**
   * Get the value of a column in the current row as a Java float.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public float getFloat(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    if (o==null) return 0;
    if (o instanceof Number)
      return ((Number)o).floatValue();
    throw new SQLException("type mismatch");
  }
  
  /**
   * Get the value of a column in the current row as a Java double.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public double getDouble(int columnIndex) throws SQLException {
    Object o = getObject(columnIndex);
    if (o==null) return 0;
    if (o instanceof Number)
      return ((Number)o).doubleValue();
    throw new SQLException("type mismatch");
  }
  
  /**
   * Get the value of a column in the current row as a java.lang.BigDecimal object.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param scale the number of digits to the right of the decimal
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   * @deprecated     
   */
  public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a Java byte array.
   * The bytes represent the raw values returned by the driver.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public byte[] getBytes(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Date object.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Date getDate(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Time object.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Time getTime(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Timestamp object.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * A column value can be retrieved as a stream of ASCII characters 
   * and then read in chunks from the stream.  This method is particularly
   * suitable for retrieving large LONGVARCHAR values.  The JDBC driver will
   * do any necessary conversion from the database format into ASCII.
   *
   * <P><B>Note:</B> All the data in the returned stream must be
   * read prior to getting the value of any other column. The next
   * call to a get method implicitly closes the stream. . Also, a
   * stream may return 0 for available() whether there is data
   * available or not.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return a Java input stream that delivers the database column value
   * as a stream of one byte ASCII characters.  If the value is SQL NULL
   * then the result is null.  
   * @throws SQLException if a database-access error occurs.
   */
  public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * A column value can be retrieved as a stream of Unicode characters 
   * and then read in chunks from the stream.  This method is particularly
   * suitable for retrieving large LONGVARCHAR values.  The JDBC driver will
   * do any necessary conversion from the database format into Unicode.
   *
   * <P><B>Note:</B> All the data in the returned stream must be
   * read prior to getting the value of any other column. The next
   * call to a get method implicitly closes the stream. . Also, a
   * stream may return 0 for available() whether there is data
   * available or not.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return a Java input stream that delivers the database column value
   * as a stream of two byte Unicode characters.  If the value is SQL NULL
   * then the result is null.  
   * @throws SQLException if a database-access error occurs.
   * @deprecated     
   */
  public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * A column value can be retrieved as a stream of uninterpreted bytes 
   * and then read in chunks from the stream.  This method is particularly
   * suitable for retrieving large LONGVARBINARY values.
   *
   * <P><B>Note:</B> All the data in the returned stream must be
   * read prior to getting the value of any other column. The next
   * call to a get method implicitly closes the stream. Also, a
   * stream may return 0 for available() whether there is data
   * available or not.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return a Java input stream that delivers the database column value
   * as a stream of uninterpreted bytes.  If the value is SQL NULL
   * then the result is null.  
   * @throws SQLException if a database-access error occurs.
   */
  public java.io.InputStream getBinaryStream(int columnIndex)
    throws SQLException {
    throw new SQLException("not implemented");
  }


  //======================================================================
  // Methods for accessing results by column name
  //======================================================================

  /**
   * <p>Get the value of a column in the current row as a Java object.
   *
   * <p>This method will return the value of the given column as a
   * Java object.  The type of the Java object will be the default
   * Java Object type corresponding to the column's SQL type,
   * following the mapping specified in the JDBC spec.
   *
   * <p>This method may also be used to read datatabase specific abstract
   * data types.
   *
   * @param columnName is the SQL name of the column
   * @return A java.lang.Object holding the column value.  
   * @throws SQLException if a database-access error occurs.
   */
  public Object getObject(String columnName) throws SQLException {
    return getObject(findColumn(columnName));
  }
  
  /**
   * Get the value of a column in the current row as a Java String.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public String getString(String columnName) throws SQLException {
    return getString(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a Java boolean.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is false
   * @throws SQLException if a database-access error occurs.
   */
  public boolean getBoolean(String columnName) throws SQLException {
    return getBoolean(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a Java byte.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public byte getByte(String columnName) throws SQLException {
    return getByte(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a Java short.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public short getShort(String columnName) throws SQLException {
    return getShort(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a Java int.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public int getInt(String columnName) throws SQLException {
    return getInt(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a Java long.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public long getLong(String columnName) throws SQLException {
    return getLong(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a Java float.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public float getFloat(String columnName) throws SQLException {
    return getFloat(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a Java double.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is 0
   * @throws SQLException if a database-access error occurs.
   */
  public double getDouble(String columnName) throws SQLException {
    return getDouble(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a java.lang.BigDecimal object.
   *
   * @param columnName is the SQL name of the column
   * @param scale the number of digits to the right of the decimal
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   * @deprecated     
   */
  public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
    return getBigDecimal(findColumn(columnName),scale);
  }

  /**
   * Get the value of a column in the current row as a Java byte array.
   * The bytes represent the raw values returned by the driver.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public byte[] getBytes(String columnName) throws SQLException {
    return getBytes(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a java.sql.Date object.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Date getDate(String columnName) throws SQLException {
    return getDate(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a java.sql.Time object.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Time getTime(String columnName) throws SQLException {
    return getTime(findColumn(columnName));
  }

  /**
   * Get the value of a column in the current row as a java.sql.Timestamp object.
   *
   * @param columnName is the SQL name of the column
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {
    return getTimestamp(findColumn(columnName));
  }

  /**
   * A column value can be retrieved as a stream of ASCII characters 
   * and then read in chunks from the stream.  This method is particularly
   * suitable for retrieving large LONGVARCHAR values.  The JDBC driver will
   * do any necessary conversion from the database format into ASCII.
   *
   * <P><B>Note:</B> All the data in the returned stream must
   * be read prior to getting the value of any other column. The
   * next call to a get method implicitly closes the stream.
   *
   * @param columnName is the SQL name of the column
   * @return a Java input stream that delivers the database column value
   * as a stream of one byte ASCII characters.  If the value is SQL NULL
   * then the result is null.
   * @throws SQLException if a database-access error occurs.
   */
  public java.io.InputStream getAsciiStream(String columnName) throws SQLException {
    return getAsciiStream(findColumn(columnName));
  }

  /**
   * A column value can be retrieved as a stream of Unicode characters 
   * and then read in chunks from the stream.  This method is particularly
   * suitable for retrieving large LONGVARCHAR values.  The JDBC driver will
   * do any necessary conversion from the database format into Unicode.
   *
   * <P><B>Note:</B> All the data in the returned stream must
   * be read prior to getting the value of any other column. The
   * next call to a get method implicitly closes the stream.
   *
   * @param columnName is the SQL name of the column
   * @return a Java input stream that delivers the database column value
   * as a stream of two byte Unicode characters.  If the value is SQL NULL
   * then the result is null.
   * @throws SQLException if a database-access error occurs.
   * @deprecated     
   */
  public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {
    return getUnicodeStream(findColumn(columnName));
  }

  /**
   * A column value can be retrieved as a stream of uninterpreted bytes 
   * and then read in chunks from the stream.  This method is particularly
   * suitable for retrieving large LONGVARBINARY values.
   *
   * <P><B>Note:</B> All the data in the returned stream must
   * be read prior to getting the value of any other column. The
   * next call to a get method implicitly closes the stream.
   *
   * @param columnName is the SQL name of the column
   * @return a Java input stream that delivers the database column value
   * as a stream of uninterpreted bytes.  If the value is SQL NULL
   * then the result is null.
   * @throws SQLException if a database-access error occurs.
   */
  public java.io.InputStream getBinaryStream(String columnName)
    throws SQLException {
    return getBinaryStream(findColumn(columnName));
  }

  //=====================================================================
  // Advanced features:
  //=====================================================================
  
  /**
   * <p>The first warning reported by calls on this ResultSet is
   * returned. Subsequent ResultSet warnings will be chained to this
   * SQLWarning.
   *
   * <P>The warning chain is automatically cleared each time a new
   * row is read.
   *
   * <P><B>Note:</B> This warning chain only covers warnings caused
   * by ResultSet methods.  Any warning caused by statement methods
   * (such as reading OUT parameters) will be chained on the
   * Statement object. 
   *
   * @return the first SQLWarning or null 
   * @throws SQLException if a database-access error occurs.
   */
  public SQLWarning getWarnings() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * After this call getWarnings returns null until a new warning is
   * reported for this ResultSet.  
   *
   * @throws SQLException if a database-access error occurs.
   */
  public void clearWarnings() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the name of the SQL cursor used by this ResultSet.
   *
   * <P>In SQL, a result table is retrieved through a cursor that is
   * named. The current row of a result can be updated or deleted
   * using a positioned update/delete statement that references the
   * cursor name. 
   * 
   * <P>JDBC supports this SQL feature by providing the name of the
   * SQL cursor used by a ResultSet. The current row of a ResultSet
   * is also the current row of this SQL cursor.
   *
   * <P><B>Note:</B> If positioned update is not supported a
   * SQLException is thrown
   *
   * @return the ResultSet's SQL cursor name
   * @throws SQLException if a database-access error occurs.
   */
  public String getCursorName() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * The number, types and properties of a ResultSet's columns
   * are provided by the getMetaData method.
   *
   * @return the description of a ResultSet's columns
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.ResultSetMetaData getMetaData() throws SQLException {
    return new ResultSetMetaData(query);
  }
  
  //----------------------------------------------------------------
  
  /**
   * Map a Resultset column name to a ResultSet column index.
   *
   * @param columnName the name of the column
   * @return the column index
   * @throws SQLException if a database-access error occurs.
   */
  public int findColumn(String columnName) throws SQLException {
    throw new SQLException("not implemented");
  }


  
  //--------------------------JDBC 2.0-----------------------------------

  //---------------------------------------------------------------------
  // Getter's and Setter's
  //---------------------------------------------------------------------
  
  /**
   * <p>Get the value of a column in the current row as a java.io.Reader.
   */
  public java.io.Reader getCharacterStream(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Get the value of a column in the current row as a java.io.Reader.
   */
  public java.io.Reader getCharacterStream(String columnName) throws SQLException {
    return getCharacterStream(findColumn(columnName));
  }
  
  /**
   * Get the value of a column in the current row as a java.math.BigDecimal 
   * object.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @return the column value (full precision); if the value is SQL NULL, 
   * the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a java.math.BigDecimal 
   * object.
   *
   */
  public BigDecimal getBigDecimal(String columnName) throws SQLException {
    return getBigDecimal(findColumn(columnName));
  }

  //---------------------------------------------------------------------
  // Traversal/Positioning
  //---------------------------------------------------------------------

  /**
   * <p>Determine if the cursor is before the first row in the result 
   * set.   
   *
   * @return true if before the first row, false otherwise. Returns
   * false when the result set contains no rows.
   * @throws SQLException if a database-access error occurs.
   */
  public boolean isBeforeFirst() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Determine if the cursor is after the last row in the result 
   * set.   
   *
   * @return true if after the last row, false otherwise.  Returns
   * false when the result set contains no rows.
   * @throws SQLException if a database-access error occurs.
   */
  public boolean isAfterLast() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Determine if the cursor is on the first row of the result set.   
   *
   * @return true if on the first row, false otherwise.   
   * @throws SQLException if a database-access error occurs.
   */
  public boolean isFirst() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Determine if the cursor is on the last row of the result set.   
   * Note: Calling isLast() may be expensive since the JDBC driver
   * might need to fetch ahead one row in order to determine 
   * whether the current row is the last row in the result set.
   *
   * @return true if on the last row, false otherwise. 
   * @throws SQLException if a database-access error occurs.
   */
  public boolean isLast() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Moves to the front of the result set, just before the
   * first row. Has no effect if the result set contains no rows.
   *
   * @throws SQLException if a database-access error occurs, or
   * result set type is TYPE_FORWARD_ONLY
   */
  public void beforeFirst() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Moves to the end of the result set, just after the last
   * row.  Has no effect if the result set contains no rows.
   *
   * @throws SQLException if a database-access error occurs, or
   * result set type is TYPE_FORWARD_ONLY.
   */
  public void afterLast() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Moves to the first row in the result set.  
   *
   * @return true if on a valid row, false if no rows in the result set.
   * @throws SQLException if a database-access error occurs, or
   * result set type is TYPE_FORWARD_ONLY.
   */
  public boolean first() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Moves to the last row in the result set.  
   *
   * @return true if on a valid row, false if no rows in the result set.
   * @throws SQLException if a database-access error occurs, or
   * result set type is TYPE_FORWARD_ONLY.
   */
  public boolean last() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Determine the current row number.  The first row is number 1, the
   * second number 2, etc.  
   *
   * @return the current row number, else return 0 if there is no 
   * current row
   * @throws SQLException if a database-access error occurs.
   */
  public int getRow() throws SQLException {
    throw new SQLException("not implemented");
  }

  /**
   * <p>Move to an absolute row number in the result set.
   *
   * <p>If row is positive, moves to an absolute row with respect to the
   * beginning of the result set.  The first row is row 1, the second
   * is row 2, etc. 
   *
   * <p>If row is negative, moves to an absolute row position with respect to
   * the end of result set.  For example, calling absolute(-1) positions the 
   * cursor on the last row, absolute(-2) indicates the next-to-last
   * row, etc.
   *
   * <p>An attempt to position the cursor beyond the first/last row in
   * the result set, leaves the cursor before/after the first/last
   * row, respectively.
   *
   * <p>Note: Calling absolute(1) is the same as calling first().
   * Calling absolute(-1) is the same as calling last().
   *
   * @return true if on the result set, false if off.
   * @throws SQLException if a database-access error occurs, or 
   * row is 0, or result set type is TYPE_FORWARD_ONLY.
   */
  public boolean absolute( int row ) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Moves a relative number of rows, either positive or negative.
   * Attempting to move beyond the first/last row in the
   * result set positions the cursor before/after the
   * the first/last row. Calling relative(0) is valid, but does
   * not change the cursor position.
   *
   * <p>Note: Calling relative(1) is different than calling next()
   * since is makes sense to call next() when there is no current row,
   * for example, when the cursor is positioned before the first row
   * or after the last row of the result set.
   *
   * @return true if on a row, false otherwise.
   * @throws SQLException if a database-access error occurs, or there
   * is no current row, or result set type is TYPE_FORWARD_ONLY.
   */
  public boolean relative( int rows ) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * <p>Moves to the previous row in the result set.  
   *
   * <p>Note: previous() is not the same as relative(-1) since it
   * makes sense to call previous() when there is no current row.
   *
   * @return true if on a valid row, false if off the result set.
   * @throws SQLException if a database-access error occurs, or
   * result set type is TYPE_FORWAR_DONLY.
   */
  public boolean previous() throws SQLException {
    throw new SQLException("not implemented");
  }

  //---------------------------------------------------------------------
  // Properties
  //---------------------------------------------------------------------
  
  /**
   * Give a hint as to the direction in which the rows in this result set
   * will be processed.  The initial value is determined by the statement
   * that produced the result set.  The fetch direction may be changed
   * at any time.
   *
   * @throws SQLException if a database-access error occurs, or
   * the result set type is TYPE_FORWARD_ONLY and direction is not 
   * FETCH_FORWARD.
   */
  public void setFetchDirection(int direction) throws SQLException {
    throw new SQLException("not implemented");
  }

  /**
   * Return the fetch direction for this result set.
   *
   * @throws SQLException if a database-access error occurs 
   */
  public int getFetchDirection() throws SQLException {
    return FETCH_FORWARD; 
  }

  /**
   * Give the JDBC driver a hint as to the number of rows that should 
   * be fetched from the database when more rows are needed for this result
   * set.  If the fetch size specified is zero, then the JDBC driver 
   * ignores the value, and is free to make its own best guess as to what
   * the fetch size should be.  The default value is set by the statement 
   * that creates the result set.  The fetch size may be changed at any 
   * time.
   *
   * @param rows the number of rows to fetch
   * @throws SQLException if a database-access error occurs, or the
   * condition 0 <= rows <= this.getMaxRows() is not satisfied.
   */
  public void setFetchSize(int rows) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Return the fetch size for this result set.
   *
   * @throws SQLException if a database-access error occurs 
   */
  public int getFetchSize() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Return the type of this result set.  The type is determined based
   * on the statement that created the result set.
   *
   * @return TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, or
   *         TYPE_SCROLL_SENSITIVE
   * @throws SQLException if a database-access error occurs
   */
  public int getType() throws SQLException {
    return TYPE_FORWARD_ONLY;
  }
  
  /**
   * Return the concurrency of this result set.  The concurrency
   * used is determined by the statement that created the result set.
   *
   * @return the concurrency type, CONCUR_READ_ONLY, etc.
   * @throws SQLException if a database-access error occurs
   */
  public int getConcurrency() throws SQLException {
    return CONCUR_READ_ONLY;
  }

  //---------------------------------------------------------------------
  // Updates
  //---------------------------------------------------------------------

  /**
   * Determine if the current row has been updated.  The value returned 
   * depends on whether or not the result set can detect updates.
   *
   * @return true if the row has been visibly updated by the owner or
   * another, and updates are detected
   * @throws SQLException if a database-access error occurs
   * 
   * @see DatabaseMetaData#updatesAreDetected
   */
  public boolean rowUpdated() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Determine if the current row has been inserted.  The value returned 
   * depends on whether or not the result set can detect visible inserts.
   *
   * @return true if inserted and inserts are detected
   * @throws SQLException if a database-access error occurs
   * 
   * @see DatabaseMetaData#insertsAreDetected
   */
  public boolean rowInserted() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Determine if this row has been deleted.  A deleted row may leave
   * a visible "hole" in a result set.  This method can be used to
   * detect holes in a result set.  The value returned depends on whether 
   * or not the result set can detect deletions.
   *
   * @return true if deleted and deletes are detected
   * @throws SQLException if a database-access error occurs
   * 
   * @see DatabaseMetaData#deletesAreDetected
   */
  public boolean rowDeleted() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Give a nullable column a null value.
   * 
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @throws SQLException if a database-access error occurs
   */
  public void updateNull(int columnIndex) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a boolean value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateBoolean(int columnIndex, boolean x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a byte value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateByte(int columnIndex, byte x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a short value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateShort(int columnIndex, short x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with an integer value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateInt(int columnIndex, int x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a long value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateLong(int columnIndex, long x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a float value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateFloat(int columnIndex, float x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a Double value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateDouble(int columnIndex, double x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a BigDecimal value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a String value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateString(int columnIndex, String x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a byte array value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateBytes(int columnIndex, byte x[]) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a Date value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateDate(int columnIndex, java.sql.Date x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a Time value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateTime(int columnIndex, java.sql.Time x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a Timestamp value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /** 
   * Update a column with an ascii stream value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @param length the length of the stream
   * @throws SQLException if a database-access error occurs
   */
  public void updateAsciiStream(int columnIndex, 
			 java.io.InputStream x, 
			 int length) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /** 
   * Update a column with a binary stream value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value     
   * @param length the length of the stream
   * @throws SQLException if a database-access error occurs
   */
  public void updateBinaryStream(int columnIndex, 
			  java.io.InputStream x,
			  int length) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a character stream value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @param length the length of the stream
   * @throws SQLException if a database-access error occurs
   */
  public void updateCharacterStream(int columnIndex,
			     java.io.Reader x,
			     int length) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with an Object value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
   *  this is the number of digits after the decimal.  For all other
   *  types this value will be ignored.
   * @throws SQLException if a database-access error occurs
   */
  public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with an Object value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateObject(int columnIndex, Object x) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update a column with a null value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @throws SQLException if a database-access error occurs
   */
  public void updateNull(String columnName) throws SQLException {
    updateNull(findColumn(columnName));
  }
  
  /**
   * Update a column with a boolean value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateBoolean(String columnName, boolean x) throws SQLException {
    updateBoolean(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a byte value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateByte(String columnName, byte x) throws SQLException {
    updateByte(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a short value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateShort(String columnName, short x) throws SQLException {
    updateShort(findColumn(columnName),x);
  }
  
  /**
   * Update a column with an integer value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateInt(String columnName, int x) throws SQLException {
    updateInt(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a long value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateLong(String columnName, long x) throws SQLException {
    updateLong(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a float value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateFloat(String columnName, float x) throws SQLException {
    updateFloat(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a double value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateDouble(String columnName, double x) throws SQLException {
    updateDouble(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a BigDecimal value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
    updateBigDecimal(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a String value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateString(String columnName, String x) throws SQLException {
    updateString(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a byte array value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateBytes(String columnName, byte x[]) throws SQLException {
    updateBytes(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a Date value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateDate(String columnName, java.sql.Date x) throws SQLException {
    updateDate(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a Time value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateTime(String columnName, java.sql.Time x) throws SQLException {
    updateTime(findColumn(columnName),x);
  }
  
  /**
   * Update a column with a Timestamp value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {
    updateTimestamp(findColumn(columnName),x);
  }
  
  /** 
   * Update a column with an ascii stream value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @param length of the stream
   * @throws SQLException if a database-access error occurs
   */
  public void updateAsciiStream(String columnName, 
			 java.io.InputStream x, 
			 int length) throws SQLException {
    updateAsciiStream(findColumn(columnName),x,length);
  }
  
  /** 
   * Update a column with a binary stream value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @param length of the stream
   * @throws SQLException if a database-access error occurs
   */
  public void updateBinaryStream(String columnName, 
			  java.io.InputStream x,
			  int length) throws SQLException {
    updateBinaryStream(findColumn(columnName),x,length);
  }
  
  /**
   * Update a column with a character stream value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @param length of the stream
   * @throws SQLException if a database-access error occurs
   */
  public void updateCharacterStream(String columnName,
			     java.io.Reader reader,
			     int length) throws SQLException {
    updateCharacterStream(findColumn(columnName),reader,length);
  }
  
  /**
   * Update a column with an Object value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
   *  this is the number of digits after the decimal.  For all other
   *  types this value will be ignored.
   * @throws SQLException if a database-access error occurs
   */
  public void updateObject(String columnName, Object x, int scale) throws SQLException {
    updateObject(findColumn(columnName),x,scale);
  }
  
  /**
   * Update a column with an Object value.
   *
   * The updateXXX() methods are used to update column values in the
   * current row, or the insert row.  The updateXXX() methods do not 
   * update the underlying database, instead the updateRow() or insertRow()
   * methods are called to update the database.
   *
   * @param columnName the name of the column
   * @param x the new column value
   * @throws SQLException if a database-access error occurs
   */
  public void updateObject(String columnName, Object x) throws SQLException {
    updateObject(findColumn(columnName),x);
  }
  
  /**
   * Insert the contents of the insert row into the result set and
   * the database.  Must be on the insert row when this method is called.
   *
   * @throws SQLException if a database-access error occurs,
   * if called when not on the insert row, or if all non-nullable columns in
   * the insert row have not been given a value
   */
  public void insertRow() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Update the underlying database with the new contents of the
   * current row.  Cannot be called when on the insert row.
   *
   * @throws SQLException if a database-access error occurs, or
   * if called when on the insert row
   */
  public void updateRow() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Delete the current row from the result set and the underlying
   * database.  Cannot be called when on the insert row.
   *
   * @throws SQLException if a database-access error occurs, or if
   * called when on the insert row.
   */
  public void deleteRow() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Refresh the value of the current row with its current value in 
   * the database.  Cannot be called when on the insert row.
   *
   * The refreshRow() method provides a way for an application to 
   * explicitly tell the JDBC driver to refetch a row(s) from the
   * database.  An application may want to call refreshRow() when 
   * caching or prefetching is being done by the JDBC driver to
   * fetch the latest value of a row from the database.  The JDBC driver 
   * may actually refresh multiple rows at once if the fetch size is 
   * greater than one.
   * 
   * All values are refetched subject to the transaction isolation 
   * level and cursor sensitivity.  If refreshRow() is called after
   * calling updateXXX(), but before calling updateRow() then the
   * updates made to the row are lost.  Calling refreshRow() frequently
   * will likely slow performance.
   *
   * @throws SQLException if a database-access error occurs, or if
   * called when on the insert row.
   */
  public void refreshRow() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * The cancelRowUpdates() method may be called after calling an
   * updateXXX() method(s) and before calling updateRow() to rollback 
   * the updates made to a row.  If no updates have been made or 
   * updateRow() has already been called, then this method has no 
   * effect.
   *
   * @throws SQLException if a database-access error occurs, or if
   * called when on the insert row.
   *
   */
  public void cancelRowUpdates () throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Move to the insert row.  The current cursor position is 
   * remembered while the cursor is positioned on the insert row.
   *
   * The insert row is a special row associated with an updatable
   * result set.  It is essentially a buffer where a new row may
   * be constructed by calling the updateXXX() methods prior to 
   * inserting the row into the result set.  
   *
   * Only the updateXXX(), getXXX(), and insertRow() methods may be 
   * called when the cursor is on the insert row.  All of the columns in 
   * a result set must be given a value each time this method is
   * called before calling insertRow().  UpdateXXX()must be called before
   * getXXX() on a column.
   *
   * @throws SQLException if a database-access error occurs,
   * or the result set is not updatable
   */
  public void moveToInsertRow() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Move the cursor to the remembered cursor position, usually the
   * current row.  Has no effect unless the cursor is on the insert 
   * row. 
   *
   * @throws SQLException if a database-access error occurs,
   * or the result set is not updatable
   */
  public void moveToCurrentRow() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Return the Statement that produced the ResultSet.
   *
   * @return the Statment that produced the result set, or
   * null if the result was produced some other way.
   * @throws SQLException if a database-access error occurs
   */
  public java.sql.Statement getStatement() throws SQLException {
    return statement;
  }
  
  /**
   * Returns the value of column @i as a Java object.  Use the 
   * @map to determine the class from which to construct data of 
   * SQL structured and distinct types.
   *
   * @param i the first column is 1, the second is 2, ...
   * @param map the mapping from SQL type names to Java classes
   * @return an object representing the SQL value
   */
  public Object getObject(int i, java.util.Map map) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get a REF(&lt;structured-type&gt;) column.
   *
   * @param i the first column is 1, the second is 2, ...
   * @return an object representing data of an SQL REF type
   */
  public Ref getRef(int i) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get a BLOB column.
   *
   * @param i the first column is 1, the second is 2, ...
   * @return an object representing a BLOB
   */
  public Blob getBlob(int i) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get a CLOB column.
   *
   * @param i the first column is 1, the second is 2, ...
   * @return an object representing a CLOB
   */
  public Clob getClob(int i) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get an array column.
   *
   * @param i the first column is 1, the second is 2, ...
   * @return an object representing an SQL array
   */
  public Array getArray(int i) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Returns the value of column @i as a Java object.  Use the 
   * @map to determine the class from which to construct data of 
   * SQL structured and distinct types.
   *
   * @param colName the column name
   * @param map the mapping from SQL type names to Java classes
   * @return an object representing the SQL value
   */
  public Object getObject(String colName, java.util.Map map) throws SQLException {
    return getObject(findColumn(colName),map);
  }
  
  /**
   * Get a REF(&lt;structured-type&gt;) column.
   *
   * @param colName the column name
   * @return an object representing data of an SQL REF type
   */
  public Ref getRef(String colName) throws SQLException {
    return getRef(findColumn(colName));
  }
  
  /**
   * Get a BLOB column.
   *
   * @param colName the column name
   * @return an object representing a BLOB
   */
  public Blob getBlob(String colName) throws SQLException {
    return getBlob(findColumn(colName));
  }
  
  /**
   * Get a CLOB column.
   *
   * @param colName the column name
   * @return an object representing a CLOB
   */
  public Clob getClob(String colName) throws SQLException {
    return getClob(findColumn(colName));
  }
  
  /**
   * Get an array column.
   *
   * @param colName the column name
   * @return an object representing an SQL array
   */
  public Array getArray(String colName) throws SQLException {
    return getArray(findColumn(colName));
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Date 
   * object.  Use the calendar to construct an appropriate millisecond
   * value for the Date, if the underlying database doesn't store
   * timezone information.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param cal the calendar to use in constructing the date
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Date 
   * object. Use the calendar to construct an appropriate millisecond
   * value for the Date, if the underlying database doesn't store
   * timezone information.
   *
   * @param columnName is the SQL name of the column
   * @param cal the calendar to use in constructing the date
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {
    return getDate(findColumn(columnName),cal);
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Time 
   * object. Use the calendar to construct an appropriate millisecond
   * value for the Time, if the underlying database doesn't store
   * timezone information.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param cal the calendar to use in constructing the time
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Time 
   * object. Use the calendar to construct an appropriate millisecond
   * value for the Time, if the underlying database doesn't store
   * timezone information.
   *
   * @param columnName is the SQL name of the column
   * @param cal the calendar to use in constructing the time
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {
    return getTime(findColumn(columnName),cal);
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Timestamp 
   * object. Use the calendar to construct an appropriate millisecond
   * value for the Timestamp, if the underlying database doesn't store
   * timezone information.
   *
   * @param columnIndex the first column is 1, the second is 2, ...
   * @param cal the calendar to use in constructing the timestamp
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) 
    throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Get the value of a column in the current row as a java.sql.Timestamp 
   * object. Use the calendar to construct an appropriate millisecond
   * value for the Timestamp, if the underlying database doesn't store
   * timezone information.
   *
   * @param columnName is the SQL name of the column
   * @param cal the calendar to use in constructing the timestamp
   * @return the column value; if the value is SQL NULL, the result is null
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Timestamp getTimestamp(String columnName, Calendar cal)	
    throws SQLException {
    return getTimestamp(findColumn(columnName),cal);
  }
}
