/*-----------------------------------------------------------------------------
 *
 * Enhydra JdbcS
 * The Initial Developer of the Original Code is Lutris Technologies Inc.
 * Portions created by Lutris are Copyright 1997-2000 Lutris Technologies Inc.
 * All Rights Reserved.
 *
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * www.enhydra.org/license/epl.html
 *
 * Software distributed under the License is distributed on an "ASIS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * -----------------------------------------------------------------------------
 * $Id$
 * -----------------------------------------------------------------------------
 */
package org.enhydra.jdbc.core;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.Map;

/**
 * This is an implementation of java.sql.Connection which simply
 * delegates everything to an underlying physical implemention
 * of the same interface.
 */
public abstract class CoreConnection implements Connection {
    public Connection con;	// the physical database connection

    /**
     * Constructor
     */
    public CoreConnection (Connection con) {
	this.con = con;
    } // method CoreConnection

    public CoreConnection () {}

    public void clearWarnings() throws SQLException {
	preInvoke();
	try {
	    con.clearWarnings();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method clearWarnings
    
    public void close() throws SQLException {
	preInvoke();
	try {
	    con.close();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method close

    public void commit() throws SQLException {
	preInvoke();
	try {
	    con.commit();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method commit
    
    public Statement createStatement() throws SQLException {
	preInvoke();
	try {
	    return con.createStatement();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method createStatement
    
    public Statement createStatement (int resultSetType, int resultSetConcurrency) 
	throws SQLException
    {
	preInvoke();
	try {
	    return con.createStatement (resultSetType, resultSetConcurrency);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method createStatement
    
    public boolean getAutoCommit() throws SQLException {
	preInvoke();
	try {
	    return con.getAutoCommit();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return false;
    } // method getAutoCommit

    public String getCatalog() throws SQLException {
	preInvoke();
	try {
	    return con.getCatalog();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getCatalog
    
    public DatabaseMetaData getMetaData() throws SQLException {
	preInvoke();
	try {
	    return con.getMetaData();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getMetaData

    public int getTransactionIsolation() throws SQLException {
	preInvoke();
	try {
	    return con.getTransactionIsolation();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getTransactionIsolation
    
    public Map getTypeMap() throws SQLException {
	preInvoke();
	try {
	    return con.getTypeMap();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getTypeMap

    public SQLWarning getWarnings() throws SQLException {
	preInvoke();
	try {
	    return con.getWarnings();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getWarnings

    public boolean isReadOnly() throws SQLException {
	preInvoke();
	try {
	    return con.isReadOnly();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return false;
    } // method isReadOnly

    public String nativeSQL(String sql) throws SQLException {
	preInvoke();	
	try {
	    return con.nativeSQL(sql);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method nativeSQL

    public CallableStatement prepareCall(String sql) throws SQLException {
	preInvoke();
	try {
	    return con.prepareCall(sql);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method CallableStatement
    
    public PreparedStatement prepareStatement(String sql) throws SQLException {
	preInvoke();
	try {
	    return con.prepareStatement(sql);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method PreparedStatement

    public PreparedStatement prepareStatement(String sql,int resultSetType,int resultSetConcurrency) 
	throws SQLException {
	preInvoke();
	try {
	    return con.prepareStatement(sql, resultSetType, resultSetConcurrency);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method PreparedStatement

    public void rollback() throws SQLException {
	preInvoke();
	try {
	    con.rollback();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method rollback

    public void setAutoCommit(boolean autoCommit) throws SQLException {
	preInvoke();
	try {
	    con.setAutoCommit(autoCommit);
	} catch (SQLException e) {
	    catchInvoke(e);
	}

    } // method setAutoCommit

    public void setCatalog(String catalog) throws SQLException {
	preInvoke();
	try {
	    con.setCatalog(catalog);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setCatalog

    public void setReadOnly(boolean readOnly) throws SQLException {
	preInvoke();
	try {
	    con.setReadOnly(readOnly);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setReadOnly

    public void setTransactionIsolation(int level) throws SQLException {
	preInvoke();
	try {
	    con.setTransactionIsolation(level);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setTransactionIsolation

    public void setTypeMap(Map map) throws SQLException {
	preInvoke();
	try {
	    con.setTypeMap(map);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setTypeMap


    /**
     * Methods used to do some works before and during the catch
     * clause, to prevent the pool that a connection is broken.
     */
    abstract public void preInvoke() throws SQLException;
    abstract public void catchInvoke(SQLException e) throws SQLException;

} // class CoreConnection
