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