/**************************************************************
 * 
 * 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 "TConnection.hxx"

#ifndef _CONNECTIVITY_ADO_ADATABASEMETADATARESULTSET_HXX_
#include "odbc/ODatabaseMetaDataResultSet.hxx"
#endif
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/sdbc/KeyRule.hpp>
#include <com/sun/star/sdbc/ProcedureResult.hpp>
#include <com/sun/star/sdbc/IndexType.hpp>
#include <comphelper/property.hxx>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
#include <com/sun/star/sdbc/ResultSetType.hpp>
#include <com/sun/star/sdbc/FetchDirection.hpp>
#include <cppuhelper/typeprovider.hxx>
#include <comphelper/sequence.hxx>
#include "odbc/OResultSetMetaData.hxx"
#include "odbc/OTools.hxx"
#include <comphelper/types.hxx>
#include "FDatabaseMetaDataResultSetMetaData.hxx"
#include <connectivity/dbexception.hxx>

using namespace ::comphelper;


using namespace connectivity::odbc;
using namespace cppu;
//------------------------------------------------------------------------------
using namespace ::com::sun::star::lang;
using namespace com::sun::star::uno;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::util;

// -------------------------------------------------------------------------
ODatabaseMetaDataResultSet::ODatabaseMetaDataResultSet(OConnection* _pConnection)
	:ODatabaseMetaDataResultSet_BASE(m_aMutex)
	,OPropertySetHelper(ODatabaseMetaDataResultSet_BASE::rBHelper)

    ,m_aStatementHandle(_pConnection->createStatementHandle())
	,m_aStatement(NULL)
    ,m_xMetaData(NULL)
    ,m_pRowStatusArray(NULL)
    ,m_pConnection(_pConnection)
    ,m_nTextEncoding(_pConnection->getTextEncoding())
    ,m_nRowPos(-1)
    ,m_nLastColumnPos(0)
    ,m_nDriverColumnCount(0)
    ,m_nCurrentFetchState(0)
    ,m_bWasNull(sal_True)
    ,m_bEOF(sal_False)
	,m_bFreeHandle(sal_False)
{
	OSL_ENSURE(m_pConnection,"ODatabaseMetaDataResultSet::ODatabaseMetaDataResultSet: No parent set!");
	osl_incrementInterlockedCount( &m_refCount );
	m_pConnection->acquire();
	m_pRowStatusArray = new SQLUSMALLINT[1]; // the default value
	osl_decrementInterlockedCount( &m_refCount );
	//	allocBuffer();
}

// -------------------------------------------------------------------------
ODatabaseMetaDataResultSet::~ODatabaseMetaDataResultSet()
{
	OSL_ENSURE(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed,"Object wasn't disposed!");
	if(!ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed)
	{
		osl_incrementInterlockedCount( &m_refCount );
		dispose();
	}
	delete [] m_pRowStatusArray;
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::disposing(void)
{
	OPropertySetHelper::disposing();

	::osl::MutexGuard aGuard(m_aMutex);
	if(m_bFreeHandle)
		m_pConnection->freeStatementHandle(m_aStatementHandle);

	m_aStatement	= NULL;
m_xMetaData.clear();
	m_pConnection->release();
}
// -------------------------------------------------------------------------
Any SAL_CALL ODatabaseMetaDataResultSet::queryInterface( const Type & rType ) throw(RuntimeException)
{
	Any aRet = OPropertySetHelper::queryInterface(rType);
	return aRet.hasValue() ? aRet : ODatabaseMetaDataResultSet_BASE::queryInterface(rType);
}
// -----------------------------------------------------------------------------
Reference< XPropertySetInfo > SAL_CALL ODatabaseMetaDataResultSet::getPropertySetInfo(  ) throw(RuntimeException)
{
	return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseMetaDataResultSet::acquire() throw()
{
	ODatabaseMetaDataResultSet_BASE::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseMetaDataResultSet::release() throw()
{
	ODatabaseMetaDataResultSet_BASE::release();
}
// -------------------------------------------------------------------------
Sequence< Type > SAL_CALL ODatabaseMetaDataResultSet::getTypes(  ) throw(RuntimeException)
{
	::cppu::OTypeCollection aTypes(	::getCppuType( (const Reference< XMultiPropertySet > *)0 ),
									::getCppuType( (const Reference< XFastPropertySet > *)0 ),
									::getCppuType( (const Reference< XPropertySet > *)0 ));

	return ::comphelper::concatSequences(aTypes.getTypes(),ODatabaseMetaDataResultSet_BASE::getTypes());
}
// -----------------------------------------------------------------------------
sal_Int32 ODatabaseMetaDataResultSet::mapColumn (sal_Int32	column)
{
	sal_Int32	map = column;

	if (!m_aColMapping.empty())
	{
		// Validate column number
		map = m_aColMapping[column];
	}

	return map;
}
// -------------------------------------------------------------------------

sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	Reference< XResultSetMetaData > xMeta = getMetaData();
	sal_Int32 nLen = xMeta->getColumnCount();
	sal_Int32 i = 1;
	for(;i<=nLen;++i)
		if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
				columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
			break;
	return i;
}
// -------------------------------------------------------------------------
Reference< ::com::sun::star::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getBinaryStream", *this );
	return NULL;
}
// -------------------------------------------------------------------------
Reference< ::com::sun::star::io::XInputStream > SAL_CALL ODatabaseMetaDataResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getCharacterStream", *this );
    return NULL;
}

// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );

	columnIndex = mapColumn(columnIndex);

	sal_Bool bRet = sal_False;
	if(columnIndex <= m_nDriverColumnCount)
	{
		sal_Int32 nType = getMetaData()->getColumnType(columnIndex);
		switch(nType)
		{
			case DataType::BIT:
				{
					sal_Int8 nValue = 0;
					OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_BIT,m_bWasNull,**this,&nValue,sizeof nValue);
					bRet = nValue != 0;
				}
				break;
			default:
				bRet = getInt(columnIndex) != 0;
		}
	}
	return bRet;
}
// -------------------------------------------------------------------------

sal_Int8 SAL_CALL ODatabaseMetaDataResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	sal_Int8  nVal = 0;
	if(columnIndex <= m_nDriverColumnCount)
	{
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_TINYINT,m_bWasNull,**this,&nVal,sizeof nVal);

		::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator	aValueRangeIter;
		if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end())
			return sal_Int8((*aValueRangeIter).second[(sal_Int32)nVal]);
	}
	else
		m_bWasNull = sal_True;
	return nVal;
}
// -------------------------------------------------------------------------

Sequence< sal_Int8 > SAL_CALL ODatabaseMetaDataResultSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	if(columnIndex <= m_nDriverColumnCount)
	{
		sal_Int32 nType = getMetaData()->getColumnType(columnIndex);
		switch(nType)
		{
			case DataType::VARCHAR:
			case DataType::LONGVARCHAR:
			{
				::rtl::OUString aRet = OTools::getStringValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_BINARY,m_bWasNull,**this,m_nTextEncoding);
				return Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aRet.getStr()),sizeof(sal_Unicode)*aRet.getLength());
            }
		}
		return OTools::getBytesValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_BINARY,m_bWasNull,**this);
	}
	else
		m_bWasNull = sal_True;
	return Sequence<sal_Int8>();
}
// -------------------------------------------------------------------------

::com::sun::star::util::Date SAL_CALL ODatabaseMetaDataResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{
	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	if(columnIndex <= m_nDriverColumnCount)
	{
		DATE_STRUCT aDate;
		aDate.day = 0;
		aDate.month = 0;
		aDate.year = 0;
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,m_pConnection->useOldDateFormat() ? SQL_C_DATE : SQL_C_TYPE_DATE,m_bWasNull,**this,&aDate,sizeof aDate);
		return Date(aDate.day,aDate.month,aDate.year);
	}
	else
		m_bWasNull = sal_True;
	return Date();
}
// -------------------------------------------------------------------------

double SAL_CALL ODatabaseMetaDataResultSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	double nValue(0.0);
	if(columnIndex <= m_nDriverColumnCount)
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_DOUBLE,m_bWasNull,**this,&nValue,sizeof nValue);
	else
		m_bWasNull = sal_True;
	return nValue;
}
// -------------------------------------------------------------------------

float SAL_CALL ODatabaseMetaDataResultSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	float nVal(0);
	if(columnIndex <= m_nDriverColumnCount)
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_FLOAT,m_bWasNull,**this,&nVal,sizeof nVal);
	else
		m_bWasNull = sal_True;
	return nVal;
}
// -------------------------------------------------------------------------

sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	sal_Int32 nVal = 0;
	if(columnIndex <= m_nDriverColumnCount)
	{
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_LONG,m_bWasNull,**this,&nVal,sizeof nVal);

		::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator	aValueRangeIter;
		if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end())
			return (*aValueRangeIter).second[(sal_Int32)nVal];
	}
	else
		m_bWasNull = sal_True;
	return nVal;
}
// -------------------------------------------------------------------------

sal_Int32 SAL_CALL ODatabaseMetaDataResultSet::getRow(  ) throw(SQLException, RuntimeException)
{
	return 0;
}
// -------------------------------------------------------------------------

sal_Int64 SAL_CALL ODatabaseMetaDataResultSet::getLong( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getLong", *this );
    return 0;
}
// -------------------------------------------------------------------------

Reference< XResultSetMetaData > SAL_CALL ODatabaseMetaDataResultSet::getMetaData(  ) throw(SQLException, RuntimeException)
{
	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );
	return m_xMetaData.is() ? m_xMetaData :  (m_xMetaData = new OResultSetMetaData(m_pConnection,m_aStatementHandle));
}
// -------------------------------------------------------------------------
Reference< XArray > SAL_CALL ODatabaseMetaDataResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getArray", *this );
    return NULL;
}
// -------------------------------------------------------------------------
Reference< XClob > SAL_CALL ODatabaseMetaDataResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getClob", *this );
    return NULL;
}
// -------------------------------------------------------------------------
Reference< XBlob > SAL_CALL ODatabaseMetaDataResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getBlob", *this );
    return NULL;
}
// -------------------------------------------------------------------------

Reference< XRef > SAL_CALL ODatabaseMetaDataResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getRef", *this );
    return NULL;
}
// -------------------------------------------------------------------------

Any SAL_CALL ODatabaseMetaDataResultSet::getObject( sal_Int32 /*columnIndex*/, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
{
    ::dbtools::throwFunctionNotSupportedException( "XRow::getObject", *this );
    return Any();
}
// -------------------------------------------------------------------------

