package ModSQL;
import java.sql.*;

/* $Id: Connection.java,v 1.4 2003/05/29 07:19:39 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 Connection represents a session with a specific
 * database. Within the context of a Connection, SQL statements are
 * executed and results are returned.
 *
 * <P>A Connection's database is able to provide information
 * describing its tables, its supported SQL grammar, its stored
 * procedures, the capabilities of this connection, etc. This
 * information is obtained with the getMetaData method.
 *
 * <P><B>Note:</B> By default the Connection automatically commits
 * changes after executing each statement. If auto commit has been
 * disabled, an explicit commit must be done or database changes will
 * not be saved.
 *
 * @see PreparedStatement
 * @see ResultSet
 * @see DatabaseMetaData
 * @author chris.studholme@utoronto.ca
 */
public class Connection implements java.sql.Connection {

  /** DatabaseManager to use for looking up tables. */
  protected DatabaseManager tablemanager;

  /**
   * Constructor.  Uses {@link MetaManager} as default DatabaseManager.
   */
  public Connection() {
    tablemanager = new MetaManager();
  }


  /**
   * SQL statements without parameters are normally
   * executed using Statement objects. If the same SQL statement 
   * is executed many times, it is more efficient to use a 
   * PreparedStatement
   *
   * @return a new Statement object 
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Statement createStatement() throws SQLException {
    //return new Statement(tablemanager,this);
    return new PreparedStatement(tablemanager,this);
  }
  
  /**
   * A SQL statement with or without IN parameters can be
   * pre-compiled and stored in a PreparedStatement object. This
   * object can then be used to efficiently execute this statement
   * multiple times.
   *
   * <P><B>Note:</B> This method is optimized for handling
   * parametric SQL statements that benefit from precompilation. If
   * the driver supports precompilation, prepareStatement will send
   * the statement to the database for precompilation. Some drivers
   * may not support precompilation. In this case, the statement may
   * not be sent to the database until the PreparedStatement is
   * executed.  This has no direct affect on users; however, it does
   * affect which method throws certain SQLExceptions.
   *
   * @param sql a SQL statement that may contain one or more '?' IN
   * parameter placeholders
   * @return a new PreparedStatement object containing the
   * pre-compiled statement 
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.PreparedStatement prepareStatement(String sql) 
    throws SQLException {
    return new PreparedStatement(tablemanager,this,sql);
  }

  /**
   * A SQL stored procedure call statement is handled by creating a
   * CallableStatement for it. The CallableStatement provides
   * methods for setting up its IN and OUT parameters, and
   * methods for executing it.
   *
   * <P><B>Note:</B> This method is optimized for handling stored
   * procedure call statements. Some drivers may send the call
   * statement to the database when the prepareCall is done; others
   * may wait until the CallableStatement is executed. This has no
   * direct affect on users; however, it does affect which method
   * throws certain SQLExceptions.
   *
   * @param sql a SQL statement that may contain one or more '?'
   * parameter placeholders. Typically this  statement is a JDBC
   * function call escape string.
   * @return a new CallableStatement object containing the
   * pre-compiled SQL statement 
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.CallableStatement prepareCall(String sql) 
    throws SQLException {
    return null;
  }
						
  /**
   * A driver may convert the JDBC sql grammar into its system's
   * native SQL grammar prior to sending it; nativeSQL returns the
   * native form of the statement that the driver would have sent.
   *
   * @param sql a SQL statement that may contain one or more '?'
   * parameter placeholders
   * @return the native form of this statement
   * @throws SQLException if a database-access error occurs.
   */
  public String nativeSQL(String sql) throws SQLException {
    return sql;
  }

  /**
   * If a connection is in auto-commit mode, then all its SQL
   * statements will be executed and committed as individual
   * transactions.  Otherwise, its SQL statements are grouped into
   * transactions that are terminated by either commit() or
   * rollback().  By default, new connections are in auto-commit
   * mode.
   *
   * The commit occurs when the statement completes or the next
   * execute occurs, whichever comes first. In the case of
   * statements returning a ResultSet, the statement completes when
   * the last row of the ResultSet has been retrieved or the
   * ResultSet has been closed. In advanced cases, a single
   * statement may return multiple results as well as output
   * parameter values. Here the commit occurs when all results and
   * output param values have been retrieved.
   *
   * @param autoCommit true enables auto-commit; false disables
   * auto-commit.  
   * @throws SQLException if a database-access error occurs.
   */
  public void setAutoCommit(boolean autoCommit) throws SQLException {
  }

  /**
   * Get the current auto-commit state.
   *
   * @return Current state of auto-commit mode.
   * @throws SQLException if a database-access error occurs.
   * @see #setAutoCommit 
   */
  public boolean getAutoCommit() throws SQLException {
    return true;
  }

  /**
   * Commit makes all changes made since the previous
   * commit/rollback permanent and releases any database locks
   * currently held by the Connection. This method should only be
   * used when auto commit has been disabled.
   *
   * @throws SQLException if a database-access error occurs.
   * @see #setAutoCommit 
   */
  public void commit() throws SQLException {
  }
  
  /**
   * Rollback drops all changes made since the previous
   * commit/rollback and releases any database locks currently held
   * by the Connection. This method should only be used when auto
   * commit has been disabled.
   *
   * @throws SQLException if a database-access error occurs.
   * @see #setAutoCommit 
   */
  public void rollback() throws SQLException {
  }

  /**
   * In some cases, it is desirable to immediately release a
   * Connection's database and JDBC resources instead of waiting for
   * them to be automatically released; the close method provides this
   * immediate release. 
   *
   * <P><B>Note:</B> A Connection is automatically closed when it is
   * garbage collected. Certain fatal errors also result in a closed
   * Connection.
   *
   * @throws SQLException if a database-access error occurs.
   */
  public void close() throws SQLException {
    tablemanager=null;
  }

  /**
   * Tests to see if a Connection is closed.
   *
   * @return true if the connection is closed; false if it's still open
   * @throws SQLException if a database-access error occurs.
   */
  public boolean isClosed() throws SQLException {
    return (tablemanager==null);
  }

  //======================================================================
  // Advanced features:

  /**
   * A Connection's database is able to provide information
   * describing its tables, its supported SQL grammar, its stored
   * procedures, the capabilities of this connection, etc. This
   * information is made available through a DatabaseMetaData
   * object.
   *
   * @return a DatabaseMetaData object for this Connection 
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.DatabaseMetaData getMetaData() throws SQLException {
    return new DatabaseMetaData();
  }

  /**
   * You can put a connection in read-only mode as a hint to enable 
   * database optimizations.
   *
   * <P><B>Note:</B> setReadOnly cannot be called while in the
   * middle of a transaction.
   *
   * @param readOnly true enables read-only mode; false disables
   * read-only mode.  
   * @throws SQLException if a database-access error occurs.
   */
  public void setReadOnly(boolean readOnly) throws SQLException {
  }

  /**
   * Tests to see if the connection is in read-only mode.
   *
   * @return true if connection is read-only
   * @throws SQLException if a database-access error occurs.
   */
  public boolean isReadOnly() throws SQLException {
    return false;
  }
  
  /**
   * A sub-space of this Connection's database may be selected by setting a
   * catalog name. If the driver does not support catalogs it will
   * silently ignore this request.
   *
   * @throws SQLException if a database-access error occurs.
   */
  public void setCatalog(String catalog) throws SQLException {
  }

  /**
   * Return the Connection's current catalog name.
   *
   * @return the current catalog name or null
   * @throws SQLException if a database-access error occurs.
   */
  public String getCatalog() throws SQLException {
    return null;
  }

  /**
   * You can call this method to try to change the transaction
   * isolation level using one of the TRANSACTION_* values.
   *
   * <P><B>Note:</B> setTransactionIsolation cannot be called while
   * in the middle of a transaction.
   *
   * @param level one of the TRANSACTION_* isolation values with the
   * exception of TRANSACTION_NONE; some databases may not support
   * other values
   * @throws SQLException if a database-access error occurs.
   * @see DatabaseMetaData#supportsTransactionIsolationLevel 
   */
  public void setTransactionIsolation(int level) throws SQLException {
  }

  /**
   * Get this Connection's current transaction isolation mode.
   *
   * @return the current TRANSACTION_* mode value
   * @throws SQLException if a database-access error occurs.
   */
  public int getTransactionIsolation() throws SQLException {
    return TRANSACTION_NONE;
  }
  
  /**
   * The first warning reported by calls on this Connection is
   * returned.  
   *
   * <P><B>Note:</B> Subsequent warnings will be chained to this
   * SQLWarning.
   *
   * @return the first SQLWarning or null 
   * @throws SQLException if a database-access error occurs.
   */
  public SQLWarning getWarnings() throws SQLException {
    return null;
  }
  
  /**
   * After this call, getWarnings returns null until a new warning is
   * reported for this Connection.  
   *
   * @throws SQLException if a database-access error occurs.
   */
  public void clearWarnings() throws SQLException {
  }

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

  /**
   * Same as createStatement() above, but allows the default result set
   * type and result set concurrency type to be overridden.
   *
   * @param resultSetType a result set type, see ResultSet.TYPE_XXX
   * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
   * @return a new Statement object 
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.Statement createStatement(int resultSetType, 
					    int resultSetConcurrency) 
    throws SQLException {
    return createStatement();
  }
  
  /**
   * Same as prepareStatement() above, but allows the default result set
   * type and result set concurrency type to be overridden.
   *
   * @param resultSetType a result set type, see ResultSet.TYPE_XXX
   * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
   * @return a new PreparedStatement object containing the
   * pre-compiled SQL statement 
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.PreparedStatement prepareStatement(String sql, 
						     int resultSetType, 
						     int resultSetConcurrency)
    throws SQLException {
    return prepareStatement(sql);
  }
  
  /**
   * Same as prepareCall() above, but allows the default result set
   * type and result set concurrency type to be overridden.
   *
   * @param resultSetType a result set type, see ResultSet.TYPE_XXX
   * @param resultSetConcurrency a concurrency type, see ResultSet.CONCUR_XXX
   * @return a new CallableStatement object containing the
   * pre-compiled SQL statement 
   * @throws SQLException if a database-access error occurs.
   */
  public java.sql.CallableStatement prepareCall(String sql, 
						int resultSetType, 
						int resultSetConcurrency) 
    throws SQLException {
    return prepareCall(sql);
  }
  
  /**
   * Not implemented.
   */
  public java.util.Map getTypeMap() throws SQLException {
    throw new SQLException("not implemented");
  }
  
  /**
   * Not implemented.
   */
  public void setTypeMap(java.util.Map map) throws SQLException {
    throw new SQLException("not implemented");
  }
}
