/**************************************************************
 *
 * 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#include <stdio.h>
#include <string.h>
#include <osl/diagnose.h>
#include "odbc/OPreparedStatement.hxx"
#include "odbc/OBoundParam.hxx"
#include <com/sun/star/sdbc/DataType.hpp>
#include "odbc/OTools.hxx"
#include "odbc/ODriver.hxx"
#include "odbc/OResultSet.hxx"
#include "odbc/OResultSetMetaData.hxx"
#include <cppuhelper/typeprovider.hxx>
#include <comphelper/sequence.hxx>
#include <com/sun/star/lang/DisposedException.hpp>
#include "connectivity/dbtools.hxx"
#include <comphelper/types.hxx>
#include "connectivity/FValue.hxx"
#include "resource/common_res.hrc"
#include "connectivity/sqlparse.hxx"

using namespace ::comphelper;
using namespace connectivity;
using namespace connectivity::odbc;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::sdbcx;
using namespace com::sun::star::container;
using namespace com::sun::star::io;
using namespace com::sun::star::util;

IMPLEMENT_SERVICE_INFO(OPreparedStatement,"com.sun.star.sdbcx.OPreparedStatement","com.sun.star.sdbc.PreparedStatement");


OPreparedStatement::OPreparedStatement( OConnection* _pConnection,const ::rtl::OUString& sql)
	:OStatement_BASE2(_pConnection)
    ,numParams(0)
	,boundParams(NULL)
	,m_bPrepared(sal_False)
{
	m_sSqlStatement = sql;
	try
	{
		if(_pConnection->isParameterSubstitutionEnabled())
		{
			OSQLParser aParser(_pConnection->getDriver()->getORB());
			::rtl::OUString sErrorMessage;
			::rtl::OUString sNewSql;
            ::std::auto_ptr<OSQLParseNode> pNode( aParser.parseTree(sErrorMessage,sql) );
			if ( pNode.get() )
			{	// special handling for parameters
				OSQLParseNode::substituteParameterNames(pNode.get());
				pNode->parseNodeToStr( sNewSql, _pConnection );
				m_sSqlStatement = sNewSql;
			}
		}
	}
	catch(Exception&)
	{
	}
}
// -----------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::acquire() throw()
{
	OStatement_BASE2::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::release() throw()
{
	OStatement_BASE2::release();
}
// -----------------------------------------------------------------------------
Any SAL_CALL OPreparedStatement::queryInterface( const Type & rType ) throw(RuntimeException)
{
	Any aRet = OStatement_BASE2::queryInterface(rType);
	return aRet.hasValue() ? aRet : OPreparedStatement_BASE::queryInterface(rType);
}
// -------------------------------------------------------------------------
::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL OPreparedStatement::getTypes(  ) throw(::com::sun::star::uno::RuntimeException)
{
	return ::comphelper::concatSequences(OPreparedStatement_BASE::getTypes(),OStatement_BASE2::getTypes());
}
// -------------------------------------------------------------------------

Reference< XResultSetMetaData > SAL_CALL OPreparedStatement::getMetaData(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);


	prepareStatement();
	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
	if(!m_xMetaData.is())
		m_xMetaData = new OResultSetMetaData(getOwnConnection(),m_aStatementHandle);
	return m_xMetaData;
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::close(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);


	// Close/clear our result set
	clearMyResultSet ();

	// Reset last warning message

	try {
		clearWarnings ();
		OStatement_BASE2::close();
		FreeParams();
	}
	catch (SQLException &) {
		// If we get an error, ignore
	}

	// Remove this Statement object from the Connection object's
	// list
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL OPreparedStatement::execute(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);


	sal_Bool needData = sal_False;

	// Reset warnings

	clearWarnings ();

	// Reset the statement handle, warning and saved Resultset

	reset();

	// Call SQLExecute
	prepareStatement();

	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
	try
	{
		SQLRETURN nReturn = N3SQLExecute(m_aStatementHandle);

		OTools::ThrowException(m_pConnection,nReturn,m_aStatementHandle,SQL_HANDLE_STMT,*this);
		needData = nReturn == SQL_NEED_DATA;

		// Now loop while more data is needed (i.e. a data-at-
		// execution parameter was given).  For each parameter
		// that needs data, put the data from the input stream.

		while (needData) {

			// Get the parameter number that requires data

			sal_Int32* paramIndex = 0;
			nReturn = N3SQLParamData(m_aStatementHandle,(SQLPOINTER*)&paramIndex);

			// If the parameter index is -1, there is no
			// more data required

			if ( !paramIndex || ( *paramIndex == -1 ) )
				needData = sal_False;
			else
			{
				// Now we have the proper parameter
				// index, get the data from the input
				// stream and do a SQLPutData
				putParamData (*paramIndex);
			}
		}

	}
	catch (const SQLWarning&)
	{
	}

	// Now loop while more data is needed (i.e. a data-at-
	// execution parameter was given).  For each parameter
	// that needs data, put the data from the input stream.

	while (needData) {

		// Get the parameter number that requires data

		sal_Int32* paramIndex = 0;
		N3SQLParamData (m_aStatementHandle,(SQLPOINTER*)&paramIndex);

		// If the parameter index is -1, there is no more
		// data required

		if (*paramIndex == -1) {
			needData = sal_False;
		}
		else {
			// Now we have the proper parameter index,
			// get the data from the input stream
			// and do a SQLPutData
			putParamData(*paramIndex);
		}
	}

	// Now determine if there is a result set associated with
	// the SQL statement that was executed.  Get the column
	// count, and if it is not zero, there is a result set.


	return getColumnCount() > 0;
}
// -------------------------------------------------------------------------

sal_Int32 SAL_CALL OPreparedStatement::executeUpdate(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);

	sal_Int32 numRows = -1;

	prepareStatement();
	// Execute the statement.  If execute returns sal_False, a
	// row count exists.

	if (!execute())
		numRows = getUpdateCount ();
	else
    {
		// No update count was produced (a ResultSet was).  Raise
		// an exception
		m_pConnection->throwGenericSQLException(STR_NO_ROWCOUNT,*this);
	}
	return numRows;
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setString( sal_Int32 parameterIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
{
	::rtl::OString aString(::rtl::OUStringToOString(x,getOwnConnection()->getTextEncoding()));
	setParameter(parameterIndex,DataType::CHAR,aString.getLength(),(void*)&x);
}
// -------------------------------------------------------------------------

Reference< XConnection > SAL_CALL OPreparedStatement::getConnection(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);

	return (Reference< XConnection >)m_pConnection;
}
// -------------------------------------------------------------------------

Reference< XResultSet > SAL_CALL OPreparedStatement::executeQuery(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);

	Reference< XResultSet > rs = NULL;

	prepareStatement();

	if (execute())
		rs = getResultSet(sal_False);
	else
    {
		// No ResultSet was produced.  Raise an exception
        m_pConnection->throwGenericSQLException(STR_NO_RESULTSET,*this);
	}
	return rs;
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setBoolean( sal_Int32 parameterIndex, sal_Bool x ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);


	sal_Int32 value = 0;

	// If the parameter is sal_True, set the value to 1
	if (x) {
		value = 1;
	}

	// Set the parameter as if it were an integer
	setInt (parameterIndex, value);
}
// -------------------------------------------------------------------------
void OPreparedStatement::setParameter(sal_Int32 parameterIndex,sal_Int32 _nType,sal_Int32 _nSize,void* _pData)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);

	prepareStatement();
	// Allocate a buffer to be used in binding.  This will be
		// a 'permanent' buffer that the bridge will fill in with
		// the bound data in native format.


	checkParameterIndex(parameterIndex);
	sal_Int32 nRealSize = _nSize;
	SQLSMALLINT fSqlType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(_nType));
	switch(fSqlType)
	{
		case SQL_CHAR:
		case SQL_VARCHAR:
		case SQL_DECIMAL:
		case SQL_NUMERIC:
			++nRealSize;
			break;
		case SQL_BINARY:
		case SQL_VARBINARY:
			nRealSize=1;    //dummy buffer, binary data isn't copied
			break;
		default:
			break;
	}

	sal_Int8* bindBuf = allocBindBuf(parameterIndex, nRealSize);

	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
	OTools::bindParameter(	m_pConnection,
							m_aStatementHandle,
							parameterIndex,
							bindBuf,
							getLengthBuf(parameterIndex),
							fSqlType,
							sal_False,
							m_pConnection->useOldDateFormat(),
							_pData,
							(Reference <XInterface>)*this,
							getOwnConnection()->getTextEncoding());
}
// -----------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setByte( sal_Int32 parameterIndex, sal_Int8 x ) throw(SQLException, RuntimeException)
{
	setParameter(parameterIndex,DataType::TINYINT,sizeof(sal_Int8),&x);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setDate( sal_Int32 parameterIndex, const Date& aData ) throw(SQLException, RuntimeException)
{
	DATE_STRUCT x = OTools::DateToOdbcDate(aData);
	setParameter(parameterIndex,DataType::DATE,sizeof(DATE_STRUCT),&x);
}
// -------------------------------------------------------------------------


void SAL_CALL OPreparedStatement::setTime( sal_Int32 parameterIndex, const Time& aVal ) throw(SQLException, RuntimeException)
{
	TIME_STRUCT x = OTools::TimeToOdbcTime(aVal);
	setParameter(parameterIndex,DataType::TIME,sizeof(TIME_STRUCT),&x);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setTimestamp( sal_Int32 parameterIndex, const DateTime& aVal ) throw(SQLException, RuntimeException)
{
	TIMESTAMP_STRUCT x = OTools::DateTimeToTimestamp(aVal);
	setParameter(parameterIndex,DataType::TIMESTAMP,sizeof(TIMESTAMP_STRUCT),&x);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setDouble( sal_Int32 parameterIndex, double x ) throw(SQLException, RuntimeException)
{
	setParameter(parameterIndex,DataType::DOUBLE,sizeof(double),&x);
}

// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setFloat( sal_Int32 parameterIndex, float x ) throw(SQLException, RuntimeException)
{
	setParameter(parameterIndex,DataType::FLOAT,sizeof(float),&x);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setInt( sal_Int32 parameterIndex, sal_Int32 x ) throw(SQLException, RuntimeException)
{
	setParameter(parameterIndex,DataType::INTEGER,sizeof(sal_Int32),&x);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setLong( sal_Int32 parameterIndex, sal_Int64 x ) throw(SQLException, RuntimeException)
{
	try
	{
		setParameter(parameterIndex,DataType::BIGINT,sizeof(sal_Int64),&x);
	}
	catch(SQLException&)
	{
		setString(parameterIndex,ORowSetValue(x));
	}
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setNull( sal_Int32 parameterIndex, sal_Int32 sqlType ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);


	prepareStatement();
	// Get the buffer needed for the length
	checkParameterIndex(parameterIndex);

	sal_Int8* lenBuf = getLengthBuf (parameterIndex);
	*(SQLLEN*)lenBuf = SQL_NULL_DATA;


	SQLLEN prec = 0;
	SQLULEN nColumnSize = 0;
	if (sqlType == SQL_CHAR || sqlType == SQL_VARCHAR || sqlType == SQL_LONGVARCHAR)
	{
		prec = 1;
		nColumnSize = 1;
	}

	SQLSMALLINT fCType = 0;
	SQLSMALLINT fSqlType = 0;

	SQLSMALLINT nDecimalDigits = 0;
	OTools::getBindTypes(	sal_False,
							m_pConnection->useOldDateFormat(),
                            (SQLSMALLINT)sqlType,
							fCType,
							fSqlType);

	SQLRETURN nReturn = N3SQLBindParameter(	m_aStatementHandle,
											(SQLUSMALLINT)parameterIndex,
											(SQLSMALLINT)SQL_PARAM_INPUT,
											fCType,
											fSqlType,
											nColumnSize,
											nDecimalDigits,
											NULL,
											prec,
											(SQLLEN*)lenBuf
											);
	OTools::ThrowException(m_pConnection,nReturn,m_aStatementHandle,SQL_HANDLE_STMT,*this);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setClob( sal_Int32 parameterIndex, const Reference< XClob >& x ) throw(SQLException, RuntimeException)
{
	if ( x.is() )
		setStream(parameterIndex, x->getCharacterStream(), (SQLLEN)x->length(), DataType::LONGVARCHAR);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setBlob( sal_Int32 parameterIndex, const Reference< XBlob >& x ) throw(SQLException, RuntimeException)
{
    if ( x.is() )
		setStream(parameterIndex, x->getBinaryStream(), (SQLLEN)x->length(), DataType::LONGVARCHAR);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setArray( sal_Int32 /*parameterIndex*/, const Reference< XArray >& /*x*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XParameters::setArray", *this );
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setRef( sal_Int32 /*parameterIndex*/, const Reference< XRef >& /*x*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XParameters::setRef", *this );
}
// -------------------------------------------------------------------------
void OPreparedStatement::setDecimal( sal_Int32 parameterIndex, const ::rtl::OUString& x )
{
	::rtl::OString aString(::rtl::OUStringToOString(x,getOwnConnection()->getTextEncoding()));
	setParameter(parameterIndex,DataType::DECIMAL,aString.getLength(),(void*)&x);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::setObjectWithInfo( sal_Int32 parameterIndex, const Any& x, sal_Int32 sqlType, sal_Int32 scale ) throw(SQLException, RuntimeException)
{
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );

	prepareStatement();
	// For each known SQL Type, call the appropriate
		// set routine

	switch (sqlType)
	{
		case DataType::VARCHAR:
		case DataType::LONGVARCHAR:
			if(x.hasValue())
			{
				::rtl::OUString sStr;
				x >>= sStr;
				::rtl::OString aString(::rtl::OUStringToOString(sStr,getOwnConnection()->getTextEncoding()));
				setParameter(parameterIndex,sqlType,aString.getLength(),&aString);
			}
			else
				setNull(parameterIndex,sqlType);
			break;
        case DataType::DECIMAL:
            {
                ORowSetValue aValue;
                aValue.fill(x);
                setDecimal(parameterIndex,aValue);
            }
            break;
        case DataType::NUMERIC:
            {
                ORowSetValue aValue;
                aValue.fill(x);
                setString(parameterIndex,aValue);
            }
            break;
		default:
			::dbtools::setObjectWithInfo(this,parameterIndex,x,sqlType,scale);
		}
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setObjectNull( sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& /*typeName*/ ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);

	setNull(parameterIndex,sqlType);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setObject( sal_Int32 parameterIndex, const Any& x ) throw(SQLException, RuntimeException)
{
	if (!::dbtools::implSetObject(this, parameterIndex, x))
	{	// there is no other setXXX call which can handle the value in x
		throw SQLException();
	}
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setShort( sal_Int32 parameterIndex, sal_Int16 x ) throw(SQLException, RuntimeException)
{
	setParameter(parameterIndex,DataType::SMALLINT,sizeof(sal_Int16),&x);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setBytes( sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
{
	setParameter(parameterIndex,DataType::BINARY,x.getLength(),(void*)&x);
	boundParams[parameterIndex-1].setSequence(x); // this assures that the sequence stays alive
}
// -------------------------------------------------------------------------


void SAL_CALL OPreparedStatement::setCharacterStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
{
	setStream(parameterIndex, x, length, DataType::LONGVARCHAR);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::setBinaryStream( sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
{
	setStream(parameterIndex, x, length, DataType::LONGVARBINARY);
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::clearParameters(  ) throw(SQLException, RuntimeException)
{
	prepareStatement();
	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
	SQLRETURN nRet = N3SQLFreeStmt (m_aStatementHandle, SQL_RESET_PARAMS);
	nRet = N3SQLFreeStmt (m_aStatementHandle, SQL_UNBIND);
}
// -------------------------------------------------------------------------
void SAL_CALL OPreparedStatement::clearBatch(  ) throw(SQLException, RuntimeException)
{
	//	clearParameters(  );
	//	m_aBatchList.erase();
}
// -------------------------------------------------------------------------

void SAL_CALL OPreparedStatement::addBatch( ) throw(SQLException, RuntimeException)
{
}
// -------------------------------------------------------------------------

Sequence< sal_Int32 > SAL_CALL OPreparedStatement::executeBatch(  ) throw(SQLException, RuntimeException)
{
	return Sequence< sal_Int32 > ();
}
// -------------------------------------------------------------------------

//====================================================================
// methods
//====================================================================

//--------------------------------------------------------------------
// initBoundParam
// Initialize the bound parameter objects
//--------------------------------------------------------------------

void OPreparedStatement::initBoundParam () throw(SQLException)
{
	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
	// Get the number of parameters
	numParams = 0;
	N3SQLNumParams (m_aStatementHandle,&numParams);

	// There are parameter markers, allocate the bound
	// parameter objects

	if (numParams > 0)
	{
		// Allocate an array of bound parameter objects

		boundParams = new OBoundParam[numParams];

		// Allocate and initialize each bound parameter

		for (sal_Int32 i = 0; i < numParams; i++)
		{
			boundParams[i] = OBoundParam();
			boundParams[i].initialize ();
		}
	}
}
// -------------------------------------------------------------------------

//--------------------------------------------------------------------
// allocBindBuf
// Allocate storage for the permanent data buffer for the bound
// parameter.
//--------------------------------------------------------------------

sal_Int8* OPreparedStatement::allocBindBuf(	sal_Int32 index,sal_Int32 bufLen)
{
	sal_Int8* b = NULL;

	// Sanity check the parameter number

	if ((index >= 1) &&
		(index <= numParams) && bufLen > 0 )
	{
		b = boundParams[index - 1].allocBindDataBuffer(bufLen);
	}

	return b;
}
// -------------------------------------------------------------------------

//--------------------------------------------------------------------
// getDataBuf
// Gets the data buffer for the given parameter index
//--------------------------------------------------------------------

sal_Int8* OPreparedStatement::getDataBuf (sal_Int32 index)
{
	sal_Int8* b = NULL;

	// Sanity check the parameter number

	if ((index >= 1) &&
		(index <= numParams))
	{
		b = boundParams[index - 1].getBindDataBuffer ();
	}

	return b;
}
// -------------------------------------------------------------------------

//--------------------------------------------------------------------
// getLengthBuf
// Gets the length buffer for the given parameter index
//--------------------------------------------------------------------

sal_Int8* OPreparedStatement::getLengthBuf (sal_Int32 index)
{
	sal_Int8* b = NULL;

	// Sanity check the parameter number

	if ((index >= 1) &&
		(index <= numParams))
	{
		b = boundParams[index - 1].getBindLengthBuffer ();
	}

	return b;
}
// -------------------------------------------------------------------------

//--------------------------------------------------------------------
// getParamLength
// Returns the length of the given parameter number.  When each
// parameter was bound, a 4-sal_Int8 buffer was given to hold the
// length (stored in native format).  Get the buffer, convert the
// buffer from native format, and return it.  If the length is -1,
// the column is considered to be NULL.
//--------------------------------------------------------------------

sal_Int32 OPreparedStatement::getParamLength (	sal_Int32 index)
{
	sal_Int32 paramLen = SQL_NULL_DATA;

	// Sanity check the parameter number

	if ((index >= 1) &&
		(index <= numParams)) {

		// Now get the length of the parameter from the
		// bound param array.  -1 is returned if it is NULL.
		long n = 0;
		memcpy (&n, boundParams[index -1].getBindLengthBuffer (), sizeof (n));
		paramLen = n;
	}
	return paramLen;
}
// -------------------------------------------------------------------------

//--------------------------------------------------------------------
// putParamData
// Puts parameter data from a previously bound input stream.  The
// input stream was bound using SQL_LEN_DATA_AT_EXEC.
//--------------------------------------------------------------------

void OPreparedStatement::putParamData (sal_Int32 index) throw(SQLException)
{
	// Sanity check the parameter index
	if ((index < 1) ||
		(index > numParams))
	{
		return;
	}

	// We'll transfer up to MAX_PUT_DATA_LENGTH at a time
    Sequence< sal_Int8 > buf( MAX_PUT_DATA_LENGTH );

	// Get the information about the input stream

	Reference< XInputStream> inputStream =	boundParams[index - 1].getInputStream ();
	if ( !inputStream.is() )
	{
        ::connectivity::SharedResources aResources;
        const ::rtl::OUString sError( aResources.getResourceString(STR_NO_INPUTSTREAM));
		throw SQLException (sError,	*this,::rtl::OUString(),0,Any());
	}

	sal_Int32 maxBytesLeft = boundParams[index - 1].getInputStreamLen ();

	// Loop while more data from the input stream
    sal_Int32 haveRead = 0;
	try
	{

		do
		{
            sal_Int32 toReadThisRound = ::std::min( MAX_PUT_DATA_LENGTH, maxBytesLeft );

			// Read some data from the input stream
			haveRead = inputStream->readBytes( buf, toReadThisRound );
            OSL_ENSURE( haveRead == buf.getLength(), "OPreparedStatement::putParamData: inconsistency!" );

            if ( !haveRead )
                // no more data in the stream - the given stream length was a maximum which could not be
                // fulfilled by the stream
                break;

		    // Put the data
            OSL_ENSURE( m_aStatementHandle, "OPreparedStatement::putParamData: StatementHandle is null!" );
		    N3SQLPutData ( m_aStatementHandle, buf.getArray(), buf.getLength() );

			// decrement the number of bytes still needed
			maxBytesLeft -= haveRead;
		}
        while ( maxBytesLeft > 0 );
	}
	catch (const IOException& ex)
	{

		// If an I/O exception was generated, turn
		// it into a SQLException

		throw SQLException(ex.Message,*this,::rtl::OUString(),0,Any());
	}
}
// -------------------------------------------------------------------------
//--------------------------------------------------------------------
// getPrecision
// Given a SQL type, return the maximum precision for the column.
// Returns -1 if not known
//--------------------------------------------------------------------

sal_Int32 OPreparedStatement::getPrecision ( sal_Int32 sqlType)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);

	sal_Int32 prec = -1;
    const TTypeInfoVector& rTypeInfo = m_pConnection->getTypeInfo();
    if ( !rTypeInfo.empty() )
    {
        m_pConnection->buildTypeInfo();
    }

	if ( !rTypeInfo.empty() )
	{
		OTypeInfo aInfo;
		aInfo.nType = (sal_Int16)sqlType;
		TTypeInfoVector::const_iterator aIter = ::std::find(rTypeInfo.begin(),rTypeInfo.end(),aInfo);
		if(aIter != rTypeInfo.end())
			prec = (*aIter).nPrecision;
	}
	return prec;
}

//--------------------------------------------------------------------
// setStream
// Sets an input stream as a parameter, using the given SQL type
//--------------------------------------------------------------------

void OPreparedStatement::setStream(
									sal_Int32 ParameterIndex,
									const Reference< XInputStream>& x,
									SQLLEN length,
									sal_Int32 SQLtype)
									throw(SQLException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(OStatement_BASE::rBHelper.bDisposed);


	prepareStatement();

	checkParameterIndex(ParameterIndex);
	// Get the buffer needed for the length

	sal_Int8* lenBuf = getLengthBuf(ParameterIndex);

	// Allocate a new buffer for the parameter data.  This buffer
	// will be returned by SQLParamData (it is set to the parameter
	// number, a 4-sal_Int8 integer)

	sal_Int8* dataBuf = allocBindBuf (ParameterIndex, 4);

    // Bind the parameter with SQL_LEN_DATA_AT_EXEC
	SQLSMALLINT   Ctype = SQL_C_CHAR;
	SQLLEN	atExec = SQL_LEN_DATA_AT_EXEC (length);
	memcpy (dataBuf, &ParameterIndex, sizeof(ParameterIndex));
	memcpy (lenBuf, &atExec, sizeof (atExec));

	if ((SQLtype == SQL_BINARY) || (SQLtype == SQL_VARBINARY) || (SQLtype == SQL_LONGVARBINARY))
		Ctype = SQL_C_BINARY;


	OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
	N3SQLBindParameter(m_aStatementHandle,
						(SQLUSMALLINT)ParameterIndex,
						(SQLUSMALLINT)SQL_PARAM_INPUT,
						Ctype,
						(SQLSMALLINT)SQLtype,
						(SQLULEN)length,
						0,
						dataBuf,
						sizeof(ParameterIndex),
						(SQLLEN*)lenBuf);

	// Save the input stream
	boundParams[ParameterIndex - 1].setInputStream (x, length);
}
// -------------------------------------------------------------------------

// -------------------------------------------------------------------------

void OPreparedStatement::FreeParams()
{
    numParams = 0;
	delete [] boundParams;
	boundParams = NULL;
}
// -------------------------------------------------------------------------
void OPreparedStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue) throw (Exception)
{
	try
	{
		switch(nHandle)
		{
			case PROPERTY_ID_RESULTSETCONCURRENCY:
				if(!isPrepared())
					setResultSetConcurrency(comphelper::getINT32(rValue));
				break;
			case PROPERTY_ID_RESULTSETTYPE:
				if(!isPrepared())
					setResultSetType(comphelper::getINT32(rValue));
				break;
			case PROPERTY_ID_FETCHDIRECTION:
				if(!isPrepared())
					setFetchDirection(comphelper::getINT32(rValue));
				break;
			case PROPERTY_ID_USEBOOKMARKS:
				if(!isPrepared())
					setUsingBookmarks(comphelper::getBOOL(rValue));
				break;
			default:
				OStatement_Base::setFastPropertyValue_NoBroadcast(nHandle,rValue);
		}
	}
	catch(const SQLException&)
	{
		//	throw Exception(e.Message,*this);
	}
}
// -----------------------------------------------------------------------------
void OPreparedStatement::prepareStatement()
{
	if(!isPrepared())
	{
		OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
		::rtl::OString aSql(::rtl::OUStringToOString(m_sSqlStatement,getOwnConnection()->getTextEncoding()));
		SQLRETURN nReturn = N3SQLPrepare(m_aStatementHandle,(SDB_ODBC_CHAR *) aSql.getStr(),aSql.getLength());
		OTools::ThrowException(m_pConnection,nReturn,m_aStatementHandle,SQL_HANDLE_STMT,*this);
        m_bPrepared = sal_True;
		initBoundParam();
	}
}
// -----------------------------------------------------------------------------
void OPreparedStatement::checkParameterIndex(sal_Int32 _parameterIndex)
{
	if(	!_parameterIndex || _parameterIndex > numParams)
	{
        ::connectivity::SharedResources aResources;
        const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(STR_WRONG_PARAM_INDEX,
            "$pos$", ::rtl::OUString::valueOf(_parameterIndex),
            "$count$", ::rtl::OUString::valueOf((sal_Int32)numParams)
            ));
        SQLException aNext(sError,*this, ::rtl::OUString(),0,Any());

        ::dbtools::throwInvalidIndexException(*this,makeAny(aNext));
	}
}
// -----------------------------------------------------------------------------
OResultSet* OPreparedStatement::createResulSet()
{
    OResultSet* pReturn = new OResultSet(m_aStatementHandle,this);
    pReturn->setMetaData(getMetaData());
	return pReturn;
}
// -----------------------------------------------------------------------------