sal_Int16 SAL_CALL ODatabaseMetaDataResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );

	columnIndex = mapColumn(columnIndex);
	sal_Int16 nVal = 0;
	if(columnIndex <= m_nDriverColumnCount)
	{
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,SQL_C_SHORT,m_bWasNull,**this,&nVal,sizeof nVal);

		::std::map<sal_Int32, ::connectivity::TInt2IntMap >::iterator	aValueRangeIter;
		if ( !m_aValueRange.empty() && (aValueRangeIter = m_aValueRange.find(columnIndex)) != m_aValueRange.end())
			return sal_Int16((*aValueRangeIter).second[(sal_Int32)nVal]);
	}
	else
		m_bWasNull = sal_True;
	return nVal;
}
// -------------------------------------------------------------------------

::rtl::OUString SAL_CALL ODatabaseMetaDataResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	::rtl::OUString aVal;
	if(columnIndex <= m_nDriverColumnCount)
		aVal = OTools::getStringValue(m_pConnection,m_aStatementHandle,columnIndex,impl_getColumnType_nothrow(columnIndex),m_bWasNull,**this,m_nTextEncoding);
	else
		m_bWasNull = sal_True;

	return aVal;
}

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


::com::sun::star::util::Time SAL_CALL ODatabaseMetaDataResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	TIME_STRUCT aTime={0,0,0};
	if(columnIndex <= m_nDriverColumnCount)
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,m_pConnection->useOldDateFormat() ? SQL_C_TIME : SQL_C_TYPE_TIME,m_bWasNull,**this,&aTime,sizeof aTime);
	else
		m_bWasNull = sal_True;
	return Time(0,aTime.second,aTime.minute,aTime.hour);
}
// -------------------------------------------------------------------------


