Tag: cws_src680_rowsetdel User: fs Date: 06/01/16 02:10:47 Modified: /dba/dbaccess/source/core/api/ RowSetBase.cxx, RowSetBase.hxx
Log: #i55731# fixed the handling when deleting records File Changes: Directory: /dba/dbaccess/source/core/api/ ========================================= File [changed]: RowSetBase.cxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/api/RowSetBase.cxx?r1=1.80&r2=1.80.12.1 Delta lines: +206 -116 ----------------------- --- RowSetBase.cxx 3 Jan 2006 16:13:39 -0000 1.80 +++ RowSetBase.cxx 16 Jan 2006 10:09:54 -0000 1.80.12.1 @@ -4,9 +4,9 @@ * * $RCSfile: RowSetBase.cxx,v $ * - * $Revision: 1.80 $ + * $Revision: 1.80.12.1 $ * - * last change: $Author: kz $ $Date: 2006/01/03 16:13:39 $ + * last change: $Author: fs $ $Date: 2006/01/16 10:09:54 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -138,12 +138,10 @@ , m_rBHelper(_rBHelper) , m_pCache(NULL) , m_pColumns(NULL) - , m_nRowCount(0) , m_bBeforeFirst(sal_True) // changed from sal_False , m_bAfterLast(sal_False) - , m_bRowCountFinal(sal_False) , m_bClone(sal_False) - , m_nPosition(-1) + , m_nDeletedPosition(-1) , m_bIgnoreResult(sal_False) , m_nLastColumnIndex(-1) , m_pEmptyCollection( NULL ) @@ -152,8 +150,10 @@ sal_Int32 nRBT = PropertyAttribute::READONLY | PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT; - registerProperty(PROPERTY_ROWCOUNT, PROPERTY_ID_ROWCOUNT, nRBT, &m_nRowCount, ::getCppuType(reinterpret_cast< sal_Int32*>(NULL))); - registerProperty(PROPERTY_ISROWCOUNTFINAL, PROPERTY_ID_ISROWCOUNTFINAL, nRBT, &m_bRowCountFinal, ::getBooleanCppuType()); + sal_Int32 nInitialRowCountValue = 0; + sal_Bool bInitialRowCountFinalValue( sal_False ); + registerPropertyNoMember( PROPERTY_ROWCOUNT, PROPERTY_ID_ROWCOUNT, nRBT, ::getCppuType( &nInitialRowCountValue ), &nInitialRowCountValue ); + registerPropertyNoMember( PROPERTY_ISROWCOUNTFINAL, PROPERTY_ID_ISROWCOUNTFINAL, nRBT, ::getBooleanCppuType(), &bInitialRowCountFinalValue ); } // ----------------------------------------------------------------------------- ORowSetBase::~ORowSetBase() @@ -195,7 +195,7 @@ switch(nHandle) { case PROPERTY_ID_ROWCOUNT: - rValue <<= m_pCache->m_nRowCount; + rValue <<= impl_getRowCount(); break; case PROPERTY_ID_ISROWCOUNTFINAL: rValue.setValue(&m_pCache->m_bRowCountFinal,::getCppuBooleanType()); @@ -246,6 +246,8 @@ return ((m_nLastColumnIndex != -1) && !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid()) ? (*(*m_aCurrentRow))[m_nLastColumnIndex].isNull() : sal_True; } // ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- const ORowSetValue& ORowSetBase::getValue(sal_Int32 columnIndex) { ::osl::MutexGuard aGuard( *m_pMutex ); @@ -256,7 +258,18 @@ throwFunctionSequenceException(*m_pMySelf); } - if ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() ) + bool bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() ); + if ( !bValidCurrentRow && !rowDeleted() ) + { + // currentrow is null when the clone moves the window + positionCache( MOVE_NONE_REFRESH_ONLY ); + m_aCurrentRow = m_pCache->m_aMatrixIter; + OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getValue: we don't stand on a valid row! Row is null."); + + bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() ); + } + + if ( bValidCurrentRow ) { #if OSL_DEBUG_LEVEL > 0 ORowSetMatrix::iterator aCacheEnd = m_pCache->getEnd(); @@ -265,19 +278,8 @@ OSL_ENSURE(!m_aCurrentRow.isNull() && m_aCurrentRow <= m_pCache->getEnd(),"Invalid iterator set for currentrow!"); return (*(*m_aCurrentRow))[m_nLastColumnIndex = columnIndex]; } - else - { // currentrow is null when the clone move the window - if ( m_aCurrentRow.isNull() ) - { - positionCache(); - m_aCurrentRow = m_pCache->m_aMatrixIter; - OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getValue: we don't stand on a valid row! Row is null."); - return getValue(columnIndex); - } - OSL_ENSURE(!m_aCurrentRow.isNull() && (m_bBeforeFirst || m_bAfterLast),"ORowSetBase::getValue: we don't stand on a valid row! Row is equal to end of matrix"); - } - // we should normally never reach this here + // we should normally reach this here only if we're deleted return m_aEmptyValue; } // ------------------------------------------------------------------------- @@ -354,7 +356,10 @@ OSL_ENSURE((m_bBeforeFirst || m_bAfterLast),"ORowSetBase::getValue: we don't stand on a valid row! Row is equal to end of matrix"); else { - positionCache(); + if ( rowDeleted() ) + return NULL; + + positionCache( MOVE_NONE_REFRESH_ONLY ); m_aCurrentRow = m_pCache->m_aMatrixIter; OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getValue: we don't stand on a valid row! Row is null."); @@ -450,7 +455,7 @@ if(bRet = notifyAllListenersCursorBeforeMove(aGuard)) { // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); ORowSetNotifier aNotifier( this ); // this will call cancelRowModification on the cache if necessary @@ -463,7 +468,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(sal_True,aOldValues,aGuard); + setCurrentRow( sal_True, sal_True, aOldValues, aGuard ); } else { @@ -487,12 +492,11 @@ checkPositioningAllowed(); - sal_Bool bRet; if(bRet = notifyAllListenersCursorBeforeMove(aGuard)) { // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); ORowSetNotifier aNotifier( this ); // this will call cancelRowModification on the cache if necessary @@ -505,7 +509,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(sal_True,aOldValues,aGuard); + setCurrentRow( sal_True, sal_True, aOldValues, aGuard ); } else movementFailed(); @@ -596,15 +600,14 @@ if(bRet = notifyAllListenersCursorBeforeMove(aGuard)) { // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); ORowSetNotifier aNotifier( this ); // this will call cancelRowModification on the cache if necessary ORowSetRow aOldValues = getOldRow(bWasNew); - if ( m_aBookmark.hasValue() ) // #104474# OJ - positionCache(); + positionCache( MOVE_FORWARD ); sal_Bool bAfterLast = m_pCache->isAfterLast(); bRet = m_pCache->next(); @@ -614,7 +617,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(bRet,aOldValues,aGuard); + setCurrentRow( bRet, sal_True, aOldValues, aGuard ); OSL_ENSURE(!m_bBeforeFirst,"BeforeFirst is true. I don't know why?"); } else @@ -637,10 +640,10 @@ // ------------------------------------------------------------------------- sal_Bool SAL_CALL ORowSetBase::isBeforeFirst( ) throw(SQLException, RuntimeException) { - DBG_TRACE1("DBACCESS ORowSetBase::isBeforeFirst() Clone = %i\n",m_bClone); ::connectivity::checkDisposed(m_rBHelper.bDisposed); ::osl::MutexGuard aGuard( *m_pMutex ); - checkPositioningAllowed(); + checkCache(); + DBG_TRACE2("DBACCESS ORowSetBase::isBeforeFirst() = %i Clone = %i\n",m_bBeforeFirst,m_bClone); return m_bBeforeFirst; @@ -648,10 +651,9 @@ // ------------------------------------------------------------------------- sal_Bool SAL_CALL ORowSetBase::isAfterLast( ) throw(SQLException, RuntimeException) { - DBG_TRACE1("DBACCESS ORowSetBase::isAfterLast() Clone = %i\n",m_bClone); ::connectivity::checkDisposed(m_rBHelper.bDisposed); ::osl::MutexGuard aGuard( *m_pMutex ); - checkPositioningAllowed(); + checkCache(); DBG_TRACE2("DBACCESS ORowSetBase::isAfterLast() = %i Clone = %i\n",m_bAfterLast,m_bClone); return m_bAfterLast; @@ -668,14 +670,16 @@ ::connectivity::checkDisposed(m_rBHelper.bDisposed); ::osl::MutexGuard aGuard( *m_pMutex ); - checkPositioningAllowed(); + checkCache(); - sal_Bool bIsFirst = !(m_bBeforeFirst || m_bAfterLast); - if(bIsFirst) - { - positionCache(); - bIsFirst = m_pCache->isFirst(); - } + if ( m_bBeforeFirst || m_bAfterLast ) + return sal_False; + + if ( rowDeleted() ) + return ( m_nDeletedPosition == 1 ); + + positionCache( MOVE_NONE_REFRESH_ONLY ); + sal_Bool bIsFirst = m_pCache->isFirst(); DBG_TRACE2("DBACCESS ORowSetBase::isFirst() = %i Clone = %i\n",bIsFirst,m_bClone); return bIsFirst; @@ -691,14 +695,20 @@ DBG_TRACE1("DBACCESS ORowSetBase::isLast() Clone = %i\n",m_bClone); ::connectivity::checkDisposed(m_rBHelper.bDisposed); ::osl::MutexGuard aGuard( *m_pMutex ); - checkPositioningAllowed(); + checkCache(); + + if ( m_bBeforeFirst || m_bAfterLast ) + return sal_False; + + if ( rowDeleted() ) + if ( !m_pCache->m_bRowCountFinal ) + return sal_False; + else + return ( m_nDeletedPosition == impl_getRowCount() ); + + positionCache( MOVE_NONE_REFRESH_ONLY ); + sal_Bool bIsLast = m_pCache->isLast(); - sal_Bool bIsLast = !(m_bBeforeFirst || m_bAfterLast); - if(bIsLast) // so we can't be on the last - { - positionCache(); - bIsLast = m_pCache->isLast(); - } DBG_TRACE2("DBACCESS ORowSetBase::isLast() = %i Clone = %i\n",bIsLast,m_bClone); return bIsLast; } @@ -712,7 +722,7 @@ checkPositioningAllowed(); // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); if((bWasNew || !m_bBeforeFirst) && notifyAllListenersCursorBeforeMove(aGuard) ) { @@ -727,7 +737,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(sal_True,aOldValues,aGuard); + setCurrentRow( sal_True, sal_True, aOldValues, aGuard ); // - IsModified // - Isnew @@ -751,7 +761,7 @@ ::osl::ResettableMutexGuard aGuard( *m_pMutex ); checkPositioningAllowed(); - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); if((bWasNew || !m_bAfterLast) && notifyAllListenersCursorBeforeMove(aGuard) ) { @@ -768,7 +778,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(sal_True,aOldValues,aGuard); + setCurrentRow( sal_True, sal_True, aOldValues, aGuard ); // - IsModified // - Isnew @@ -793,7 +803,7 @@ if(bRet = notifyAllListenersCursorBeforeMove(aGuard) ) { // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); ORowSetNotifier aNotifier( this ); // this will call cancelRowModification on the cache if necessary @@ -809,7 +819,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(bMoved,aOldValues,aGuard); + setCurrentRow( bMoved, sal_True, aOldValues, aGuard ); } else { // first goes wrong so there is no row @@ -850,29 +860,25 @@ checkCache(); sal_Int32 nPos = 0; - if(!(m_bAfterLast || m_bBeforeFirst)) // we are on no valid row - { - // check if we are inserting a row - if(!(!m_bClone && m_pCache->m_bInserted)) - { - if(!m_aBookmark.hasValue()) // check if we are standing on a deleted row - nPos = m_nPosition; + if ( m_bBeforeFirst ) + nPos = 0; + else if ( m_bAfterLast ) + nPos = impl_getRowCount() + 1; + else if ( rowDeleted() ) + nPos = m_nDeletedPosition; + else if ( !m_bClone && m_pCache->m_bInserted ) + nPos = 0; else { - if(m_pCache->m_bAfterLast || m_pCache->m_bBeforeFirst || m_pCache->compareBookmarks(m_aBookmark,m_pCache->getBookmark()) != CompareBookmark::EQUAL) + if ( m_pCache->isAfterLast() + || m_pCache->isBeforeFirst() + || ( m_pCache->compareBookmarks( m_aBookmark, m_pCache->getBookmark() ) != CompareBookmark::EQUAL ) + ) { -#ifdef DBG_UTIL - sal_Bool bRet = m_pCache->moveToBookmark(m_aBookmark); - OSL_ENSURE(bRet,"moveToBookamrk failed so the position isn't valid!"); -#else - m_pCache->moveToBookmark(m_aBookmark); - -#endif + positionCache( MOVE_NONE_REFRESH_ONLY ); } nPos = m_pCache->getRow(); } - } - } DBG_TRACE2("DBACCESS ORowSetBase::getRow() = %i Clone = %i\n",nPos,m_bClone); return nPos; } @@ -889,7 +895,7 @@ if ( bRet && (bRet = notifyAllListenersCursorBeforeMove(aGuard)) ) { // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); ORowSetNotifier aNotifier( this ); // this will call cancelRowModification on the cache if necessary @@ -903,7 +909,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(sal_True,aOldValues,aGuard); + setCurrentRow( sal_True, sal_True, aOldValues, aGuard ); } else { // absolute movement goes wrong we stand left or right side of the rows @@ -933,21 +939,20 @@ checkPositioningAllowed(); - sal_Bool bRet =!((m_bAfterLast && rows > 1) || (m_bBeforeFirst && rows < 0)); // we are already behind the last row or before the first + sal_Bool bRet =!((m_bAfterLast && rows > 0) || (m_bBeforeFirst && rows < 0)); // we are already behind the last row or before the first if(bRet && (bRet = notifyAllListenersCursorBeforeMove(aGuard))) { // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); ORowSetNotifier aNotifier( this ); // this will call cancelRowModification on the cache if necessary ORowSetRow aOldValues = getOldRow(bWasNew); - if ( m_aBookmark.hasValue() ) // #104474# OJ - positionCache(); + positionCache( rows > 0 ? MOVE_FORWARD : MOVE_BACKWARD ); bRet = m_pCache->relative(rows); if(bRet) @@ -955,7 +960,7 @@ // notification order // - column values // - cursorMoved - setCurrentRow(sal_True,aOldValues,aGuard); + setCurrentRow( sal_True, sal_True, aOldValues, aGuard ); } else { @@ -986,15 +991,14 @@ if(bRet && (bRet = notifyAllListenersCursorBeforeMove(aGuard))) { // check if we are inserting a row - sal_Bool bWasNew = m_pCache->m_bInserted || m_pCache->m_bDeleted; + sal_Bool bWasNew = m_pCache->m_bInserted || rowDeleted(); ORowSetNotifier aNotifier( this ); // this will call cancelRowModification on the cache if necessary ORowSetRow aOldValues = getOldRow(bWasNew); - if ( m_aBookmark.hasValue() ) // #104474# OJ - positionCache(); + positionCache( MOVE_BACKWARD ); bRet = m_pCache->previous(); // if m_bBeforeFirst is false and bRet is false than we stood on the first row @@ -1003,10 +1007,13 @@ // notification order // - column values // - cursorMoved - setCurrentRow(sal_True,aOldValues,aGuard); + setCurrentRow( sal_True, sal_True, aOldValues, aGuard ); } else { + DBG_ERROR( "ORowSetBase::previous: inconsistency!" ); + // we should never reach this place, as we should not get into this whole branch if m_bBeforeFirst + // was |true| from the beginning movementFailed(); } @@ -1018,7 +1025,7 @@ return bRet; } // ----------------------------------------------------------------------------- -void ORowSetBase::setCurrentRow(sal_Bool _bMoved,const ORowSetRow& _rOldValues,::osl::ResettableMutexGuard& _rGuard) +void ORowSetBase::setCurrentRow( sal_Bool _bMoved, sal_Bool _bDoNotify, const ORowSetRow& _rOldValues, ::osl::ResettableMutexGuard& _rGuard ) { DBG_TRACE1("DBACCESS ORowSetBase::setCurrentRow() Clone = %i",m_bClone); m_bBeforeFirst = m_pCache->isBeforeFirst(); @@ -1036,41 +1043,39 @@ OSL_ENSURE(m_aBookmark.hasValue(),"Bookmark has no value!"); sal_Int32 nOldRow = m_pCache->getRow(); - positionCache(); + positionCache( MOVE_NONE_REFRESH_ONLY ); sal_Int32 nNewRow = m_pCache->getRow(); OSL_ENSURE(nOldRow == nNewRow,"Old position is not equal to new postion"); m_aCurrentRow = m_pCache->m_aMatrixIter; OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!"); - } - else - { - m_aOldRow->clearRow(); - m_aCurrentRow = m_pCache->getEnd(); - m_aBookmark = Any(); - m_aCurrentRow.setBookmark(m_aBookmark); - } - if ( _bMoved ) - { // the cache could repositioned so we need to adjust the cache // #104144# OJ - if ( m_aCurrentRow.isNull() ) + if ( _bMoved && m_aCurrentRow.isNull() ) { - positionCache(); + positionCache( MOVE_NONE_REFRESH_ONLY ); m_aCurrentRow = m_pCache->m_aMatrixIter; OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!"); } } + else + { + m_aOldRow->clearRow(); + m_aCurrentRow = m_pCache->getEnd(); + m_aBookmark = Any(); + m_aCurrentRow.setBookmark(m_aBookmark); + } // notification order // - column values + if ( _bDoNotify ) firePropertyChange(_rOldValues); // TODO: can this be done before the notifications? if(!(m_bBeforeFirst || m_bAfterLast) && !m_aCurrentRow.isNull() && m_aCurrentRow->isValid() && m_aCurrentRow != m_pCache->getEnd()) m_aOldRow->setRow(new ORowSetValueVector(m_aCurrentRow->getBody())); - if ( _bMoved ) + if ( _bMoved && _bDoNotify ) // - cursorMoved notifyAllListenersCursorMoved( _rGuard ); @@ -1092,11 +1097,14 @@ { ::connectivity::checkDisposed(m_rBHelper.bDisposed); ::osl::MutexGuard aGuard( *m_pMutex ); - checkPositioningAllowed(); + checkCache(); + + if ( rowDeleted() ) + throwSQLException( "The current row is deleted", SQL_INVALID_CURSOR_STATE, Reference< XRowSet >( this ) ); if(!(m_bBeforeFirst || m_bAfterLast)) { - positionCache(); + positionCache( MOVE_NONE_REFRESH_ONLY ); m_pCache->refreshRow(); } } @@ -1122,7 +1130,7 @@ ::osl::MutexGuard aGuard( *m_pMutex ); checkCache(); - return m_pCache->rowDeleted(); + return !m_aBookmark.hasValue() && !m_bBeforeFirst && !m_bAfterLast; } // ------------------------------------------------------------------------- // XWarningsSupplier @@ -1186,16 +1194,58 @@ } // ----------------------------------------------------------------------------- -void ORowSetBase::positionCache() +void ORowSetBase::positionCache( CursorMoveDirection _ePrepareForDirection ) { DBG_TRACE1("DBACCESS ORowSetBase::positionCache() Clone = %i\n",m_bClone); - if(m_aBookmark.hasValue()) + + sal_Bool bSuccess = sal_False; + if ( m_aBookmark.hasValue() ) + { + bSuccess = m_pCache->moveToBookmark( m_aBookmark ); + } + else + { + if ( m_bBeforeFirst ) { - sal_Bool bOK = m_pCache->moveToBookmark(m_aBookmark); - OSL_ENSURE(bOK ,"ORowSetBase::positionCache: positioning cache fails!"); + bSuccess = m_pCache->beforeFirst(); + } + else if ( m_bAfterLast ) + { + bSuccess = m_pCache->afterLast(); + } + else + { + OSL_ENSURE( m_nDeletedPosition >= 1, "ORowSetBase::positionCache: no bookmark, and no valid 'deleted position'!" ); + switch ( _ePrepareForDirection ) + { + case MOVE_FORWARD: + if ( m_nDeletedPosition > 1 ) + bSuccess = m_pCache->absolute( m_nDeletedPosition - 1 ); + else + { + m_pCache->beforeFirst(); + bSuccess = sal_True; + } + break; + + case MOVE_BACKWARD: + if ( m_pCache->m_bRowCountFinal && ( m_nDeletedPosition == impl_getRowCount() ) ) + { + m_pCache->afterLast(); + bSuccess = sal_True; } else - OSL_ENSURE(0,"ORowSetBase::positionCache: no bookmark set!"); + bSuccess = m_pCache->absolute( m_nDeletedPosition ); + break; + + case MOVE_NONE_REFRESH_ONLY: + bSuccess = sal_False; // will be asserted below + break; + } + } + } + OSL_ENSURE( bSuccess, "ORowSetBase::positionCache: failed!" ); + DBG_TRACE1("DBACCESS ORowSetBase::positionCache() Clone = %i\n",m_bClone); } // ----------------------------------------------------------------------------- @@ -1232,6 +1282,47 @@ { return Any(); } +// ----------------------------------------------------------------------------- +void ORowSetBase::onDeleteRow(const Any& _rBookmark) +{ + if ( rowDeleted() ) + // nothing to do. The row at which we're currently positioned is already deleted, so + // we're not interested in if another one also gets deleted + return; + + if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 ) + { + OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::onDeleteRow: Bookmark isn't valid!" ); + ::osl::MutexGuard aGuard( *m_pMutex ); + positionCache( MOVE_NONE_REFRESH_ONLY ); + m_nDeletedPosition = m_pCache->getRow(); + } +} +// ----------------------------------------------------------------------------- +void ORowSetBase::onDeletedRow(const Any& _rBookmark) +{ + if ( rowDeleted() ) + // nothing to do. The row at which we're currently positioned is already deleted, so + // we're not interested in if another one also has been deleted + return; + + if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 ) + { + m_aOldRow->clearRow(); + m_aCurrentRow = m_pCache->getEnd(); + m_aBookmark = Any(); + m_aCurrentRow.setBookmark( m_aBookmark ); + } +} +// ----------------------------------------------------------------------------- +sal_Int32 ORowSetBase::impl_getRowCount() const +{ + sal_Int32 nRowCount( m_pCache->m_nRowCount ); + if ( const_cast< ORowSetBase* >( this )->rowDeleted() ) + ++nRowCount; + return nRowCount; +} + // ============================================================================= DBG_NAME(ORowSetNotifier) // ----------------------------------------------------------------------------- @@ -1259,7 +1350,6 @@ // ----------------------------------------------------------------------------- ORowSetNotifier::~ORowSetNotifier( ) { - DBG_DTOR(ORowSetNotifier,NULL); } File [changed]: RowSetBase.hxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/api/RowSetBase.hxx?r1=1.32&r2=1.32.74.1 Delta lines: +54 -27 --------------------- --- RowSetBase.hxx 8 Sep 2005 10:01:22 -0000 1.32 +++ RowSetBase.hxx 16 Jan 2006 10:10:23 -0000 1.32.74.1 @@ -4,9 +4,9 @@ * * $RCSfile: RowSetBase.hxx,v $ * - * $Revision: 1.32 $ + * $Revision: 1.32.74.1 $ * - * last change: $Author: rt $ $Date: 2005/09/08 10:01:22 $ + * last change: $Author: fs $ $Date: 2006/01/16 10:10:23 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -149,13 +149,11 @@ ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatTypes> m_xNumberFormatTypes; OEmptyCollection* m_pEmptyCollection; - sal_Int32 m_nRowCount; // contains the current count of rows which have been fetched sal_Int32 m_nLastColumnIndex; // the last column ask for, used for wasNull() - sal_Int32 m_nPosition; // is set only when a row was deleted + sal_Int32 m_nDeletedPosition; // is set only when a row was deleted sal_Int32 m_nResultSetType; // fetch property sal_Int32 m_nResultSetConcurrency; sal_Bool m_bClone; // I'm clone or not - sal_Bool m_bRowCountFinal; sal_Bool m_bIgnoreResult ; sal_Bool m_bBeforeFirst : 1; sal_Bool m_bAfterLast : 1; @@ -166,10 +164,6 @@ // fire a notification for all that are listening on column::VALUE property void firePropertyChange(const ORowSetRow& _rOldRow); virtual void fireRowcount() { } // fire if rowcount changed - virtual sal_Bool notifyAllListenersRowBeforeChange(::osl::ResettableMutexGuard& _rGuard,const ::com::sun::star::sdb::RowChangeEvent &rEvt) - {return sal_True; } // fire if rowcount changed - virtual void notifyAllListenersRowChanged(::osl::ResettableMutexGuard& _rGuard,const ::com::sun::star::sdb::RowChangeEvent &rEvt) - {} // notify row changed virtual sal_Bool notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard) {return sal_True; } // notify row changed virtual void notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard) { } // notify cursor moved @@ -190,12 +184,38 @@ // OPropertyStateContainer virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 _nHandle ) const; virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue,sal_Int32 nHandle) const; - // postions the cache which the currently bookmark m_aBookmark - void positionCache(); + + enum CursorMoveDirection + { + /// denotes a cursor move forward + MOVE_FORWARD, + /// denotes a cursor move backwards + MOVE_BACKWARD, + /// denotes no cursor move at all, used when the current row is to be refreshed only + MOVE_NONE_REFRESH_ONLY + }; + /** positions the cache in preparation of a cursor move + + Normally, the cache is simply moved to our bookmark (m_aBookmark). If however the current + row is deleted, then the cache is properly positioned for a following cursor movement in the + given direction. + + @param _ePrepareForDirection + the direction into which the cursor should be moved after the call. If we're currently not on + a deleted row, this parameter is ignored, since in this case the cache is simply moved to + m_aBookmark.</br> + If, however, we're currently on a deleted row, this is used to properly position the cache + using <member>m_nDeletedPosition</member>.<br/> + In this case, MOVE_NONE_REFRESH_ONLY is not supported. This is because the deleted row + (to which the RowSet currently points to) is not present in the cache. So, you cannot move the + cache to this row. + */ + void positionCache( CursorMoveDirection _ePrepareForDirection ); + // returns a value of a column of the current row const connectivity::ORowSetValue& getValue(sal_Int32 columnIndex); // sets the current and the bookmark - void setCurrentRow(sal_Bool _bMoved,const ORowSetRow& _rOldValues,::osl::ResettableMutexGuard& _rGuard); + void setCurrentRow( sal_Bool _bMoved, sal_Bool _bDoNotify, const ORowSetRow& _rOldValues, ::osl::ResettableMutexGuard& _rGuard); void checkPositioningAllowed() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); // checks if the cache is null void checkCache(); @@ -227,6 +247,17 @@ */ sal_Bool isOnLast(); + /** returns the current row count + + This function takes into account that we might actually be positioned on a + deleted row, so that m_pCache->m_nRowCount does not really reflect the actual + count. + + @precond + Our mutext is locked. + */ + sal_Int32 impl_getRowCount() const; + public: virtual ~ORowSetBase(); @@ -315,18 +346,14 @@ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getStatement( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); // ::com::sun::star::sdbc::XRowSet - virtual void SAL_CALL execute( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) - { // when not implemented by derived classes then throw - throw ::com::sun::star::sdbc::SQLException(); - } - virtual void SAL_CALL addRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) - { // when not implemented by derived classes then throw - throw ::com::sun::star::sdbc::SQLException(); - } - virtual void SAL_CALL removeRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) - { // when not implemented by derived classes then throw - throw ::com::sun::star::sdbc::SQLException(); - } + virtual void SAL_CALL execute( ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0; + virtual void SAL_CALL addRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) = 0; + virtual void SAL_CALL removeRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) = 0; + + // is called when the rowset is going to delete this bookmark _rBookmark + void onDeleteRow(const ::com::sun::star::uno::Any& _rBookmark); + // is called when the rowset has deleted this bookmark _rBookmark + void onDeletedRow(const ::com::sun::star::uno::Any& _rBookmark); // ========================================================== // granular access control --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
