/*

   Derby - Class com.pivotal.gemfirexd.internal.client.am.LogicalConnection40

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

/*
 * Changes for GemFireXD distributed data platform (some marked by "GemStone changes")
 *
 * Portions Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You
 * may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License. See accompanying
 * LICENSE file.
 */

package com.pivotal.gemfirexd.internal.client.am;

import java.sql.Array;
import java.sql.Blob;
import java.sql.SQLClientInfoException;
import java.sql.Clob;
import java.sql.NClob;
import java.sql.SQLXML;
import java.sql.SQLException;
import java.sql.Struct;
import java.sql.Wrapper;
import java.util.Properties;

import com.pivotal.gemfirexd.internal.client.ClientPooledConnection;
import com.pivotal.gemfirexd.internal.shared.common.reference.SQLState;

import java.util.Map;
import java.util.concurrent.Executor;

/**
 * A simple delegation wrapper handle for a physical connection.
 * This class only contains JDBC 4.0 specific methods.
 *
 * NOTE: All non-implemented JDBC 4.0 methods are located here, but when they
 *       are implemented, they should be moved to the superclass if possible.
 */
public class LogicalConnection40
    extends LogicalConnection {

    public LogicalConnection40(Connection physicalConnection,
                               ClientPooledConnection pooledConnection) 
        throws SqlException {
        super(physicalConnection, pooledConnection);
    }

    public Array createArrayOf(String typeName, Object[] elements)
        throws SQLException {
        try
        {
    		checkForNullPhysicalConnection();
            return physicalConnection_.createArrayOf( typeName, elements );
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }
    
    public Blob createBlob()
        throws SQLException {
        try
        {
    		checkForNullPhysicalConnection();
            return physicalConnection_.createBlob();
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }

    public Clob createClob()
        throws SQLException {
        try
        {
    		checkForNullPhysicalConnection();
            return physicalConnection_.createClob();
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }
    
    public NClob createNClob()
        throws SQLException {
        try
        {
    		checkForNullPhysicalConnection();
            return physicalConnection_.createNClob();
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }

    public SQLXML createSQLXML()
        throws SQLException {
        try
        {
    		checkForNullPhysicalConnection();
            return physicalConnection_.createSQLXML();
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }

    public Struct createStruct(String typeName, Object[] attributes)
        throws SQLException {
        try
        {
    		checkForNullPhysicalConnection();
            return physicalConnection_.createStruct( typeName, attributes );
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }

    /**
     * <code>getClientInfo</code> forwards to
     * <code>physicalConnection_</code>.
     * <code>getClientInfo</code> always returns an empty
     * <code>Properties</code> object since Derby doesn't support
     * ClientInfoProperties.
     *
     * @return an empty <code>Properties</code> object
     * @exception SQLException if an error occurs
     */
    public Properties getClientInfo()
        throws SQLException {
        try
        {
        	checkForNullPhysicalConnection();
        	return physicalConnection_.getClientInfo();
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }
    
    /**
     * <code>getClientInfo</code> forwards to
     * <code>physicalConnection_</code>. Always returns a <code>null
     * String</code> since Derby does not support
     * ClientInfoProperties.
     *
     * @param name a property key to get <code>String</code>
     * @return a property value <code>String</code>
     * @exception SQLException if an error occurs
     */
    public String getClientInfo(String name)
        throws SQLException {
        try
        {
        	checkForNullPhysicalConnection();
        	return physicalConnection_.getClientInfo(name);
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }

    /**
     * Returns the type map for this connection.
     *
     * @return type map for this connection
     * @exception SQLException if a database access error occurs
     */
    public Map<String, Class<?>> getTypeMap() throws SQLException {
        try
        {
            checkForNullPhysicalConnection();
            return ((java.sql.Connection) physicalConnection_).getTypeMap();
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }

    /**
     * Checks if the connection has not been closed and is still valid. 
     * The validity is checked by running a simple query against the 
     * database.
     *
     * @param timeout The time in seconds to wait for the database
     * operation used to validate the connection to complete. If the 
     * timeout period expires before the operation completes, this 
     * method returns false. A value of 0 indicates a timeout is not 
     * applied to the database operation.
     * @return true if the connection is valid, false otherwise
     * @throws SQLException if the call on the physical connection throws an
     * exception.
     */
    synchronized public boolean isValid(int timeout) throws SQLException {
        try
        {
            // Check if we have a underlying physical connection
            if (physicalConnection_ == null) {
                return false;
            }
            return physicalConnection_.isValid(timeout);
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }
   

    public boolean isWrapperFor(Class<?> interfaces)
        throws SQLException {
        try
        {
            checkForNullPhysicalConnection();
            return interfaces.isInstance(this);
		} catch (SQLException sqle) {
			notifyException(sqle);
			throw sqle;
		}
    }

    /**
     * <code>setClientInfo</code> forwards to
     * <code>physicalConnection_</code>.
     *
     * @param properties a <code>Properties</code> object with the
     * properties to set
     * @exception SQLClientInfoException if an error occurs
     */
    public void setClientInfo(Properties properties)
        throws SQLClientInfoException {
        try
        {
    		checkForNullPhysicalConnection(); 
        	physicalConnection_.setClientInfo(properties);
        } catch (SQLClientInfoException cie) {
            notifyException(cie);
            throw cie;
    	} catch (SQLException sqle) {
    		notifyException(sqle);
    	    throw new SQLClientInfoException
    		(sqle.getMessage(), sqle.getSQLState(), 
    				sqle.getErrorCode(),
    				(new FailedProperties40(properties)).getProperties());
    	}
    }
    
    /**
     * <code>setClientInfo</code> forwards to
     * <code>physicalConnection_</code>.
     *
     * @param name a property key <code>String</code>
     * @param value a property value <code>String</code>
     * @exception SQLException if an error occurs
     */
    public void setClientInfo(String name, String value)
        throws SQLClientInfoException {
        try
        {
    		checkForNullPhysicalConnection(); 
        	physicalConnection_.setClientInfo(name, value);
        } catch (SQLClientInfoException cie) {
            notifyException(cie);
            throw cie;
    	} catch (SQLException sqle) {
    		notifyException(sqle);
            throw new SQLClientInfoException
            (sqle.getMessage(), sqle.getSQLState(),
            		sqle.getErrorCode(),
             new FailedProperties40
             (FailedProperties40.makeProperties
              (name,value)).getProperties());
    	}
    }
    
    public <T>T unwrap(Class<T> interfaces)
        throws SQLException {
        try
        {
            checkForNullPhysicalConnection();
            // Derby does not implement non-standard methods on JDBC objects
            try {
                return interfaces.cast(this);
            } catch (ClassCastException cce) {
                throw new SqlException(null,
                                       new ClientMessageId(SQLState.UNABLE_TO_UNWRAP),
                                       interfaces).getSQLException(
                                           physicalConnection_ != null
                                               ? physicalConnection_.agent_
                                               : null /* GemStoneAddition */);
            }
    	} catch (SQLException sqle) {
    		notifyException(sqle);
    		throw sqle;
    	}
    }

    
    public void setSchema(String schema) throws SQLException {
      // TODO Auto-generated method stub
      
    }

    
    public String getSchema() throws SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    
    public void abort(Executor executor) throws SQLException {
      // TODO Auto-generated method stub
      
    }

    
    public void setNetworkTimeout(Executor executor, int milliseconds)
        throws SQLException {
      // TODO Auto-generated method stub
      
    }

    
    public int getNetworkTimeout() throws SQLException {
      // TODO Auto-generated method stub
      return 0;
    }
    
} // End class LogicalConnection40