::com::sun::star::util::DateTime SAL_CALL ODatabaseMetaDataResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	columnIndex = mapColumn(columnIndex);
	TIMESTAMP_STRUCT aTime={0,0,0,0,0,0,0};
	if(columnIndex <= m_nDriverColumnCount)
		OTools::getValue(m_pConnection,m_aStatementHandle,columnIndex,m_pConnection->useOldDateFormat() ? SQL_C_TIMESTAMP : SQL_C_TYPE_TIMESTAMP,m_bWasNull,**this,&aTime,sizeof aTime);
	else
		m_bWasNull = sal_True;
	return DateTime((sal_uInt16)aTime.fraction*1000,aTime.second,aTime.minute,aTime.hour,aTime.day,aTime.month,aTime.year);
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isAfterLast(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_nCurrentFetchState == SQL_NO_DATA;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isFirst(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_nRowPos == 1;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isLast(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_bEOF && m_nCurrentFetchState != SQL_NO_DATA;
}
// -------------------------------------------------------------------------
void SAL_CALL ODatabaseMetaDataResultSet::beforeFirst(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	if(first())
		previous();
	m_nCurrentFetchState = SQL_SUCCESS;
}
// -------------------------------------------------------------------------
void SAL_CALL ODatabaseMetaDataResultSet::afterLast(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	if(last())
		next();
	m_bEOF = sal_True;
}
// -------------------------------------------------------------------------

void SAL_CALL ODatabaseMetaDataResultSet::close(  ) throw(SQLException, RuntimeException)
{
	{

		checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
		::osl::MutexGuard aGuard( m_aMutex );

	}
	dispose();
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL ODatabaseMetaDataResultSet::first(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_FIRST,0);
	OTools::ThrowException(m_pConnection,m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
    sal_Bool bRet = ( m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO );
	if( bRet )
		m_nRowPos = 1;
	return bRet;
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL ODatabaseMetaDataResultSet::last(  ) throw(SQLException, RuntimeException)
{
	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed );
	::osl::MutexGuard aGuard( m_aMutex );


	m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_LAST,0);
	OTools::ThrowException(m_pConnection,m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	// here I know definitely that I stand on the last record
	return (m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO);
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_ABSOLUTE,row);
	OTools::ThrowException(m_pConnection,m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	sal_Bool bRet = m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
	if(bRet)
		m_nRowPos = row;
	return bRet;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,row);
	OTools::ThrowException(m_pConnection,m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	sal_Bool bRet = m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
	if(bRet)
		m_nRowPos += row;
	return bRet;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::previous(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_PRIOR,0);
	OTools::ThrowException(m_pConnection,m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	sal_Bool bRet = m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
	if(bRet)
		--m_nRowPos;
	return bRet;
}
// -------------------------------------------------------------------------
Reference< XInterface > SAL_CALL ODatabaseMetaDataResultSet::getStatement(  ) throw(SQLException, RuntimeException)
{
	return NULL;
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowDeleted(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_pRowStatusArray[0] == SQL_ROW_DELETED;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowInserted(  ) throw(SQLException, RuntimeException)
{
	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_pRowStatusArray[0] == SQL_ROW_ADDED;
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseMetaDataResultSet::rowUpdated(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_pRowStatusArray[0] == SQL_ROW_UPDATED;
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL ODatabaseMetaDataResultSet::isBeforeFirst(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_nRowPos == 0;
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL ODatabaseMetaDataResultSet::next(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	//	m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_NEXT,0);
	m_nCurrentFetchState = N3SQLFetch(m_aStatementHandle);
	OTools::ThrowException(m_pConnection,m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	return m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
}
// -------------------------------------------------------------------------

sal_Bool SAL_CALL ODatabaseMetaDataResultSet::wasNull(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	return m_bWasNull;
}
// -------------------------------------------------------------------------
void SAL_CALL ODatabaseMetaDataResultSet::refreshRow(  ) throw(SQLException, RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );

}
// -------------------------------------------------------------------------

void SAL_CALL ODatabaseMetaDataResultSet::cancel(  ) throw(RuntimeException)
{

	checkDisposed(ODatabaseMetaDataResultSet_BASE::rBHelper.bDisposed);
	::osl::MutexGuard aGuard( m_aMutex );


	OTools::ThrowException(m_pConnection,N3SQLCancel(m_aStatementHandle),m_aStatementHandle,SQL_HANDLE_STMT,*this);
}
// -------------------------------------------------------------------------
void SAL_CALL ODatabaseMetaDataResultSet::clearWarnings(  ) throw(SQLException, RuntimeException)
{
}
// -------------------------------------------------------------------------
Any SAL_CALL ODatabaseMetaDataResultSet::getWarnings(  ) throw(SQLException, RuntimeException)
{
	return Any();
}
//------------------------------------------------------------------------------
sal_Int32 ODatabaseMetaDataResultSet::getResultSetConcurrency() const throw(SQLException, RuntimeException)
{
	return ResultSetConcurrency::READ_ONLY;
}
//------------------------------------------------------------------------------
sal_Int32 ODatabaseMetaDataResultSet::getResultSetType() const throw(SQLException, RuntimeException)
{
	return ResultSetType::FORWARD_ONLY;
}
//------------------------------------------------------------------------------
sal_Int32 ODatabaseMetaDataResultSet::getFetchDirection() const throw(SQLException, RuntimeException)
{
	return FetchDirection::FORWARD;
}
//------------------------------------------------------------------------------
sal_Int32 ODatabaseMetaDataResultSet::getFetchSize() const throw(SQLException, RuntimeException)
{
	sal_Int32 nValue=1;
	return nValue;
}
//------------------------------------------------------------------------------
::rtl::OUString ODatabaseMetaDataResultSet::getCursorName() const throw(SQLException, RuntimeException)
{
	return ::rtl::OUString();
}

// -------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* ODatabaseMetaDataResultSet::createArrayHelper( ) const
{

	Sequence< com::sun::star::beans::Property > aProps(5);
	com::sun::star::beans::Property* pProperties = aProps.getArray();
	sal_Int32 nPos = 0;
	DECL_PROP0(CURSORNAME,			::rtl::OUString);
	DECL_PROP0(FETCHDIRECTION,		sal_Int32);
	DECL_PROP0(FETCHSIZE,			sal_Int32);
	DECL_PROP0(RESULTSETCONCURRENCY,sal_Int32);
	DECL_PROP0(RESULTSETTYPE,		sal_Int32);

	return new ::cppu::OPropertyArrayHelper(aProps);
}
// -------------------------------------------------------------------------
::cppu::IPropertyArrayHelper & ODatabaseMetaDataResultSet::getInfoHelper()
{
	return *const_cast<ODatabaseMetaDataResultSet*>(this)->getArrayHelper();
}
// -------------------------------------------------------------------------
sal_Bool ODatabaseMetaDataResultSet::convertFastPropertyValue(
							Any & rConvertedValue,
							Any & rOldValue,
							sal_Int32 nHandle,
							const Any& rValue )
								throw (::com::sun::star::lang::IllegalArgumentException)
{
	switch(nHandle)
	{
		case PROPERTY_ID_CURSORNAME:
		case PROPERTY_ID_RESULTSETCONCURRENCY:
		case PROPERTY_ID_RESULTSETTYPE:
			throw ::com::sun::star::lang::IllegalArgumentException();
		case PROPERTY_ID_FETCHDIRECTION:
			return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
		case PROPERTY_ID_FETCHSIZE:
			return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
		default:
			;
	}
	return sal_False;
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& /*rValue*/ ) throw (Exception)
{
	switch(nHandle)
	{
		case PROPERTY_ID_CURSORNAME:
		case PROPERTY_ID_RESULTSETCONCURRENCY:
		case PROPERTY_ID_RESULTSETTYPE:
		case PROPERTY_ID_FETCHDIRECTION:
		case PROPERTY_ID_FETCHSIZE:
			throw Exception();
		default:
			OSL_ENSURE(0,"setFastPropertyValue_NoBroadcast: Illegal handle value!");
	}
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
{
	switch(nHandle)
	{
		case PROPERTY_ID_CURSORNAME:
			rValue <<= getCursorName();
			break;
		case PROPERTY_ID_RESULTSETCONCURRENCY:
			rValue <<= getResultSetConcurrency();
			break;
		case PROPERTY_ID_RESULTSETTYPE:
			rValue <<= getResultSetType();
			break;
		case PROPERTY_ID_FETCHDIRECTION:
			rValue <<= getFetchDirection();
			break;
		case PROPERTY_ID_FETCHSIZE:
			rValue <<= getFetchSize();
			break;
	}
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openTypeInfo() throw(SQLException, RuntimeException)
{
	TInt2IntMap aMap;
	aMap[SQL_BIT]				= DataType::BIT;
	aMap[SQL_TINYINT]			= DataType::TINYINT;
	aMap[SQL_SMALLINT]			= DataType::SMALLINT;
	aMap[SQL_INTEGER]			= DataType::INTEGER;
	aMap[SQL_FLOAT]				= DataType::FLOAT;
	aMap[SQL_REAL]				= DataType::REAL;
	aMap[SQL_DOUBLE]			= DataType::DOUBLE;
	aMap[SQL_BIGINT]			= DataType::BIGINT;

	aMap[SQL_CHAR]				= DataType::CHAR;
	aMap[SQL_WCHAR]				= DataType::CHAR;
	aMap[SQL_VARCHAR]			= DataType::VARCHAR;
	aMap[SQL_WVARCHAR]			= DataType::VARCHAR;
	aMap[SQL_LONGVARCHAR]		= DataType::LONGVARCHAR;
	aMap[SQL_WLONGVARCHAR]		= DataType::LONGVARCHAR;

	aMap[SQL_TYPE_DATE]			= DataType::DATE;
	aMap[SQL_DATE]				= DataType::DATE;
	aMap[SQL_TYPE_TIME]			= DataType::TIME;
	aMap[SQL_TIME]				= DataType::TIME;
	aMap[SQL_TYPE_TIMESTAMP]	= DataType::TIMESTAMP;
	aMap[SQL_TIMESTAMP]			= DataType::TIMESTAMP;

	aMap[SQL_DECIMAL]			= DataType::DECIMAL;
	aMap[SQL_NUMERIC]			= DataType::NUMERIC;

	aMap[SQL_BINARY]			= DataType::BINARY;
	aMap[SQL_VARBINARY]			= DataType::VARBINARY;
	aMap[SQL_LONGVARBINARY]		= DataType::LONGVARBINARY;

	aMap[SQL_GUID]				= DataType::VARBINARY;


	m_aValueRange[2] = aMap;

	OTools::ThrowException(m_pConnection,N3SQLGetTypeInfo(m_aStatementHandle, SQL_ALL_TYPES),m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
//-----------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openTables(const Any& catalog, const ::rtl::OUString& schemaPattern,
							const ::rtl::OUString& tableNamePattern,
							const Sequence< ::rtl::OUString >& types )	throw(SQLException, RuntimeException)
{
	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN,aCOL;
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schemaPattern.toChar() != '%')
		pSchemaPat = &schemaPattern;
	else
		pSchemaPat = NULL;

    if ( catalog.hasValue() )
	    aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schemaPattern,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(tableNamePattern,m_nTextEncoding)).getStr();


	const char	*pCOL = NULL;
	const char* pComma = ",";
	const ::rtl::OUString* pBegin = types.getConstArray();
	const ::rtl::OUString* pEnd = pBegin + types.getLength();
	for(;pBegin != pEnd;++pBegin)
	{
		aCOL += ::rtl::OUStringToOString(*pBegin,m_nTextEncoding);
		aCOL += pComma;
	}
	if ( aCOL.getLength() )
	{
		aCOL = aCOL.replaceAt(aCOL.getLength()-1,1,pComma);
		pCOL = aCOL.getStr();
	}
	else
		pCOL = SQL_ALL_TABLE_TYPES;

	SQLRETURN nRetcode = N3SQLTables(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS,
							(SDB_ODBC_CHAR *) pCOL, pCOL ? SQL_NTS : 0);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();

}
//-----------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openTablesTypes( )	throw(SQLException, RuntimeException)
{
	m_bFreeHandle = sal_True;
	SQLRETURN nRetcode = N3SQLTables(m_aStatementHandle,
							0,0,
							0,0,
							0,0,
							(SDB_ODBC_CHAR *) SQL_ALL_TABLE_TYPES,SQL_NTS);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);

	m_aColMapping.clear();
	m_aColMapping.push_back(-1);
	m_aColMapping.push_back(4);
	m_xMetaData = new OResultSetMetaData(m_pConnection,m_aStatementHandle,m_aColMapping);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openCatalogs() throw(SQLException, RuntimeException)
{
	m_bFreeHandle = sal_True;
	SQLRETURN nRetcode = N3SQLTables(m_aStatementHandle,
							(SDB_ODBC_CHAR *) SQL_ALL_CATALOGS,SQL_NTS,
							(SDB_ODBC_CHAR *) "",SQL_NTS,
							(SDB_ODBC_CHAR *) "",SQL_NTS,
							(SDB_ODBC_CHAR *) "",SQL_NTS);

	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);

	m_aColMapping.clear();
	m_aColMapping.push_back(-1);
	m_aColMapping.push_back(1);
	m_xMetaData = new OResultSetMetaData(m_pConnection,m_aStatementHandle,m_aColMapping);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openSchemas() throw(SQLException, RuntimeException)
{
	m_bFreeHandle = sal_True;
	SQLRETURN nRetcode = N3SQLTables(m_aStatementHandle,
							(SDB_ODBC_CHAR *) "",SQL_NTS,
							(SDB_ODBC_CHAR *) SQL_ALL_SCHEMAS,SQL_NTS,
							(SDB_ODBC_CHAR *) "",SQL_NTS,
							(SDB_ODBC_CHAR *) "",SQL_NTS);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);

	m_aColMapping.clear();
	m_aColMapping.push_back(-1);
	m_aColMapping.push_back(2);
	m_xMetaData = new OResultSetMetaData(m_pConnection,m_aStatementHandle,m_aColMapping);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openColumnPrivileges(	const Any& catalog,	const ::rtl::OUString& schema,
										const ::rtl::OUString& table,	const ::rtl::OUString& columnNamePattern )
										throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schema.toChar() != '%')
		pSchemaPat = &schema;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN,aCOL;

	if ( catalog.hasValue() )
		aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schema,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(table,m_nTextEncoding)).getStr(),
				*pCOL = (aCOL = ::rtl::OUStringToOString(columnNamePattern,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLColumnPrivileges(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0 ,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS,
							(SDB_ODBC_CHAR *) pCOL, SQL_NTS);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);

	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openColumns(	const Any& catalog,				const ::rtl::OUString& schemaPattern,
								const ::rtl::OUString& tableNamePattern,	const ::rtl::OUString& columnNamePattern )
								throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schemaPattern.toChar() != '%')
		pSchemaPat = &schemaPattern;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN,aCOL;
	if ( catalog.hasValue() )
		aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schemaPattern,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(tableNamePattern,m_nTextEncoding)).getStr(),
				*pCOL = (aCOL = ::rtl::OUStringToOString(columnNamePattern,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLColumns(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS,
							(SDB_ODBC_CHAR *) pCOL, SQL_NTS);

	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	TInt2IntMap aMap;
	aMap[SQL_BIT]				= DataType::BIT;
	aMap[SQL_TINYINT]			= DataType::TINYINT;
	aMap[SQL_SMALLINT]			= DataType::SMALLINT;
	aMap[SQL_INTEGER]			= DataType::INTEGER;
	aMap[SQL_FLOAT]				= DataType::FLOAT;
	aMap[SQL_REAL]				= DataType::REAL;
	aMap[SQL_DOUBLE]			= DataType::DOUBLE;
	aMap[SQL_BIGINT]			= DataType::BIGINT;

	aMap[SQL_CHAR]				= DataType::CHAR;
	aMap[SQL_WCHAR]				= DataType::CHAR;
	aMap[SQL_VARCHAR]			= DataType::VARCHAR;
	aMap[SQL_WVARCHAR]			= DataType::VARCHAR;
	aMap[SQL_LONGVARCHAR]		= DataType::LONGVARCHAR;
	aMap[SQL_WLONGVARCHAR]		= DataType::LONGVARCHAR;

	aMap[SQL_TYPE_DATE]			= DataType::DATE;
	aMap[SQL_DATE]				= DataType::DATE;
	aMap[SQL_TYPE_TIME]			= DataType::TIME;
	aMap[SQL_TIME]				= DataType::TIME;
	aMap[SQL_TYPE_TIMESTAMP]	= DataType::TIMESTAMP;
	aMap[SQL_TIMESTAMP]			= DataType::TIMESTAMP;

	aMap[SQL_DECIMAL]			= DataType::DECIMAL;
	aMap[SQL_NUMERIC]			= DataType::NUMERIC;

	aMap[SQL_BINARY]			= DataType::BINARY;
	aMap[SQL_VARBINARY]			= DataType::VARBINARY;
	aMap[SQL_LONGVARBINARY]		= DataType::LONGVARBINARY;

	aMap[SQL_GUID]				= DataType::VARBINARY;

	m_aValueRange[5] = aMap;
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openProcedureColumns(	const Any& catalog,		const ::rtl::OUString& schemaPattern,
								const ::rtl::OUString& procedureNamePattern,const ::rtl::OUString& columnNamePattern )
								throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schemaPattern.toChar() != '%')
		pSchemaPat = &schemaPattern;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN,aCOL;
	if ( catalog.hasValue() )
		aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schemaPattern,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(procedureNamePattern,m_nTextEncoding)).getStr(),
				*pCOL = (aCOL = ::rtl::OUStringToOString(columnNamePattern,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLProcedureColumns(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0 ,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS,
							(SDB_ODBC_CHAR *) pCOL, SQL_NTS);

	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openProcedures(const Any& catalog, const ::rtl::OUString& schemaPattern,
								const ::rtl::OUString& procedureNamePattern)
								throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schemaPattern.toChar() != '%')
		pSchemaPat = &schemaPattern;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN,aCOL;

	if ( catalog.hasValue() )
		aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schemaPattern,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(procedureNamePattern,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLProcedures(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0 ,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openSpecialColumns(sal_Bool _bRowVer,const Any& catalog, const ::rtl::OUString& schema,
									const ::rtl::OUString& table,sal_Int32 scope, 	sal_Bool nullable )
									throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schema.toChar() != '%')
		pSchemaPat = &schema;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN,aCOL;
	if ( catalog.hasValue() )
	aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schema,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(table,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLSpecialColumns(m_aStatementHandle,_bRowVer ? SQL_ROWVER : SQL_BEST_ROWID,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0 ,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS,
							(SQLSMALLINT)scope,
							nullable ? SQL_NULLABLE : SQL_NO_NULLS);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openVersionColumns(const Any& catalog, const ::rtl::OUString& schema,
									const ::rtl::OUString& table)  throw(SQLException, RuntimeException)
{
	openSpecialColumns(sal_True,catalog,schema,table,SQL_SCOPE_TRANSACTION,sal_False);
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openBestRowIdentifier( const Any& catalog, const ::rtl::OUString& schema,
										const ::rtl::OUString& table,sal_Int32 scope,sal_Bool nullable ) throw(SQLException, RuntimeException)
{
	openSpecialColumns(sal_False,catalog,schema,table,scope,nullable);
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openForeignKeys( const Any& catalog, const ::rtl::OUString* schema,
								  const ::rtl::OUString* table,
								  const Any& catalog2, const ::rtl::OUString* schema2,
								  const ::rtl::OUString* table2) throw(SQLException, RuntimeException)
{
	m_bFreeHandle = sal_True;

	::rtl::OString aPKQ,aPKO,aPKN, aFKQ, aFKO, aFKN;
    if ( catalog.hasValue() )
	    aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
    if ( catalog2.hasValue() )
	    aFKQ = ::rtl::OUStringToOString(comphelper::getString(catalog2),m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = schema && schema->getLength() ? ::rtl::OUStringToOString(*schema,m_nTextEncoding).getStr() : NULL,
				*pPKN = table   ? (aPKN = ::rtl::OUStringToOString(*table,m_nTextEncoding)).getStr(): NULL,
				*pFKQ = catalog2.hasValue() && aFKQ.getLength() ? aFKQ.getStr()	: NULL,
				*pFKO = schema2 && schema2->getLength() ? (aFKO = ::rtl::OUStringToOString(*schema2,m_nTextEncoding)).getStr() : NULL,
				*pFKN = table2  ? (aFKN = ::rtl::OUStringToOString(*table2,m_nTextEncoding)).getStr() : NULL;


	SQLRETURN nRetcode = N3SQLForeignKeys(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKN, pPKN ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pFKQ, (catalog2.hasValue() && aFKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pFKO, pFKO ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pFKN, SQL_NTS
							);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openImportedKeys(const Any& catalog, const ::rtl::OUString& schema,
								  const ::rtl::OUString& table)	throw(SQLException, RuntimeException)
{

	openForeignKeys(Any(),NULL,NULL,catalog,!schema.compareToAscii("%") ? &schema : NULL,&table);
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openExportedKeys(const Any& catalog, const ::rtl::OUString& schema,
								  const ::rtl::OUString& table)	throw(SQLException, RuntimeException)
{
	openForeignKeys(catalog,!schema.compareToAscii("%") ? &schema : NULL,&table,Any(),NULL,NULL);
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openPrimaryKeys(const Any& catalog, const ::rtl::OUString& schema,
								  const ::rtl::OUString& table)	throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schema.toChar() != '%')
		pSchemaPat = &schema;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN,aCOL;

	if ( catalog.hasValue() )
		aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schema,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(table,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLPrimaryKeys(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0 ,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openTablePrivileges(const Any& catalog, const ::rtl::OUString& schemaPattern,
								  const ::rtl::OUString& tableNamePattern) throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schemaPattern.toChar() != '%')
		pSchemaPat = &schemaPattern;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN;

	if ( catalog.hasValue() )
		aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schemaPattern,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(tableNamePattern,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLTablePrivileges(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0 ,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::openIndexInfo( const Any& catalog, const ::rtl::OUString& schema,
								const ::rtl::OUString& table,sal_Bool unique,sal_Bool approximate )
								throw(SQLException, RuntimeException)
{
	const ::rtl::OUString *pSchemaPat = NULL;

	if(schema.toChar() != '%')
		pSchemaPat = &schema;
	else
		pSchemaPat = NULL;

	m_bFreeHandle = sal_True;
	::rtl::OString aPKQ,aPKO,aPKN;

	if ( catalog.hasValue() )
		aPKQ = ::rtl::OUStringToOString(comphelper::getString(catalog),m_nTextEncoding);
	aPKO = ::rtl::OUStringToOString(schema,m_nTextEncoding);

	const char	*pPKQ = catalog.hasValue() && aPKQ.getLength() ? aPKQ.getStr()	: NULL,
				*pPKO = pSchemaPat && pSchemaPat->getLength() ? aPKO.getStr() : NULL,
				*pPKN = (aPKN = ::rtl::OUStringToOString(table,m_nTextEncoding)).getStr();


	SQLRETURN nRetcode = N3SQLStatistics(m_aStatementHandle,
							(SDB_ODBC_CHAR *) pPKQ, (catalog.hasValue() && aPKQ.getLength()) ? SQL_NTS : 0,
							(SDB_ODBC_CHAR *) pPKO, pPKO ? SQL_NTS : 0 ,
							(SDB_ODBC_CHAR *) pPKN, SQL_NTS,
							unique ? SQL_INDEX_UNIQUE : SQL_INDEX_ALL,
							approximate);
	OTools::ThrowException(m_pConnection,nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
	checkColumnCount();
}
// -------------------------------------------------------------------------
void ODatabaseMetaDataResultSet::checkColumnCount()
{
	sal_Int16 nNumResultCols=0;
	OTools::ThrowException(m_pConnection,N3SQLNumResultCols(m_aStatementHandle,&nNumResultCols),m_aStatementHandle,SQL_HANDLE_STMT,*this);
	m_nDriverColumnCount = nNumResultCols;
}
// -----------------------------------------------------------------------------

SWORD ODatabaseMetaDataResultSet::impl_getColumnType_nothrow(sal_Int32 columnIndex)
{
    ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex);
    if ( aFind == m_aODBCColumnTypes.end() )
        aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pConnection,m_aStatementHandle,*this,columnIndex))).first;
    return aFind->second;
}

