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