Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / connectivity / source / drivers / ado / AResultSet.cxx
blob85ca2b081a077d10968963ec4202ab83cec23377
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <ado/AResultSet.hxx>
21 #include <ado/AResultSetMetaData.hxx>
22 #include <com/sun/star/sdbc/DataType.hpp>
23 #include <com/sun/star/sdbc/KeyRule.hpp>
24 #include <com/sun/star/sdbc/IndexType.hpp>
25 #include <com/sun/star/sdbcx/CompareBookmark.hpp>
26 #include <comphelper/property.hxx>
27 #include <com/sun/star/lang/DisposedException.hpp>
28 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
29 #include <com/sun/star/sdbc/ResultSetType.hpp>
30 #include <com/sun/star/sdbc/FetchDirection.hpp>
31 #include <cppuhelper/typeprovider.hxx>
32 #include <cppuhelper/supportsservice.hxx>
33 #include <comphelper/sequence.hxx>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <comphelper/seqstream.hxx>
36 #include <connectivity/dbexception.hxx>
37 #include <connectivity/dbtools.hxx>
38 #include <comphelper/types.hxx>
40 using namespace ::comphelper;
43 #include <oledb.h>
45 #define CHECK_RETURN(x) \
46 if(!SUCCEEDED(x)) \
47 ADOS::ThrowException(m_pStmt->m_pConnection->getConnection(),*this);
49 using namespace connectivity::ado;
50 using namespace com::sun::star::uno;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::beans;
53 using namespace com::sun::star::sdbc;
56 // IMPLEMENT_SERVICE_INFO(OResultSet,"com.sun.star.sdbcx.AResultSet","com.sun.star.sdbc.ResultSet");
57 OUString SAL_CALL OResultSet::getImplementationName( )
59 return "com.sun.star.sdbcx.ado.ResultSet";
62 css::uno::Sequence< OUString > SAL_CALL OResultSet::getSupportedServiceNames( )
64 return {"com.sun.star.sdbc.ResultSet","com.sun.star.sdbcx.ResultSet"};
67 sal_Bool SAL_CALL OResultSet::supportsService( const OUString& _rServiceName )
69 return cppu::supportsService(this, _rServiceName);
72 OResultSet::OResultSet(ADORecordset* _pRecordSet,OStatement_Base* pStmt) : OResultSet_BASE(m_aMutex)
73 ,OPropertySetHelper(OResultSet_BASE::rBHelper)
74 ,m_pRecordSet(_pRecordSet)
75 ,m_pStmt(pStmt)
76 ,m_xStatement(*pStmt)
77 ,m_nRowPos(0)
78 ,m_bEOF(false)
79 ,m_bOnFirstAfterOpen(false)
83 OResultSet::OResultSet(ADORecordset* _pRecordSet) : OResultSet_BASE(m_aMutex)
84 ,OPropertySetHelper(OResultSet_BASE::rBHelper)
85 ,m_pRecordSet(_pRecordSet)
86 ,m_pStmt(nullptr)
87 ,m_nRowPos(0)
88 ,m_bEOF(false)
89 ,m_bOnFirstAfterOpen(false)
93 void OResultSet::construct()
95 osl_atomic_increment( &m_refCount );
96 if (!m_pRecordSet)
98 OSL_FAIL( "OResultSet::construct: no RecordSet!" );
99 Reference< XInterface > xInt( *this );
100 osl_atomic_decrement( &m_refCount );
101 ::dbtools::throwFunctionSequenceException( xInt );
103 m_pRecordSet->AddRef();
104 VARIANT_BOOL bIsAtBOF;
105 CHECK_RETURN(m_pRecordSet->get_BOF(&bIsAtBOF))
106 m_bOnFirstAfterOpen = bIsAtBOF != VARIANT_TRUE;
107 osl_atomic_decrement( &m_refCount );
110 OResultSet::~OResultSet()
112 if(m_pRecordSet)
113 m_pRecordSet->Release();
116 void OResultSet::disposing()
118 OPropertySetHelper::disposing();
120 ::osl::MutexGuard aGuard(m_aMutex);
121 if(m_pRecordSet)
122 m_pRecordSet->Close();
123 m_xStatement.clear();
124 m_xMetaData.clear();
127 Any SAL_CALL OResultSet::queryInterface( const Type & rType )
129 Any aRet = OPropertySetHelper::queryInterface(rType);
130 return aRet.hasValue() ? aRet : OResultSet_BASE::queryInterface(rType);
133 css::uno::Sequence< css::uno::Type > SAL_CALL OResultSet::getTypes( )
135 ::cppu::OTypeCollection aTypes( cppu::UnoType<css::beans::XMultiPropertySet>::get(),
136 cppu::UnoType<css::beans::XFastPropertySet>::get(),
137 cppu::UnoType<css::beans::XPropertySet>::get());
139 return ::comphelper::concatSequences(aTypes.getTypes(),OResultSet_BASE::getTypes());
143 sal_Int32 SAL_CALL OResultSet::findColumn( const OUString& columnName )
145 ::osl::MutexGuard aGuard( m_aMutex );
146 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
149 Reference< XResultSetMetaData > xMeta = getMetaData();
150 sal_Int32 nLen = xMeta->getColumnCount();
151 sal_Int32 i = 1;
152 for(;i<=nLen;++i)
154 if(xMeta->isCaseSensitive(i) ? columnName == xMeta->getColumnName(i) :
155 columnName.equalsIgnoreAsciiCase(xMeta->getColumnName(i)))
156 return i;
159 ::dbtools::throwInvalidColumnException( columnName, *this );
160 assert(false);
161 return 0; // Never reached
163 #define BLOCK_SIZE 256
165 Reference< css::io::XInputStream > SAL_CALL OResultSet::getBinaryStream( sal_Int32 columnIndex )
167 ::osl::MutexGuard aGuard( m_aMutex );
168 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
170 WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex);
172 if((aField.GetAttributes() & adFldLong) == adFldLong)
174 //Copy the data only up to the Actual Size of Field.
175 sal_Int32 nSize = aField.GetActualSize();
176 Sequence<sal_Int8> aData(nSize);
177 sal_Int32 index = 0;
178 while(index < nSize)
180 m_aValue = aField.GetChunk(BLOCK_SIZE);
181 if(m_aValue.isNull())
182 break;
183 UCHAR chData;
184 for(LONG index2 = 0;index2 < BLOCK_SIZE;++index2)
186 HRESULT hr = ::SafeArrayGetElement(m_aValue.parray,&index2,&chData);
187 if(SUCCEEDED(hr))
189 //Take BYTE by BYTE and advance Memory Location
190 aData.getArray()[index++] = chData;
192 else
193 break;
197 return new ::comphelper::SequenceInputStream(aData);
199 // else we ask for a bytesequence
200 aField.get_Value(m_aValue);
202 return m_aValue.isNull() ? nullptr : new ::comphelper::SequenceInputStream(m_aValue.getByteSequence());
205 Reference< css::io::XInputStream > SAL_CALL OResultSet::getCharacterStream( sal_Int32 /*columnIndex*/ )
207 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getCharacterStream", *this );
208 return nullptr;
211 OLEVariant OResultSet::getValue(sal_Int32 columnIndex )
213 ::osl::MutexGuard aGuard( m_aMutex );
214 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
216 WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex);
217 aField.get_Value(m_aValue);
218 return m_aValue;
221 sal_Bool SAL_CALL OResultSet::getBoolean( sal_Int32 columnIndex )
223 return getValue(columnIndex).getBool();
227 sal_Int8 SAL_CALL OResultSet::getByte( sal_Int32 columnIndex )
229 return getValue(columnIndex).getInt8();
233 Sequence< sal_Int8 > SAL_CALL OResultSet::getBytes( sal_Int32 columnIndex )
235 return getValue(columnIndex).getByteSequence();
239 css::util::Date SAL_CALL OResultSet::getDate( sal_Int32 columnIndex )
241 return getValue(columnIndex).getDate();
245 double SAL_CALL OResultSet::getDouble( sal_Int32 columnIndex )
247 return getValue(columnIndex).getDouble();
251 float SAL_CALL OResultSet::getFloat( sal_Int32 columnIndex )
253 return getValue(columnIndex).getFloat();
257 sal_Int32 SAL_CALL OResultSet::getInt( sal_Int32 columnIndex )
259 return getValue(columnIndex).getInt32();
263 sal_Int32 SAL_CALL OResultSet::getRow( )
265 ::osl::MutexGuard aGuard( m_aMutex );
266 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
269 PositionEnum_Param aPos;
270 m_pRecordSet->get_AbsolutePosition(&aPos);
271 return (aPos > 0) ? static_cast<sal_Int32>(aPos) : m_nRowPos;
272 // return the rowcount from driver if the driver doesn't support this return our count
276 sal_Int64 SAL_CALL OResultSet::getLong( sal_Int32 /*columnIndex*/ )
278 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getLong", *this );
279 return sal_Int64(0);
283 Reference< XResultSetMetaData > SAL_CALL OResultSet::getMetaData( )
285 ::osl::MutexGuard aGuard( m_aMutex );
286 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
289 if(!m_xMetaData.is())
290 m_xMetaData = new OResultSetMetaData(m_pRecordSet);
291 return m_xMetaData;
294 Reference< XArray > SAL_CALL OResultSet::getArray( sal_Int32 /*columnIndex*/ )
296 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getArray", *this );
297 return nullptr;
301 Reference< XClob > SAL_CALL OResultSet::getClob( sal_Int32 /*columnIndex*/ )
303 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getClob", *this );
304 return nullptr;
307 Reference< XBlob > SAL_CALL OResultSet::getBlob( sal_Int32 /*columnIndex*/ )
309 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getBlob", *this );
310 return nullptr;
314 Reference< XRef > SAL_CALL OResultSet::getRef( sal_Int32 /*columnIndex*/ )
316 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRef", *this );
317 return nullptr;
321 Any SAL_CALL OResultSet::getObject( sal_Int32 columnIndex, const Reference< css::container::XNameAccess >& /*typeMap*/ )
323 return getValue(columnIndex).makeAny();
327 sal_Int16 SAL_CALL OResultSet::getShort( sal_Int32 columnIndex )
329 return getValue(columnIndex).getInt16();
333 OUString SAL_CALL OResultSet::getString( sal_Int32 columnIndex )
335 return getValue(columnIndex).getString();
339 css::util::Time SAL_CALL OResultSet::getTime( sal_Int32 columnIndex )
341 return getValue(columnIndex).getTime();
345 css::util::DateTime SAL_CALL OResultSet::getTimestamp( sal_Int32 columnIndex )
347 return getValue(columnIndex).getDateTime();
351 sal_Bool SAL_CALL OResultSet::isAfterLast( )
353 ::osl::MutexGuard aGuard( m_aMutex );
354 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
357 VARIANT_BOOL bIsAtEOF;
358 CHECK_RETURN(m_pRecordSet->get_EOF(&bIsAtEOF))
359 return bIsAtEOF == VARIANT_TRUE;
362 sal_Bool SAL_CALL OResultSet::isFirst( )
364 ::osl::MutexGuard aGuard( m_aMutex );
365 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
368 return m_nRowPos == 1;
371 sal_Bool SAL_CALL OResultSet::isLast( )
373 ::osl::MutexGuard aGuard( m_aMutex );
374 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
377 return true;
380 void SAL_CALL OResultSet::beforeFirst( )
382 ::osl::MutexGuard aGuard( m_aMutex );
383 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
386 if(first())
387 m_bOnFirstAfterOpen = !previous();
390 void SAL_CALL OResultSet::afterLast( )
392 ::osl::MutexGuard aGuard( m_aMutex );
393 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
396 if(last())
397 next();
398 m_bEOF = true;
402 void SAL_CALL OResultSet::close( )
405 ::osl::MutexGuard aGuard( m_aMutex );
406 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
409 dispose();
413 sal_Bool SAL_CALL OResultSet::first( )
415 ::osl::MutexGuard aGuard( m_aMutex );
416 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
419 if(SUCCEEDED(m_pRecordSet->MoveFirst()))
421 m_nRowPos = 1;
422 m_bOnFirstAfterOpen = false;
423 return true;
425 return false;
429 sal_Bool SAL_CALL OResultSet::last( )
431 ::osl::MutexGuard aGuard( m_aMutex );
432 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
435 bool bRet = SUCCEEDED(m_pRecordSet->MoveLast());
436 if(bRet)
438 m_pRecordSet->get_RecordCount(&m_nRowPos);
439 m_bOnFirstAfterOpen = false;
441 return bRet;
444 sal_Bool SAL_CALL OResultSet::absolute( sal_Int32 row )
446 ::osl::MutexGuard aGuard( m_aMutex );
447 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
450 if(!row) // absolute with zero not allowed
451 ::dbtools::throwFunctionSequenceException(*this);
453 bool bCheck = true;
454 if(row < 0)
456 bCheck = SUCCEEDED(m_pRecordSet->MoveLast());
457 if ( bCheck )
459 while(++row < 0 && bCheck)
460 bCheck = SUCCEEDED(m_pRecordSet->MovePrevious());
463 else
465 first();
466 OLEVariant aEmpty;
467 aEmpty.setNoArg();
468 bCheck = SUCCEEDED(m_pRecordSet->Move(row-1,aEmpty)); // move to row -1 because we stand already on the first
469 if(bCheck)
470 m_nRowPos = row;
472 if(bCheck)
473 m_bOnFirstAfterOpen = false;
474 return bCheck;
477 sal_Bool SAL_CALL OResultSet::relative( sal_Int32 row )
479 ::osl::MutexGuard aGuard( m_aMutex );
480 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
483 OLEVariant aEmpty;
484 aEmpty.setNoArg();
485 sal_Int32 nNewPos = row;
486 if ( m_bOnFirstAfterOpen && nNewPos > 0 )
487 --nNewPos;
488 bool bRet = SUCCEEDED(m_pRecordSet->Move(row,aEmpty));
489 if(bRet)
491 m_nRowPos += row;
492 m_bOnFirstAfterOpen = false;
494 return bRet;
497 sal_Bool SAL_CALL OResultSet::previous( )
499 ::osl::MutexGuard aGuard( m_aMutex );
500 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
502 bool bRet = SUCCEEDED(m_pRecordSet->MovePrevious());
503 if(bRet)
505 --m_nRowPos;
506 m_bOnFirstAfterOpen = false;
508 return bRet;
511 Reference< XInterface > SAL_CALL OResultSet::getStatement( )
513 ::osl::MutexGuard aGuard( m_aMutex );
514 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
515 return m_xStatement;
519 sal_Bool SAL_CALL OResultSet::rowDeleted( )
521 ::osl::MutexGuard aGuard( m_aMutex );
522 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
525 sal_Int32 eRec;
526 m_pRecordSet->get_Status(&eRec);
527 bool bRet = (RecordStatusEnum(eRec) & adRecDeleted) == adRecDeleted;
528 if(bRet)
529 --m_nRowPos;
530 return bRet;
533 sal_Bool SAL_CALL OResultSet::rowInserted( )
534 { ::osl::MutexGuard aGuard( m_aMutex );
535 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
538 sal_Int32 eRec;
539 m_pRecordSet->get_Status(&eRec);
540 bool bRet = (RecordStatusEnum(eRec) & adRecNew) == adRecNew;
541 if(bRet)
542 ++m_nRowPos;
543 return bRet;
546 sal_Bool SAL_CALL OResultSet::rowUpdated( )
548 ::osl::MutexGuard aGuard( m_aMutex );
549 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
552 sal_Int32 eRec;
553 m_pRecordSet->get_Status(&eRec);
554 return (RecordStatusEnum(eRec) & adRecModified) == adRecModified;
558 sal_Bool SAL_CALL OResultSet::isBeforeFirst( )
560 ::osl::MutexGuard aGuard( m_aMutex );
561 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
564 OSL_ENSURE(!m_nRowPos,"OResultSet::isBeforeFirst: Error in setting m_nRowPos!");
565 VARIANT_BOOL bIsAtBOF = VARIANT_TRUE;
566 if(!m_bOnFirstAfterOpen)
568 OSL_ENSURE(!m_nRowPos,"OResultSet::isBeforeFirst: Error in setting m_nRowPos!");
569 m_pRecordSet->get_BOF(&bIsAtBOF);
571 return bIsAtBOF == VARIANT_TRUE;
575 sal_Bool SAL_CALL OResultSet::next( )
577 ::osl::MutexGuard aGuard( m_aMutex );
578 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
581 bool bRet = true;
582 if(m_bOnFirstAfterOpen)
584 m_bOnFirstAfterOpen = false;
585 ++m_nRowPos;
587 else
589 bRet = SUCCEEDED(m_pRecordSet->MoveNext());
591 if(bRet)
593 VARIANT_BOOL bIsAtEOF;
594 CHECK_RETURN(m_pRecordSet->get_EOF(&bIsAtEOF))
595 bRet = bIsAtEOF != VARIANT_TRUE;
596 ++m_nRowPos;
598 else
599 ADOS::ThrowException(m_pStmt->m_pConnection->getConnection(),*this);
602 return bRet;
606 sal_Bool SAL_CALL OResultSet::wasNull( )
608 ::osl::MutexGuard aGuard( m_aMutex );
609 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
612 return m_aValue.isNull();
616 void SAL_CALL OResultSet::cancel( )
618 ::osl::MutexGuard aGuard( m_aMutex );
619 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
622 m_pRecordSet->Cancel();
625 void SAL_CALL OResultSet::clearWarnings( )
629 Any SAL_CALL OResultSet::getWarnings( )
631 return Any();
634 void SAL_CALL OResultSet::insertRow( )
636 ::osl::MutexGuard aGuard( m_aMutex );
637 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
640 OLEVariant aEmpty;
641 aEmpty.setNoArg();
642 m_pRecordSet->AddNew(aEmpty,aEmpty);
645 void SAL_CALL OResultSet::updateRow( )
647 ::osl::MutexGuard aGuard( m_aMutex );
648 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
651 OLEVariant aEmpty;
652 aEmpty.setNoArg();
653 m_pRecordSet->Update(aEmpty,aEmpty);
656 void SAL_CALL OResultSet::deleteRow( )
658 ::osl::MutexGuard aGuard( m_aMutex );
659 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
662 m_pRecordSet->Delete();
663 m_pRecordSet->UpdateBatch(adAffectCurrent);
667 void SAL_CALL OResultSet::cancelRowUpdates( )
669 ::osl::MutexGuard aGuard( m_aMutex );
670 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
673 m_pRecordSet->CancelUpdate();
677 void SAL_CALL OResultSet::moveToInsertRow( )
679 // ::osl::MutexGuard aGuard( m_aMutex );
680 //checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
681 // if ( getResultSetConcurrency() == ResultSetConcurrency::READ_ONLY )
682 // throw SQLException();
686 void SAL_CALL OResultSet::moveToCurrentRow( )
690 void OResultSet::updateValue(sal_Int32 columnIndex,const OLEVariant& x)
692 ::osl::MutexGuard aGuard( m_aMutex );
693 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
695 WpADOField aField = ADOS::getField(m_pRecordSet,columnIndex);
696 aField.PutValue(x);
699 void SAL_CALL OResultSet::updateNull( sal_Int32 columnIndex )
701 OLEVariant x;
702 x.setNull();
703 updateValue(columnIndex,x);
707 void SAL_CALL OResultSet::updateBoolean( sal_Int32 columnIndex, sal_Bool x )
709 updateValue(columnIndex,bool(x));
712 void SAL_CALL OResultSet::updateByte( sal_Int32 columnIndex, sal_Int8 x )
714 updateValue(columnIndex,x);
718 void SAL_CALL OResultSet::updateShort( sal_Int32 columnIndex, sal_Int16 x )
720 updateValue(columnIndex,x);
723 void SAL_CALL OResultSet::updateInt( sal_Int32 columnIndex, sal_Int32 x )
725 updateValue(columnIndex,x);
728 void SAL_CALL OResultSet::updateLong( sal_Int32 columnIndex, sal_Int64 x )
730 updateValue(columnIndex,x);
733 void SAL_CALL OResultSet::updateFloat( sal_Int32 columnIndex, float x )
735 updateValue(columnIndex,x);
739 void SAL_CALL OResultSet::updateDouble( sal_Int32 columnIndex, double x )
741 updateValue(columnIndex,x);
744 void SAL_CALL OResultSet::updateString( sal_Int32 columnIndex, const OUString& x )
746 updateValue(columnIndex,x);
749 void SAL_CALL OResultSet::updateBytes( sal_Int32 columnIndex, const Sequence< sal_Int8 >& x )
751 updateValue(columnIndex,x);
754 void SAL_CALL OResultSet::updateDate( sal_Int32 columnIndex, const css::util::Date& x )
756 updateValue(columnIndex,x);
760 void SAL_CALL OResultSet::updateTime( sal_Int32 columnIndex, const css::util::Time& x )
762 updateValue(columnIndex,x);
766 void SAL_CALL OResultSet::updateTimestamp( sal_Int32 columnIndex, const css::util::DateTime& x )
768 updateValue(columnIndex,x);
772 void SAL_CALL OResultSet::updateBinaryStream( sal_Int32 columnIndex, const Reference< css::io::XInputStream >& x, sal_Int32 length )
774 if(!x.is())
775 ::dbtools::throwFunctionSequenceException(*this);
777 Sequence<sal_Int8> aSeq;
778 x->readBytes(aSeq,length);
779 updateBytes(columnIndex,aSeq);
782 void SAL_CALL OResultSet::updateCharacterStream( sal_Int32 columnIndex, const Reference< css::io::XInputStream >& x, sal_Int32 length )
784 if(!x.is())
785 ::dbtools::throwFunctionSequenceException(*this);
787 Sequence<sal_Int8> aSeq;
788 x->readBytes(aSeq,length);
789 updateBytes(columnIndex,aSeq);
792 void SAL_CALL OResultSet::refreshRow( )
794 ::osl::MutexGuard aGuard( m_aMutex );
795 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
798 m_pRecordSet->Resync(adAffectCurrent);
801 void SAL_CALL OResultSet::updateObject( sal_Int32 columnIndex, const Any& x )
803 if (!::dbtools::implUpdateObject(this, columnIndex, x))
804 throw SQLException();
808 void SAL_CALL OResultSet::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/ )
810 if (!::dbtools::implUpdateObject(this, columnIndex, x))
811 throw SQLException();
814 // XRowLocate
815 Any SAL_CALL OResultSet::getBookmark( )
817 ::osl::MutexGuard aGuard( m_aMutex );
818 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
820 if(m_nRowPos < static_cast<sal_Int32>(m_aBookmarks.size())) // this bookmark was already fetched
821 return Any(sal_Int32(m_nRowPos-1));
823 OLEVariant aVar;
824 m_pRecordSet->get_Bookmark(&aVar);
825 m_aBookmarks.push_back(aVar);
826 return Any(static_cast<sal_Int32>(m_aBookmarks.size()-1));
830 sal_Bool SAL_CALL OResultSet::moveToBookmark( const Any& bookmark )
832 ::osl::MutexGuard aGuard( m_aMutex );
833 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
836 sal_Int32 nPos = 0;
837 bookmark >>= nPos;
838 OSL_ENSURE(nPos >= 0 && nPos < static_cast<sal_Int32>(m_aBookmarks.size()),"Invalid Index for vector");
839 if(nPos < 0 || nPos >= static_cast<sal_Int32>(m_aBookmarks.size()))
840 ::dbtools::throwFunctionSequenceException(*this);
842 return SUCCEEDED(m_pRecordSet->Move(0,m_aBookmarks[nPos]));
845 sal_Bool SAL_CALL OResultSet::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows )
847 ::osl::MutexGuard aGuard( m_aMutex );
848 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
851 sal_Int32 nPos = 0;
852 bookmark >>= nPos;
853 nPos += rows;
854 OSL_ENSURE(nPos >= 0 && nPos < static_cast<sal_Int32>(m_aBookmarks.size()),"Invalid Index for vector");
855 if(nPos < 0 || nPos >= static_cast<sal_Int32>(m_aBookmarks.size()))
856 ::dbtools::throwFunctionSequenceException(*this);
857 return SUCCEEDED(m_pRecordSet->Move(rows,m_aBookmarks[nPos]));
860 sal_Int32 SAL_CALL OResultSet::compareBookmarks( const Any& bookmark1, const Any& bookmark2 )
862 ::osl::MutexGuard aGuard( m_aMutex );
863 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
865 sal_Int32 nPos1 = 0;
866 bookmark1 >>= nPos1;
867 sal_Int32 nPos2 = 0;
868 bookmark2 >>= nPos2;
869 if(nPos1 == nPos2) // they should be equal
870 return css::sdbcx::CompareBookmark::EQUAL;
872 OSL_ENSURE((nPos1 >= 0 && nPos1 < static_cast<sal_Int32>(m_aBookmarks.size())) || (nPos1 >= 0 && nPos2 < static_cast<sal_Int32>(m_aBookmarks.size())),"Invalid Index for vector");
874 CompareEnum eNum;
875 m_pRecordSet->CompareBookmarks(m_aBookmarks[nPos1],m_aBookmarks[nPos2],&eNum);
876 return static_cast<sal_Int32>(eNum) - 1;
879 sal_Bool SAL_CALL OResultSet::hasOrderedBookmarks( )
881 ::osl::MutexGuard aGuard( m_aMutex );
882 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
885 WpADOProperties aProps;
886 m_pRecordSet->get_Properties(&aProps);
887 ADOS::ThrowException(static_cast<OConnection*>(m_pStmt->getConnection().get())->getConnection(),*this);
888 OSL_ENSURE(aProps.IsValid(),"There are no properties at the connection");
890 WpADOProperty aProp(aProps.GetItem(OUString("Bookmarks Ordered")));
891 OLEVariant aVar;
892 if(aProp.IsValid())
893 aVar = aProp.GetValue();
894 else
895 ADOS::ThrowException(static_cast<OConnection*>(m_pStmt->getConnection().get())->getConnection(),*this);
897 bool bValue(false);
898 if(!aVar.isNull() && !aVar.isEmpty())
899 bValue = aVar.getBool();
900 return bValue;
903 sal_Int32 SAL_CALL OResultSet::hashBookmark( const Any& bookmark )
905 ::osl::MutexGuard aGuard( m_aMutex );
906 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
909 sal_Int32 nPos = 0;
910 bookmark >>= nPos;
911 return nPos;
914 // XDeleteRows
915 Sequence< sal_Int32 > SAL_CALL OResultSet::deleteRows( const Sequence< Any >& rows )
917 ::osl::MutexGuard aGuard( m_aMutex );
918 checkDisposed(OResultSet_BASE::rBHelper.bDisposed);
921 OLEVariant aVar;
922 sal_Int32 nPos = 0;
924 // Create SafeArray Bounds and initialize the array
925 SAFEARRAYBOUND rgsabound[1];
926 rgsabound[0].lLbound = 0;
927 rgsabound[0].cElements = rows.getLength();
928 SAFEARRAY *psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound );
930 const Any* pBegin = rows.getConstArray();
931 const Any* pEnd = pBegin + rows.getLength();
932 for(sal_Int32 i=0;pBegin != pEnd ;++pBegin,++i)
934 *pBegin >>= nPos;
935 SafeArrayPutElement(psa,&i,&m_aBookmarks[nPos]);
938 // Initialize and fill the SafeArray
939 OLEVariant vsa;
940 vsa.setArray(psa,VT_VARIANT);
942 m_pRecordSet->put_Filter(vsa);
943 m_pRecordSet->Delete(adAffectGroup);
944 m_pRecordSet->UpdateBatch(adAffectGroup);
946 Sequence< sal_Int32 > aSeq(rows.getLength());
947 if(first())
949 sal_Int32* pSeq = aSeq.getArray();
950 sal_Int32 i=0;
953 OSL_ENSURE(i<aSeq.getLength(),"Index greater than length of sequence");
954 m_pRecordSet->get_Status(&pSeq[i]);
955 if(pSeq[i++] == adRecDeleted)
956 --m_nRowPos;
958 while(next());
960 return aSeq;
963 sal_Int32 OResultSet::getResultSetConcurrency() const
965 sal_Int32 nValue=ResultSetConcurrency::READ_ONLY;
966 LockTypeEnum eRet;
967 if(!SUCCEEDED(m_pRecordSet->get_LockType(&eRet)))
969 switch(eRet)
971 case adLockReadOnly:
972 nValue = ResultSetConcurrency::READ_ONLY;
973 break;
974 default:
975 nValue = ResultSetConcurrency::UPDATABLE;
976 break;
979 return nValue;
982 sal_Int32 OResultSet::getResultSetType() const
984 sal_Int32 nValue=0;
985 CursorTypeEnum eRet;
986 if(!SUCCEEDED(m_pRecordSet->get_CursorType(&eRet)))
988 switch(eRet)
990 case adOpenUnspecified:
991 case adOpenForwardOnly:
992 nValue = ResultSetType::FORWARD_ONLY;
993 break;
994 case adOpenStatic:
995 case adOpenKeyset:
996 nValue = ResultSetType::SCROLL_INSENSITIVE;
997 break;
998 case adOpenDynamic:
999 nValue = ResultSetType::SCROLL_SENSITIVE;
1000 break;
1003 return nValue;
1006 sal_Int32 OResultSet::getFetchDirection()
1008 return FetchDirection::FORWARD;
1011 sal_Int32 OResultSet::getFetchSize() const
1013 sal_Int32 nValue=-1;
1014 m_pRecordSet->get_CacheSize(&nValue);
1015 return nValue;
1018 OUString OResultSet::getCursorName()
1020 return OUString();
1024 void OResultSet::setFetchDirection(sal_Int32 /*_par0*/)
1026 ::dbtools::throwFeatureNotImplementedSQLException( "ResultSet::FetchDirection", *this );
1029 void OResultSet::setFetchSize(sal_Int32 _par0)
1031 m_pRecordSet->put_CacheSize(_par0);
1034 ::cppu::IPropertyArrayHelper* OResultSet::createArrayHelper( ) const
1036 return new ::cppu::OPropertyArrayHelper
1040 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHDIRECTION),
1041 PROPERTY_ID_FETCHDIRECTION, cppu::UnoType<sal_Int32>::get(), 0
1044 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FETCHSIZE),
1045 PROPERTY_ID_FETCHSIZE, cppu::UnoType<sal_Int32>::get(), 0
1048 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISBOOKMARKABLE),
1049 PROPERTY_ID_ISBOOKMARKABLE, cppu::UnoType<bool>::get(), PropertyAttribute::READONLY
1052 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETCONCURRENCY),
1053 PROPERTY_ID_RESULTSETCONCURRENCY, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY
1056 ::connectivity::OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_RESULTSETTYPE),
1057 PROPERTY_ID_RESULTSETTYPE, cppu::UnoType<sal_Int32>::get(), PropertyAttribute::READONLY
1063 ::cppu::IPropertyArrayHelper & OResultSet::getInfoHelper()
1065 return *getArrayHelper();
1068 sal_Bool OResultSet::convertFastPropertyValue(
1069 Any & rConvertedValue,
1070 Any & rOldValue,
1071 sal_Int32 nHandle,
1072 const Any& rValue )
1074 switch(nHandle)
1076 case PROPERTY_ID_ISBOOKMARKABLE:
1077 case PROPERTY_ID_CURSORNAME:
1078 case PROPERTY_ID_RESULTSETCONCURRENCY:
1079 case PROPERTY_ID_RESULTSETTYPE:
1080 throw css::lang::IllegalArgumentException();
1081 break;
1082 case PROPERTY_ID_FETCHDIRECTION:
1083 return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchDirection());
1084 case PROPERTY_ID_FETCHSIZE:
1085 return ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, getFetchSize());
1086 default:
1089 return false;
1092 void OResultSet::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)
1094 switch(nHandle)
1096 case PROPERTY_ID_ISBOOKMARKABLE:
1097 case PROPERTY_ID_CURSORNAME:
1098 case PROPERTY_ID_RESULTSETCONCURRENCY:
1099 case PROPERTY_ID_RESULTSETTYPE:
1100 throw Exception("cannot set prop " + OUString::number(nHandle), nullptr);
1101 break;
1102 case PROPERTY_ID_FETCHDIRECTION:
1103 setFetchDirection(getINT32(rValue));
1104 break;
1105 case PROPERTY_ID_FETCHSIZE:
1106 setFetchSize(getINT32(rValue));
1107 break;
1108 default:
1113 void OResultSet::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
1115 switch(nHandle)
1117 case PROPERTY_ID_ISBOOKMARKABLE:
1119 VARIANT_BOOL bBool;
1120 m_pRecordSet->Supports(adBookmark,&bBool);
1121 rValue <<= (bBool == VARIANT_TRUE);
1123 break;
1124 case PROPERTY_ID_CURSORNAME:
1125 rValue <<= getCursorName();
1126 break;
1127 case PROPERTY_ID_RESULTSETCONCURRENCY:
1128 rValue <<= getResultSetConcurrency();
1129 break;
1130 case PROPERTY_ID_RESULTSETTYPE:
1131 rValue <<= getResultSetType();
1132 break;
1133 case PROPERTY_ID_FETCHDIRECTION:
1134 rValue <<= getFetchDirection();
1135 break;
1136 case PROPERTY_ID_FETCHSIZE:
1137 rValue <<= getFetchSize();
1138 break;
1142 void SAL_CALL OResultSet::acquire() noexcept
1144 OResultSet_BASE::acquire();
1147 void SAL_CALL OResultSet::release() noexcept
1149 OResultSet_BASE::release();
1152 css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL OResultSet::getPropertySetInfo( )
1154 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */