1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "RowSetBase.hxx"
21 #include "CRowSetDataColumn.hxx"
22 #include <connectivity/sdbcx/VCollection.hxx>
23 #include "RowSetCache.hxx"
24 #include "dbastrings.hrc"
25 #include "core_resource.hrc"
26 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include <com/sun/star/sdbcx/CompareBookmark.hpp>
29 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
30 #include <com/sun/star/lang/Locale.hpp>
31 #include <com/sun/star/util/NumberFormat.hpp>
32 #include <comphelper/sequence.hxx>
33 #include <comphelper/seqstream.hxx>
34 #include <connectivity/dbexception.hxx>
35 #include <tools/debug.hxx>
37 using namespace dbaccess
;
38 using namespace connectivity
;
39 using namespace connectivity::sdbcx
;
40 using namespace comphelper
;
41 using namespace dbtools
;
42 using namespace ::com::sun::star::uno
;
43 using namespace ::com::sun::star::beans
;
44 using namespace ::com::sun::star::sdbc
;
45 using namespace ::com::sun::star::sdb
;
46 using namespace ::com::sun::star::sdbcx
;
47 using namespace ::com::sun::star::container
;
48 using namespace ::com::sun::star::lang
;
49 using namespace ::com::sun::star::util
;
50 using namespace ::cppu
;
51 using namespace ::osl
;
57 class OEmptyCollection
: public sdbcx::OCollection
60 virtual void impl_refresh() throw(RuntimeException
) SAL_OVERRIDE
;
61 virtual connectivity::sdbcx::ObjectType
createObject(const OUString
& _rName
) SAL_OVERRIDE
;
63 OEmptyCollection(::cppu::OWeakObject
& _rParent
,::osl::Mutex
& _rMutex
) : OCollection(_rParent
, true, _rMutex
, ::std::vector
< OUString
>()){}
66 void OEmptyCollection::impl_refresh() throw(RuntimeException
)
70 connectivity::sdbcx::ObjectType
OEmptyCollection::createObject(const OUString
& /*_rName*/)
72 return connectivity::sdbcx::ObjectType();
77 ORowSetBase::ORowSetBase( const Reference
<XComponentContext
>& _rContext
, ::cppu::OBroadcastHelper
& _rBHelper
, ::osl::Mutex
* _pMutex
)
78 :OPropertyStateContainer(_rBHelper
)
83 ,m_rBHelper(_rBHelper
)
84 ,m_pEmptyCollection( NULL
)
85 ,m_aContext( _rContext
)
86 ,m_aErrors( _rContext
)
87 ,m_nLastColumnIndex(-1)
88 ,m_nDeletedPosition(-1)
89 ,m_nResultSetType( ResultSetType::FORWARD_ONLY
)
90 ,m_nResultSetConcurrency( ResultSetConcurrency::READ_ONLY
)
92 ,m_bIgnoreResult(false)
93 ,m_bBeforeFirst(true) // changed from sal_False
95 ,m_bIsInsertRow(false)
97 sal_Int32 nRBT
= PropertyAttribute::READONLY
| PropertyAttribute::BOUND
| PropertyAttribute::TRANSIENT
;
99 sal_Int32 nInitialRowCountValue
= 0;
100 sal_Bool
bInitialRowCountFinalValue( sal_False
);
101 registerPropertyNoMember( PROPERTY_ROWCOUNT
, PROPERTY_ID_ROWCOUNT
, nRBT
, cppu::UnoType
<decltype(nInitialRowCountValue
)>::get(), &nInitialRowCountValue
);
102 registerPropertyNoMember( PROPERTY_ISROWCOUNTFINAL
, PROPERTY_ID_ISROWCOUNTFINAL
, nRBT
, cppu::UnoType
<bool>::get(), &bInitialRowCountFinalValue
);
105 ORowSetBase::~ORowSetBase()
109 TDataColumns().swap(m_aDataColumns
);
110 m_pColumns
->acquire();
111 m_pColumns
->disposing();
116 if ( m_pEmptyCollection
)
117 delete m_pEmptyCollection
;
121 // com::sun::star::lang::XTypeProvider
122 Sequence
< Type
> ORowSetBase::getTypes() throw (RuntimeException
, std::exception
)
124 return ::comphelper::concatSequences(ORowSetBase_BASE::getTypes(),OPropertyStateContainer::getTypes());
127 // com::sun::star::uno::XInterface
128 Any
ORowSetBase::queryInterface( const Type
& rType
) throw (RuntimeException
, std::exception
)
130 Any aRet
= ORowSetBase_BASE::queryInterface(rType
);
132 aRet
= OPropertyStateContainer::queryInterface(rType
);
136 void SAL_CALL
ORowSetBase::getFastPropertyValue(Any
& rValue
,sal_Int32 nHandle
) const
142 case PROPERTY_ID_ROWCOUNT
:
143 rValue
<<= impl_getRowCount();
145 case PROPERTY_ID_ISROWCOUNTFINAL
:
146 rValue
.setValue(&m_pCache
->m_bRowCountFinal
,cppu::UnoType
<bool>::get());
149 OPropertyStateContainer::getFastPropertyValue(rValue
,nHandle
);
153 OPropertyStateContainer::getFastPropertyValue(rValue
,nHandle
);
157 void SAL_CALL
ORowSetBase::disposing()
159 MutexGuard
aGuard(*m_pMutex
);
163 TDataColumns().swap(m_aDataColumns
);
164 m_pColumns
->disposing();
168 m_pCache
->deregisterOldRow(m_aOldRow
);
169 m_pCache
->deleteIterator(this);
174 // comphelper::OPropertyArrayUsageHelper
175 ::cppu::IPropertyArrayHelper
* ORowSetBase::createArrayHelper( ) const
177 Sequence
< Property
> aProps
;
178 describeProperties(aProps
);
179 return new ::cppu::OPropertyArrayHelper(aProps
);
182 // cppu::OPropertySetHelper
183 ::cppu::IPropertyArrayHelper
& SAL_CALL
ORowSetBase::getInfoHelper()
185 return *getArrayHelper();
189 sal_Bool SAL_CALL
ORowSetBase::wasNull( ) throw(SQLException
, RuntimeException
, std::exception
)
191 ::osl::MutexGuard
aGuard( *m_pMutex
);
193 return impl_wasNull();
196 bool ORowSetBase::impl_wasNull()
198 return !((m_nLastColumnIndex
!= -1) && !m_aCurrentRow
.isNull() && m_aCurrentRow
!= m_pCache
->getEnd() && m_aCurrentRow
->is()) || ((*m_aCurrentRow
)->get())[m_nLastColumnIndex
].isNull();
201 const ORowSetValue
& ORowSetBase::getValue(sal_Int32 columnIndex
)
204 return impl_getValue(columnIndex
);
207 const ORowSetValue
& ORowSetBase::impl_getValue(sal_Int32 columnIndex
)
209 if ( m_bBeforeFirst
|| m_bAfterLast
)
211 SAL_WARN("dbaccess", "ORowSetBase::getValue: Illegal call here (we're before first or after last)!");
212 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER
), SQL_INVALID_CURSOR_POSITION
, *m_pMySelf
);
215 if ( impl_rowDeleted() )
217 return m_aEmptyValue
;
220 bool bValidCurrentRow
= ( !m_aCurrentRow
.isNull() && m_aCurrentRow
!= m_pCache
->getEnd() && m_aCurrentRow
->is() );
221 if ( !bValidCurrentRow
)
223 // currentrow is null when the clone moves the window
224 positionCache( MOVE_NONE
);
225 m_aCurrentRow
= m_pCache
->m_aMatrixIter
;
226 m_bIsInsertRow
= false;
227 OSL_ENSURE(!m_aCurrentRow
.isNull(),"ORowSetBase::getValue: we don't stand on a valid row! Row is null.");
229 bValidCurrentRow
= ( !m_aCurrentRow
.isNull() && m_aCurrentRow
!= m_pCache
->getEnd() && m_aCurrentRow
->is() );
232 if ( bValidCurrentRow
)
234 #if OSL_DEBUG_LEVEL > 0
235 ORowSetMatrix::iterator aCacheEnd
;
236 ORowSetMatrix::iterator aCurrentRow
;
237 aCacheEnd
= m_pCache
->getEnd();
238 aCurrentRow
= m_aCurrentRow
;
239 ORowSetCacheMap::iterator aCacheIter
= m_aCurrentRow
.getIter();
240 ORowSetCacheIterator_Helper aHelper
= aCacheIter
->second
;
241 ORowSetMatrix::iterator k
= aHelper
.aIterator
;
242 for (; k
!= m_pCache
->getEnd(); ++k
)
244 ORowSetValueVector
* pTemp
= k
->get();
245 OSL_ENSURE( pTemp
!= reinterpret_cast<void*>(0xfeeefeee),"HALT!" );
248 OSL_ENSURE(!m_aCurrentRow
.isNull() && m_aCurrentRow
< m_pCache
->getEnd() && aCacheIter
!= m_pCache
->m_aCacheIterators
.end(),"Invalid iterator set for currentrow!");
249 #if OSL_DEBUG_LEVEL > 0
250 ORowSetRow rRow
= (*m_aCurrentRow
);
251 OSL_ENSURE(rRow
.is() && static_cast<sal_uInt16
>(columnIndex
) < (rRow
->get()).size(),"Invalid size of vector!");
253 return ((*m_aCurrentRow
)->get())[m_nLastColumnIndex
= columnIndex
];
256 // we should normally never reach this
257 return m_aEmptyValue
;
260 OUString SAL_CALL
ORowSetBase::getString( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
262 ::osl::MutexGuard
aGuard( *m_pMutex
);
263 return getValue(columnIndex
);
266 sal_Bool SAL_CALL
ORowSetBase::getBoolean( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
268 ::osl::MutexGuard
aGuard( *m_pMutex
);
269 return getValue(columnIndex
);
272 sal_Int8 SAL_CALL
ORowSetBase::getByte( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
274 ::osl::MutexGuard
aGuard( *m_pMutex
);
275 return getValue(columnIndex
);
278 sal_Int16 SAL_CALL
ORowSetBase::getShort( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
280 ::osl::MutexGuard
aGuard( *m_pMutex
);
281 return getValue(columnIndex
);
284 sal_Int32 SAL_CALL
ORowSetBase::getInt( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
286 ::osl::MutexGuard
aGuard( *m_pMutex
);
287 return getValue(columnIndex
);
290 sal_Int64 SAL_CALL
ORowSetBase::getLong( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
292 ::osl::MutexGuard
aGuard( *m_pMutex
);
293 return getValue(columnIndex
);
296 float SAL_CALL
ORowSetBase::getFloat( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
298 ::osl::MutexGuard
aGuard( *m_pMutex
);
299 return getValue(columnIndex
);
302 double SAL_CALL
ORowSetBase::getDouble( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
304 ::osl::MutexGuard
aGuard( *m_pMutex
);
305 return getValue(columnIndex
);
308 Sequence
< sal_Int8
> SAL_CALL
ORowSetBase::getBytes( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
310 ::osl::MutexGuard
aGuard( *m_pMutex
);
311 return getValue(columnIndex
);
314 ::com::sun::star::util::Date SAL_CALL
ORowSetBase::getDate( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
316 ::osl::MutexGuard
aGuard( *m_pMutex
);
317 return getValue(columnIndex
);
320 ::com::sun::star::util::Time SAL_CALL
ORowSetBase::getTime( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
322 ::osl::MutexGuard
aGuard( *m_pMutex
);
323 return getValue(columnIndex
);
326 ::com::sun::star::util::DateTime SAL_CALL
ORowSetBase::getTimestamp( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
328 ::osl::MutexGuard
aGuard( *m_pMutex
);
329 return getValue(columnIndex
);
332 Reference
< ::com::sun::star::io::XInputStream
> SAL_CALL
ORowSetBase::getBinaryStream( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
334 ::osl::MutexGuard
aGuard( *m_pMutex
);
337 if ( m_bBeforeFirst
|| m_bAfterLast
)
339 SAL_WARN("dbaccess", "ORowSetBase::getBinaryStream: Illegal call here (we're before first or after last)!");
340 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER
), SQL_INVALID_CURSOR_POSITION
, *m_pMySelf
);
343 if ( impl_rowDeleted() )
348 bool bValidCurrentRow
= ( !m_aCurrentRow
.isNull() && m_aCurrentRow
!= m_pCache
->getEnd() && m_aCurrentRow
->is() );
349 if ( !bValidCurrentRow
)
351 positionCache( MOVE_NONE
);
352 m_aCurrentRow
= m_pCache
->m_aMatrixIter
;
353 m_bIsInsertRow
= false;
354 OSL_ENSURE(!m_aCurrentRow
.isNull(),"ORowSetBase::getBinaryStream: we don't stand on a valid row! Row is null.");
356 bValidCurrentRow
= ( !m_aCurrentRow
.isNull() && m_aCurrentRow
!= m_pCache
->getEnd() && m_aCurrentRow
->is() );
359 if ( bValidCurrentRow
)
360 return new ::comphelper::SequenceInputStream(((*m_aCurrentRow
)->get())[m_nLastColumnIndex
= columnIndex
].getSequence());
362 // we should normally never reach this
363 return Reference
< ::com::sun::star::io::XInputStream
>();
366 Reference
< ::com::sun::star::io::XInputStream
> SAL_CALL
ORowSetBase::getCharacterStream( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
368 return getBinaryStream(columnIndex
);
371 Any SAL_CALL
ORowSetBase::getObject( sal_Int32 columnIndex
, const Reference
< XNameAccess
>& /*typeMap*/ ) throw(SQLException
, RuntimeException
, std::exception
)
373 ::osl::MutexGuard
aGuard( *m_pMutex
);
376 return getValue(columnIndex
).makeAny();
379 Reference
< XRef
> SAL_CALL
ORowSetBase::getRef( sal_Int32
/*columnIndex*/ ) throw(SQLException
, RuntimeException
, std::exception
)
381 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getRef", *m_pMySelf
);
385 Reference
< XBlob
> SAL_CALL
ORowSetBase::getBlob( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
387 return Reference
< XBlob
>(getValue(columnIndex
).makeAny(),UNO_QUERY
);
390 Reference
< XClob
> SAL_CALL
ORowSetBase::getClob( sal_Int32 columnIndex
) throw(SQLException
, RuntimeException
, std::exception
)
392 return Reference
< XClob
>(getValue(columnIndex
).makeAny(),UNO_QUERY
);
395 Reference
< XArray
> SAL_CALL
ORowSetBase::getArray( sal_Int32
/*columnIndex*/ ) throw(SQLException
, RuntimeException
, std::exception
)
397 ::dbtools::throwFeatureNotImplementedSQLException( "XRow::getArray", *m_pMySelf
);
401 // ::com::sun::star::sdbcx::XRowLocate
402 Any SAL_CALL
ORowSetBase::getBookmark( ) throw(SQLException
, RuntimeException
, std::exception
)
404 SAL_INFO("dbaccess", "ORowSetBase::getBookmark() Clone = " << m_bClone
);
405 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
406 ::osl::MutexGuard
aGuard( *m_pMutex
);
409 if ( m_bBeforeFirst
|| m_bAfterLast
)
410 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_BEFORE_OR_AFTER
), SQL_INVALID_CURSOR_POSITION
, *m_pMySelf
);
412 if ( impl_rowDeleted() )
413 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_DELETED
), SQL_INVALID_CURSOR_POSITION
, *m_pMySelf
);
415 OSL_ENSURE( m_aBookmark
.hasValue(), "ORowSetBase::getBookmark: bookmark has no value!" );
419 sal_Bool SAL_CALL
ORowSetBase::moveToBookmark( const Any
& bookmark
) throw(SQLException
, RuntimeException
, std::exception
)
421 SAL_INFO("dbaccess", "ORowSetBase::moveToBookmark(Any) Clone = " << m_bClone
);
422 OSL_ENSURE(bookmark
.hasValue(),"ORowSetBase::moveToBookmark bookmark has no value!");
423 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
425 if(!bookmark
.hasValue() || m_nResultSetType
== ResultSetType::FORWARD_ONLY
)
427 if(bookmark
.hasValue())
428 SAL_WARN("dbaccess", "MoveToBookmark is not possible when we are only forward");
430 SAL_WARN("dbaccess", "Bookmark is not valid");
431 throwFunctionSequenceException(*m_pMySelf
);
436 bool bRet( notifyAllListenersCursorBeforeMove( aGuard
) );
439 // check if we are inserting a row
440 bool bWasNew
= m_pCache
->m_bNew
|| impl_rowDeleted();
442 ORowSetNotifier
aNotifier( this );
443 // this will call cancelRowModification on the cache if necessary
445 ORowSetRow aOldValues
= getOldRow(bWasNew
);
447 bRet
= m_pCache
->moveToBookmark(bookmark
);
448 doCancelModification( );
451 // notification order
454 setCurrentRow( true, true, aOldValues
, aGuard
);
465 SAL_INFO("dbaccess", "ORowSetBase::moveToBookmark(Any) = " << bRet
<< " Clone = " << m_bClone
);
469 sal_Bool SAL_CALL
ORowSetBase::moveRelativeToBookmark( const Any
& bookmark
, sal_Int32 rows
) throw(SQLException
, RuntimeException
, std::exception
)
471 SAL_INFO("dbaccess", "ORowSetBase::moveRelativeToBookmark(Any," << rows
<< ") Clone = " << m_bClone
);
472 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
474 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
476 checkPositioningAllowed();
478 bool bRet( notifyAllListenersCursorBeforeMove( aGuard
) );
481 // check if we are inserting a row
482 bool bWasNew
= m_pCache
->m_bNew
|| rowDeleted();
484 ORowSetNotifier
aNotifier( this );
485 // this will call cancelRowModification on the cache if necessary
487 ORowSetRow aOldValues
= getOldRow(bWasNew
);
489 bRet
= m_pCache
->moveRelativeToBookmark(bookmark
,rows
);
490 doCancelModification( );
493 // notification order
496 setCurrentRow( true, true, aOldValues
, aGuard
);
505 // RowCount/IsRowCountFinal
508 SAL_INFO("dbaccess", "ORowSetBase::moveRelativeToBookmark(Any," << rows
<< ") = " << bRet
<< " Clone = " << m_bClone
);
512 sal_Int32 SAL_CALL
ORowSetBase::compareBookmarks( const Any
& _first
, const Any
& _second
) throw(SQLException
, RuntimeException
, std::exception
)
514 ::osl::MutexGuard
aGuard( *m_pMutex
);
516 return m_pCache
->compareBookmarks(_first
,_second
);
519 sal_Bool SAL_CALL
ORowSetBase::hasOrderedBookmarks( ) throw(SQLException
, RuntimeException
, std::exception
)
521 ::osl::MutexGuard
aGuard( *m_pMutex
);
523 return m_pCache
->hasOrderedBookmarks();
526 sal_Int32 SAL_CALL
ORowSetBase::hashBookmark( const Any
& bookmark
) throw(SQLException
, RuntimeException
, std::exception
)
528 ::osl::MutexGuard
aGuard( *m_pMutex
);
530 return m_pCache
->hashBookmark(bookmark
);
533 // XResultSetMetaDataSupplier
534 Reference
< XResultSetMetaData
> SAL_CALL
ORowSetBase::getMetaData( ) throw(SQLException
, RuntimeException
, std::exception
)
536 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
538 Reference
< XResultSetMetaData
> xMeta
;
540 xMeta
= m_pCache
->getMetaData();
546 sal_Int32 SAL_CALL
ORowSetBase::findColumn( const OUString
& columnName
) throw(SQLException
, RuntimeException
, std::exception
)
548 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
550 ::osl::MutexGuard
aGuard( m_aColumnsMutex
);
551 // it is possible to save some time here when we remember the names - position relation in a map
552 return m_pColumns
? m_pColumns
->findColumn(columnName
) : sal_Int32(0);
555 // ::com::sun::star::sdbcx::XColumnsSupplier
556 Reference
< XNameAccess
> SAL_CALL
ORowSetBase::getColumns( ) throw(RuntimeException
, std::exception
)
558 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
560 ::osl::MutexGuard
aGuard( m_aColumnsMutex
);
563 if (!m_pEmptyCollection
)
564 m_pEmptyCollection
= new OEmptyCollection(*m_pMySelf
,m_aColumnsMutex
);
565 return m_pEmptyCollection
;
572 sal_Bool SAL_CALL
ORowSetBase::next( ) throw(SQLException
, RuntimeException
, std::exception
)
574 SAL_INFO("dbaccess", "ORowSetBase::next() Clone = " << m_bClone
);
575 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
578 bool bRet( notifyAllListenersCursorBeforeMove( aGuard
) );
581 // check if we are inserting a row
582 bool bWasNew
= m_pCache
->m_bNew
|| impl_rowDeleted();
584 ORowSetNotifier
aNotifier( this );
585 // this will call cancelRowModification on the cache if necessary
587 ORowSetRow aOldValues
= getOldRow(bWasNew
);
589 positionCache( MOVE_FORWARD
);
590 bool bAfterLast
= m_pCache
->isAfterLast();
591 bRet
= m_pCache
->next();
592 doCancelModification( );
594 // if we were afterLast before next() then we still are,
595 // i.e. bAfterLast implies m_pCache->isAfterLast()
597 assert(m_pCache
->isAfterLast());
598 // so the only way bAfterLast != m_pCache->isAfterLast()
599 // would be that we just arrived there,
600 if (bAfterLast
!= m_pCache
->isAfterLast())
603 assert(m_pCache
->isAfterLast());
605 // in which case we *did* move the cursor
606 if ( bRet
|| bAfterLast
!= m_pCache
->isAfterLast() )
608 // notification order
611 setCurrentRow( true, true, aOldValues
, aGuard
);
612 OSL_ENSURE(!m_bBeforeFirst
,"BeforeFirst is true. I don't know why?");
616 // moved after the last row
618 OSL_ENSURE(m_bAfterLast
,"AfterLast is false. I don't know why?");
625 // - RowCount/IsRowCountFinal
628 SAL_INFO("dbaccess", "ORowSetBase::next() = " << bRet
<< " Clone = " << m_bClone
);
632 sal_Bool SAL_CALL
ORowSetBase::isBeforeFirst( ) throw(SQLException
, RuntimeException
, std::exception
)
634 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
635 ::osl::MutexGuard
aGuard( *m_pMutex
);
638 SAL_INFO("dbaccess", "ORowSetBase::isBeforeFirst() = " << m_bBeforeFirst
<< " Clone = " << m_bClone
);
640 return m_bBeforeFirst
;
643 sal_Bool SAL_CALL
ORowSetBase::isAfterLast( ) throw(SQLException
, RuntimeException
, std::exception
)
645 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
646 ::osl::MutexGuard
aGuard( *m_pMutex
);
648 SAL_INFO("dbaccess", "ORowSetBase::isAfterLast() = " << m_bAfterLast
<< " Clone = " << m_bClone
);
653 bool ORowSetBase::isOnFirst()
658 sal_Bool SAL_CALL
ORowSetBase::isFirst( ) throw(SQLException
, RuntimeException
, std::exception
)
660 SAL_INFO("dbaccess", "ORowSetBase::isFirst() Clone = " << m_bClone
);
662 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
663 ::osl::MutexGuard
aGuard( *m_pMutex
);
666 if ( m_bBeforeFirst
|| m_bAfterLast
)
669 if ( impl_rowDeleted() )
670 return ( m_nDeletedPosition
== 1 );
672 positionCache( MOVE_NONE
);
673 bool bIsFirst
= m_pCache
->isFirst();
675 SAL_INFO("dbaccess", "ORowSetBase::isFirst() = " << bIsFirst
<< " Clone = " << m_bClone
);
679 bool ORowSetBase::isOnLast()
684 sal_Bool SAL_CALL
ORowSetBase::isLast( ) throw(SQLException
, RuntimeException
, std::exception
)
686 SAL_INFO("dbaccess", "ORowSetBase::isLast() Clone = " << m_bClone
);
687 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
688 ::osl::MutexGuard
aGuard( *m_pMutex
);
691 if ( m_bBeforeFirst
|| m_bAfterLast
)
694 if ( impl_rowDeleted() )
696 if ( !m_pCache
->m_bRowCountFinal
)
699 return ( m_nDeletedPosition
== impl_getRowCount() );
702 positionCache( MOVE_NONE
);
703 bool bIsLast
= m_pCache
->isLast();
705 SAL_INFO("dbaccess", "ORowSetBase::isLast() = " << bIsLast
<< " Clone = " << m_bClone
);
709 void SAL_CALL
ORowSetBase::beforeFirst( ) throw(SQLException
, RuntimeException
, std::exception
)
711 SAL_INFO("dbaccess", "ORowSetBase::beforeFirst() Clone = " << m_bClone
);
712 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
713 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
715 checkPositioningAllowed();
717 // check if we are inserting a row
718 bool bWasNew
= m_pCache
->m_bNew
|| impl_rowDeleted();
720 if((bWasNew
|| !m_bBeforeFirst
) && notifyAllListenersCursorBeforeMove(aGuard
) )
722 ORowSetNotifier
aNotifier( this );
723 // this will call cancelRowModification on the cache if necessary
725 if ( !m_bBeforeFirst
)
727 ORowSetRow aOldValues
= getOldRow(bWasNew
);
728 m_pCache
->beforeFirst();
729 doCancelModification( );
731 // notification order
734 setCurrentRow( true, true, aOldValues
, aGuard
);
740 // - RowCount/IsRowCountFinal
744 // to be done _after_ the notifications!
745 m_aOldRow
->clearRow();
747 SAL_INFO("dbaccess", "ORowSetBase::beforeFirst() Clone = " << m_bClone
);
750 void SAL_CALL
ORowSetBase::afterLast( ) throw(SQLException
, RuntimeException
, std::exception
)
752 SAL_INFO("dbaccess", "ORowSetBase::afterLast() Clone = " << m_bClone
);
753 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
755 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
756 checkPositioningAllowed();
758 bool bWasNew
= m_pCache
->m_bNew
|| impl_rowDeleted();
760 if((bWasNew
|| !m_bAfterLast
) && notifyAllListenersCursorBeforeMove(aGuard
) )
762 // check if we are inserting a row
763 ORowSetNotifier
aNotifier( this );
764 // this will call cancelRowModification on the cache if necessary
768 ORowSetRow aOldValues
= getOldRow(bWasNew
);
770 m_pCache
->afterLast();
771 doCancelModification( );
773 // notification order
776 setCurrentRow( true, true, aOldValues
, aGuard
);
782 // - RowCount/IsRowCountFinal
786 SAL_INFO("dbaccess", "ORowSetBase::afterLast() Clone = " << m_bClone
);
789 bool SAL_CALL
ORowSetBase::move( ::std::mem_fun_t
<bool,ORowSetBase
>& _aCheckFunctor
,
790 ::std::mem_fun_t
<bool,ORowSetCache
>& _aMovementFunctor
)
792 SAL_INFO("dbaccess", "ORowSetBase::move() Clone = " << m_bClone
);
793 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
794 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
795 checkPositioningAllowed();
797 bool bRet( notifyAllListenersCursorBeforeMove( aGuard
) );
800 // check if we are inserting a row
801 bool bWasNew
= m_pCache
->m_bNew
|| rowDeleted();
803 ORowSetNotifier
aNotifier( this );
804 // this will call cancelRowModification on the cache if necessary
806 ORowSetRow aOldValues
= getOldRow(bWasNew
);
808 bool bMoved
= ( bWasNew
|| !_aCheckFunctor(this) );
810 bRet
= _aMovementFunctor(m_pCache
);
811 doCancelModification( );
815 // notification order
818 setCurrentRow( bMoved
, true, aOldValues
, aGuard
);
821 { // first goes wrong so there is no row
829 // - RowCount/IsRowCountFinal
832 SAL_INFO("dbaccess", "ORowSetBase::move() = " << bRet
<< " Clone = " << m_bClone
);
836 sal_Bool SAL_CALL
ORowSetBase::first( ) throw(SQLException
, RuntimeException
, std::exception
)
838 SAL_INFO("dbaccess", "ORowSetBase::first() Clone = " << m_bClone
);
839 ::std::mem_fun_t
<bool,ORowSetBase
> ioF_tmp(&ORowSetBase::isOnFirst
);
840 ::std::mem_fun_t
<bool,ORowSetCache
> F_tmp(&ORowSetCache::first
);
841 return move(ioF_tmp
,F_tmp
);
844 sal_Bool SAL_CALL
ORowSetBase::last( ) throw(SQLException
, RuntimeException
, std::exception
)
846 SAL_INFO("dbaccess", "ORowSetBase::last() Clone = " << m_bClone
);
847 ::std::mem_fun_t
<bool,ORowSetBase
> ioL_tmp(&ORowSetBase::isOnLast
);
848 ::std::mem_fun_t
<bool,ORowSetCache
> L_tmp(&ORowSetCache::last
);
849 return move(ioL_tmp
,L_tmp
);
852 sal_Int32 SAL_CALL
ORowSetBase::getRow( ) throw(SQLException
, RuntimeException
, std::exception
)
854 SAL_INFO("dbaccess", "ORowSetBase::getRow() Clone = " << m_bClone
);
855 ::osl::MutexGuard
aGuard( *m_pMutex
);
858 return impl_getRow();
861 sal_Int32
ORowSetBase::impl_getRow()
864 if ( m_bBeforeFirst
)
866 else if ( m_bAfterLast
)
867 nPos
= impl_getRowCount() + 1;
868 else if ( impl_rowDeleted() )
869 nPos
= m_nDeletedPosition
;
870 else if ( !m_bClone
&& m_pCache
->m_bNew
)
874 positionCache( MOVE_NONE
);
875 nPos
= m_pCache
->getRow();
877 SAL_INFO("dbaccess", "ORowSetBase::impl_getRow() = " << nPos
<< " Clone = " << m_bClone
);
881 sal_Bool SAL_CALL
ORowSetBase::absolute( sal_Int32 row
) throw(SQLException
, RuntimeException
, std::exception
)
883 SAL_INFO("dbaccess", "ORowSetBase::absolute(" << row
<< ") Clone = " << m_bClone
);
884 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
885 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
886 checkPositioningAllowed();
888 bool bRet
= ( row
> 0 )
889 && notifyAllListenersCursorBeforeMove( aGuard
);
892 // check if we are inserting a row
893 bool bWasNew
= m_pCache
->m_bNew
|| rowDeleted();
895 ORowSetNotifier
aNotifier( this );
896 // this will call cancelRowModification on the cache if necessary
898 ORowSetRow aOldValues
= getOldRow(bWasNew
);
900 bRet
= m_pCache
->absolute(row
);
901 doCancelModification( );
905 // notification order
908 setCurrentRow( true, true, aOldValues
, aGuard
);
911 { // absolute movement goes wrong we stand left or right side of the rows
919 // - RowCount/IsRowCountFinal
922 SAL_INFO("dbaccess", "ORowSetBase::absolute(" << row
<< ") = " << bRet
<< " Clone = " << m_bClone
);
926 sal_Bool SAL_CALL
ORowSetBase::relative( sal_Int32 rows
) throw(SQLException
, RuntimeException
, std::exception
)
928 SAL_INFO("dbaccess", "ORowSetBase::relative(" << rows
<< ") Clone = " << m_bClone
);
929 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
931 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
934 return sal_True
; // in this case do nothing
936 checkPositioningAllowed();
939 ( ( !m_bAfterLast
|| rows
<= 0 )
940 && ( !m_bBeforeFirst
|| rows
>= 0 )
941 && notifyAllListenersCursorBeforeMove( aGuard
)
946 // check if we are inserting a row
947 bool bWasNew
= m_pCache
->m_bNew
|| rowDeleted();
949 ORowSetNotifier
aNotifier( this );
950 // this will call cancelRowModification on the cache if necessary
952 ORowSetRow aOldValues
= getOldRow(bWasNew
);
954 positionCache( rows
> 0 ? MOVE_FORWARD
: MOVE_BACKWARD
);
955 bRet
= m_pCache
->relative(rows
);
956 doCancelModification( );
960 // notification order
963 setCurrentRow( true, true, aOldValues
, aGuard
);
974 // - RowCount/IsRowCountFinal
977 SAL_INFO("dbaccess", "ORowSetBase::relative(" << rows
<< ") = " << bRet
<< " Clone = " << m_bClone
);
981 sal_Bool SAL_CALL
ORowSetBase::previous( ) throw(SQLException
, RuntimeException
, std::exception
)
983 SAL_INFO("dbaccess", "ORowSetBase::previous() Clone = " << m_bClone
);
984 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
985 ::osl::ResettableMutexGuard
aGuard( *m_pMutex
);
987 checkPositioningAllowed();
989 bool bRet
= !m_bBeforeFirst
990 && notifyAllListenersCursorBeforeMove(aGuard
);
994 // check if we are inserting a row
995 bool bWasNew
= m_pCache
->m_bNew
|| rowDeleted();
997 ORowSetNotifier
aNotifier( this );
998 // this will call cancelRowModification on the cache if necessary
1000 ORowSetRow aOldValues
= getOldRow(bWasNew
);
1002 positionCache( MOVE_BACKWARD
);
1003 bRet
= m_pCache
->previous();
1004 doCancelModification( );
1006 // if m_bBeforeFirst is false and bRet is false than we stood on the first row
1007 if(!m_bBeforeFirst
|| bRet
)
1009 // notification order
1012 setCurrentRow( true, true, aOldValues
, aGuard
);
1016 SAL_WARN("dbaccess", "ORowSetBase::previous: inconsistency!" );
1017 // we should never reach this place, as we should not get into this whole branch if m_bBeforeFirst
1018 // was |true| from the beginning
1026 // - RowCount/IsRowCountFinal
1029 SAL_INFO("dbaccess", "ORowSetBase::previous() = " << bRet
<< " Clone = " << m_bClone
);
1033 void ORowSetBase::setCurrentRow( bool _bMoved
, bool _bDoNotify
, const ORowSetRow
& _rOldValues
, ::osl::ResettableMutexGuard
& _rGuard
)
1035 SAL_INFO("dbaccess", "ORowSetBase::setCurrentRow() Clone = " << m_bClone
);
1036 m_bBeforeFirst
= m_pCache
->isBeforeFirst();
1037 m_bAfterLast
= m_pCache
->isAfterLast();
1039 if(!(m_bBeforeFirst
|| m_bAfterLast
))
1041 m_aBookmark
= m_pCache
->getBookmark();
1042 OSL_ENSURE(m_aBookmark
.hasValue(),"Bookmark has no value!");
1043 m_aCurrentRow
= m_pCache
->m_aMatrixIter
;
1044 m_bIsInsertRow
= false;
1045 OSL_ENSURE(!m_aCurrentRow
.isNull(),"CurrentRow is null!");
1046 m_aCurrentRow
.setBookmark(m_aBookmark
);
1047 OSL_ENSURE(!m_aCurrentRow
.isNull() && m_aCurrentRow
!= m_pCache
->getEnd(),"Position of matrix iterator isn't valid!");
1048 OSL_ENSURE(m_aCurrentRow
->is(),"Currentrow isn't valid");
1049 OSL_ENSURE(m_aBookmark
.hasValue(),"Bookmark has no value!");
1051 m_aCurrentRow
= m_pCache
->m_aMatrixIter
;
1052 m_bIsInsertRow
= false;
1053 OSL_ENSURE(!m_aCurrentRow
.isNull(),"CurrentRow is nul after positionCache!");
1054 #if OSL_DEBUG_LEVEL > 0
1055 ORowSetRow rRow
= (*m_aCurrentRow
);
1056 OSL_ENSURE(rRow
.is() ,"Invalid size of vector!");
1059 // notification order
1062 firePropertyChange(_rOldValues
);
1067 m_aOldRow
->clearRow();
1068 m_aCurrentRow
= m_pCache
->getEnd();
1069 m_aBookmark
= Any();
1070 m_aCurrentRow
.setBookmark(m_aBookmark
);
1073 // TODO: can this be done before the notifications?
1074 if(!(m_bBeforeFirst
|| m_bAfterLast
) && !m_aCurrentRow
.isNull() && m_aCurrentRow
->is() && m_aCurrentRow
!= m_pCache
->getEnd())
1075 m_aOldRow
->setRow(new ORowSetValueVector( *(*m_aCurrentRow
) ));
1077 if ( _bMoved
&& _bDoNotify
)
1079 notifyAllListenersCursorMoved( _rGuard
);
1081 SAL_INFO("dbaccess", "ORowSetBase::setCurrentRow() Clone = " << m_bClone
);
1084 void ORowSetBase::checkPositioningAllowed() throw( SQLException
, RuntimeException
)
1086 if(!m_pCache
|| m_nResultSetType
== ResultSetType::FORWARD_ONLY
)
1087 throwFunctionSequenceException(*m_pMySelf
);
1090 Reference
< XInterface
> ORowSetBase::getStatement() throw( SQLException
, RuntimeException
, std::exception
)
1095 void SAL_CALL
ORowSetBase::refreshRow( ) throw(SQLException
, RuntimeException
, std::exception
)
1097 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
1098 ::osl::MutexGuard
aGuard( *m_pMutex
);
1100 if ( impl_rowDeleted() )
1101 throwSQLException( "The current row is deleted", SQL_INVALID_CURSOR_STATE
, Reference
< XRowSet
>( this ) );
1103 if(!(m_bBeforeFirst
|| m_bAfterLast
))
1105 bool bWasNew
= m_pCache
->m_bNew
|| impl_rowDeleted();
1106 ORowSetRow aOldValues
= getOldRow(bWasNew
);
1107 positionCache( MOVE_NONE
);
1108 m_pCache
->refreshRow();
1109 firePropertyChange(aOldValues
);
1113 sal_Bool SAL_CALL
ORowSetBase::rowUpdated( ) throw(SQLException
, RuntimeException
, std::exception
)
1115 ::osl::MutexGuard
aGuard( *m_pMutex
);
1118 if ( impl_rowDeleted() )
1121 return m_pCache
->rowUpdated();
1124 sal_Bool SAL_CALL
ORowSetBase::rowInserted( ) throw(SQLException
, RuntimeException
, std::exception
)
1126 ::osl::MutexGuard
aGuard( *m_pMutex
);
1130 if ( impl_rowDeleted() )
1133 return m_pCache
->rowInserted();
1136 sal_Bool SAL_CALL
ORowSetBase::rowDeleted( ) throw(SQLException
, RuntimeException
, std::exception
)
1138 ::osl::MutexGuard
aGuard( *m_pMutex
);
1140 return impl_rowDeleted();
1143 bool ORowSetBase::impl_rowDeleted( )
1145 return !m_aBookmark
.hasValue() && !m_bBeforeFirst
&& !m_bAfterLast
;
1148 // XWarningsSupplier
1149 Any SAL_CALL
ORowSetBase::getWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
1151 ::osl::MutexGuard
aGuard( *m_pMutex
);
1155 Reference
< XWarningsSupplier
> xWarnings( m_pCache
->m_xSet
.get(), UNO_QUERY
);
1156 if ( xWarnings
.is() )
1157 return xWarnings
->getWarnings();
1163 void SAL_CALL
ORowSetBase::clearWarnings( ) throw(SQLException
, RuntimeException
, std::exception
)
1165 ::osl::MutexGuard
aGuard( *m_pMutex
);
1169 Reference
< XWarningsSupplier
> xWarnings( m_pCache
->m_xSet
.get(), UNO_QUERY
);
1170 if ( xWarnings
.is() )
1171 xWarnings
->clearWarnings();
1175 void ORowSetBase::firePropertyChange(const ORowSetRow
& _rOldRow
)
1177 if (!isPropertyChangeNotificationEnabled())
1180 SAL_INFO("dbaccess", "ORowSetBase::firePropertyChange" );
1181 SAL_INFO("dbaccess", "ORowSetBase::firePropertyChange() Clone = " << m_bClone
);
1182 OSL_ENSURE(m_pColumns
,"Columns can not be NULL here!");
1184 TDataColumns::iterator aEnd
= m_aDataColumns
.end();
1185 for(TDataColumns::iterator aIter
= m_aDataColumns
.begin();aIter
!= aEnd
;++aIter
,++i
)
1189 (*aIter
)->fireValueChange(_rOldRow
.is() ? (_rOldRow
->get())[i
+1] : ::connectivity::ORowSetValue());
1191 catch (const Exception
&)
1193 SAL_WARN("dbaccess", "firePropertyChange: Exception on column " << i
);
1196 SAL_INFO("dbaccess", "ORowSetBase::firePropertyChange() Clone = " << m_bClone
);
1199 void ORowSetBase::firePropertyChange(sal_Int32 _nPos
,const ::connectivity::ORowSetValue
& _rOldValue
)
1201 OSL_ENSURE(_nPos
< (sal_Int32
)m_aDataColumns
.size(),"nPos is invalid!");
1202 m_aDataColumns
[_nPos
]->fireValueChange(_rOldValue
);
1205 void ORowSetBase::fireRowcount()
1209 bool ORowSetBase::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard
& /*_rGuard*/)
1214 void ORowSetBase::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard
& /*_rGuard*/)
1218 void ORowSetBase::notifyAllListeners(::osl::ResettableMutexGuard
& /*_rGuard*/)
1222 bool ORowSetBase::isPropertyChangeNotificationEnabled() const
1227 void ORowSetBase::fireProperty( sal_Int32 _nProperty
, bool _bNew
, bool _bOld
)
1229 Any aNew
= css::uno::makeAny( _bNew
);
1230 Any aOld
= css::uno::makeAny( _bOld
);
1231 fire( &_nProperty
, &aNew
, &aOld
, 1, sal_False
);
1234 void ORowSetBase::positionCache( CursorMoveDirection _ePrepareForDirection
)
1236 SAL_INFO("dbaccess", "ORowSetBase::positionCache() Clone = " << m_bClone
);
1238 bool bSuccess
= false;
1239 if ( m_aBookmark
.hasValue() )
1241 if (_ePrepareForDirection
== MOVE_NONE_REFRESH
||
1242 (m_pCache
->isAfterLast() != bool(isAfterLast())) || ( m_pCache
->isBeforeFirst() != bool(isBeforeFirst()) ) ||
1243 m_pCache
->compareBookmarks( m_aBookmark
, m_pCache
->getBookmark() ) != CompareBookmark::EQUAL
)
1244 bSuccess
= m_pCache
->moveToBookmark( m_aBookmark
);
1250 if ( m_bBeforeFirst
)
1252 bSuccess
= m_pCache
->beforeFirst();
1254 else if ( m_bAfterLast
)
1256 bSuccess
= m_pCache
->afterLast();
1260 OSL_ENSURE( m_nDeletedPosition
>= 1, "ORowSetBase::positionCache: no bookmark, and no valid 'deleted position'!" );
1261 switch ( _ePrepareForDirection
)
1264 if ( m_nDeletedPosition
> 1 )
1265 bSuccess
= m_pCache
->absolute( m_nDeletedPosition
- 1 );
1268 m_pCache
->beforeFirst();
1274 if ( m_pCache
->m_bRowCountFinal
&& ( m_nDeletedPosition
== impl_getRowCount() ) )
1276 m_pCache
->afterLast();
1280 bSuccess
= m_pCache
->absolute( m_nDeletedPosition
);
1284 case MOVE_NONE_REFRESH
:
1285 bSuccess
= false; // will be asserted below
1290 OSL_ENSURE( bSuccess
, "ORowSetBase::positionCache: failed!" );
1293 SAL_INFO("dbaccess", "ORowSetBase::positionCache() Clone = " << m_bClone
);
1296 void ORowSetBase::checkCache()
1298 ::connectivity::checkDisposed(m_rBHelper
.bDisposed
);
1300 throwFunctionSequenceException(*m_pMySelf
);
1303 void ORowSetBase::movementFailed()
1305 SAL_INFO("dbaccess", "ORowSetBase::movementFailed() Clone = " << m_bClone
);
1306 m_aOldRow
->clearRow();
1307 m_aCurrentRow
= m_pCache
->getEnd();
1308 m_bBeforeFirst
= m_pCache
->isBeforeFirst();
1309 m_bAfterLast
= m_pCache
->isAfterLast();
1310 m_aBookmark
= Any();
1311 m_aCurrentRow
.setBookmark(m_aBookmark
);
1312 OSL_ENSURE(m_bBeforeFirst
|| m_bAfterLast
,"BeforeFirst or AfterLast is wrong!");
1313 SAL_INFO("dbaccess", "ORowSetBase::movementFailed() Clone = " << m_bClone
);
1316 ORowSetRow
ORowSetBase::getOldRow(bool _bWasNew
)
1318 OSL_ENSURE(m_aOldRow
.is(),"RowSetRowHElper isn't valid!");
1319 ORowSetRow aOldValues
;
1320 if ( !_bWasNew
&& m_aOldRow
->getRow().is() )
1321 aOldValues
= new ORowSetValueVector( *(m_aOldRow
->getRow())); // remember the old values
1325 void ORowSetBase::getPropertyDefaultByHandle( sal_Int32
/*_nHandle*/, Any
& _rDefault
) const
1330 void ORowSetBase::onDeleteRow( const Any
& _rBookmark
)
1333 // not interested in
1336 ::osl::MutexGuard
aGuard( *m_pMutex
);
1337 //OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::onDeleteRow: Bookmark isn't valid!" );
1338 if ( compareBookmarks( _rBookmark
, m_aBookmark
) == CompareBookmark::EQUAL
)
1340 positionCache( MOVE_NONE
);
1341 m_nDeletedPosition
= m_pCache
->getRow();
1345 void ORowSetBase::onDeletedRow( const Any
& _rBookmark
, sal_Int32 _nPos
)
1349 // if we're a clone, and on a deleted row, and the main RowSet deleted another
1350 // row (only the main RowSet can, clones can't), which is *before* our
1351 // deleted position, then we have to adjust this position
1352 if ( m_bClone
&& ( _nPos
< m_nDeletedPosition
) )
1353 --m_nDeletedPosition
;
1357 ::osl::MutexGuard
aGuard( *m_pMutex
);
1358 if ( compareBookmarks( _rBookmark
, m_aBookmark
) == CompareBookmark::EQUAL
)
1360 m_aOldRow
->clearRow();
1361 m_aCurrentRow
= m_pCache
->getEnd();
1362 m_aBookmark
= Any();
1363 m_aCurrentRow
.setBookmark( m_aBookmark
);
1367 sal_Int32
ORowSetBase::impl_getRowCount() const
1369 sal_Int32
nRowCount( m_pCache
->m_nRowCount
);
1370 if ( const_cast< ORowSetBase
* >( this )->rowDeleted() && !m_pCache
->m_bNew
)
1375 struct ORowSetNotifierImpl
1377 ::std::vector
<sal_Int32
> aChangedColumns
;
1378 ::std::vector
<Any
> aChangedBookmarks
;
1379 ORowSetValueVector::Vector aRow
;
1384 ORowSetNotifier::ORowSetNotifier( ORowSetBase
* _pRowSet
)
1385 :m_pRowSet( _pRowSet
)
1387 ,m_bWasModified( false )
1389 ,m_bNotifyCalled( false )
1393 OSL_ENSURE( m_pRowSet
, "ORowSetNotifier::ORowSetNotifier: invalid row set. This wil crash." );
1395 // remember the "inserted" and "modified" state for later firing
1396 m_bWasNew
= m_pRowSet
->isNew( ORowSetBase::GrantNotifierAccess() );
1397 m_bWasModified
= m_pRowSet
->isModified( ORowSetBase::GrantNotifierAccess() );
1399 // if the row set is on the insert row, then we need to cancel this
1400 if ( m_pRowSet
->isModification( ORowSetBase::GrantNotifierAccess() ) )
1401 m_pRowSet
->doCancelModification( ORowSetBase::GrantNotifierAccess() );
1404 ORowSetNotifier::ORowSetNotifier( ORowSetBase
* _pRowSet
,const ORowSetValueVector::Vector
& i_aRow
)
1405 :m_pImpl(new ORowSetNotifierImpl
)
1406 ,m_pRowSet( _pRowSet
)
1408 ,m_bWasModified( false )
1410 ,m_bNotifyCalled( false )
1414 OSL_ENSURE( m_pRowSet
, "ORowSetNotifier::ORowSetNotifier: invalid row set. This wil crash." );
1415 m_pImpl
->aRow
= i_aRow
; // yes, create a copy to store the old values
1418 ORowSetNotifier::~ORowSetNotifier( )
1422 void ORowSetNotifier::fire()
1424 // we're not interested in firing changes FALSE->TRUE, only TRUE->FALSE.
1425 // (the former would be quite pathological, e.g. after a failed movement)
1428 && ( m_bWasModified
!= m_pRowSet
->isModified( ORowSetBase::GrantNotifierAccess() ) )
1430 m_pRowSet
->fireProperty( PROPERTY_ID_ISMODIFIED
, false, true, ORowSetBase::GrantNotifierAccess() );
1433 && ( m_bWasNew
!= m_pRowSet
->isNew( ORowSetBase::GrantNotifierAccess() ) )
1435 m_pRowSet
->fireProperty( PROPERTY_ID_ISNEW
, false, true, ORowSetBase::GrantNotifierAccess() );
1438 m_bNotifyCalled
= true;
1442 ::std::vector
<sal_Int32
>& ORowSetNotifier::getChangedColumns() const
1444 OSL_ENSURE(m_pImpl
.get(),"Illegal CTor call, use the other one!");
1445 return m_pImpl
->aChangedColumns
;
1448 void ORowSetNotifier::firePropertyChange()
1450 OSL_ENSURE(m_pImpl
.get(),"Illegal CTor call, use the other one!");
1453 ::std::vector
<sal_Int32
>::iterator aIter
= m_pImpl
->aChangedColumns
.begin();
1454 for(;aIter
!= m_pImpl
->aChangedColumns
.end();++aIter
)
1456 m_pRowSet
->firePropertyChange((*aIter
)-1 ,m_pImpl
->aRow
[(*aIter
)-1], ORowSetBase::GrantNotifierAccess());
1458 if ( !m_pImpl
->aChangedColumns
.empty() )
1459 m_pRowSet
->fireProperty(PROPERTY_ID_ISMODIFIED
,true,false, ORowSetBase::GrantNotifierAccess());
1463 } // namespace dbaccess
1465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */