Bump for 3.6-28
[LibreOffice.git] / connectivity / source / drivers / odbcbase / OResultSet.cxx
blob0934e919b8b09c219d4aa3e048c21c4477a1f2ae
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "odbc/OResultSet.hxx"
30 #include "odbc/OTools.hxx"
31 #include "odbc/OResultSetMetaData.hxx"
32 #include <com/sun/star/sdbc/DataType.hpp>
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34 #include <com/sun/star/sdbcx/CompareBookmark.hpp>
35 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
36 #include <com/sun/star/sdbc/FetchDirection.hpp>
37 #include <com/sun/star/sdbc/ResultSetType.hpp>
38 #include <comphelper/property.hxx>
39 #include <comphelper/sequence.hxx>
40 #include <cppuhelper/typeprovider.hxx>
41 #include <comphelper/extract.hxx>
42 #include <com/sun/star/lang/DisposedException.hpp>
43 #include <comphelper/types.hxx>
44 #include "connectivity/dbtools.hxx"
45 #include "connectivity/dbexception.hxx"
46 #include "diagnose_ex.h"
47 #include <rtl/logfile.hxx>
49 #include <o3tl/compat_functional.hxx>
51 using namespace ::comphelper;
52 using namespace connectivity;
53 using namespace connectivity::odbc;
54 using namespace cppu;
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::lang;
57 using namespace com::sun::star::beans;
58 using namespace com::sun::star::sdbc;
59 using namespace com::sun::star::sdbcx;
60 using namespace com::sun::star::container;
61 using namespace com::sun::star::io;
62 using namespace com::sun::star::util;
64 #define ODBC_SQL_NOT_DEFINED 99UL
66 //------------------------------------------------------------------------------
67 // IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.OResultSet","com.sun.star.sdbc.ResultSet");
68 ::rtl::OUString SAL_CALL OResultSet::getImplementationName( ) throw ( RuntimeException)
70 return ::rtl::OUString("com.sun.star.sdbcx.odbc.ResultSet");
72 // -------------------------------------------------------------------------
73 Sequence< ::rtl::OUString > SAL_CALL OResultSet::getSupportedServiceNames( ) throw( RuntimeException)
75 Sequence< ::rtl::OUString > aSupported(2);
76 aSupported[0] = ::rtl::OUString("com.sun.star.sdbc.ResultSet");
77 aSupported[1] = ::rtl::OUString("com.sun.star.sdbcx.ResultSet");
78 return aSupported;
80 // -------------------------------------------------------------------------
81 sal_Bool SAL_CALL OResultSet::supportsService( const ::rtl::OUString& _rServiceName ) throw( RuntimeException)
83 Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
84 const ::rtl::OUString* pSupported = aSupported.getConstArray();
85 const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
86 for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
89 return pSupported != pEnd;
92 // -------------------------------------------------------------------------
93 OResultSet::OResultSet(SQLHANDLE _pStatementHandle ,OStatement_Base* pStmt) : OResultSet_BASE(m_aMutex)
94 ,OPropertySetHelper(OResultSet_BASE::rBHelper)
95 ,m_aStatementHandle(_pStatementHandle)
96 ,m_aConnectionHandle(pStmt->getConnectionHandle())
97 ,m_pStatement(pStmt)
98 ,m_pSkipDeletedSet(NULL)
99 ,m_xStatement(*pStmt)
100 ,m_xMetaData(NULL)
101 ,m_pRowStatusArray( NULL )
102 ,m_nTextEncoding(pStmt->getOwnConnection()->getTextEncoding())
103 ,m_nRowPos(0)
104 ,m_nLastColumnPos(0)
105 ,m_nUseBookmarks(ODBC_SQL_NOT_DEFINED)
106 ,m_nCurrentFetchState(0)
107 ,m_bWasNull(sal_True)
108 ,m_bEOF(sal_True)
109 ,m_bLastRecord(sal_False)
110 ,m_bFreeHandle(sal_False)
111 ,m_bInserting(sal_False)
112 ,m_bFetchData(sal_True)
113 ,m_bRowInserted(sal_False)
114 ,m_bRowDeleted(sal_False)
115 ,m_bUseFetchScroll(sal_False)
117 osl_incrementInterlockedCount( &m_refCount );
120 m_pRowStatusArray = new SQLUSMALLINT[1]; // the default value
121 setStmtOption<SQLUSMALLINT*, SQL_IS_POINTER>(SQL_ATTR_ROW_STATUS_PTR, m_pRowStatusArray);
123 catch(const Exception&)
124 { // we don't want our result destroy here
126 SQLULEN nCurType = 0;
129 nCurType = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE);
130 SQLUINTEGER nValueLen = m_pStatement->getCursorProperties(nCurType,sal_False);
131 if( (nValueLen & SQL_CA2_SENSITIVITY_DELETIONS) != SQL_CA2_SENSITIVITY_DELETIONS ||
132 (nValueLen & SQL_CA2_CRC_EXACT) != SQL_CA2_CRC_EXACT)
133 m_pSkipDeletedSet = new OSkipDeletedSet(this);
135 catch(const Exception&)
136 { // we don't want our result destroy here
140 SQLUINTEGER nValueLen = 0;
141 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_GETDATA_EXTENSIONS,nValueLen,NULL);
142 m_bFetchData = !((SQL_GD_ANY_ORDER & nValueLen) == SQL_GD_ANY_ORDER && nCurType != SQL_CURSOR_FORWARD_ONLY);
144 catch(const Exception&)
145 { // we don't want our result destroy here
146 m_bFetchData = sal_True;
150 if ( getOdbcFunction(ODBC3SQLGetFunctions) )
152 SQLUSMALLINT nSupported = 0;
153 m_bUseFetchScroll = ( N3SQLGetFunctions(m_aConnectionHandle,SQL_API_SQLFETCHSCROLL,&nSupported) == SQL_SUCCESS && nSupported == 1 );
156 catch(const Exception&)
158 m_bUseFetchScroll = sal_False;
161 osl_decrementInterlockedCount( &m_refCount );
163 // -------------------------------------------------------------------------
164 OResultSet::~OResultSet()
166 delete [] m_pRowStatusArray;
167 delete m_pSkipDeletedSet;
169 // -----------------------------------------------------------------------------
170 void OResultSet::construct()
172 osl_incrementInterlockedCount( &m_refCount );
173 allocBuffer();
174 osl_decrementInterlockedCount( &m_refCount );
176 // -------------------------------------------------------------------------
177 void OResultSet::disposing(void)
179 SQLRETURN nRet = N3SQLCloseCursor(m_aStatementHandle);
180 OSL_UNUSED( nRet );
181 OPropertySetHelper::disposing();
183 ::osl::MutexGuard aGuard(m_aMutex);
184 if(!m_aBindVector.empty())
185 releaseBuffer();
186 if(m_bFreeHandle)
187 m_pStatement->getOwnConnection()->freeStatementHandle(m_aStatementHandle);
189 m_xStatement.clear();
190 m_xMetaData.clear();
192 // -------------------------------------------------------------------------
193 SQLRETURN OResultSet::unbind(sal_Bool _bUnbindHandle)
195 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::unbind" );
196 SQLRETURN nRet = 0;
197 if ( _bUnbindHandle )
198 nRet = N3SQLFreeStmt(m_aStatementHandle,SQL_UNBIND);
200 if ( m_aBindVector.size() > 1 )
202 TVoidVector::iterator pValue = m_aBindVector.begin() + 1;
203 TVoidVector::iterator pEnd = m_aBindVector.end();
204 for(; pValue != pEnd; ++pValue)
206 switch (pValue->second)
208 case DataType::CHAR:
209 case DataType::VARCHAR:
210 delete static_cast< ::rtl::OString* >(reinterpret_cast< void * >(pValue->first));
211 break;
212 case DataType::BIGINT:
213 delete static_cast< sal_Int64* >(reinterpret_cast< void * >(pValue->first));
214 break;
215 case DataType::DECIMAL:
216 case DataType::NUMERIC:
217 delete static_cast< ::rtl::OString* >(reinterpret_cast< void * >(pValue->first));
218 break;
219 case DataType::REAL:
220 case DataType::DOUBLE:
221 delete static_cast< double* >(reinterpret_cast< void * >(pValue->first));
222 break;
223 case DataType::LONGVARCHAR:
224 case DataType::CLOB:
225 delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first));
226 break;
227 case DataType::LONGVARBINARY:
228 case DataType::BLOB:
229 delete [] static_cast< char* >(reinterpret_cast< void * >(pValue->first));
230 break;
231 case DataType::DATE:
232 delete static_cast< DATE_STRUCT* >(reinterpret_cast< void * >(pValue->first));
233 break;
234 case DataType::TIME:
235 delete static_cast< TIME_STRUCT* >(reinterpret_cast< void * >(pValue->first));
236 break;
237 case DataType::TIMESTAMP:
238 delete static_cast< TIMESTAMP_STRUCT* >(reinterpret_cast< void * >(pValue->first));
239 break;
240 case DataType::BIT:
241 case DataType::TINYINT:
242 delete static_cast< sal_Int8* >(reinterpret_cast< void * >(pValue->first));
243 break;
244 case DataType::SMALLINT:
245 delete static_cast< sal_Int16* >(reinterpret_cast< void * >(pValue->first));
246 break;
247 case DataType::INTEGER:
248 delete static_cast< sal_Int32* >(reinterpret_cast< void * >(pValue->first));
249 break;
250 case DataType::FLOAT:
251 delete static_cast< float* >(reinterpret_cast< void * >(pValue->first));
252 break;
253 case DataType::BINARY:
254 case DataType::VARBINARY:
255 delete static_cast< sal_Int8* >(reinterpret_cast< void * >(pValue->first));
256 break;
259 m_aBindVector.clear();
260 m_aBindVector.push_back(TVoidPtr(0,0)); // the first is reserved for the bookmark
262 return nRet;
264 // -------------------------------------------------------------------------
265 TVoidPtr OResultSet::allocBindColumn(sal_Int32 _nType,sal_Int32 _nColumnIndex)
267 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::allocBindColumn" );
268 TVoidPtr aPair;
269 switch (_nType)
271 case DataType::CHAR:
272 case DataType::VARCHAR:
273 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new ::rtl::OString()),_nType);
274 break;
275 case DataType::BIGINT:
276 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int64(0)),_nType);
277 break;
278 case DataType::DECIMAL:
279 case DataType::NUMERIC:
280 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new ::rtl::OString()),_nType);
281 break;
282 case DataType::REAL:
283 case DataType::DOUBLE:
284 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new double(0.0)),_nType);
285 break;
286 case DataType::LONGVARCHAR:
287 case DataType::CLOB:
288 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType); // only for finding
289 break;
290 case DataType::LONGVARBINARY:
291 case DataType::BLOB:
292 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new char[2]),_nType); // only for finding
293 break;
294 case DataType::DATE:
295 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new DATE_STRUCT),_nType);
296 break;
297 case DataType::TIME:
298 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new TIME_STRUCT),_nType);
299 break;
300 case DataType::TIMESTAMP:
301 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new TIMESTAMP_STRUCT),_nType);
302 break;
303 case DataType::BIT:
304 case DataType::TINYINT:
305 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int8(0)),_nType);
306 break;
307 case DataType::SMALLINT:
308 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int16(0)),_nType);
309 break;
310 case DataType::INTEGER:
311 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int32(0)),_nType);
312 break;
313 case DataType::FLOAT:
314 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new float(0)),_nType);
315 break;
316 case DataType::BINARY:
317 case DataType::VARBINARY:
318 aPair = TVoidPtr(reinterpret_cast< sal_Int64 >(new sal_Int8[m_aRow[_nColumnIndex].getSequence().getLength()]),_nType);
319 break;
320 default:
321 OSL_FAIL("Unknown type");
322 aPair = TVoidPtr(0,_nType);
324 return aPair;
326 // -------------------------------------------------------------------------
327 void OResultSet::allocBuffer()
329 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::allocBuffer" );
330 Reference< XResultSetMetaData > xMeta = getMetaData();
331 sal_Int32 nLen = xMeta->getColumnCount();
333 m_aBindVector.reserve(nLen+1);
334 m_aBindVector.push_back(TVoidPtr(0,0)); // the first is reserved for the bookmark
335 m_aRow.resize(nLen+1);
337 for(sal_Int32 i = 1;i<=nLen;++i)
339 sal_Int32 nType = xMeta->getColumnType(i);
340 m_aRow[i].setTypeKind( nType );
342 m_aLengthVector.resize(nLen + 1);
344 // -------------------------------------------------------------------------
345 void OResultSet::releaseBuffer()
347 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::releaseBuffer" );
348 unbind(sal_False);
349 m_aLengthVector.clear();
351 // -------------------------------------------------------------------------
352 Any SAL_CALL OResultSet::queryInterface( const Type & rType ) throw(RuntimeException)
354 Any aRet = OPropertySetHelper::queryInterface(rType);
355 return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType);
357 // -------------------------------------------------------------------------
358 Sequence< Type > SAL_CALL OResultSet::getTypes( ) throw( RuntimeException)
360 OTypeCollection aTypes( ::getCppuType( (const Reference< ::com::sun::star::beans::XMultiPropertySet > *)0 ),
361 ::getCppuType( (const Reference< ::com::sun::star::beans::XFastPropertySet > *)0 ),
362 ::getCppuType( (const Reference< ::com::sun::star::beans::XPropertySet > *)0 ));
364 return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes());
366 // -------------------------------------------------------------------------
368 sal_Int32 SAL_CALL OResultSet::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
370 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::findColumn" );
371 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
374 ::osl::MutexGuard aGuard( m_aMutex );
376 Reference< XResultSetMetaData > xMeta = getMetaData();
377 sal_Int32 nLen = xMeta->getColumnCount();
378 sal_Int32 i = 1;
379 for(;i<=nLen;++i)
380 if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
381 columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
382 break;
383 return i;
385 // -------------------------------------------------------------------------
386 Reference< XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
388 ::osl::MutexGuard aGuard( m_aMutex );
389 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
392 // TODO use getBytes instead of
393 return NULL;
395 // -------------------------------------------------------------------------
396 Reference< XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
398 ::osl::MutexGuard aGuard( m_aMutex );
399 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
402 // TODO use getBytes instead of
403 return NULL;
405 // -----------------------------------------------------------------------------
406 const ORowSetValue& OResultSet::getValue(sal_Int32 _nColumnIndex,SQLSMALLINT _nType,void* _pValue,SQLINTEGER _rSize)
408 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getValue" );
409 ::osl::MutexGuard aGuard( m_aMutex );
410 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
412 if(m_bFetchData)
414 if(_nColumnIndex > m_nLastColumnPos)
415 fillRow(_nColumnIndex);
416 return m_aRow[_nColumnIndex];
418 else
419 OTools::getValue(m_pStatement->getOwnConnection(),m_aStatementHandle,_nColumnIndex,_nType,m_bWasNull,**this,_pValue,_rSize);
421 return m_aEmptyValue;
423 // -------------------------------------------------------------------------
424 sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
426 sal_Int8 nVal(0);
427 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_BIT,&nVal,sizeof nVal);
428 return (&aValue == &m_aEmptyValue) ? (sal_Bool)nVal : (sal_Bool)aValue;
430 // -------------------------------------------------------------------------
432 sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
434 sal_Int8 nRet(0);
435 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_TINYINT,&nRet,sizeof nRet);
436 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int8)aValue;
438 // -------------------------------------------------------------------------
440 Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
442 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getBytes" );
444 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
445 ::osl::MutexGuard aGuard( m_aMutex );
448 if(m_bFetchData)
450 if(columnIndex > m_nLastColumnPos)
451 fillRow(columnIndex);
452 Sequence< sal_Int8 > nRet;
453 switch(m_aRow[columnIndex].getTypeKind())
455 case DataType::BINARY:
456 case DataType::VARBINARY:
457 case DataType::LONGVARBINARY:
458 nRet = m_aRow[columnIndex];
459 break;
460 default:
462 ::rtl::OUString sRet;
463 sRet = m_aRow[columnIndex].getString();
464 nRet = Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(sRet.getStr()),sizeof(sal_Unicode)*sRet.getLength());
467 return nRet;
470 const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex);
472 switch(nColumnType)
474 case SQL_WVARCHAR:
475 case SQL_WCHAR:
476 case SQL_WLONGVARCHAR:
477 case SQL_VARCHAR:
478 case SQL_CHAR:
479 case SQL_LONGVARCHAR:
481 ::rtl::OUString aRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding);
482 return Sequence<sal_Int8>(reinterpret_cast<const sal_Int8*>(aRet.getStr()),sizeof(sal_Unicode)*aRet.getLength());
484 default:
487 return OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,SQL_C_BINARY,m_bWasNull,**this);
489 // -------------------------------------------------------------------------
491 Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
493 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getDate" );
494 DATE_STRUCT aDate;
495 aDate.day = 0;
496 aDate.month = 0;
497 aDate.year = 0;
499 const ORowSetValue& aValue = getValue( columnIndex,
500 m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_DATE : SQL_C_TYPE_DATE,
501 &aDate,sizeof aDate);
502 return (&aValue == &m_aEmptyValue) ? Date(aDate.day,aDate.month,aDate.year) : (Date)aValue;
504 // -------------------------------------------------------------------------
506 double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
508 double nRet(0);
509 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_DOUBLE,&nRet,sizeof nRet);
510 return (&aValue == &m_aEmptyValue) ? nRet : (double)aValue;
512 // -------------------------------------------------------------------------
514 float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
516 float nRet(0);
517 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_FLOAT,&nRet,sizeof nRet);
518 return (&aValue == &m_aEmptyValue) ? nRet : (float)aValue;
520 // -------------------------------------------------------------------------
522 sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
524 sal_Int32 nRet(0);
525 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_LONG,&nRet,sizeof nRet);
526 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int32)aValue;
528 // -------------------------------------------------------------------------
530 sal_Int32 SAL_CALL OResultSet::getRow( ) throw(SQLException, RuntimeException)
532 ::osl::MutexGuard aGuard( m_aMutex );
533 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
535 return m_pSkipDeletedSet ? m_pSkipDeletedSet->getMappedPosition(getDriverPos()) : getDriverPos();
537 // -------------------------------------------------------------------------
539 sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
541 sal_Int64 nRet(0);
544 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_SBIGINT,&nRet,sizeof nRet);
545 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int64)aValue;
547 catch(const SQLException&)
549 nRet = getString(columnIndex).toInt64();
551 return nRet;
553 // -------------------------------------------------------------------------
555 Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData( ) throw(SQLException, RuntimeException)
557 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getMetaData" );
558 ::osl::MutexGuard aGuard( m_aMutex );
559 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
562 if(!m_xMetaData.is())
563 m_xMetaData = new OResultSetMetaData(m_pStatement->getOwnConnection(),m_aStatementHandle);
564 return m_xMetaData;
566 // -------------------------------------------------------------------------
567 Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
569 ::dbtools::throwFunctionNotSupportedException( "XRow::getArray", *this );
570 return NULL;
573 // -------------------------------------------------------------------------
575 Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
577 ::dbtools::throwFunctionNotSupportedException( "XRow::getClob", *this );
578 return NULL;
580 // -------------------------------------------------------------------------
581 Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
583 ::dbtools::throwFunctionNotSupportedException( "XRow::getBlob", *this );
584 return NULL;
586 // -------------------------------------------------------------------------
588 Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
590 ::dbtools::throwFunctionNotSupportedException( "XRow::getRef", *this );
591 return NULL;
593 // -------------------------------------------------------------------------
595 Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
597 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getObject" );
598 ::osl::MutexGuard aGuard( m_aMutex );
599 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
601 fillRow(columnIndex);
602 return m_aRow[columnIndex].makeAny();
604 // -------------------------------------------------------------------------
606 sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
608 sal_Int16 nRet(0);
609 const ORowSetValue& aValue = getValue(columnIndex,SQL_C_SHORT,&nRet,sizeof nRet);
610 return (&aValue == &m_aEmptyValue) ? nRet : (sal_Int16)aValue;
612 // -------------------------------------------------------------------------
615 ::rtl::OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
617 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getString" );
618 ::osl::MutexGuard aGuard( m_aMutex );
620 ::rtl::OUString nRet;
621 if ( m_bFetchData )
622 nRet = getValue(columnIndex,0,NULL,0);
623 else
625 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
626 const SWORD nColumnType = impl_getColumnType_nothrow(columnIndex);
627 nRet = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,columnIndex,nColumnType,m_bWasNull,**this,m_nTextEncoding);
629 return nRet;
631 // -------------------------------------------------------------------------
633 Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
635 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getTime" );
636 TIME_STRUCT aTime={0,0,0};
637 const ORowSetValue& aValue = getValue(columnIndex,
638 m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_TIME : SQL_C_TYPE_TIME,
639 &aTime,sizeof aTime);
640 return (&aValue == &m_aEmptyValue) ? Time(0,aTime.second,aTime.minute,aTime.hour) : (Time)aValue;
642 // -------------------------------------------------------------------------
645 DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
647 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getTimestamp" );
648 TIMESTAMP_STRUCT aTime={0,0,0,0,0,0,0};
649 const ORowSetValue& aValue = getValue(columnIndex,
650 m_pStatement->getOwnConnection()->useOldDateFormat() ? SQL_C_TIMESTAMP : SQL_C_TYPE_TIMESTAMP,
651 &aTime,sizeof aTime);
652 return (&aValue == &m_aEmptyValue)
654 DateTime(static_cast<sal_uInt16>(aTime.fraction/ODBC_FRACTION_UNITS_PER_HSECOND),aTime.second,aTime.minute,aTime.hour,aTime.day,aTime.month,aTime.year)
656 (DateTime)aValue;
658 // -------------------------------------------------------------------------
660 sal_Bool SAL_CALL OResultSet::isBeforeFirst( ) throw(SQLException, RuntimeException)
662 ::osl::MutexGuard aGuard( m_aMutex );
663 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
664 return m_nRowPos == 0;
666 // -------------------------------------------------------------------------
667 sal_Bool SAL_CALL OResultSet::isAfterLast( ) throw(SQLException, RuntimeException)
669 ::osl::MutexGuard aGuard( m_aMutex );
670 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
672 return m_nRowPos != 0 && m_nCurrentFetchState == SQL_NO_DATA;
674 // -------------------------------------------------------------------------
675 sal_Bool SAL_CALL OResultSet::isFirst( ) throw(SQLException, RuntimeException)
677 ::osl::MutexGuard aGuard( m_aMutex );
678 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
680 return m_nRowPos == 1;
682 // -------------------------------------------------------------------------
683 sal_Bool SAL_CALL OResultSet::isLast( ) throw(SQLException, RuntimeException)
685 ::osl::MutexGuard aGuard( m_aMutex );
686 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
689 return m_bEOF && m_nCurrentFetchState != SQL_NO_DATA;
691 // -------------------------------------------------------------------------
692 void SAL_CALL OResultSet::beforeFirst( ) throw(SQLException, RuntimeException)
694 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::beforeFirst" );
695 ::osl::MutexGuard aGuard( m_aMutex );
696 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
699 if(first())
700 previous();
701 m_nCurrentFetchState = SQL_SUCCESS;
703 // -------------------------------------------------------------------------
704 void SAL_CALL OResultSet::afterLast( ) throw(SQLException, RuntimeException)
706 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::afterLast" );
707 ::osl::MutexGuard aGuard( m_aMutex );
708 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
710 if(last())
711 next();
712 m_bEOF = sal_True;
714 // -------------------------------------------------------------------------
716 void SAL_CALL OResultSet::close( ) throw(SQLException, RuntimeException)
719 ::osl::MutexGuard aGuard( m_aMutex );
720 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
723 dispose();
725 // -------------------------------------------------------------------------
727 sal_Bool SAL_CALL OResultSet::first( ) throw(SQLException, RuntimeException)
729 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::first" );
730 return moveImpl(IResultSetHelper::FIRST,0,sal_True);
732 // -------------------------------------------------------------------------
734 sal_Bool SAL_CALL OResultSet::last( ) throw(SQLException, RuntimeException)
736 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::last" );
737 return moveImpl(IResultSetHelper::LAST,0,sal_True);
739 // -------------------------------------------------------------------------
740 sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
742 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::absolute" );
743 return moveImpl(IResultSetHelper::ABSOLUTE,row,sal_True);
745 // -------------------------------------------------------------------------
746 sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row ) throw(SQLException, RuntimeException)
748 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::relative" );
749 return moveImpl(IResultSetHelper::RELATIVE,row,sal_True);
751 // -------------------------------------------------------------------------
752 sal_Bool SAL_CALL OResultSet::previous( ) throw(SQLException, RuntimeException)
754 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::previous" );
755 return moveImpl(IResultSetHelper::PRIOR,0,sal_True);
757 // -------------------------------------------------------------------------
758 Reference< XInterface > SAL_CALL OResultSet::getStatement( ) throw(SQLException, RuntimeException)
760 ::osl::MutexGuard aGuard( m_aMutex );
761 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
762 return m_xStatement;
764 // -------------------------------------------------------------------------
766 sal_Bool SAL_CALL OResultSet::rowDeleted() throw(SQLException, RuntimeException)
768 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::rowDeleted" );
769 ::osl::MutexGuard aGuard( m_aMutex );
770 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
772 sal_Bool bRet = m_bRowDeleted;
773 m_bRowDeleted = sal_False;
775 return bRet;
777 // -------------------------------------------------------------------------
778 sal_Bool SAL_CALL OResultSet::rowInserted( ) throw(SQLException, RuntimeException)
780 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::rowInserted" );
781 ::osl::MutexGuard aGuard( m_aMutex );
782 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
784 sal_Bool bInserted = m_bRowInserted;
785 m_bRowInserted = sal_False;
787 return bInserted;
789 // -------------------------------------------------------------------------
790 sal_Bool SAL_CALL OResultSet::rowUpdated( ) throw(SQLException, RuntimeException)
792 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::rowUpdated" );
793 ::osl::MutexGuard aGuard( m_aMutex );
794 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
797 return m_pRowStatusArray[0] == SQL_ROW_UPDATED;
799 // -------------------------------------------------------------------------
801 sal_Bool SAL_CALL OResultSet::next( ) throw(SQLException, RuntimeException)
803 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::next" );
804 return moveImpl(IResultSetHelper::NEXT,1,sal_True);
806 // -------------------------------------------------------------------------
808 sal_Bool SAL_CALL OResultSet::wasNull( ) throw(SQLException, RuntimeException)
810 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::wasNull" );
811 ::osl::MutexGuard aGuard( m_aMutex );
812 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
815 return m_bFetchData ? m_aRow[m_nLastColumnPos].isNull() : m_bWasNull;
817 // -------------------------------------------------------------------------
819 void SAL_CALL OResultSet::cancel( ) throw(RuntimeException)
821 ::osl::MutexGuard aGuard( m_aMutex );
822 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
825 OTools::ThrowException(m_pStatement->getOwnConnection(),N3SQLCancel(m_aStatementHandle),m_aStatementHandle,SQL_HANDLE_STMT,*this);
827 // -------------------------------------------------------------------------
828 void SAL_CALL OResultSet::clearWarnings( ) throw(SQLException, RuntimeException)
831 // -------------------------------------------------------------------------
832 Any SAL_CALL OResultSet::getWarnings( ) throw(SQLException, RuntimeException)
834 return Any();
836 // -------------------------------------------------------------------------
837 void SAL_CALL OResultSet::insertRow( ) throw(SQLException, RuntimeException)
839 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::insertRow" );
840 ::osl::MutexGuard aGuard( m_aMutex );
841 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
844 const SQLLEN nMaxLen = 20;
845 SQLLEN nRealLen = 0;
846 Sequence<sal_Int8> aBookmark(nMaxLen);
847 assert (static_cast<size_t>(nMaxLen) >= sizeof(SQLLEN));
849 SQLRETURN nRet = N3SQLBindCol(m_aStatementHandle,
851 SQL_C_VARBOOKMARK,
852 aBookmark.getArray(),
853 nMaxLen,
854 &nRealLen
856 // Sequence<sal_Int8> aRealBookmark(nMaxLen);
858 sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) );
859 if ( bPositionByBookmark )
861 nRet = N3SQLBulkOperations( m_aStatementHandle, SQL_ADD );
862 fillNeededData( nRet );
864 else
866 if(isBeforeFirst())
867 next(); // must be done
868 nRet = N3SQLSetPos( m_aStatementHandle, 1, SQL_ADD, SQL_LOCK_NO_CHANGE );
869 fillNeededData( nRet );
873 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
875 catch(const SQLException&)
877 nRet = unbind();
878 throw;
882 if ( bPositionByBookmark )
884 setStmtOption<SQLLEN*, SQL_IS_POINTER>(SQL_ATTR_FETCH_BOOKMARK_PTR, reinterpret_cast<SQLLEN*>(aBookmark.getArray()));
886 nRet = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,0);
888 else
889 nRet = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,0); // OJ 06.03.2004
890 // sometimes we got an error but we are not interested in anymore #106047# OJ
891 // OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
892 nRet = unbind();
893 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
895 if(m_pSkipDeletedSet)
897 aBookmark.realloc(nRealLen);
898 if(moveToBookmark(makeAny(aBookmark)))
900 sal_Int32 nRowPos = getDriverPos();
901 if ( -1 == m_nRowPos )
903 nRowPos = m_aPosToBookmarks.size() + 1;
905 if ( nRowPos == m_nRowPos )
906 ++nRowPos;
907 m_nRowPos = nRowPos;
908 m_pSkipDeletedSet->insertNewPosition(nRowPos);
909 m_aPosToBookmarks[aBookmark] = nRowPos;
912 m_bRowInserted = sal_True;
915 // -------------------------------------------------------------------------
916 void SAL_CALL OResultSet::updateRow( ) throw(SQLException, RuntimeException)
918 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::updateRow" );
919 ::osl::MutexGuard aGuard( m_aMutex );
920 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
922 SQLRETURN nRet;
924 sal_Bool bPositionByBookmark = ( NULL != getOdbcFunction( ODBC3SQLBulkOperations ) );
925 if ( bPositionByBookmark )
927 SQLLEN nRealLen = 0;
928 nRet = N3SQLBindCol(m_aStatementHandle,
930 SQL_C_VARBOOKMARK,
931 m_aBookmark.getArray(),
932 m_aBookmark.getLength(),
933 &nRealLen
935 fillNeededData(nRet = N3SQLBulkOperations(m_aStatementHandle, SQL_UPDATE_BY_BOOKMARK));
937 else
938 fillNeededData(nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_UPDATE,SQL_LOCK_NO_CHANGE));
939 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
940 // now unbind all columns so we can fetch all columns again with SQLGetData
941 nRet = unbind();
942 OSL_ENSURE(nRet == SQL_SUCCESS,"Could not unbind the columns!");
944 // -------------------------------------------------------------------------
945 void SAL_CALL OResultSet::deleteRow( ) throw(SQLException, RuntimeException)
947 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::deleteRow" );
948 SQLRETURN nRet = SQL_SUCCESS;
949 sal_Int32 nPos = getDriverPos();
950 nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_DELETE,SQL_LOCK_NO_CHANGE);
951 OTools::ThrowException(m_pStatement->getOwnConnection(),nRet,m_aStatementHandle,SQL_HANDLE_STMT,*this);
953 m_bRowDeleted = ( m_pRowStatusArray[0] == SQL_ROW_DELETED );
954 if ( m_bRowDeleted )
956 TBookmarkPosMap::iterator aIter = m_aPosToBookmarks.begin();
957 TBookmarkPosMap::iterator aEnd = m_aPosToBookmarks.end();
958 for (; aIter != aEnd; ++aIter)
960 if ( aIter->second == nPos )
962 m_aPosToBookmarks.erase(aIter);
963 break;
967 if ( m_pSkipDeletedSet )
968 m_pSkipDeletedSet->deletePosition(nPos);
970 // -------------------------------------------------------------------------
972 void SAL_CALL OResultSet::cancelRowUpdates( ) throw(SQLException, RuntimeException)
975 // -------------------------------------------------------------------------
977 void SAL_CALL OResultSet::moveToInsertRow( ) throw(SQLException, RuntimeException)
979 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::moveToInsertRow" );
980 ::osl::MutexGuard aGuard( m_aMutex );
981 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
984 m_nLastColumnPos = 0;
985 // first unbound all columns
986 OSL_VERIFY_EQUALS( unbind(), SQL_SUCCESS, "Could not unbind columns!" );
987 // SQLRETURN nRet = N3SQLSetStmtAttr(m_aStatementHandle,SQL_ATTR_ROW_ARRAY_SIZE ,(SQLPOINTER)1,SQL_IS_INTEGER);
988 m_bInserting = sal_True;
990 // -------------------------------------------------------------------------
992 void SAL_CALL OResultSet::moveToCurrentRow( ) throw(SQLException, RuntimeException)
994 m_nLastColumnPos = 0;
996 // -------------------------------------------------------------------------
997 void OResultSet::updateValue(sal_Int32 columnIndex,SQLSMALLINT _nType,void* _pValue) throw(SQLException, RuntimeException)
999 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::updateValue" );
1000 ::osl::MutexGuard aGuard( m_aMutex );
1001 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1003 m_aBindVector.push_back(allocBindColumn(OTools::MapOdbcType2Jdbc(_nType),columnIndex));
1004 void* pData = reinterpret_cast<void*>(m_aBindVector.rbegin()->first);
1005 OSL_ENSURE(pData != NULL,"Data for update is NULL!");
1006 OTools::bindValue( m_pStatement->getOwnConnection(),
1007 m_aStatementHandle,
1008 columnIndex,
1009 _nType,
1011 _pValue,
1012 pData,
1013 &m_aLengthVector[columnIndex],
1014 **this,
1015 m_nTextEncoding,
1016 m_pStatement->getOwnConnection()->useOldDateFormat());
1018 // -----------------------------------------------------------------------------
1019 void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
1021 ::osl::MutexGuard aGuard( m_aMutex );
1022 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1024 m_aBindVector.push_back(allocBindColumn(DataType::CHAR,columnIndex));
1025 void* pData = reinterpret_cast<void*>(m_aBindVector.rbegin()->first);
1026 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());
1028 // -------------------------------------------------------------------------
1030 void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x ) throw(SQLException, RuntimeException)
1032 updateValue(columnIndex,SQL_BIT,&x);
1034 // -------------------------------------------------------------------------
1035 void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x ) throw(SQLException, RuntimeException)
1037 updateValue(columnIndex,SQL_CHAR,&x);
1039 // -------------------------------------------------------------------------
1041 void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x ) throw(SQLException, RuntimeException)
1043 updateValue(columnIndex,SQL_TINYINT,&x);
1045 // -------------------------------------------------------------------------
1046 void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x ) throw(SQLException, RuntimeException)
1048 updateValue(columnIndex,SQL_INTEGER,&x);
1050 // -------------------------------------------------------------------------
1051 void SAL_CALL OResultSet::updateLong( sal_Int32 /*columnIndex*/, sal_Int64 /*x*/ ) throw(SQLException, RuntimeException)
1053 ::dbtools::throwFunctionNotSupportedException( "XRowUpdate::updateLong", *this );
1055 // -----------------------------------------------------------------------
1056 void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x ) throw(SQLException, RuntimeException)
1058 updateValue(columnIndex,SQL_REAL,&x);
1060 // -------------------------------------------------------------------------
1062 void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x ) throw(SQLException, RuntimeException)
1064 updateValue(columnIndex,SQL_DOUBLE,&x);
1066 // -------------------------------------------------------------------------
1067 void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const ::rtl::OUString& x ) throw(SQLException, RuntimeException)
1069 sal_Int32 nType = m_aRow[columnIndex].getTypeKind();
1070 SQLSMALLINT nOdbcType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(nType));
1071 m_aRow[columnIndex] = x;
1072 m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarchar will be recognized by fillNeededData
1073 updateValue(columnIndex,nOdbcType,(void*)&x);
1075 // -------------------------------------------------------------------------
1076 void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x ) throw(SQLException, RuntimeException)
1078 sal_Int32 nType = m_aRow[columnIndex].getTypeKind();
1079 SQLSMALLINT nOdbcType = static_cast<SQLSMALLINT>(OTools::jdbcTypeToOdbc(nType));
1080 m_aRow[columnIndex] = x;
1081 m_aRow[columnIndex].setTypeKind(nType); // OJ: otherwise longvarbinary will be recognized by fillNeededData
1082 updateValue(columnIndex,nOdbcType,(void*)&x);
1084 // -------------------------------------------------------------------------
1085 void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const Date& x ) throw(SQLException, RuntimeException)
1087 DATE_STRUCT aVal = OTools::DateToOdbcDate(x);
1088 updateValue(columnIndex,SQL_DATE,&aVal);
1090 // -------------------------------------------------------------------------
1092 void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const Time& x ) throw(SQLException, RuntimeException)
1094 TIME_STRUCT aVal = OTools::TimeToOdbcTime(x);
1095 updateValue(columnIndex,SQL_TIME,&aVal);
1097 // -------------------------------------------------------------------------
1099 void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const DateTime& x ) throw(SQLException, RuntimeException)
1101 TIMESTAMP_STRUCT aVal = OTools::DateTimeToTimestamp(x);
1102 updateValue(columnIndex,SQL_TIMESTAMP,&aVal);
1104 // -------------------------------------------------------------------------
1106 void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
1108 if(!x.is())
1109 ::dbtools::throwFunctionSequenceException(*this);
1111 Sequence<sal_Int8> aSeq;
1112 x->readBytes(aSeq,length);
1113 updateBytes(columnIndex,aSeq);
1115 // -------------------------------------------------------------------------
1116 void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< XInputStream >& x, sal_Int32 length ) throw(SQLException, RuntimeException)
1118 updateBinaryStream(columnIndex,x,length);
1120 // -------------------------------------------------------------------------
1121 void SAL_CALL OResultSet::refreshRow( ) throw(SQLException, RuntimeException)
1123 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::refreshRow" );
1124 ::osl::MutexGuard aGuard( m_aMutex );
1125 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1128 // SQLRETURN nRet = N3SQLSetPos(m_aStatementHandle,1,SQL_REFRESH,SQL_LOCK_NO_CHANGE);
1129 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_RELATIVE,0);
1130 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
1132 // -------------------------------------------------------------------------
1133 void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x ) throw(SQLException, RuntimeException)
1135 if (!::dbtools::implUpdateObject(this, columnIndex, x))
1136 throw SQLException();
1138 // -------------------------------------------------------------------------
1140 void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ ) throw(SQLException, RuntimeException)
1142 if (!::dbtools::implUpdateObject(this, columnIndex, x))
1143 throw SQLException();
1145 // -------------------------------------------------------------------------
1146 // XRowLocate
1147 Any SAL_CALL OResultSet::getBookmark( ) throw( SQLException, RuntimeException)
1149 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::getBookmark" );
1150 ::osl::MutexGuard aGuard( m_aMutex );
1151 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1153 TBookmarkPosMap::iterator aFind = ::std::find_if(m_aPosToBookmarks.begin(),m_aPosToBookmarks.end(),
1154 ::o3tl::compose1(::std::bind2nd(::std::equal_to<sal_Int32>(),m_nRowPos),::o3tl::select2nd<TBookmarkPosMap::value_type>()));
1156 if ( aFind == m_aPosToBookmarks.end() )
1158 if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED )
1160 m_nUseBookmarks = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS, SQL_UB_OFF);
1162 if(m_nUseBookmarks == SQL_UB_OFF)
1163 throw SQLException();
1165 m_aBookmark = OTools::getBytesValue(m_pStatement->getOwnConnection(),m_aStatementHandle,0,SQL_C_VARBOOKMARK,m_bWasNull,**this);
1166 m_aPosToBookmarks[m_aBookmark] = m_nRowPos;
1167 OSL_ENSURE(m_aBookmark.getLength(),"Invalid bookmark from length 0!");
1169 else
1170 m_aBookmark = aFind->first;
1171 return makeAny(m_aBookmark);
1173 // -------------------------------------------------------------------------
1174 sal_Bool SAL_CALL OResultSet::moveToBookmark( const Any& bookmark ) throw( SQLException, RuntimeException)
1176 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::moveToBookmark" );
1177 ::osl::MutexGuard aGuard( m_aMutex );
1178 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1180 m_nLastColumnPos = 0;
1181 bookmark >>= m_aBookmark;
1182 OSL_ENSURE(m_aBookmark.getLength(),"Invalid bookmark from length 0!");
1183 if(m_aBookmark.getLength())
1185 SQLRETURN nReturn = setStmtOption<SQLLEN*, SQL_IS_POINTER>(SQL_ATTR_FETCH_BOOKMARK_PTR, reinterpret_cast<SQLLEN*>(m_aBookmark.getArray()));
1187 if ( SQL_INVALID_HANDLE != nReturn && SQL_ERROR != nReturn )
1189 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,0);
1190 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
1191 TBookmarkPosMap::iterator aFind = m_aPosToBookmarks.find(m_aBookmark);
1192 if(aFind != m_aPosToBookmarks.end())
1193 m_nRowPos = aFind->second;
1194 else
1195 m_nRowPos = -1;
1196 return m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
1199 return sal_False;
1201 // -------------------------------------------------------------------------
1202 sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw( SQLException, RuntimeException)
1204 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::moveRelativeToBookmark" );
1205 ::osl::MutexGuard aGuard( m_aMutex );
1206 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1209 m_nLastColumnPos = 0;
1210 bookmark >>= m_aBookmark;
1211 SQLRETURN nReturn = setStmtOption<SQLLEN*, SQL_IS_POINTER>(SQL_ATTR_FETCH_BOOKMARK_PTR, reinterpret_cast<SQLLEN*>(m_aBookmark.getArray()));
1212 OSL_UNUSED( nReturn );
1214 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,SQL_FETCH_BOOKMARK,rows);
1215 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
1216 return m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
1218 // -------------------------------------------------------------------------
1219 sal_Int32 SAL_CALL OResultSet::compareBookmarks( const Any& lhs, const Any& rhs ) throw( SQLException, RuntimeException)
1221 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::compareBookmarks" );
1222 ::osl::MutexGuard aGuard( m_aMutex );
1223 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1225 return (lhs == rhs) ? CompareBookmark::EQUAL : CompareBookmark::NOT_EQUAL;
1227 // -------------------------------------------------------------------------
1228 sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks( ) throw( SQLException, RuntimeException)
1230 return sal_False;
1232 // -------------------------------------------------------------------------
1233 sal_Int32 SAL_CALL OResultSet::hashBookmark( const Any& /*bookmark*/ ) throw( SQLException, RuntimeException)
1235 ::dbtools::throwFunctionNotSupportedException( "XRowLocate::hashBookmark", *this );
1236 return 0;
1238 // -------------------------------------------------------------------------
1239 // XDeleteRows
1240 Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows( const Sequence< Any >& rows ) throw( SQLException, RuntimeException)
1242 Sequence< sal_Int32 > aRet(rows.getLength());
1243 sal_Int32 *pRet = aRet.getArray();
1245 const Any *pBegin = rows.getConstArray();
1246 const Any *pEnd = pBegin + rows.getLength();
1248 for(;pBegin != pEnd;++pBegin,++pRet)
1252 if(moveToBookmark(*pBegin))
1254 deleteRow();
1255 *pRet = 1;
1258 catch(const SQLException&)
1260 *pRet = 0;
1263 return aRet;
1265 //------------------------------------------------------------------------------
1266 template < typename T, SQLINTEGER BufferLength > T OResultSet::getStmtOption (SQLINTEGER fOption, T dflt) const
1268 T result (dflt);
1269 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
1270 N3SQLGetStmtAttr(m_aStatementHandle, fOption, &result, BufferLength, NULL);
1271 return result;
1273 template < typename T, SQLINTEGER BufferLength > SQLRETURN OResultSet::setStmtOption (SQLINTEGER fOption, T value) const
1275 OSL_ENSURE(m_aStatementHandle,"StatementHandle is null!");
1276 SQLPOINTER sv = reinterpret_cast<SQLPOINTER>(value);
1277 return N3SQLSetStmtAttr(m_aStatementHandle, fOption, sv, BufferLength);
1279 //------------------------------------------------------------------------------
1280 sal_Int32 OResultSet::getResultSetConcurrency() const
1282 sal_uInt32 nValue = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CONCURRENCY);
1283 if(SQL_CONCUR_READ_ONLY == nValue)
1284 nValue = ResultSetConcurrency::READ_ONLY;
1285 else
1286 nValue = ResultSetConcurrency::UPDATABLE;
1288 return nValue;
1290 //------------------------------------------------------------------------------
1291 sal_Int32 OResultSet::getResultSetType() const
1293 sal_uInt32 nValue = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_SENSITIVITY);
1294 if(SQL_SENSITIVE == nValue)
1295 nValue = ResultSetType::SCROLL_SENSITIVE;
1296 else if(SQL_INSENSITIVE == nValue)
1297 nValue = ResultSetType::SCROLL_INSENSITIVE;
1298 else
1300 SQLULEN nCurType = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE);
1301 if(SQL_CURSOR_KEYSET_DRIVEN == nCurType)
1302 nValue = ResultSetType::SCROLL_SENSITIVE;
1303 else if(SQL_CURSOR_STATIC == nCurType)
1304 nValue = ResultSetType::SCROLL_INSENSITIVE;
1305 else if(SQL_CURSOR_FORWARD_ONLY == nCurType)
1306 nValue = ResultSetType::FORWARD_ONLY;
1307 else if(SQL_CURSOR_DYNAMIC == nCurType)
1308 nValue = ResultSetType::SCROLL_SENSITIVE;
1310 return nValue;
1312 //------------------------------------------------------------------------------
1313 sal_Int32 OResultSet::getFetchDirection() const
1315 return FetchDirection::FORWARD;
1317 //------------------------------------------------------------------------------
1318 sal_Int32 OResultSet::getFetchSize() const
1320 return getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_ARRAY_SIZE);
1322 //------------------------------------------------------------------------------
1323 ::rtl::OUString OResultSet::getCursorName() const
1325 SQLCHAR pName[258];
1326 SQLSMALLINT nRealLen = 0;
1327 N3SQLGetCursorName(m_aStatementHandle,(SQLCHAR*)pName,256,&nRealLen);
1328 return ::rtl::OUString::createFromAscii((const char*)pName);
1330 // -------------------------------------------------------------------------
1331 sal_Bool OResultSet::isBookmarkable() const
1333 if(!m_aConnectionHandle)
1334 return sal_False;
1336 const SQLULEN nCursorType = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE);
1338 sal_Int32 nAttr = 0;
1341 switch(nCursorType)
1343 case SQL_CURSOR_FORWARD_ONLY:
1344 return sal_False;
1345 case SQL_CURSOR_STATIC:
1346 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_STATIC_CURSOR_ATTRIBUTES1,nAttr,NULL);
1347 break;
1348 case SQL_CURSOR_KEYSET_DRIVEN:
1349 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_KEYSET_CURSOR_ATTRIBUTES1,nAttr,NULL);
1350 break;
1351 case SQL_CURSOR_DYNAMIC:
1352 OTools::GetInfo(m_pStatement->getOwnConnection(),m_aConnectionHandle,SQL_DYNAMIC_CURSOR_ATTRIBUTES1,nAttr,NULL);
1353 break;
1356 catch(const Exception&)
1358 return sal_False;
1361 if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED )
1363 m_nUseBookmarks = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS, SQL_UB_OFF);
1366 return (m_nUseBookmarks != SQL_UB_OFF) && (nAttr & SQL_CA1_BOOKMARK) == SQL_CA1_BOOKMARK;
1368 //------------------------------------------------------------------------------
1369 void OResultSet::setFetchDirection(sal_Int32 _par0)
1371 OSL_ENSURE(_par0>0,"Illegal fetch direction!");
1372 if ( _par0 > 0 )
1374 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_CURSOR_TYPE, _par0);
1377 //------------------------------------------------------------------------------
1378 void OResultSet::setFetchSize(sal_Int32 _par0)
1380 OSL_ENSURE(_par0>0,"Illegal fetch size!");
1381 if ( _par0 > 0 )
1383 setStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_ARRAY_SIZE, _par0);
1384 delete [] m_pRowStatusArray;
1386 m_pRowStatusArray = new SQLUSMALLINT[_par0];
1387 setStmtOption<SQLUSMALLINT*, SQL_IS_POINTER>(SQL_ATTR_ROW_STATUS_PTR, m_pRowStatusArray);
1390 // -------------------------------------------------------------------------
1391 IPropertyArrayHelper* OResultSet::createArrayHelper( ) const
1393 Sequence< Property > aProps(6);
1394 Property* pProperties = aProps.getArray();
1395 sal_Int32 nPos = 0;
1396 DECL_PROP1IMPL(CURSORNAME, ::rtl::OUString) PropertyAttribute::READONLY);
1397 DECL_PROP0(FETCHDIRECTION, sal_Int32);
1398 DECL_PROP0(FETCHSIZE, sal_Int32);
1399 DECL_BOOL_PROP1IMPL(ISBOOKMARKABLE) PropertyAttribute::READONLY);
1400 DECL_PROP1IMPL(RESULTSETCONCURRENCY,sal_Int32) PropertyAttribute::READONLY);
1401 DECL_PROP1IMPL(RESULTSETTYPE, sal_Int32) PropertyAttribute::READONLY);
1403 return new OPropertyArrayHelper(aProps);
1405 // -------------------------------------------------------------------------
1406 IPropertyArrayHelper & OResultSet::getInfoHelper()
1408 return *const_cast<OResultSet*>(this)->getArrayHelper();
1410 // -------------------------------------------------------------------------
1411 sal_Bool OResultSet::convertFastPropertyValue(
1412 Any & rConvertedValue,
1413 Any & rOldValue,
1414 sal_Int32 nHandle,
1415 const Any& rValue )
1416 throw (::com::sun::star::lang::IllegalArgumentException)
1418 switch(nHandle)
1420 case PROPERTY_ID_ISBOOKMARKABLE:
1421 case PROPERTY_ID_CURSORNAME:
1422 case PROPERTY_ID_RESULTSETCONCURRENCY:
1423 case PROPERTY_ID_RESULTSETTYPE:
1424 throw ::com::sun::star::lang::IllegalArgumentException();
1425 case PROPERTY_ID_FETCHDIRECTION:
1426 return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
1427 case PROPERTY_ID_FETCHSIZE:
1428 return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
1429 default:
1432 return sal_False;
1434 // -------------------------------------------------------------------------
1435 void OResultSet::setFastPropertyValue_NoBroadcast(
1436 sal_Int32 nHandle,
1437 const Any& rValue
1439 throw (Exception)
1441 switch(nHandle)
1443 case PROPERTY_ID_ISBOOKMARKABLE:
1444 case PROPERTY_ID_CURSORNAME:
1445 case PROPERTY_ID_RESULTSETCONCURRENCY:
1446 case PROPERTY_ID_RESULTSETTYPE:
1447 throw Exception();
1448 case PROPERTY_ID_FETCHDIRECTION:
1449 setFetchDirection(getINT32(rValue));
1450 break;
1451 case PROPERTY_ID_FETCHSIZE:
1452 setFetchSize(getINT32(rValue));
1453 break;
1454 default:
1458 // -------------------------------------------------------------------------
1459 void OResultSet::getFastPropertyValue(
1460 Any& rValue,
1461 sal_Int32 nHandle
1462 ) const
1464 switch(nHandle)
1466 case PROPERTY_ID_ISBOOKMARKABLE:
1467 rValue = bool2any(isBookmarkable());
1468 break;
1469 case PROPERTY_ID_CURSORNAME:
1470 rValue <<= getCursorName();
1471 break;
1472 case PROPERTY_ID_RESULTSETCONCURRENCY:
1473 rValue <<= getResultSetConcurrency();
1474 break;
1475 case PROPERTY_ID_RESULTSETTYPE:
1476 rValue <<= getResultSetType();
1477 break;
1478 case PROPERTY_ID_FETCHDIRECTION:
1479 rValue <<= getFetchDirection();
1480 break;
1481 case PROPERTY_ID_FETCHSIZE:
1482 rValue <<= getFetchSize();
1483 break;
1486 // -------------------------------------------------------------------------
1487 void OResultSet::fillRow(sal_Int32 _nToColumn)
1489 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::fillRow" );
1490 if((sal_Int32)m_aRow.size() <= _nToColumn)
1492 m_aRow.resize(_nToColumn+1);
1493 m_aRow[_nToColumn].setBound(sal_True);
1495 m_bFetchData = sal_False;
1497 sal_Int32 nColumn = m_nLastColumnPos + 1;
1498 TDataRow::iterator pColumn = m_aRow.begin() + nColumn;
1499 TDataRow::iterator pColumnEnd = m_aRow.begin() + _nToColumn + 1;
1501 for (; pColumn < pColumnEnd; ++nColumn, ++pColumn)
1503 const sal_Int32 nType = pColumn->getTypeKind();
1504 switch (nType)
1506 case DataType::CHAR:
1507 case DataType::VARCHAR:
1508 case DataType::DECIMAL:
1509 case DataType::NUMERIC:
1510 case DataType::LONGVARCHAR:
1511 case DataType::CLOB:
1513 const SWORD nColumnType = impl_getColumnType_nothrow(nColumn);
1514 *pColumn = OTools::getStringValue(m_pStatement->getOwnConnection(),m_aStatementHandle,nColumn,nColumnType,m_bWasNull,**this,m_nTextEncoding);
1516 break;
1517 case DataType::BIGINT:
1518 *pColumn = getLong(nColumn);
1519 break;
1520 case DataType::REAL:
1521 case DataType::DOUBLE:
1522 *pColumn = getDouble(nColumn);
1523 break;
1524 case DataType::LONGVARBINARY:
1525 case DataType::BLOB:
1526 *pColumn = getBytes(nColumn);
1527 break;
1528 case DataType::DATE:
1529 *pColumn = getDate(nColumn);
1530 break;
1531 case DataType::TIME:
1532 *pColumn = getTime(nColumn);
1533 break;
1534 case DataType::TIMESTAMP:
1535 *pColumn = getTimestamp(nColumn);
1536 break;
1537 case DataType::BIT:
1538 *pColumn = getBoolean(nColumn);
1539 break;
1540 case DataType::TINYINT:
1541 *pColumn = getByte(nColumn);
1542 break;
1543 case DataType::SMALLINT:
1544 *pColumn = getShort(nColumn);
1545 break;
1546 case DataType::INTEGER:
1547 *pColumn = getInt(nColumn);
1548 break;
1549 case DataType::FLOAT:
1550 *pColumn = getFloat(nColumn);
1551 break;
1552 case DataType::BINARY:
1553 case DataType::VARBINARY:
1554 *pColumn = getBytes(nColumn);
1555 break;
1558 if ( m_bWasNull )
1559 pColumn->setNull();
1560 if(nType != pColumn->getTypeKind())
1562 pColumn->setTypeKind(nType);
1565 m_nLastColumnPos = _nToColumn;
1566 m_bFetchData = sal_True;
1568 // -----------------------------------------------------------------------------
1569 void SAL_CALL OResultSet::acquire() throw()
1571 OResultSet_BASE::acquire();
1573 // -----------------------------------------------------------------------------
1574 void SAL_CALL OResultSet::release() throw()
1576 OResultSet_BASE::release();
1578 // -----------------------------------------------------------------------------
1579 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException)
1581 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1583 // -----------------------------------------------------------------------------
1584 sal_Bool OResultSet::move(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool /*_bRetrieveData*/)
1586 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::move" );
1587 SQLSMALLINT nFetchOrientation = SQL_FETCH_NEXT;
1588 switch(_eCursorPosition)
1590 case IResultSetHelper::NEXT:
1591 nFetchOrientation = SQL_FETCH_NEXT;
1592 break;
1593 case IResultSetHelper::PRIOR:
1594 nFetchOrientation = SQL_FETCH_PRIOR;
1595 break;
1596 case IResultSetHelper::FIRST:
1597 nFetchOrientation = SQL_FETCH_FIRST;
1598 break;
1599 case IResultSetHelper::LAST:
1600 nFetchOrientation = SQL_FETCH_LAST;
1601 break;
1602 case IResultSetHelper::RELATIVE:
1603 nFetchOrientation = SQL_FETCH_RELATIVE;
1604 break;
1605 case IResultSetHelper::ABSOLUTE:
1606 nFetchOrientation = SQL_FETCH_ABSOLUTE;
1607 break;
1608 case IResultSetHelper::BOOKMARK: // special case here because we are only called with position numbers
1610 TBookmarkPosMap::iterator aIter = m_aPosToBookmarks.begin();
1611 TBookmarkPosMap::iterator aEnd = m_aPosToBookmarks.end();
1612 for (; aIter != aEnd; ++aIter)
1614 if ( aIter->second == _nOffset )
1615 return moveToBookmark(makeAny(aIter->first));
1617 OSL_FAIL("Bookmark not found!");
1619 return sal_False;
1622 m_bEOF = sal_False;
1623 m_nLastColumnPos = 0;
1625 SQLRETURN nOldFetchStatus = m_nCurrentFetchState;
1626 if ( !m_bUseFetchScroll && _eCursorPosition == IResultSetHelper::NEXT )
1627 m_nCurrentFetchState = N3SQLFetch(m_aStatementHandle);
1628 else
1629 m_nCurrentFetchState = N3SQLFetchScroll(m_aStatementHandle,nFetchOrientation,_nOffset);
1631 OSL_TRACE( __FILE__": OSkipDeletedSet::OResultSet::move(%d,%d), FetchState = %d",nFetchOrientation,_nOffset,m_nCurrentFetchState);
1632 OTools::ThrowException(m_pStatement->getOwnConnection(),m_nCurrentFetchState,m_aStatementHandle,SQL_HANDLE_STMT,*this);
1634 const bool bSuccess = m_nCurrentFetchState == SQL_SUCCESS || m_nCurrentFetchState == SQL_SUCCESS_WITH_INFO;
1635 if ( bSuccess )
1637 switch(_eCursorPosition)
1639 case IResultSetHelper::NEXT:
1640 ++m_nRowPos;
1641 break;
1642 case IResultSetHelper::PRIOR:
1643 --m_nRowPos;
1644 break;
1645 case IResultSetHelper::FIRST:
1646 m_nRowPos = 1;
1647 break;
1648 case IResultSetHelper::LAST:
1649 m_bEOF = sal_True;
1650 break;
1651 case IResultSetHelper::RELATIVE:
1652 m_nRowPos += _nOffset;
1653 break;
1654 case IResultSetHelper::ABSOLUTE:
1655 case IResultSetHelper::BOOKMARK: // special case here because we are only called with position numbers
1656 m_nRowPos = _nOffset;
1657 break;
1658 } // switch(_eCursorPosition)
1659 if ( m_nUseBookmarks == ODBC_SQL_NOT_DEFINED )
1661 m_nUseBookmarks = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_USE_BOOKMARKS, SQL_UB_OFF);
1663 if ( m_nUseBookmarks != SQL_UB_OFF )
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!");
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;
1676 return bSuccess;
1678 // -----------------------------------------------------------------------------
1679 sal_Int32 OResultSet::getDriverPos() const
1681 sal_Int32 nValue = getStmtOption<SQLULEN, SQL_IS_UINTEGER>(SQL_ATTR_ROW_NUMBER);
1682 OSL_TRACE( __FILE__": OResultSet::getDriverPos() = RowNum = %d, RowPos = %d", nValue, m_nRowPos);
1683 return nValue ? nValue : m_nRowPos;
1685 // -----------------------------------------------------------------------------
1686 sal_Bool OResultSet::deletedVisible() const
1688 return sal_False;
1690 // -----------------------------------------------------------------------------
1691 sal_Bool OResultSet::isRowDeleted() const
1693 return m_pRowStatusArray[0] == SQL_ROW_DELETED;
1695 // -----------------------------------------------------------------------------
1696 sal_Bool OResultSet::moveImpl(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData)
1698 ::osl::MutexGuard aGuard( m_aMutex );
1699 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
1700 return (m_pSkipDeletedSet != NULL)
1701 ? m_pSkipDeletedSet->skipDeleted(_eCursorPosition,_nOffset,_bRetrieveData)
1702 : move(_eCursorPosition,_nOffset,_bRetrieveData);
1704 // -----------------------------------------------------------------------------
1705 void OResultSet::fillNeededData(SQLRETURN _nRet)
1707 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "odbc", "Ocke.Janssen@sun.com", "OResultSet::fillNeededData" );
1708 SQLRETURN nRet = _nRet;
1709 if( nRet == SQL_NEED_DATA)
1711 void* pColumnIndex = 0;
1712 nRet = N3SQLParamData(m_aStatementHandle,&pColumnIndex);
1716 if (nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO && nRet != SQL_NEED_DATA)
1717 break;
1719 sal_IntPtr nColumnIndex ( reinterpret_cast<sal_IntPtr>(pColumnIndex));
1720 Sequence< sal_Int8 > aSeq;
1721 switch(m_aRow[nColumnIndex].getTypeKind())
1723 case DataType::BINARY:
1724 case DataType::VARBINARY:
1725 case DataType::LONGVARBINARY:
1726 case DataType::BLOB:
1727 aSeq = m_aRow[nColumnIndex];
1728 N3SQLPutData (m_aStatementHandle, aSeq.getArray(), aSeq.getLength());
1729 break;
1730 case SQL_WLONGVARCHAR:
1732 ::rtl::OUString sRet;
1733 sRet = m_aRow[nColumnIndex].getString();
1734 nRet = N3SQLPutData (m_aStatementHandle, (SQLPOINTER)sRet.getStr(), sizeof(sal_Unicode)*sRet.getLength());
1735 break;
1737 case DataType::LONGVARCHAR:
1738 case DataType::CLOB:
1740 ::rtl::OUString sRet;
1741 sRet = m_aRow[nColumnIndex].getString();
1742 ::rtl::OString aString(::rtl::OUStringToOString(sRet,m_nTextEncoding));
1743 nRet = N3SQLPutData (m_aStatementHandle, (SQLPOINTER)aString.getStr(), aString.getLength());
1744 break;
1746 default:
1747 OSL_FAIL("Not supported at the moment!");
1749 nRet = N3SQLParamData(m_aStatementHandle,&pColumnIndex);
1751 while (nRet == SQL_NEED_DATA);
1754 // -----------------------------------------------------------------------------
1755 SWORD OResultSet::impl_getColumnType_nothrow(sal_Int32 columnIndex)
1757 ::std::map<sal_Int32,SWORD>::iterator aFind = m_aODBCColumnTypes.find(columnIndex);
1758 if ( aFind == m_aODBCColumnTypes.end() )
1759 aFind = m_aODBCColumnTypes.insert(::std::map<sal_Int32,SWORD>::value_type(columnIndex,OResultSetMetaData::getColumnODBCType(m_pStatement->getOwnConnection(),m_aStatementHandle,*this,columnIndex))).first;
1760 return aFind->second;
1763 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */