package ModSQL;
import java.sql.*;

/* $Id: Table.java,v 1.6 2003/05/29 05:48:45 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.
 */

/**
 * A table is zero or more rows.  Each row consists of one or more columns.
 *
 * @author chris.studholme@utoronto.ca
 */
public interface Table {

  /**
   * Some functions (most notably IndirectValue) needs to register themselves
   * before optimize() can be called.  This method must call the registerWith()
   * method on all Function objects contained within.  Most implementations 
   * will simply pass this call on to all contained Function objects.
   *
   * @param o object to register with
   * @throws SQLException if an error occurs
   */
  public void registerWith(Object o) throws SQLException;
  
  /**
   * Prepare the table for use.  This method should call optimize() for
   * all Function objects contained within.
   *
   * @throws SQLException if an error occurs
   */
  public void optimize() throws SQLException;

  /**
   * Return human readable description of table.
   *
   * @param with_brackets bracket the expression
   * @return String representing table
   */
  public String toString(boolean with_brackets);


  /****************  result meta-data  ****************/

  /**
   * <p>Determine if this table is constant.  
   *
   * <p>This method can only be called after optimize().
   *
   * @return true if the table is constant
   * @throws SQLException if an error occurs
   */
  public boolean isConstant() throws SQLException;

  /**
   * <p>Get count of number of rows, if known.  This method is best called
   * immediately after a call to beforeFirst(); however, it still might
   * return -1 in that case too.
   *
   * <p>This method can only be called after optimize().
   *
   * @return number of rows or -1 if count is not known
   * @throws SQLException if an error occurs
   */
  public long getRowCount() throws SQLException;

  /**
   * <p>Returns the number of columns in the table.  The returned value must
   * be greater than zero.
   *
   * <p>This method can only be called after optimize().
   *
   * @return number of columns in table
   * @throws SQLException if an error occurs
   */
  public int getColumnCount() throws SQLException;

  /**
   * <p>Get the name of a column.
   *
   * <p>This method can only be called after optimize().
   * 
   * @param column column number (starting from zero)
   * @return name of column (or null if column has no name)
   * @throws SQLException if an error occurs
   */
  public String getColumnName(int column) throws SQLException;

  /**
   * <p>Return the SQL type of the specified column.
   *
   * <p>This method can only be called after optimize().
   *
   * @param column column number (starting from zero)
   * @return SQL type of data to be returned
   * @throws SQLException if an error occurs
   */
  public int getSQLType(int column) throws SQLException;

  /**
   * <p>Return the maximum number of characters String values in the specified
   * column will have.  If the column is not of String type or if the maximum
   * length is not known, -1 should be returned.
   *
   * <p>This method can only be called after optimize().
   *
   * @param column column number (starting from zero)
   * @return maximum size of String returned or -1 if unknown
   * @throws SQLException if an error occurs
   */
  public int getMaxResultSize(int column) throws SQLException;


  /****************  evaluation methods  ****************/

  /**
   * <p>Reset the table to before the first row.  After a call to this method,
   * next() should advance to the first row in the table.
   *
   * <p>This method can only be called after optimize().
   *
   * @throws SQLException if an error occurs
   */
  public void beforeFirst() throws SQLException;

  /**
   * <p>The table 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>This method can only be called after optimize().
   *
   * @return true if the new current row is valid; false if there
   * are no more rows
   * @throws SQLException if an error occurs
   * @throws EndOfTable if the table is advanced beyond that last row
   */
  public boolean next() throws SQLException, EndOfTable;

  /**
   * <p>Get the current row as an array of Objects.  
   *
   * <p>This method can only be called after optimize().
   *
   * @return array of objects or null if current row is not valid
   * @throws SQLException if an error occurs
   * @throws EndOfTable if the table is advanced beyond that last row
   */
  public Object[] getRow() throws SQLException, EndOfTable;

  /**
   * <p>Get the value of a column in the current row as a Java object.  This
   * method will throw an exception if the current row is not valid.
   *
   * <p>This method can only be called after optimize().
   *
   * @param column column number (starting from zero)
   * @return an Object holding the column value
   * @throws SQLException if an error occurs
   * @throws EndOfTable if the table is advanced beyond that last row
   */
  public Object getObject(int column) throws SQLException, EndOfTable;


};
