LCOV - code coverage report
Current view: top level - connectivity/source/drivers/odbc - OResultSet.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 880 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 147 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "odbc/OResultSet.hxx"
      21             : #include "odbc/OTools.hxx"
      22             : #include "odbc/OResultSetMetaData.hxx"
      23             : #include <com/sun/star/sdbc/DataType.hpp>
      24             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      25             : #include <com/sun/star/beans/PropertyVetoException.hpp>
      26             : #include <com/sun/star/sdbcx/CompareBookmark.hpp>
      27             : #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
      28             : #include <com/sun/star/sdbc/FetchDirection.hpp>
      29             : #include <com/sun/star/sdbc/ResultSetType.hpp>
      30             : #include <comphelper/property.hxx>
      31             : #include <comphelper/sequence.hxx>
      32             : #include <cppuhelper/typeprovider.hxx>
      33             : #include <cppuhelper/supportsservice.hxx>
      34             : #include <com/sun/star/lang/DisposedException.hpp>
      35             : #include <comphelper/types.hxx>
      36             : #include <connectivity/dbtools.hxx>
      37             : #include <connectivity/dbexception.hxx>
      38             : #include "diagnose_ex.h"
      39             : 
      40             : #include <o3tl/compat_functional.hxx>
      41             : 
      42             : using namespace ::comphelper;
      43             : using namespace connectivity;
      44             : using namespace connectivity::odbc;
      45             : using namespace cppu;
      46             : using namespace com::sun::star::uno;
      47             : using namespace com::sun::star::lang;
      48             : using namespace com::sun::star::beans;
      49             : using namespace com::sun::star::sdbc;
      50             : using namespace com::sun::star::sdbcx;
      51             : using namespace com::sun::star::container;
      52             : using namespace com::sun::star::io;
      53             : using namespace com::sun::star::util;
      54             : 
      55             : #define ODBC_SQL_NOT_DEFINED    99UL
      56             : static_assert(ODBC_SQL_NOT_DEFINED != SQL_UB_OFF, "ODBC_SQL_NOT_DEFINED must be unique");
      57             : static_assert(ODBC_SQL_NOT_DEFINED != SQL_UB_ON, "ODBC_SQL_NOT_DEFINED must be unique");
      58             : static_assert(ODBC_SQL_NOT_DEFINED != SQL_UB_FIXED, "ODBC_SQL_NOT_DEFINED must be unique");
      59             : static_assert(ODBC_SQL_NOT_DEFINED != SQL_UB_VARIABLE, "ODBC_SQL_NOT_DEFINED must be unique");
      60             : 
      61             : namespace
      62             : {
      63             :     const SQLLEN nMaxBookmarkLen = 20;
      64             : }
      65             : 
      66             : 
      67             : //  IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.OResultSet","com.sun.star.sdbc.ResultSet");
      68           0 : OUString SAL_CALL OResultSet::getImplementationName(  ) throw ( RuntimeException, std::exception)
      69             : {
      70           0 :     return OUString("com.sun.star.sdbcx.odbc.ResultSet");
      71             : }
      72             : 
      73           0 :  Sequence< OUString > SAL_CALL OResultSet::getSupportedServiceNames(  ) throw( RuntimeException, std::exception)
      74             : {
      75           0 :      Sequence< OUString > aSupported(2);
      76           0 :     aSupported[0] = "com.sun.star.sdbc.ResultSet";
      77           0 :     aSupported[1] = "com.sun.star.sdbcx.ResultSet";
      78           0 :     return aSupported;
      79             : }
      80             : 
      81           0 : sal_Bool SAL_CALL OResultSet::supportsService( const OUString& _rServiceName ) throw( RuntimeException, std::exception)
      82             : {
      83           0 :     return cppu::supportsService(this, _rServiceName);
      84             : }
      85             : 
      86             : 
      87           0 : OResultSet::OResultSet(SQLHANDLE _pStatementHandle ,OStatement_Base* pStmt) :   OResultSet_BASE(m_aMutex)
      88             :                         ,OPropertySetHelper(OResultSet_BASE::rBHelper)
      89             :                         ,m_bFetchDataInOrder(true)
      90             :                         ,m_aStatementHandle(_pStatementHandle)
      91           0 :                         ,m_aConnectionHandle(pStmt->getConnectionHandle())
      92             :                         ,m_pStatement(pStmt)
      93             :                         ,m_pSkipDeletedSet(NULL)
      94             :                         ,m_xStatement(*pStmt)
      95             :                         ,m_xMetaData(NULL)
      96             :                         ,m_pRowStatusArray( NULL )
      97           0 :                         ,m_nTextEncoding(pStmt->getOwnConnection()->getTextEncoding())
      98             :                         ,m_nRowPos(0)
      99             :                         ,m_nUseBookmarks(ODBC_SQL_NOT_DEFINED)
     100             :                         ,m_nCurrentFetchState(0)
     101             :                         ,m_bWasNull(true)
     102             :                         ,m_bEOF(true)
     103             :                         ,m_bLastRecord(false)
     104             :                         ,m_bFreeHandle(false)
     105             :                         ,m_bInserting(false)
     106             :                         ,m_bRowInserted(false)
     107             :                         ,m_bRowDeleted(false)
     108           0 :                         ,m_bUseFetchScroll(false)
     109             : {
     110           0 :     osl_atomic_increment( &m_refCount );
     111             :     try
     112             :     {
     113           0 :         m_pRowStatusArray = new SQLUSMALLINT[1]; // the default value
     114           0 :         setStmtOption<SQLUSMALLINT*, SQL_IS_POINTER>(SQL_ATTR_ROW_STATUS_PTR, m_pRowStatusArray);
     115             :     }
     116           0 :     catch(const Exception&)
     117             :     { // we don't want our result destroy here
     118             :     }
     119           0 :     SQLULEN nCurType = 0;
     120             :     try
     121             :     {
     122           0 :         nCurType = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE);
     123           0 :         SQLUINTEGER nValueLen = m_pStatement->getCursorProperties(nCurType,false);
     124           0 :         if( (nValueLen & SQL_CA2_SENSITIVITY_DELETIONS) != SQL_CA2_SENSITIVITY_DELETIONS ||
     125           0 :             (nValueLen & SQL_CA2_CRC_EXACT) != SQL_CA2_CRC_EXACT)
     126           0 :             m_pSkipDeletedSet = new OSkipDeletedSet(this);
     127             :     }
     128           0 :     catch(const Exception&)
     129             :     { // we don't want our result destroy here
     130             :     }
     131             :     try
     132             :     {
     133           0 :         SQLUINTEGER nValueLen = 0;
     134             :         // Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/ms715441%28v=vs.85%29.aspx
     135             :         // LibreOffice ODBC binds columns only on update, so we don't care about SQL_GD_ANY_COLUMN / SQL_GD_BOUND
     136             :         // TODO: maybe a problem if a column is updated, then an earlier column fetched?
     137             :         //       an updated column is bound...
     138             :         // TODO: aren't we assuming SQL_GD_OUTPUT_PARAMS?
     139             :         //       If yes, we should at least OSL_ENSURE it,
     140             :         //       even better throw an exception any OUT parameter registration if !SQL_GD_OUTPUT_PARAMS.
     141             :         // If !SQL_GD_ANY_ORDER, cache the whole row so that callers can access columns in any order.
     142             :         // In other words, isolate them from ODBC restrictions.
     143             :         // TODO: we assume SQL_GD_BLOCK, unless fetchSize is 1
     144           0 :         OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_GETDATA_EXTENSIONS,nValueLen,NULL);
     145           0 :         m_bFetchDataInOrder = !((SQL_GD_ANY_ORDER & nValueLen) == SQL_GD_ANY_ORDER);
     146             :     }
     147           0 :     catch(const Exception&)
     148             :     {
     149           0 :         m_bFetchDataInOrder = true;
     150             :     }
     151             :     try
     152             :     {
     153             :         // TODO: this does *not* do what it appears.
     154             :         //       We use SQLFetchScroll unconditionally in several places
     155             :         //       the *only* difference this makes is whether ::next() uses SQLFetchScroll or SQLFetch
     156             :         //       so this test seems pointless
     157           0 :         if ( getOdbcFunction(ODBC3SQLFunctionId::GetFunctions) )
     158             :         {
     159           0 :             SQLUSMALLINT nSupported = 0;
     160           0 :             m_bUseFetchScroll = ( N3SQLGetFunctions(m_aConnectionHandle,SQL_API_SQLFETCHSCROLL,&nSupported) == SQL_SUCCESS && nSupported == 1 );
     161             :         }
     162             :     }
     163           0 :     catch(const Exception&)
     164             :     {
     165           0 :         m_bUseFetchScroll = false;
     166             :     }
     167             : 
     168           0 :     osl_atomic_decrement( &m_refCount );
     169           0 : }
     170             : 
     171           0 : OResultSet::~OResultSet()
     172             : {
     173           0 :     delete [] m_pRowStatusArray;
     174           0 :     delete m_pSkipDeletedSet;
     175           0 : }
     176             : 
     177           0 : void OResultSet::construct()
     178             : {
     179           0 :     osl_atomic_increment( &m_refCount );
     180           0 :     allocBuffer();
     181           0 :     osl_atomic_decrement( &m_refCount );
     182           0 : }
     183             : 
     184           0 : void OResultSet::disposing()
     185             : {
     186           0 :     SQLRETURN nRet = N3SQLCloseCursor(m_aStatementHandle);
     187             :     OSL_UNUSED( nRet );
     188           0 :     OPropertySetHelper::disposing();
     189             : 
     190           0 :     ::osl::MutexGuard aGuard(m_aMutex);
     191           0 :     releaseBuffer();
     192           0 :     if(m_bFreeHandle)
     193           0 :         m_pStatement->getOwnConnection()->freeStatementHandle(m_aStatementHandle);
     194             : 
     195           0 :     m_xStatement.clear();
     196           0 :     m_xMetaData.clear();
     197           0 : }
     198             : 
     199           0 : SQLRETURN OResultSet::unbind(bool _bUnbindHandle)
     200             : {
     201           0 :     SQLRETURN nRet = 0;
     202           0 :     if ( _bUnbindHandle )
     203           0 :         nRet = N3SQLFreeStmt(m_aStatementHandle,SQL_UNBIND);
     204             : 
     205           0 :     if ( m_aBindVector.size() > 0 )
     206             :     {
     207           0 :         TVoidVector::iterator pValue = m_aBindVector.begin();
     208           0 :         TVoidVector::iterator pEnd = m_aBindVector.end();
     209           0 :         for(; pValue != pEnd; ++pValue)
     210             :         {
     211           0 :             switch (pValue->second)
     212             :             {
     213             :                 case DataType::CHAR:
     214             :                 case DataType::VARCHAR:
     215           0 :                     delete static_cast< OString* >(reinterpret_cast< void * >(pValue->first));
     216           0 :                     break;
     217             :                 case DataType::BIGINT:
     218           0 :                     delete static_cast< sal_Int64* >(reinterpret_cast< void * >(pValue->first));
     219           0 :                     break;
     220             :                 case DataType::DECIMAL:
     221             :                 case DataType::NUMERIC:
     222           0 :                     delete static_cast< OString* >(reinterpret_cast< void * >(pValue->first));
     223           0 :                     break;
     224             :                 case DataType::REAL:
     225             :                 case DataType::DOUBLE:
     226           0 :                     delete static_cast< double* >(reinterpret_cast< void * >(pValue->first));
     227           0 :                     break;
     228             :                 case DataType::LONGVARCHAR:
     229             :                 case DataType::CLOB:
     230           0 :                     delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first));
     231           0 :                     break;
     232             :                 case DataType::LONGVARBINARY:
     233             :                 case DataType::BLOB:
     234           0 :                     delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first));
     235           0 :                     break;
     236             :                 case DataType::DATE:
     237           0 :                     delete static_cast< DATE_STRUCT* >(reinterpret_cast< void * >(pValue->first));
     238           0 :                     break;
     239             :                 case DataType::TIME:
     240           0 :                     delete static_cast< TIME_STRUCT* >(reinterpret_cast< void * >(pValue->first));
     241           0 :                     break;
     242             :                 case DataType::TIMESTAMP:
     243           0 :                     delete static_cast< TIMESTAMP_STRUCT* >(reinterpret_cast< void * >(pValue->first));
     244           0 :                     break;
     245             :                 case DataType::BIT:
     246             :                 case DataType::TINYINT:
     247           0 :                     delete static_cast< sal_Int8* >(reinterpret_cast< void * >(pValue->first));
     248           0 :                     break;
     249             :                 case DataType::SMALLINT:
     250           0 :                     delete static_cast< sal_Int16* >(reinterpret_cast< void * >(pValue->first));
     251           0 :                     break;
     252             :                 case DataType::INTEGER:
     253           0 :                     delete static_cast< sal_Int32* >(reinterpret_cast< void * >(pValue->first));
     254           0 :                     break;
     255             :                 case DataType::FLOAT:
     256           0 :                     delete static_cast< float* >(reinterpret_cast< void * >(pValue->first));
     257           0 :                     break;
     258             :                 case DataType::BINARY:
     259             :                 case DataType::VARBINARY:
     260           0 :                     delete static_cast< sal_Int8* >(reinterpret_cast< void * >(pValue->first));
     261           0 :                     break;
     262             :             }
     263             :         }
     264           0 :         m_aBindVector.clear();
     265             :     }
     266           0 :     return nRet;
     267             : }
     268             : 
     269           0 : TVoidPtr OResultSet::allocBindColumn(sal_Int32 _nType,sal_Int32 _nColumnIndex)
     270             : {
     271           0 :     TVoidPtr aPair;
     272           0 :     switch (_nType)
     273             :     {
     274             :         case DataType::CHAR:
     275             :         case DataType::VARCHAR:
     276           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new OString()),_nType);
     277           0 :             break;
     278             :         case DataType::BIGINT:
     279           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int64(0)),_nType);
     280           0 :             break;
     281             :         case DataType::DECIMAL:
     282             :         case DataType::NUMERIC:
     283           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new OString()),_nType);
     284           0 :             break;
     285             :         case DataType::REAL:
     286             :         case DataType::DOUBLE:
     287           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new double(0.0)),_nType);
     288           0 :             break;
     289             :         case DataType::LONGVARCHAR:
     290             :         case DataType::CLOB:
     291           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType);  // only for finding
     292           0 :             break;
     293             :         case DataType::LONGVARBINARY:
     294             :         case DataType::BLOB:
     295           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType);  // only for finding
     296           0 :             break;
     297             :         case DataType::DATE:
     298           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new DATE_STRUCT),_nType);
     299           0 :             break;
     300             :         case DataType::TIME:
     301           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new TIME_STRUCT),_nType);
     302           0 :             break;
     303             :         case DataType::TIMESTAMP:
     304           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new TIMESTAMP_STRUCT),_nType);
     305           0 :             break;
     306             :         case DataType::BIT:
     307             :         case DataType::TINYINT:
     308           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int8(0)),_nType);
     309           0 :             break;
     310             :         case DataType::SMALLINT:
     311           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int16(0)),_nType);
     312           0 :             break;
     313             :         case DataType::INTEGER:
     314           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int32(0)),_nType);
     315           0 :             break;
     316             :         case DataType::FLOAT:
     317           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new float(0)),_nType);
     318           0 :             break;
     319             :         case DataType::BINARY:
     320             :         case DataType::VARBINARY:
     321           0 :             aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int8[m_aRow[_nColumnIndex].getSequence().getLength()]),_nType);
     322           0 :             break;
     323             :         default:
     324             :             SAL_WARN( "connectivity.drivers", "Unknown type");
     325           0 :             aPair = TVoidPtr(0,_nType);
     326             :     }
     327           0 :     return aPair;
     328             : }
     329             : 
     330           0 : void OResultSet::allocBuffer()
     331             : {
     332           0 :     Reference< XResultSetMetaData > xMeta = getMetaData();
     333           0 :     sal_Int32 nLen = xMeta->getColumnCount();
     334             : 
     335           0 :     m_aBindVector.reserve(nLen);
     336           0 :     m_aRow.resize(nLen+1);
     337             : 
     338           0 :     m_aRow[0].setTypeKind(DataType::VARBINARY);
     339           0 :     m_aRow[0].setBound( false );
     340             : 
     341           0 :     for(sal_Int32 i = 1;i<=nLen;++i)
     342             :     {
     343           0 :         sal_Int32 nType = xMeta->getColumnType(i);
     344           0 :         m_aRow[i].setTypeKind( nType );
     345           0 :         m_aRow[i].setBound( false );
     346             :     }
     347           0 :     m_aLengthVector.resize(nLen + 1);
     348           0 : }
     349             : 
     350           0 : void OResultSet::releaseBuffer()
     351             : {
     352           0 :     unbind(false);
     353           0 :     m_aLengthVector.clear();
     354           0 : }
     355             : 
     356           0 : Any SAL_CALL OResultSet::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
     357             : {
     358           0 :     Any aRet = OPropertySetHelper::queryInterface(rType);
     359           0 :     return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType);
     360             : }
     361             : 
     362           0 :  Sequence<  Type > SAL_CALL OResultSet::getTypes(  ) throw( RuntimeException, std::exception)
     363             : {
     364           0 :     OTypeCollection aTypes( cppu::UnoType<com::sun::star::beans::XMultiPropertySet>::get(),
     365           0 :                                                 cppu::UnoType<com::sun::star::beans::XFastPropertySet>::get(),
     366           0 :                                                 cppu::UnoType<com::sun::star::beans::XPropertySet>::get());
     367             : 
     368           0 :     return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes());
     369             : }
     370             : 
     371             : 
     372           0 : sal_Int32 SAL_CALL OResultSet::findColumn( const OUString& columnName ) throw(SQLException, RuntimeException, std::exception)
     373             : {
     374           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     375             : 
     376             : 
     377           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     378             : 
     379           0 :     Reference< XResultSetMetaData > xMeta = getMetaData();
     380           0 :     sal_Int32 nLen = xMeta->getColumnCount();
     381           0 :     sal_Int32 i = 1;
     382           0 :     for(;i<=nLen;++i)
     383             :     {
     384           0 :         if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
     385           0 :                 columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
     386           0 :             return i;
     387             :     }
     388             : 
     389           0 :     ::dbtools::throwInvalidColumnException( columnName, *this );
     390             :     assert(false);
     391           0 :     return 0; // Never reached
     392             : }
     393             : 
     394           0 : void OResultSet::ensureCacheForColumn(sal_Int32 columnIndex)
     395             : {
     396             :     SAL_INFO( "connectivity.drivers", "odbc  lionel@mamane.lu OResultSet::ensureCacheForColumn" );
     397             : 
     398             :     assert(columnIndex >= 0);
     399             : 
     400           0 :     const TDataRow::size_type oldCacheSize = m_aRow.size();
     401           0 :     const TDataRow::size_type uColumnIndex = static_cast<TDataRow::size_type>(columnIndex);
     402             : 
     403           0 :     if (oldCacheSize > uColumnIndex)
     404             :         // nothing to do
     405           0 :         return;
     406             : 
     407           0 :     m_aRow.resize(columnIndex + 1);
     408           0 :     TDataRow::iterator i (m_aRow.begin() + oldCacheSize);
     409           0 :     const TDataRow::const_iterator end(m_aRow.end());
     410           0 :     for (; i != end; ++i)
     411             :     {
     412           0 :         i->setBound(false);
     413             :     }
     414             : }
     415           0 : void OResultSet::invalidateCache()
     416             : {
     417           0 :     const TDataRow::const_iterator end = m_aRow.end();
     418           0 :     for(TDataRow::iterator i=m_aRow.begin(); i!=end; ++i)
     419             :     {
     420           0 :         i->setBound(false);
     421             :     }
     422           0 : }
     423             : 
     424           0 : Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
     425             : {
     426           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     427           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     428             : 
     429           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBinaryStream", *this );
     430             : 
     431           0 :     return NULL;
     432             : }
     433             : 
     434           0 : Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
     435             : {
     436           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     437           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     438             : 
     439           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBinaryStream", *this );
     440             : 
     441           0 :     return NULL;
     442             : }
     443             : 
     444           0 : template < typename T > T OResultSet::impl_getValue( const sal_Int32 _nColumnIndex, SQLSMALLINT nType )
     445             : {
     446             :     T val;
     447             : 
     448           0 :     OTools::getValue(m_pStatement->getOwnConnection(), m_aStatementHandle, _nColumnIndex, nType, m_bWasNull, **this, &val, sizeof(val));
     449             : 
     450           0 :     return val;
     451             : }
     452             : 
     453             : // this function exists for the implicit conversion to sal_Bool (compared to a direct call to impl_getValue)
     454           0 : bool OResultSet::impl_getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
     455             : {
     456           0 :     return impl_getValue<sal_Int8>(columnIndex, SQL_C_BIT);
     457             : }
     458             : 
     459           0 : template < typename T > T OResultSet::getValue( sal_Int32 columnIndex )
     460             : {
     461           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     462           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     463           0 :     fillColumn(columnIndex);
     464           0 :     m_bWasNull = m_aRow[columnIndex].isNull();
     465           0 :     return m_aRow[columnIndex];
     466             : }
     467           0 : sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     468             : {
     469           0 :     return getValue<sal_Bool>( columnIndex );
     470             : }
     471             : 
     472           0 : sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     473             : {
     474           0 :     return getValue<sal_Int8>( columnIndex );
     475             : }
     476             : 
     477             : 
     478           0 : Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     479             : {
     480           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     481           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     482           0 :     fillColumn(columnIndex);
     483           0 :     m_bWasNull = m_aRow[columnIndex].isNull();
     484             : 
     485           0 :     Sequence< sal_Int8 > nRet;
     486           0 :     switch(m_aRow[columnIndex].getTypeKind())
     487             :     {
     488             :     case DataType::BINARY:
     489             :     case DataType::VARBINARY:
     490             :     case DataType::LONGVARBINARY:
     491           0 :         nRet = m_aRow[columnIndex];
     492           0 :         break;
     493             :     default:
     494             :     {
     495           0 :         OUString sRet;
     496           0 :         sRet = m_aRow[columnIndex].getString();
     497           0 :         nRet = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(sRet.getStr()),sizeof(sal_Unicode)*sRet.getLength());
     498             :     }
     499             :     }
     500           0 :     return nRet;
     501             : }
     502           0 : Sequence< sal_Int8 > OResultSet::impl_getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
     503             : {
     504           0 :     const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex);
     505             : 
     506           0 :     switch(nColumnType)
     507             :     {
     508             :     case SQL_WVARCHAR:
     509             :     case SQL_WCHAR:
     510             :     case SQL_WLONGVARCHAR:
     511             :     case SQL_VARCHAR:
     512             :     case SQL_CHAR:
     513             :     case SQL_LONGVARCHAR:
     514             :     {
     515           0 :         OUString aRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding);
     516           0 :         return Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aRet.getStr()),sizeof(sal_Unicode)*aRet.getLength());
     517             :     }
     518             :     default:
     519           0 :         return OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,SQL_C_BINARY,m_bWasNull,**this);
     520             :     }
     521             : }
     522             : 
     523           0 : Date OResultSet::impl_getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
     524             : {
     525             :     DATE_STRUCT aDate = impl_getValue< DATE_STRUCT> ( columnIndex,
     526           0 :                                                       m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_DATE : SQL_C_TYPE_DATE  );
     527             : 
     528           0 :     return Date(aDate.day, aDate.month, aDate.year);
     529             : }
     530             : 
     531           0 : Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     532             : {
     533           0 :     return getValue<Date>( columnIndex );
     534             : }
     535             : 
     536             : 
     537           0 : double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     538             : {
     539           0 :     return getValue<double>( columnIndex );
     540             : }
     541             : 
     542             : 
     543           0 : float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     544             : {
     545           0 :     return getValue<float>( columnIndex );
     546             : }
     547             : 
     548           0 : sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     549             : {
     550           0 :     return getValue<sal_Int16>( columnIndex );
     551             : }
     552             : 
     553           0 : sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     554             : {
     555           0 :     return getValue<sal_Int32>( columnIndex );
     556             : }
     557             : 
     558           0 : sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     559             : {
     560           0 :     return getValue<sal_Int64>( columnIndex );
     561             : }
     562           0 : sal_Int64 OResultSet::impl_getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
     563             : {
     564             :     try
     565             :     {
     566           0 :         return impl_getValue<sal_Int64>(columnIndex, SQL_C_SBIGINT);
     567             :     }
     568           0 :     catch(const SQLException&)
     569             :     {
     570           0 :         return getString(columnIndex).toInt64();
     571             :     }
     572             : }
     573             : 
     574           0 : sal_Int32 SAL_CALL OResultSet::getRow(  ) throw(SQLException, RuntimeException, std::exception)
     575             : {
     576           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     577           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     578             : 
     579           0 :     return m_pSkipDeletedSet ? m_pSkipDeletedSet->getMappedPosition(getDriverPos()) : getDriverPos();
     580             : }
     581             : 
     582           0 : Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData(  ) throw(SQLException, RuntimeException, std::exception)
     583             : {
     584           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     585           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     586             : 
     587             : 
     588           0 :     if(!m_xMetaData.is())
     589           0 :         m_xMetaData = new OResultSetMetaData(m_pStatement->getOwnConnection(),m_aStatementHandle);
     590           0 :     return m_xMetaData;
     591             : }
     592             : 
     593           0 : Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
     594             : {
     595           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getArray", *this );
     596           0 :     return NULL;
     597             : }
     598             : 
     599             : 
     600             : 
     601           0 : Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
     602             : {
     603           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getClob", *this );
     604           0 :     return NULL;
     605             : }
     606             : 
     607           0 : Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
     608             : {
     609           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getBlob", *this );
     610           0 :     return NULL;
     611             : }
     612             : 
     613             : 
     614           0 : Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException, std::exception)
     615             : {
     616           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRow::getRef", *this );
     617           0 :     return NULL;
     618             : }
     619             : 
     620             : 
     621           0 : Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException, std::exception)
     622             : {
     623           0 :     return getValue<ORowSetValue>( columnIndex ).makeAny();
     624             : }
     625             : 
     626           0 : OUString OResultSet::impl_getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
     627             : {
     628           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     629           0 :     const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex);
     630           0 :     return OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding);
     631             : }
     632           0 : OUString OResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     633             : {
     634           0 :     return getValue<OUString>( columnIndex );
     635             : }
     636             : 
     637           0 : Time OResultSet::impl_getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
     638             : {
     639             :     TIME_STRUCT aTime = impl_getValue< TIME_STRUCT > ( columnIndex,
     640           0 :                                                       m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_TIME : SQL_C_TYPE_TIME );
     641             : 
     642           0 :     return Time(0, aTime.second,aTime.minute,aTime.hour, false);
     643             : }
     644           0 : Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     645             : {
     646           0 :     return getValue<Time>( columnIndex );
     647             : }
     648             : 
     649           0 : DateTime OResultSet::impl_getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
     650             : {
     651             :     TIMESTAMP_STRUCT aTime = impl_getValue< TIMESTAMP_STRUCT > ( columnIndex,
     652           0 :                                                                  m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_TIMESTAMP : SQL_C_TYPE_TIMESTAMP );
     653             : 
     654             :     return DateTime(aTime.fraction,
     655             :                     aTime.second,
     656             :                     aTime.minute,
     657             :                     aTime.hour,
     658             :                     aTime.day,
     659             :                     aTime.month,
     660             :                     aTime.year,
     661           0 :                     false);
     662             : }
     663           0 : DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
     664             : {
     665           0 :     return getValue<DateTime>( columnIndex );
     666             : }
     667             : 
     668           0 : sal_Bool SAL_CALL OResultSet::isBeforeFirst(  ) throw(SQLException, RuntimeException, std::exception)
     669             : {
     670           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     671           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     672           0 :     return m_nRowPos == 0;
     673             : }
     674             : 
     675           0 : sal_Bool SAL_CALL OResultSet::isAfterLast(  ) throw(SQLException, RuntimeException, std::exception)
     676             : {
     677           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     678           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     679             : 
     680           0 :     return m_nRowPos != 0 && m_nCurrentFetchState == SQL_NO_DATA;
     681             : }
     682             : 
     683           0 : sal_Bool SAL_CALL OResultSet::isFirst(  ) throw(SQLException, RuntimeException, std::exception)
     684             : {
     685           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     686           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     687             : 
     688           0 :     return m_nRowPos == 1;
     689             : }
     690             : 
     691           0 : sal_Bool SAL_CALL OResultSet::isLast(  ) throw(SQLException, RuntimeException, std::exception)
     692             : {
     693           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     694           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     695             : 
     696             : 
     697           0 :     return m_bEOF && m_nCurrentFetchState != SQL_NO_DATA;
     698             : }
     699             : 
     700           0 : void SAL_CALL OResultSet::beforeFirst(  ) throw(SQLException, RuntimeException, std::exception)
     701             : {
     702           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     703           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     704             : 
     705             : 
     706           0 :     if(first())
     707           0 :         previous();
     708           0 :     m_nCurrentFetchState = SQL_SUCCESS;
     709           0 : }
     710             : 
     711           0 : void SAL_CALL OResultSet::afterLast(  ) throw(SQLException, RuntimeException, std::exception)
     712             : {
     713           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     714           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     715             : 
     716           0 :     if(last())
     717           0 :         next();
     718           0 :     m_bEOF = true;
     719           0 : }
     720             : 
     721             : 
     722           0 : void SAL_CALL OResultSet::close(  ) throw(SQLException, RuntimeException, std::exception)
     723             : {
     724             :     {
     725           0 :         ::osl::MutexGuard aGuard( m_aMutex );
     726           0 :         checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     727             : 
     728             :     }
     729           0 :     dispose();
     730           0 : }
     731             : 
     732             : 
     733           0 : sal_Bool SAL_CALL OResultSet::first(  ) throw(SQLException, RuntimeException, std::exception)
     734             : {
     735           0 :     return moveImpl(IResultSetHelper::FIRST,0,true);
     736             : }
     737             : 
     738             : 
     739           0 : sal_Bool SAL_CALL OResultSet::last(  ) throw(SQLException, RuntimeException, std::exception)
     740             : {
     741           0 :     return moveImpl(IResultSetHelper::LAST,0,true);
     742             : }
     743             : 
     744           0 : sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException, std::exception)
     745             : {
     746           0 :     return moveImpl(IResultSetHelper::ABSOLUTE1,row,true);
     747             : }
     748             : 
     749           0 : sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException, std::exception)
     750             : {
     751           0 :     return moveImpl(IResultSetHelper::RELATIVE1,row,true);
     752             : }
     753             : 
     754           0 : sal_Bool SAL_CALL OResultSet::previous(  ) throw(SQLException, RuntimeException, std::exception)
     755             : {
     756           0 :     return moveImpl(IResultSetHelper::PRIOR,0,true);
     757             : }
     758             : 
     759           0 : Reference< XInterface > SAL_CALL OResultSet::getStatement(  ) throw(SQLException, RuntimeException, std::exception)
     760             : {
     761           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     762           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     763           0 :     return m_xStatement;
     764             : }
     765             : 
     766             : 
     767           0 : sal_Bool SAL_CALL OResultSet::rowDeleted() throw(SQLException, RuntimeException, std::exception)
     768             : {
     769           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     770           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     771             : 
     772           0 :     bool bRet = m_bRowDeleted;
     773           0 :     m_bRowDeleted = false;
     774             : 
     775           0 :     return bRet;
     776             : }
     777             : 
     778           0 : sal_Bool SAL_CALL OResultSet::rowInserted(  ) throw(SQLException, RuntimeException, std::exception)
     779             : {
     780           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     781           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     782             : 
     783           0 :     bool bInserted = m_bRowInserted;
     784           0 :     m_bRowInserted = false;
     785             : 
     786           0 :     return bInserted;
     787             : }
     788             : 
     789           0 : sal_Bool SAL_CALL OResultSet::rowUpdated(  ) throw(SQLException, RuntimeException, std::exception)
     790             : {
     791           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     792           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     793             : 
     794             : 
     795           0 :     return m_pRowStatusArray[0] == SQL_ROW_UPDATED;
     796             : }
     797             : 
     798             : 
     799           0 : sal_Bool SAL_CALL OResultSet::next(  ) throw(SQLException, RuntimeException, std::exception)
     800             : {
     801           0 :     return moveImpl(IResultSetHelper::NEXT,1,true);
     802             : }
     803             : 
     804             : 
     805           0 : sal_Bool SAL_CALL OResultSet::wasNull(  ) throw(SQLException, RuntimeException, std::exception)
     806             : {
     807           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     808           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     809             : 
     810           0 :     return m_bWasNull;
     811             : }
     812             : 
     813             : 
     814           0 : void SAL_CALL OResultSet::cancel(  ) throw(RuntimeException, std::exception)
     815             : {
     816           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     817           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     818             : 
     819             : 
     820           0 :     N3SQLCancel(m_aStatementHandle);
     821           0 : }
     822             : 
     823           0 : void SAL_CALL OResultSet::clearWarnings(  ) throw(SQLException, RuntimeException, std::exception)
     824             : {
     825           0 : }
     826             : 
     827           0 : Any SAL_CALL OResultSet::getWarnings(  ) throw(SQLException, RuntimeException, std::exception)
     828             : {
     829           0 :     return Any();
     830             : }
     831             : 
     832           0 : void SAL_CALL OResultSet::insertRow(  ) throw(SQLException, RuntimeException, std::exception)
     833             : {
     834           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     835           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     836             : 
     837             : 
     838           0 :     SQLLEN nRealLen = 0;
     839           0 :     Sequence<sal_Int8> aBookmark(nMaxBookmarkLen);
     840             :     static_assert(static_cast<size_t>(nMaxBookmarkLen) >= sizeof(SQLLEN), "must be larger");
     841             : 
     842           0 :     SQLRETURN nRet = N3SQLBindCol(m_aStatementHandle,
     843             :                                 0,
     844             :                                 SQL_C_VARBOOKMARK,
     845             :                                 aBookmark.getArray(),
     846             :                                 nMaxBookmarkLen,
     847             :                                 &nRealLen
     848             :                                 );
     849             : 
     850           0 :     bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLFunctionId::BulkOperations ) );
     851           0 :     if ( bPositionByBookmark )
     852             :     {
     853           0 :         nRet = N3SQLBulkOperations( m_aStatementHandle, SQL_ADD );
     854           0 :         fillNeededData( nRet );
     855             :     }
     856             :     else
     857             :     {
     858           0 :         if(isBeforeFirst())
     859           0 :             next(); // must be done
     860           0 :         nRet = N3SQLSetPos( m_aStatementHandle, 1, SQL_ADD, SQL_LOCK_NO_CHANGE );
     861           0 :         fillNeededData( nRet );
     862             :     }
     863           0 :     aBookmark.realloc(nRealLen);
     864             :     try
     865             :     {
     866           0 :         OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     867             :     }
     868           0 :     catch(const SQLException&)
     869             :     {
     870           0 :         nRet = unbind();
     871           0 :         throw;
     872             :     }
     873             : 
     874           0 :     nRet = unbind();
     875           0 :     OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     876             : 
     877           0 :     if ( bPositionByBookmark )
     878             :     {
     879           0 :         setStmtOption<SQLLEN*, SQL_IS_POINTER>(SQL_ATTR_FETCH_BOOKMARK_PTR, reinterpret_cast<SQLLEN*>(aBookmark.getArray()));
     880             : 
     881           0 :         nRet = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,0);
     882             :     }
     883             :     else
     884           0 :         nRet = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,0); // OJ 06.03.2004
     885             :     // sometimes we got an error but we are not interested in anymore #106047# OJ
     886             :     //  OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     887             : 
     888           0 :     if(m_pSkipDeletedSet)
     889             :     {
     890           0 :         if(moveToBookmark(makeAny(aBookmark)))
     891             :         {
     892           0 :             sal_Int32 nRowPos = getDriverPos();
     893           0 :             if ( -1 == m_nRowPos )
     894             :             {
     895           0 :                 nRowPos = m_aPosToBookmarks.size() + 1;
     896             :             }
     897           0 :             if ( nRowPos == m_nRowPos )
     898           0 :                 ++nRowPos;
     899           0 :             m_nRowPos = nRowPos;
     900           0 :             m_pSkipDeletedSet->insertNewPosition(nRowPos);
     901           0 :             m_aPosToBookmarks[aBookmark] = nRowPos;
     902             :         }
     903             :     }
     904           0 :     m_bRowInserted = true;
     905             : 
     906           0 : }
     907             : 
     908           0 : void SAL_CALL OResultSet::updateRow(  ) throw(SQLException, RuntimeException, std::exception)
     909             : {
     910           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     911           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     912             : 
     913             :     SQLRETURN nRet;
     914             : 
     915             :     try
     916             :     {
     917           0 :         bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLFunctionId::BulkOperations ) );
     918           0 :         if ( bPositionByBookmark )
     919             :         {
     920           0 :             getBookmark();
     921             :             assert(m_aRow[0].isBound());
     922           0 :             Sequence<sal_Int8> aBookmark(m_aRow[0].getSequence());
     923           0 :             SQLLEN nRealLen = aBookmark.getLength();
     924           0 :             nRet = N3SQLBindCol(m_aStatementHandle,
     925             :                                 0,
     926             :                                 SQL_C_VARBOOKMARK,
     927             :                                 aBookmark.getArray(),
     928             :                                 aBookmark.getLength(),
     929             :                                 &nRealLen
     930           0 :                                 );
     931           0 :             OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     932           0 :             fillNeededData(nRet = N3SQLBulkOperations(m_aStatementHandle, SQL_UPDATE_BY_BOOKMARK));
     933             :             // the driver should not have touched this
     934             :             // (neither the contents of aBookmark FWIW)
     935           0 :             assert(nRealLen == aBookmark.getLength());
     936             :         }
     937             :         else
     938             :         {
     939           0 :             fillNeededData(nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_UPDATE,SQL_LOCK_NO_CHANGE));
     940             :         }
     941           0 :         OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     942             :         // unbind all columns so we can fetch all columns again with SQLGetData
     943             :         // (and also so that our buffers don't clobber anything, and
     944             :         //  so that a subsequent fetch does not overwrite m_aRow[0])
     945           0 :         invalidateCache();
     946           0 :         nRet = unbind();
     947             :         OSL_ENSURE(nRet == SQL_SUCCESS,"ODBC insert could not unbind the columns after success");
     948             :     }
     949           0 :     catch(...)
     950             :     {
     951             :         // unbind all columns so that a subsequent fetch does not overwrite m_aRow[0]
     952           0 :         nRet = unbind();
     953             :         OSL_ENSURE(nRet == SQL_SUCCESS,"ODBC insert could not unbind the columns after failure");
     954           0 :         throw;
     955           0 :     }
     956           0 : }
     957             : 
     958           0 : void SAL_CALL OResultSet::deleteRow(  ) throw(SQLException, RuntimeException, std::exception)
     959             : {
     960           0 :     SQLRETURN nRet = SQL_SUCCESS;
     961           0 :     sal_Int32 nPos = getDriverPos();
     962           0 :     nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_DELETE,SQL_LOCK_NO_CHANGE);
     963           0 :     OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
     964             : 
     965           0 :     m_bRowDeleted = ( m_pRowStatusArray[0] == SQL_ROW_DELETED );
     966           0 :     if ( m_bRowDeleted )
     967             :     {
     968           0 :         TBookmarkPosMap::iterator aIter = m_aPosToBookmarks.begin();
     969           0 :         TBookmarkPosMap::iterator aEnd = m_aPosToBookmarks.end();
     970           0 :         for (; aIter != aEnd; ++aIter)
     971             :         {
     972           0 :             if ( aIter->second == nPos )
     973             :             {
     974           0 :                 m_aPosToBookmarks.erase(aIter);
     975           0 :                 break;
     976             :             }
     977             :         }
     978             :     }
     979           0 :     if ( m_pSkipDeletedSet )
     980           0 :         m_pSkipDeletedSet->deletePosition(nPos);
     981           0 : }
     982             : 
     983             : 
     984           0 : void SAL_CALL OResultSet::cancelRowUpdates(  ) throw(SQLException, RuntimeException, std::exception)
     985             : {
     986           0 : }
     987             : 
     988             : 
     989           0 : void SAL_CALL OResultSet::moveToInsertRow(  ) throw(SQLException, RuntimeException, std::exception)
     990             : {
     991           0 :     ::osl::MutexGuard aGuard( m_aMutex );
     992           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
     993             : 
     994             : 
     995           0 :     invalidateCache();
     996             :     // first unbound all columns
     997           0 :     OSL_VERIFY_EQUALS( unbind(), SQL_SUCCESS, "Could not unbind columns!" );
     998             :     //  SQLRETURN nRet = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_ARRAY_SIZE ,(SQLPOINTER)1,SQL_IS_INTEGER);
     999           0 :     m_bInserting = true;
    1000           0 : }
    1001             : 
    1002             : 
    1003           0 : void SAL_CALL OResultSet::moveToCurrentRow(  ) throw(SQLException, RuntimeException, std::exception)
    1004             : {
    1005           0 :     invalidateCache();
    1006           0 : }
    1007             : 
    1008           0 : void OResultSet::updateValue(sal_Int32 columnIndex,SQLSMALLINT _nType,void* _pValue) throw(SQLException, RuntimeException)
    1009             : {
    1010           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1011           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1012             : 
    1013           0 :     m_aBindVector.push_back(allocBindColumn(OTools::MapOdbcType2Jdbc(_nType),columnIndex));
    1014           0 :     void* pData = reinterpret_cast<void*>(m_aBindVector.rbegin()->first);
    1015             :     OSL_ENSURE(pData != NULL,"Data for update is NULL!");
    1016             :     OTools::bindValue(  m_pStatement->getOwnConnection(),
    1017             :                         m_aStatementHandle,
    1018             :                         columnIndex,
    1019             :                         _nType,
    1020             :                         0,
    1021             :                         _pValue,
    1022             :                         pData,
    1023           0 :                         &m_aLengthVector[columnIndex],
    1024             :                         **this,
    1025             :                         m_nTextEncoding,
    1026           0 :                         m_pStatement->getOwnConnection()->useOldDateFormat());
    1027           0 : }
    1028             : 
    1029           0 : void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException, std::exception)
    1030             : {
    1031           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1032           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1033             : 
    1034           0 :     m_aBindVector.push_back(allocBindColumn(DataType::CHAR,columnIndex));
    1035           0 :     void* pData = reinterpret_cast<void*>(m_aBindVector.rbegin()->first);
    1036           0 :     OTools::bindValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,SQL_CHAR,0,nullptr,pData,&m_aLengthVector[columnIndex],**this,m_nTextEncoding,m_pStatement->getOwnConnection()->useOldDateFormat());
    1037           0 : }
    1038             : 
    1039             : 
    1040           0 : void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException, std::exception)
    1041             : {
    1042           0 :     updateValue(columnIndex,SQL_BIT,&x);
    1043           0 : }
    1044             : 
    1045           0 : void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException, std::exception)
    1046             : {
    1047           0 :     updateValue(columnIndex,SQL_CHAR,&x);
    1048           0 : }
    1049             : 
    1050             : 
    1051           0 : void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException, std::exception)
    1052             : {
    1053           0 :     updateValue(columnIndex,SQL_TINYINT,&x);
    1054           0 : }
    1055             : 
    1056           0 : void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException, std::exception)
    1057             : {
    1058           0 :     updateValue(columnIndex,SQL_INTEGER,&x);
    1059           0 : }
    1060             : 
    1061           0 : void SAL_CALL OResultSet::updateLong( sal_Int32 /*columnIndex*/, sal_Int64 /*x*/ ) throw(SQLException, RuntimeException, std::exception)
    1062             : {
    1063           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRowUpdate::updateLong", *this );
    1064           0 : }
    1065             : 
    1066           0 : void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException, std::exception)
    1067             : {
    1068           0 :     updateValue(columnIndex,SQL_REAL,&x);
    1069           0 : }
    1070             : 
    1071             : 
    1072           0 : void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException, std::exception)
    1073             : {
    1074           0 :     updateValue(columnIndex,SQL_DOUBLE,&x);
    1075           0 : }
    1076             : 
    1077           0 : void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const OUString& x ) throw(SQLException, RuntimeException, std::exception)
    1078             : {
    1079           0 :     sal_Int32 nType = m_aRow[columnIndex].getTypeKind();
    1080           0 :     SQLSMALLINT nOdbcType = OTools::jdbcTypeToOdbc(nType);
    1081           0 :     m_aRow[columnIndex] = x;
    1082           0 :     m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarchar will be recognized by fillNeededData
    1083           0 :     m_aRow[columnIndex].setBound(true);
    1084           0 :     updateValue(columnIndex,nOdbcType,const_cast<OUString *>(&x));
    1085           0 : }
    1086             : 
    1087           0 : void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException, std::exception)
    1088             : {
    1089           0 :     sal_Int32 nType = m_aRow[columnIndex].getTypeKind();
    1090           0 :     SQLSMALLINT nOdbcType = OTools::jdbcTypeToOdbc(nType);
    1091           0 :     m_aRow[columnIndex] = x;
    1092           0 :     m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarbinary will be recognized by fillNeededData
    1093           0 :     m_aRow[columnIndex].setBound(true);
    1094           0 :     updateValue(columnIndex,nOdbcType,const_cast<css::uno::Sequence<sal_Int8> *>(&x));
    1095           0 : }
    1096             : 
    1097           0 : void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const Date& x ) throw(SQLException, RuntimeException, std::exception)
    1098             : {
    1099           0 :     DATE_STRUCT aVal = OTools::DateToOdbcDate(x);
    1100           0 :     updateValue(columnIndex,SQL_DATE,&aVal);
    1101           0 : }
    1102             : 
    1103             : 
    1104           0 : void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const css::util::Time& x ) throw(SQLException, RuntimeException, std::exception)
    1105             : {
    1106           0 :     TIME_STRUCT aVal = OTools::TimeToOdbcTime(x);
    1107           0 :     updateValue(columnIndex,SQL_TIME,&aVal);
    1108           0 : }
    1109             : 
    1110             : 
    1111           0 : void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const DateTime& x ) throw(SQLException, RuntimeException, std::exception)
    1112             : {
    1113           0 :     TIMESTAMP_STRUCT aVal = OTools::DateTimeToTimestamp(x);
    1114           0 :     updateValue(columnIndex,SQL_TIMESTAMP,&aVal);
    1115           0 : }
    1116             : 
    1117             : 
    1118           0 : void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
    1119             : {
    1120           0 :     if(!x.is())
    1121           0 :         ::dbtools::throwFunctionSequenceException(*this);
    1122             : 
    1123           0 :     Sequence<sal_Int8> aSeq;
    1124           0 :     x->readBytes(aSeq,length);
    1125           0 :     updateBytes(columnIndex,aSeq);
    1126           0 : }
    1127             : 
    1128           0 : void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException, std::exception)
    1129             : {
    1130           0 :     updateBinaryStream(columnIndex,x,length);
    1131           0 : }
    1132             : 
    1133           0 : void SAL_CALL OResultSet::refreshRow(  ) throw(SQLException, RuntimeException, std::exception)
    1134             : {
    1135           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1136           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1137             : 
    1138             : 
    1139             :     //  SQLRETURN nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_REFRESH,SQL_LOCK_NO_CHANGE);
    1140           0 :     m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,0);
    1141           0 :     OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
    1142           0 : }
    1143             : 
    1144           0 : void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException, std::exception)
    1145             : {
    1146           0 :     if (!::dbtools::implUpdateObject(this, columnIndex, x))
    1147           0 :         throw SQLException();
    1148           0 : }
    1149             : 
    1150             : 
    1151           0 : void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException, std::exception)
    1152             : {
    1153           0 :     if (!::dbtools::implUpdateObject(this, columnIndex, x))
    1154           0 :         throw SQLException();
    1155           0 : }
    1156             : 
    1157             : // XRowLocate
    1158           0 : Any SAL_CALL OResultSet::getBookmark(  ) throw( SQLException,  RuntimeException, std::exception)
    1159             : {
    1160           0 :     fillColumn(0);
    1161           0 :     if(m_aRow[0].isNull())
    1162           0 :         throw SQLException();
    1163           0 :     return m_aRow[0].makeAny();
    1164             : }
    1165           0 : Sequence<sal_Int8> OResultSet::impl_getBookmark(  ) throw( SQLException,  RuntimeException)
    1166             : {
    1167           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1168             : 
    1169             :     TBookmarkPosMap::iterator aFind = ::std::find_if(m_aPosToBookmarks.begin(),m_aPosToBookmarks.end(),
    1170           0 :         ::o3tl::compose1(::std::bind2nd(::std::equal_to<sal_Int32>(),m_nRowPos),::o3tl::select2nd<TBookmarkPosMap::value_type>()));
    1171             : 
    1172           0 :     if ( aFind == m_aPosToBookmarks.end() )
    1173             :     {
    1174           0 :         if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED )
    1175             :         {
    1176           0 :             m_nUseBookmarks = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS, SQL_UB_OFF);
    1177             :         }
    1178           0 :         if(m_nUseBookmarks == SQL_UB_OFF)
    1179           0 :             throw SQLException();
    1180             : 
    1181           0 :         Sequence<sal_Int8> bookmark = OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,0,SQL_C_VARBOOKMARK,m_bWasNull,**this);
    1182           0 :         m_aPosToBookmarks[bookmark] = m_nRowPos;
    1183             :         OSL_ENSURE(bookmark.getLength(),"Invalid bookmark from length 0!");
    1184           0 :         return bookmark;
    1185             :     }
    1186             :     else
    1187             :     {
    1188           0 :         return aFind->first;
    1189             :     }
    1190             : }
    1191             : 
    1192           0 : sal_Bool SAL_CALL OResultSet::moveToBookmark( const  Any& bookmark ) throw( SQLException,  RuntimeException, std::exception)
    1193             : {
    1194           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1195           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1196             : 
    1197           0 :     invalidateCache();
    1198           0 :     Sequence<sal_Int8> aBookmark;
    1199           0 :     bookmark >>= aBookmark;
    1200             :     OSL_ENSURE(aBookmark.getLength(),"Invalid bookmark from length 0!");
    1201           0 :     if(aBookmark.getLength())
    1202             :     {
    1203           0 :         SQLRETURN nReturn = setStmtOption<SQLLEN*, SQL_IS_POINTER>(SQL_ATTR_FETCH_BOOKMARK_PTR, reinterpret_cast<SQLLEN*>(aBookmark.getArray()));
    1204             : 
    1205           0 :         if ( SQL_INVALID_HANDLE != nReturn && SQL_ERROR != nReturn )
    1206             :         {
    1207           0 :             m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,0);
    1208           0 :             OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
    1209           0 :             TBookmarkPosMap::iterator aFind = m_aPosToBookmarks.find(aBookmark);
    1210           0 :             if(aFind != m_aPosToBookmarks.end())
    1211           0 :                 m_nRowPos = aFind->second;
    1212             :             else
    1213           0 :                 m_nRowPos = -1;
    1214           0 :             return m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
    1215             :         }
    1216             :     }
    1217           0 :     return sal_False;
    1218             : }
    1219             : 
    1220           0 : sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark( const  Any& bookmark, sal_Int32 rows ) throw( SQLException,  RuntimeException, std::exception)
    1221             : {
    1222           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1223           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1224             : 
    1225             : 
    1226           0 :     invalidateCache();
    1227           0 :     Sequence<sal_Int8> aBookmark;
    1228           0 :     bookmark >>= aBookmark;
    1229           0 :     SQLRETURN nReturn = setStmtOption<SQLLEN*, SQL_IS_POINTER>(SQL_ATTR_FETCH_BOOKMARK_PTR, reinterpret_cast<SQLLEN*>(aBookmark.getArray()));
    1230             :     OSL_UNUSED( nReturn );
    1231             : 
    1232           0 :     m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,rows);
    1233           0 :     OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
    1234           0 :     return m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
    1235             : }
    1236             : 
    1237           0 : sal_Int32 SAL_CALL OResultSet::compareBookmarks( const Any& lhs, const  Any& rhs ) throw( SQLException,  RuntimeException, std::exception)
    1238             : {
    1239           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1240           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1241             : 
    1242           0 :     return (lhs == rhs) ? CompareBookmark::EQUAL : CompareBookmark::NOT_EQUAL;
    1243             : }
    1244             : 
    1245           0 : sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks(  ) throw( SQLException,  RuntimeException, std::exception)
    1246             : {
    1247           0 :     return sal_False;
    1248             : }
    1249             : 
    1250           0 : sal_Int32 SAL_CALL OResultSet::hashBookmark( const  Any& /*bookmark*/ ) throw( SQLException,  RuntimeException, std::exception)
    1251             : {
    1252           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "XRowLocate::hashBookmark", *this );
    1253           0 :     return 0;
    1254             : }
    1255             : 
    1256             : // XDeleteRows
    1257           0 : Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows( const  Sequence<  Any >& rows ) throw( SQLException,  RuntimeException, std::exception)
    1258             : {
    1259           0 :     Sequence< sal_Int32 > aRet(rows.getLength());
    1260           0 :     sal_Int32 *pRet = aRet.getArray();
    1261             : 
    1262           0 :     const Any *pBegin   = rows.getConstArray();
    1263           0 :     const Any *pEnd     = pBegin + rows.getLength();
    1264             : 
    1265           0 :     for(;pBegin != pEnd;++pBegin,++pRet)
    1266             :     {
    1267             :         try
    1268             :         {
    1269           0 :             if(moveToBookmark(*pBegin))
    1270             :             {
    1271           0 :                 deleteRow();
    1272           0 :                 *pRet = 1;
    1273             :             }
    1274             :         }
    1275           0 :         catch(const SQLException&)
    1276             :         {
    1277           0 :             *pRet = 0;
    1278             :         }
    1279             :     }
    1280           0 :     return aRet;
    1281             : }
    1282             : 
    1283           0 : template < typename T, SQLINTEGER BufferLength > T OResultSet::getStmtOption (SQLINTEGER fOption, T dflt) const
    1284             : {
    1285           0 :     T result (dflt);
    1286             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
    1287           0 :     N3SQLGetStmtAttr(m_aStatementHandle, fOption, &result, BufferLength, NULL);
    1288           0 :     return result;
    1289             : }
    1290           0 : template < typename T, SQLINTEGER BufferLength > SQLRETURN OResultSet::setStmtOption (SQLINTEGER fOption, T value) const
    1291             : {
    1292             :     OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
    1293           0 :     SQLPOINTER sv = reinterpret_cast<SQLPOINTER>(value);
    1294           0 :     return N3SQLSetStmtAttr(m_aStatementHandle, fOption, sv, BufferLength);
    1295             : }
    1296             : 
    1297           0 : sal_Int32 OResultSet::getResultSetConcurrency() const
    1298             : {
    1299           0 :     sal_uInt32 nValue = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CONCURRENCY);
    1300           0 :     if(SQL_CONCUR_READ_ONLY == nValue)
    1301           0 :         nValue = ResultSetConcurrency::READ_ONLY;
    1302             :     else
    1303           0 :         nValue = ResultSetConcurrency::UPDATABLE;
    1304             : 
    1305           0 :     return nValue;
    1306             : }
    1307             : 
    1308           0 : sal_Int32 OResultSet::getResultSetType() const
    1309             : {
    1310           0 :     sal_uInt32 nValue = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_SENSITIVITY);
    1311           0 :     if(SQL_SENSITIVE == nValue)
    1312           0 :         nValue = ResultSetType::SCROLL_SENSITIVE;
    1313           0 :     else if(SQL_INSENSITIVE == nValue)
    1314           0 :         nValue = ResultSetType::SCROLL_INSENSITIVE;
    1315             :     else
    1316             :     {
    1317           0 :         SQLULEN nCurType = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE);
    1318           0 :         if(SQL_CURSOR_KEYSET_DRIVEN == nCurType)
    1319           0 :             nValue = ResultSetType::SCROLL_SENSITIVE;
    1320           0 :         else if(SQL_CURSOR_STATIC  == nCurType)
    1321           0 :             nValue = ResultSetType::SCROLL_INSENSITIVE;
    1322           0 :         else if(SQL_CURSOR_FORWARD_ONLY == nCurType)
    1323           0 :             nValue = ResultSetType::FORWARD_ONLY;
    1324           0 :         else if(SQL_CURSOR_DYNAMIC == nCurType)
    1325           0 :             nValue = ResultSetType::SCROLL_SENSITIVE;
    1326             :     }
    1327           0 :     return nValue;
    1328             : }
    1329             : 
    1330           0 : sal_Int32 OResultSet::getFetchSize() const
    1331             : {
    1332           0 :     return getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_ARRAY_SIZE);
    1333             : }
    1334             : 
    1335           0 : OUString OResultSet::getCursorName() const
    1336             : {
    1337             :     SQLCHAR pName[258];
    1338           0 :     SQLSMALLINT nRealLen = 0;
    1339           0 :     N3SQLGetCursorName(m_aStatementHandle,pName,256,&nRealLen);
    1340           0 :     return OUString::createFromAscii(reinterpret_cast<char*>(pName));
    1341             : }
    1342             : 
    1343           0 : bool  OResultSet::isBookmarkable() const
    1344             : {
    1345           0 :     if(!m_aConnectionHandle)
    1346           0 :         return false;
    1347             : 
    1348           0 :     const SQLULEN nCursorType = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE);
    1349             : 
    1350           0 :     sal_Int32 nAttr = 0;
    1351             :     try
    1352             :     {
    1353           0 :         switch(nCursorType)
    1354             :         {
    1355             :         case SQL_CURSOR_FORWARD_ONLY:
    1356           0 :             return false;
    1357             :         case SQL_CURSOR_STATIC:
    1358           0 :             OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_STATIC_CURSOR_ATTRIBUTES1,nAttr,NULL);
    1359           0 :             break;
    1360             :         case SQL_CURSOR_KEYSET_DRIVEN:
    1361           0 :             OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_KEYSET_CURSOR_ATTRIBUTES1,nAttr,NULL);
    1362           0 :             break;
    1363             :         case SQL_CURSOR_DYNAMIC:
    1364           0 :             OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_DYNAMIC_CURSOR_ATTRIBUTES1,nAttr,NULL);
    1365           0 :             break;
    1366             :         }
    1367             :     }
    1368           0 :     catch(const Exception&)
    1369             :     {
    1370           0 :         return false;
    1371             :     }
    1372             : 
    1373           0 :     if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED )
    1374             :     {
    1375           0 :         m_nUseBookmarks = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS, SQL_UB_OFF);
    1376             :     }
    1377             : 
    1378           0 :     return (m_nUseBookmarks != SQL_UB_OFF) && (nAttr & SQL_CA1_BOOKMARK) == SQL_CA1_BOOKMARK;
    1379             : }
    1380             : 
    1381           0 : void OResultSet::setFetchDirection(sal_Int32 _par0)
    1382             : {
    1383           0 :     ::dbtools::throwFunctionNotSupportedSQLException( "setFetchDirection", *this );
    1384             : 
    1385             :     OSL_ENSURE(_par0>0,"Illegal fetch direction!");
    1386           0 :     if ( _par0 > 0 )
    1387             :     {
    1388           0 :         setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE, _par0);
    1389             :     }
    1390           0 : }
    1391             : 
    1392           0 : void OResultSet::setFetchSize(sal_Int32 _par0)
    1393             : {
    1394             :     OSL_ENSURE(_par0>0,"Illegal fetch size!");
    1395           0 :     if ( _par0 != 1 )
    1396             :     {
    1397           0 :         throw ::com::sun::star::beans::PropertyVetoException("SDBC/ODBC layer not prepared for fetchSize > 1", *this);
    1398             :     }
    1399           0 :     if ( _par0 > 0 )
    1400             :     {
    1401           0 :         setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_ARRAY_SIZE, _par0);
    1402           0 :         delete [] m_pRowStatusArray;
    1403             : 
    1404           0 :         m_pRowStatusArray = new SQLUSMALLINT[_par0];
    1405           0 :         setStmtOption<SQLUSMALLINT*, SQL_IS_POINTER>(SQL_ATTR_ROW_STATUS_PTR, m_pRowStatusArray);
    1406             :     }
    1407           0 : }
    1408             : 
    1409           0 : IPropertyArrayHelper* OResultSet::createArrayHelper( ) const
    1410             : {
    1411           0 :     Sequence< Property > aProps(6);
    1412           0 :     Property* pProperties = aProps.getArray();
    1413           0 :     sal_Int32 nPos = 0;
    1414           0 :     pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_CURSORNAME),
    1415           0 :         PROPERTY_ID_CURSORNAME, cppu::UnoType<OUString>::get(), PropertyAttribute::READONLY);
    1416             : 
    1417           0 :     pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
    1418           0 :         PROPERTY_ID_FETCHDIRECTION, cppu::UnoType<sal_Int32>::get(), 0);
    1419             : 
    1420           0 :     pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
    1421           0 :         PROPERTY_ID_FETCHSIZE, cppu::UnoType<sal_Int32>::get(), 0);
    1422             : 
    1423           0 :     pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISBOOKMARKABLE),
    1424           0 :         PROPERTY_ID_ISBOOKMARKABLE, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY);
    1425             : 
    1426           0 :     pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
    1427           0 :         PROPERTY_ID_RESULTSETCONCURRENCY, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
    1428             : 
    1429           0 :     pProperties[nPos++] = ::com::sun::star::beans::Property(::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
    1430           0 :         PROPERTY_ID_RESULTSETTYPE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY);
    1431             : 
    1432           0 :     return new OPropertyArrayHelper(aProps);
    1433             : }
    1434             : 
    1435           0 : IPropertyArrayHelper & OResultSet::getInfoHelper()
    1436             : {
    1437           0 :     return *getArrayHelper();
    1438             : }
    1439             : 
    1440           0 : sal_Bool OResultSet::convertFastPropertyValue(
    1441             :                             Any & rConvertedValue,
    1442             :                             Any & rOldValue,
    1443             :                             sal_Int32 nHandle,
    1444             :                             const Any& rValue )
    1445             :                                 throw (::com::sun::star::lang::IllegalArgumentException)
    1446             : {
    1447           0 :     switch(nHandle)
    1448             :     {
    1449             :         case PROPERTY_ID_ISBOOKMARKABLE:
    1450             :         case PROPERTY_ID_CURSORNAME:
    1451             :         case PROPERTY_ID_RESULTSETCONCURRENCY:
    1452             :         case PROPERTY_ID_RESULTSETTYPE:
    1453           0 :             throw ::com::sun::star::lang::IllegalArgumentException();
    1454             :         case PROPERTY_ID_FETCHDIRECTION:
    1455           0 :             return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
    1456             :         case PROPERTY_ID_FETCHSIZE:
    1457           0 :             return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
    1458             :         default:
    1459             :             ;
    1460             :     }
    1461           0 :     return sal_False;
    1462             : }
    1463             : 
    1464           0 : void OResultSet::setFastPropertyValue_NoBroadcast(
    1465             :                                 sal_Int32 nHandle,
    1466             :                                 const Any& rValue
    1467             :                                                  )
    1468             :                                                  throw (Exception, std::exception)
    1469             : {
    1470           0 :     switch(nHandle)
    1471             :     {
    1472             :         case PROPERTY_ID_ISBOOKMARKABLE:
    1473             :         case PROPERTY_ID_CURSORNAME:
    1474             :         case PROPERTY_ID_RESULTSETCONCURRENCY:
    1475             :         case PROPERTY_ID_RESULTSETTYPE:
    1476           0 :             throw Exception();
    1477             :         case PROPERTY_ID_FETCHDIRECTION:
    1478           0 :             setFetchDirection(getINT32(rValue));
    1479           0 :             break;
    1480             :         case PROPERTY_ID_FETCHSIZE:
    1481           0 :             setFetchSize(getINT32(rValue));
    1482           0 :             break;
    1483             :         default:
    1484             :             ;
    1485             :     }
    1486           0 : }
    1487             : 
    1488           0 : void OResultSet::getFastPropertyValue(
    1489             :                                 Any& rValue,
    1490             :                                 sal_Int32 nHandle
    1491             :                                      ) const
    1492             : {
    1493           0 :     switch(nHandle)
    1494             :     {
    1495             :         case PROPERTY_ID_ISBOOKMARKABLE:
    1496           0 :             rValue = css::uno::makeAny(isBookmarkable());
    1497           0 :             break;
    1498             :         case PROPERTY_ID_CURSORNAME:
    1499           0 :             rValue <<= getCursorName();
    1500           0 :             break;
    1501             :         case PROPERTY_ID_RESULTSETCONCURRENCY:
    1502           0 :             rValue <<= getResultSetConcurrency();
    1503           0 :             break;
    1504             :         case PROPERTY_ID_RESULTSETTYPE:
    1505           0 :             rValue <<= getResultSetType();
    1506           0 :             break;
    1507             :         case PROPERTY_ID_FETCHDIRECTION:
    1508           0 :             rValue <<= getFetchDirection();
    1509           0 :             break;
    1510             :         case PROPERTY_ID_FETCHSIZE:
    1511           0 :             rValue <<= getFetchSize();
    1512           0 :             break;
    1513             :     }
    1514           0 : }
    1515             : 
    1516           0 : void OResultSet::fillColumn(const sal_Int32 _nColumn)
    1517             : {
    1518           0 :     ensureCacheForColumn(_nColumn);
    1519             : 
    1520           0 :     if (m_aRow[_nColumn].isBound())
    1521           0 :         return;
    1522             : 
    1523             :     sal_Int32 curCol;
    1524           0 :     if(m_bFetchDataInOrder)
    1525             :     {
    1526             :         // m_aRow necessarily has a prefix of bound values, then all unbound values
    1527             :         // EXCEPT for column 0
    1528             :         // so use binary search to find the earliest unbound value before or at _nColumn
    1529           0 :         sal_Int32 lower=0;
    1530           0 :         sal_Int32 upper=_nColumn;
    1531             : 
    1532           0 :         while (lower < upper)
    1533             :         {
    1534           0 :             const sal_Int32 middle=(upper-lower)/2 + lower;
    1535           0 :             if(m_aRow[middle].isBound())
    1536             :             {
    1537           0 :                 lower=middle+1;
    1538             :             }
    1539             :             else
    1540             :             {
    1541           0 :                 upper=middle;
    1542             :             }
    1543             :         }
    1544             : 
    1545           0 :         curCol = upper;
    1546             :     }
    1547             :     else
    1548             :     {
    1549           0 :         curCol = _nColumn;
    1550             :     }
    1551             : 
    1552           0 :     TDataRow::iterator pColumn      = m_aRow.begin() + curCol;
    1553           0 :     const TDataRow::const_iterator pColumnEnd   = m_aRow.begin() + _nColumn + 1;
    1554             : 
    1555           0 :     if(curCol==0)
    1556             :     {
    1557             :         try
    1558             :         {
    1559           0 :             *pColumn=impl_getBookmark();
    1560             :         }
    1561           0 :         catch (SQLException &)
    1562             :         {
    1563           0 :             pColumn->setNull();
    1564             :         }
    1565           0 :         pColumn->setBound(true);
    1566           0 :         ++curCol;
    1567           0 :         ++pColumn;
    1568             :     }
    1569             : 
    1570           0 :     for (; pColumn != pColumnEnd; ++curCol, ++pColumn)
    1571             :     {
    1572           0 :         const sal_Int32 nType = pColumn->getTypeKind();
    1573           0 :         switch (nType)
    1574             :         {
    1575             :         case DataType::CHAR:
    1576             :         case DataType::VARCHAR:
    1577             :         case DataType::DECIMAL:
    1578             :         case DataType::NUMERIC:
    1579             :         case DataType::LONGVARCHAR:
    1580             :         case DataType::CLOB:
    1581           0 :             *pColumn=impl_getString(curCol);
    1582           0 :             break;
    1583             :         case DataType::FLOAT:
    1584           0 :             *pColumn = impl_getValue<float>(curCol, SQL_C_FLOAT);
    1585           0 :             break;
    1586             :         case DataType::REAL:
    1587             :         case DataType::DOUBLE:
    1588           0 :             *pColumn = impl_getValue<double>(curCol, SQL_C_DOUBLE);
    1589           0 :             break;
    1590             :         case DataType::BINARY:
    1591             :         case DataType::VARBINARY:
    1592             :         case DataType::LONGVARBINARY:
    1593             :         case DataType::BLOB:
    1594           0 :             *pColumn = impl_getBytes(curCol);
    1595           0 :             break;
    1596             :         case DataType::DATE:
    1597           0 :             *pColumn = impl_getDate(curCol);
    1598           0 :             break;
    1599             :         case DataType::TIME:
    1600           0 :             *pColumn = impl_getTime(curCol);
    1601           0 :             break;
    1602             :         case DataType::TIMESTAMP:
    1603           0 :             *pColumn = impl_getTimestamp(curCol);
    1604           0 :             break;
    1605             :         case DataType::BIT:
    1606           0 :             *pColumn = impl_getBoolean(curCol);
    1607           0 :             break;
    1608             :         case DataType::TINYINT:
    1609           0 :             *pColumn = impl_getValue<sal_Int8>(curCol, SQL_C_TINYINT);
    1610           0 :             break;
    1611             :         case DataType::SMALLINT:
    1612           0 :             *pColumn = impl_getValue<sal_Int16>(curCol, SQL_C_SHORT);
    1613           0 :             break;
    1614             :         case DataType::INTEGER:
    1615           0 :             *pColumn = impl_getValue<sal_Int32>(curCol, SQL_C_LONG);
    1616           0 :             break;
    1617             :         case DataType::BIGINT:
    1618           0 :             *pColumn = impl_getLong(curCol);
    1619           0 :             break;
    1620             :         default:
    1621             :             SAL_WARN( "connectivity.drivers","Unknown DataType");
    1622             :         }
    1623             : 
    1624           0 :         if ( m_bWasNull )
    1625           0 :             pColumn->setNull();
    1626           0 :         pColumn->setBound(true);
    1627           0 :         if(nType != pColumn->getTypeKind())
    1628             :         {
    1629           0 :             pColumn->setTypeKind(nType);
    1630             :         }
    1631             :     }
    1632             : }
    1633             : 
    1634           0 : void SAL_CALL OResultSet::acquire() throw()
    1635             : {
    1636           0 :     OResultSet_BASE::acquire();
    1637           0 : }
    1638             : 
    1639           0 : void SAL_CALL OResultSet::release() throw()
    1640             : {
    1641           0 :     OResultSet_BASE::release();
    1642           0 : }
    1643             : 
    1644           0 : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException, std::exception)
    1645             : {
    1646           0 :     return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
    1647             : }
    1648             : 
    1649           0 : bool OResultSet::move(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, bool /*_bRetrieveData*/)
    1650             : {
    1651           0 :     SQLSMALLINT nFetchOrientation = SQL_FETCH_NEXT;
    1652           0 :     switch(_eCursorPosition)
    1653             :     {
    1654             :         case IResultSetHelper::NEXT:
    1655           0 :             nFetchOrientation = SQL_FETCH_NEXT;
    1656           0 :             break;
    1657             :         case IResultSetHelper::PRIOR:
    1658           0 :             nFetchOrientation = SQL_FETCH_PRIOR;
    1659           0 :             break;
    1660             :         case IResultSetHelper::FIRST:
    1661           0 :             nFetchOrientation = SQL_FETCH_FIRST;
    1662           0 :             break;
    1663             :         case IResultSetHelper::LAST:
    1664           0 :             nFetchOrientation = SQL_FETCH_LAST;
    1665           0 :             break;
    1666             :         case IResultSetHelper::RELATIVE1:
    1667           0 :             nFetchOrientation = SQL_FETCH_RELATIVE;
    1668           0 :             break;
    1669             :         case IResultSetHelper::ABSOLUTE1:
    1670           0 :             nFetchOrientation = SQL_FETCH_ABSOLUTE;
    1671           0 :             break;
    1672             :         case IResultSetHelper::BOOKMARK: // special case here because we are only called with position numbers
    1673             :         {
    1674           0 :             TBookmarkPosMap::iterator aIter = m_aPosToBookmarks.begin();
    1675           0 :             TBookmarkPosMap::iterator aEnd = m_aPosToBookmarks.end();
    1676           0 :             for (; aIter != aEnd; ++aIter)
    1677             :             {
    1678           0 :                 if ( aIter->second == _nOffset )
    1679           0 :                     return moveToBookmark(makeAny(aIter->first));
    1680             :             }
    1681             :             SAL_WARN( "connectivity.drivers","Bookmark not found!");
    1682             :         }
    1683           0 :         return false;
    1684             :     }
    1685             : 
    1686           0 :     m_bEOF = false;
    1687           0 :     invalidateCache();
    1688             : 
    1689           0 :     SQLRETURN nOldFetchStatus = m_nCurrentFetchState;
    1690             :     // TODO FIXME: both of these will misbehave for
    1691             :     // _eCursorPosition == IResultSetHelper::NEXT/PREVIOUS
    1692             :     // when fetchSize > 1
    1693           0 :     if ( !m_bUseFetchScroll && _eCursorPosition == IResultSetHelper::NEXT )
    1694           0 :         m_nCurrentFetchState = N3SQLFetch(m_aStatementHandle);
    1695             :     else
    1696           0 :         m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,nFetchOrientation,_nOffset);
    1697             : 
    1698             :     SAL_INFO(
    1699             :         "connectivity.odbc",
    1700             :         "move(" << nFetchOrientation << "," << _nOffset << "), FetchState = "
    1701             :             << m_nCurrentFetchState);
    1702           0 :     OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
    1703             : 
    1704           0 :     const bool bSuccess = m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
    1705           0 :     if ( bSuccess )
    1706             :     {
    1707           0 :         switch(_eCursorPosition)
    1708             :         {
    1709             :             case IResultSetHelper::NEXT:
    1710           0 :                 ++m_nRowPos;
    1711           0 :                 break;
    1712             :             case IResultSetHelper::PRIOR:
    1713           0 :                 --m_nRowPos;
    1714           0 :                 break;
    1715             :             case IResultSetHelper::FIRST:
    1716           0 :                 m_nRowPos = 1;
    1717           0 :                 break;
    1718             :             case IResultSetHelper::LAST:
    1719           0 :                 m_bEOF = true;
    1720           0 :                 break;
    1721             :             case IResultSetHelper::RELATIVE1:
    1722           0 :                 m_nRowPos += _nOffset;
    1723           0 :                 break;
    1724             :             case IResultSetHelper::ABSOLUTE1:
    1725             :             case IResultSetHelper::BOOKMARK: // special case here because we are only called with position numbers
    1726           0 :                 m_nRowPos = _nOffset;
    1727           0 :                 break;
    1728             :         } // switch(_eCursorPosition)
    1729           0 :         if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED )
    1730             :         {
    1731           0 :             m_nUseBookmarks = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS, SQL_UB_OFF);
    1732             :         }
    1733           0 :         if ( m_nUseBookmarks == SQL_UB_OFF )
    1734             :         {
    1735           0 :             m_aRow[0].setNull();
    1736             :         }
    1737             :         else
    1738             :         {
    1739           0 :             ensureCacheForColumn(0);
    1740           0 :             Sequence<sal_Int8> bookmark  = OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,0,SQL_C_VARBOOKMARK,m_bWasNull,**this);
    1741           0 :             m_aPosToBookmarks[bookmark] = m_nRowPos;
    1742             :             OSL_ENSURE(bookmark.getLength(),"Invalid bookmark from length 0!");
    1743           0 :             m_aRow[0] = bookmark;
    1744             :         }
    1745           0 :         m_aRow[0].setBound(true);
    1746             :     }
    1747           0 :     else if ( IResultSetHelper::PRIOR == _eCursorPosition && m_nCurrentFetchState == SQL_NO_DATA )
    1748             :         // we went beforeFirst
    1749           0 :         m_nRowPos = 0;
    1750           0 :     else if(IResultSetHelper::NEXT == _eCursorPosition && m_nCurrentFetchState == SQL_NO_DATA && nOldFetchStatus != SQL_NO_DATA)
    1751             :         // we went afterLast
    1752           0 :         ++m_nRowPos;
    1753             : 
    1754           0 :     return bSuccess;
    1755             : }
    1756             : 
    1757           0 : sal_Int32 OResultSet::getDriverPos() const
    1758             : {
    1759           0 :     sal_Int32 nValue = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_NUMBER);
    1760             :     SAL_INFO(
    1761             :         "connectivity.odbc",
    1762             :         "RowNum = " << nValue << ", RowPos = " << m_nRowPos);
    1763           0 :     return nValue ? nValue : m_nRowPos;
    1764             : }
    1765             : 
    1766           0 : bool OResultSet::deletedVisible() const
    1767             : {
    1768           0 :     return false;
    1769             : }
    1770             : 
    1771           0 : bool OResultSet::isRowDeleted() const
    1772             : {
    1773           0 :     return m_pRowStatusArray[0] == SQL_ROW_DELETED;
    1774             : }
    1775             : 
    1776           0 : bool OResultSet::moveImpl(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, bool _bRetrieveData)
    1777             : {
    1778           0 :     ::osl::MutexGuard aGuard( m_aMutex );
    1779           0 :     checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
    1780           0 :     return (m_pSkipDeletedSet != NULL)
    1781           0 :                 ?   m_pSkipDeletedSet->skipDeleted(_eCursorPosition,_nOffset,_bRetrieveData)
    1782           0 :                 :   move(_eCursorPosition,_nOffset,_bRetrieveData);
    1783             : }
    1784             : 
    1785           0 : void OResultSet::fillNeededData(SQLRETURN _nRet)
    1786             : {
    1787           0 :     SQLRETURN nRet = _nRet;
    1788           0 :     if( nRet == SQL_NEED_DATA)
    1789             :     {
    1790           0 :         void* pColumnIndex = 0;
    1791           0 :         nRet = N3SQLParamData(m_aStatementHandle,&pColumnIndex);
    1792             : 
    1793           0 :         do
    1794             :         {
    1795           0 :             if (nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO && nRet != SQL_NEED_DATA)
    1796           0 :                 break;
    1797             : 
    1798           0 :             sal_IntPtr nColumnIndex ( reinterpret_cast<sal_IntPtr>(pColumnIndex));
    1799           0 :             Sequence< sal_Int8 > aSeq;
    1800           0 :             switch(m_aRow[nColumnIndex].getTypeKind())
    1801             :             {
    1802             :                 case DataType::BINARY:
    1803             :                 case DataType::VARBINARY:
    1804             :                 case DataType::LONGVARBINARY:
    1805             :                 case DataType::BLOB:
    1806           0 :                     aSeq = m_aRow[nColumnIndex];
    1807           0 :                     N3SQLPutData (m_aStatementHandle, aSeq.getArray(), aSeq.getLength());
    1808           0 :                     break;
    1809             :                 case SQL_WLONGVARCHAR:
    1810             :                 {
    1811           0 :                     OUString sRet;
    1812           0 :                     sRet = m_aRow[nColumnIndex].getString();
    1813           0 :                     nRet = N3SQLPutData (m_aStatementHandle, static_cast<SQLPOINTER>(const_cast<sal_Unicode *>(sRet.getStr())), sizeof(sal_Unicode)*sRet.getLength());
    1814           0 :                     break;
    1815             :                 }
    1816             :                 case DataType::LONGVARCHAR:
    1817             :                 case DataType::CLOB:
    1818             :                 {
    1819           0 :                     OUString sRet;
    1820           0 :                     sRet = m_aRow[nColumnIndex].getString();
    1821           0 :                     OString aString(OUStringToOString(sRet,m_nTextEncoding));
    1822           0 :                     nRet = N3SQLPutData (m_aStatementHandle, static_cast<SQLPOINTER>(const_cast<char *>(aString.getStr())), aString.getLength());
    1823           0 :                     break;
    1824             :                 }
    1825             :                 default:
    1826             :                     SAL_WARN( "connectivity.drivers","Not supported at the moment!");
    1827             :             }
    1828           0 :             nRet = N3SQLParamData(m_aStatementHandle,&pColumnIndex);
    1829             :         }
    1830             :         while (nRet == SQL_NEED_DATA);
    1831             :     }
    1832           0 : }
    1833             : 
    1834           0 : SWORD OResultSet::impl_getColumnType_nothrow(sal_Int32 columnIndex)
    1835             : {
    1836           0 :     ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex);
    1837           0 :     if ( aFind == m_aODBCColumnTypes.end() )
    1838           0 :         aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pStatement->getOwnConnection(),m_aStatementHandle,*this,columnIndex))).first;
    1839           0 :     return aFind->second;
    1840             : }
    1841             : 
    1842             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11