Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / dbaccess / source / core / api / RowSetBase.cxx
blob8b4087d97b3052090867ef979092e78679eeb105
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 .
21 #include "RowSetBase.hxx"
22 #include "CRowSetDataColumn.hxx"
23 #include <connectivity/sdbcx/VCollection.hxx>
24 #include "RowSetCache.hxx"
25 #include "dbastrings.hrc"
26 #include "core_resource.hrc"
27 #include <com/sun/star/lang/DisposedException.hpp>
28 #include <com/sun/star/beans/PropertyAttribute.hpp>
29 #include <com/sun/star/sdbcx/CompareBookmark.hpp>
30 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
31 #include <com/sun/star/lang/Locale.hpp>
32 #include <com/sun/star/util/NumberFormat.hpp>
33 #include <comphelper/sequence.hxx>
34 #include <comphelper/extract.hxx>
35 #include <comphelper/seqstream.hxx>
36 #include <connectivity/dbexception.hxx>
37 #include <osl/thread.h>
38 #include <tools/debug.hxx>
39 #include <rtl/logfile.hxx>
41 using namespace dbaccess;
42 using namespace connectivity;
43 using namespace connectivity::sdbcx;
44 using namespace comphelper;
45 using namespace dbtools;
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::sdbc;
49 using namespace ::com::sun::star::sdb;
50 using namespace ::com::sun::star::sdbcx;
51 using namespace ::com::sun::star::container;
52 using namespace ::com::sun::star::lang;
53 using namespace ::com::sun::star::util;
54 using namespace ::cppu;
55 using namespace ::osl;
57 namespace dbaccess
60 // =========================================================================
61 // = OEmptyCollection
62 // =========================================================================
63 class OEmptyCollection : public sdbcx::OCollection
65 protected:
66 virtual void impl_refresh() throw(RuntimeException);
67 virtual connectivity::sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
68 public:
69 OEmptyCollection(::cppu::OWeakObject& _rParent,::osl::Mutex& _rMutex) : OCollection(_rParent,sal_True,_rMutex,::std::vector< ::rtl::OUString>()){}
72 void OEmptyCollection::impl_refresh() throw(RuntimeException)
76 connectivity::sdbcx::ObjectType OEmptyCollection::createObject(const ::rtl::OUString& /*_rName*/)
78 return connectivity::sdbcx::ObjectType();
81 // =========================================================================
82 // = ORowSetBase
83 // =========================================================================
84 DBG_NAME(ORowSetBase)
86 ORowSetBase::ORowSetBase( const ::comphelper::ComponentContext& _rContext, ::cppu::OBroadcastHelper& _rBHelper, ::osl::Mutex* _pMutex )
87 :OPropertyStateContainer(_rBHelper)
88 ,m_pMutex(_pMutex)
89 ,m_pCache(NULL)
90 ,m_pColumns(NULL)
91 ,m_rBHelper(_rBHelper)
92 ,m_pEmptyCollection( NULL )
93 ,m_aContext( _rContext )
94 ,m_aErrors( _rContext )
95 ,m_nLastColumnIndex(-1)
96 ,m_nDeletedPosition(-1)
97 ,m_nResultSetType( ResultSetType::FORWARD_ONLY )
98 ,m_nResultSetConcurrency( ResultSetConcurrency::READ_ONLY )
99 ,m_bClone(sal_False)
100 ,m_bIgnoreResult(sal_False)
101 ,m_bBeforeFirst(sal_True) // changed from sal_False
102 ,m_bAfterLast(sal_False)
103 ,m_bIsInsertRow(sal_False)
105 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::ORowSetBase" );
106 DBG_CTOR(ORowSetBase,NULL);
108 sal_Int32 nRBT = PropertyAttribute::READONLY | PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT;
110 sal_Int32 nInitialRowCountValue = 0;
111 sal_Bool bInitialRowCountFinalValue( sal_False );
112 registerPropertyNoMember( PROPERTY_ROWCOUNT, PROPERTY_ID_ROWCOUNT, nRBT, ::getCppuType( &nInitialRowCountValue ), &nInitialRowCountValue );
113 registerPropertyNoMember( PROPERTY_ISROWCOUNTFINAL, PROPERTY_ID_ISROWCOUNTFINAL, nRBT, ::getBooleanCppuType(), &bInitialRowCountFinalValue );
116 ORowSetBase::~ORowSetBase()
118 if(m_pColumns)
120 TDataColumns().swap(m_aDataColumns);
121 m_pColumns->acquire();
122 m_pColumns->disposing();
123 delete m_pColumns;
124 m_pColumns = NULL;
127 if ( m_pEmptyCollection )
128 delete m_pEmptyCollection;
130 DBG_DTOR(ORowSetBase,NULL);
133 // com::sun::star::lang::XTypeProvider
134 Sequence< Type > ORowSetBase::getTypes() throw (RuntimeException)
136 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTypes" );
137 return ::comphelper::concatSequences(ORowSetBase_BASE::getTypes(),OPropertyStateContainer::getTypes());
140 // com::sun::star::uno::XInterface
141 Any ORowSetBase::queryInterface( const Type & rType ) throw (RuntimeException)
143 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::queryInterface" );
144 Any aRet = ORowSetBase_BASE::queryInterface(rType);
145 if(!aRet.hasValue())
146 aRet = OPropertyStateContainer::queryInterface(rType);
147 return aRet;
150 void SAL_CALL ORowSetBase::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
152 //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getFastPropertyValue" );
153 if(m_pCache)
155 switch(nHandle)
157 case PROPERTY_ID_ROWCOUNT:
158 rValue <<= impl_getRowCount();
159 break;
160 case PROPERTY_ID_ISROWCOUNTFINAL:
161 rValue.setValue(&m_pCache->m_bRowCountFinal,::getCppuBooleanType());
162 break;
163 default:
164 OPropertyStateContainer::getFastPropertyValue(rValue,nHandle);
167 else
168 OPropertyStateContainer::getFastPropertyValue(rValue,nHandle);
171 // OComponentHelper
172 void SAL_CALL ORowSetBase::disposing(void)
174 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::disposing" );
175 MutexGuard aGuard(*m_pMutex);
177 if ( m_pColumns )
179 TDataColumns().swap(m_aDataColumns);
180 m_pColumns->disposing();
182 if ( m_pCache )
184 m_pCache->deregisterOldRow(m_aOldRow);
185 m_pCache->deleteIterator(this);
187 m_pCache = NULL;
190 // comphelper::OPropertyArrayUsageHelper
191 ::cppu::IPropertyArrayHelper* ORowSetBase::createArrayHelper( ) const
193 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::createArrayHelper" );
194 Sequence< Property > aProps;
195 describeProperties(aProps);
196 return new ::cppu::OPropertyArrayHelper(aProps);
199 // cppu::OPropertySetHelper
200 ::cppu::IPropertyArrayHelper& SAL_CALL ORowSetBase::getInfoHelper()
202 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getInfoHelper" );
203 return *const_cast<ORowSetBase*>(this)->getArrayHelper();
206 // XRow
207 sal_Bool SAL_CALL ORowSetBase::wasNull( ) throw(SQLException, RuntimeException)
209 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::wasNull" );
210 ::osl::MutexGuard aGuard( *m_pMutex );
211 checkCache();
212 return impl_wasNull();
215 sal_Bool ORowSetBase::impl_wasNull()
217 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_wasNull" );
218 return ((m_nLastColumnIndex != -1) && !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->is()) ? ((*m_aCurrentRow)->get())[m_nLastColumnIndex].isNull() : sal_True;
221 const ORowSetValue& ORowSetBase::getValue(sal_Int32 columnIndex)
223 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getValue" );
224 checkCache();
225 return impl_getValue(columnIndex);
228 const ORowSetValue& ORowSetBase::impl_getValue(sal_Int32 columnIndex)
230 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getValue" );
231 if ( m_bBeforeFirst || m_bAfterLast )
233 OSL_FAIL("ORowSetBase::getValue: Illegal call here (we're before first or after last)!");
234 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
237 if ( impl_rowDeleted() )
239 return m_aEmptyValue;
242 bool bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->is() );
243 if ( !bValidCurrentRow )
245 // currentrow is null when the clone moves the window
246 positionCache( MOVE_NONE_REFRESH_ONLY );
247 m_aCurrentRow = m_pCache->m_aMatrixIter;
248 m_bIsInsertRow = sal_False;
249 OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getValue: we don't stand on a valid row! Row is null.");
251 bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->is() );
254 if ( bValidCurrentRow )
256 #if OSL_DEBUG_LEVEL > 0
257 ORowSetMatrix::iterator aCacheEnd;
258 ORowSetMatrix::iterator aCurrentRow;
259 aCacheEnd = m_pCache->getEnd();
260 aCurrentRow = m_aCurrentRow;
261 ORowSetCacheMap::iterator aCacheIter = m_aCurrentRow.getIter();
262 ORowSetCacheIterator_Helper aHelper = aCacheIter->second;
263 ORowSetMatrix::iterator k = aHelper.aIterator;
264 for (; k != m_pCache->getEnd(); ++k)
266 ORowSetValueVector* pTemp = k->get();
267 OSL_ENSURE( pTemp != (void*)0xfeeefeee,"HALT!" );
269 #endif
270 OSL_ENSURE(!m_aCurrentRow.isNull() && m_aCurrentRow < m_pCache->getEnd() && aCacheIter != m_pCache->m_aCacheIterators.end(),"Invalid iterator set for currentrow!");
271 #if OSL_DEBUG_LEVEL > 0
272 ORowSetRow rRow = (*m_aCurrentRow);
273 OSL_ENSURE(rRow.is() && static_cast<sal_uInt16>(columnIndex) < (rRow->get()).size(),"Invalid size of vector!");
274 #endif
275 return ((*m_aCurrentRow)->get())[m_nLastColumnIndex = columnIndex];
278 // we should normally never reach this
279 return m_aEmptyValue;
282 ::rtl::OUString SAL_CALL ORowSetBase::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
284 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getString" );
285 ::osl::MutexGuard aGuard( *m_pMutex );
286 return getValue(columnIndex);
289 sal_Bool SAL_CALL ORowSetBase::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
291 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBoolean" );
292 ::osl::MutexGuard aGuard( *m_pMutex );
293 return getValue(columnIndex);
296 sal_Int8 SAL_CALL ORowSetBase::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
298 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getByte" );
299 ::osl::MutexGuard aGuard( *m_pMutex );
300 return getValue(columnIndex);
303 sal_Int16 SAL_CALL ORowSetBase::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
305 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getShort" );
306 ::osl::MutexGuard aGuard( *m_pMutex );
307 return getValue(columnIndex);
310 sal_Int32 SAL_CALL ORowSetBase::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
312 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getInt" );
313 ::osl::MutexGuard aGuard( *m_pMutex );
314 return getValue(columnIndex);
317 sal_Int64 SAL_CALL ORowSetBase::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
319 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getLong" );
320 ::osl::MutexGuard aGuard( *m_pMutex );
321 return getValue(columnIndex);
324 float SAL_CALL ORowSetBase::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
326 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getFloat" );
327 ::osl::MutexGuard aGuard( *m_pMutex );
328 return getValue(columnIndex);
331 double SAL_CALL ORowSetBase::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
333 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getDouble" );
334 ::osl::MutexGuard aGuard( *m_pMutex );
335 return getValue(columnIndex);
338 Sequence< sal_Int8 > SAL_CALL ORowSetBase::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
340 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBytes" );
341 ::osl::MutexGuard aGuard( *m_pMutex );
342 return getValue(columnIndex);
345 ::com::sun::star::util::Date SAL_CALL ORowSetBase::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
347 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getDate" );
348 ::osl::MutexGuard aGuard( *m_pMutex );
349 return getValue(columnIndex);
352 ::com::sun::star::util::Time SAL_CALL ORowSetBase::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
354 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTime" );
355 ::osl::MutexGuard aGuard( *m_pMutex );
356 return getValue(columnIndex);
359 ::com::sun::star::util::DateTime SAL_CALL ORowSetBase::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
361 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTimestamp" );
362 ::osl::MutexGuard aGuard( *m_pMutex );
363 return getValue(columnIndex);
366 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSetBase::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
368 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBinaryStream" );
369 ::osl::MutexGuard aGuard( *m_pMutex );
370 checkCache();
372 if ( m_bBeforeFirst || m_bAfterLast )
374 OSL_FAIL("ORowSetBase::getBinaryStream: Illegal call here (we're before first or after last)!");
375 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
378 if ( impl_rowDeleted() )
380 return NULL;
383 bool bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->is() );
384 if ( !bValidCurrentRow )
386 positionCache( MOVE_NONE_REFRESH_ONLY );
387 m_aCurrentRow = m_pCache->m_aMatrixIter;
388 m_bIsInsertRow = sal_False;
389 OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getBinaryStream: we don't stand on a valid row! Row is null.");
391 bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->is() );
394 if ( bValidCurrentRow )
395 return new ::comphelper::SequenceInputStream(((*m_aCurrentRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
397 // we should normally never reach this
398 return Reference< ::com::sun::star::io::XInputStream >();
401 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSetBase::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
403 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getCharacterStream" );
404 return getBinaryStream(columnIndex);
407 Any SAL_CALL ORowSetBase::getObject( sal_Int32 columnIndex, const Reference< XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
409 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getObject" );
410 ::osl::MutexGuard aGuard( *m_pMutex );
411 checkCache();
413 return getValue(columnIndex).makeAny();
416 Reference< XRef > SAL_CALL ORowSetBase::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
418 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getRef" );
419 ::dbtools::throwFeatureNotImplementedException( "XRow::getRef", *m_pMySelf );
420 return NULL;
423 Reference< XBlob > SAL_CALL ORowSetBase::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
425 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBlob" );
426 return Reference< XBlob >(getValue(columnIndex).makeAny(),UNO_QUERY);
429 Reference< XClob > SAL_CALL ORowSetBase::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
431 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getClob" );
432 return Reference< XClob >(getValue(columnIndex).makeAny(),UNO_QUERY);
435 Reference< XArray > SAL_CALL ORowSetBase::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
437 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getArray" );
438 ::dbtools::throwFeatureNotImplementedException( "XRow::getArray", *m_pMySelf );
439 return NULL;
442 // ::com::sun::star::sdbcx::XRowLocate
443 Any SAL_CALL ORowSetBase::getBookmark( ) throw(SQLException, RuntimeException)
445 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBookmark" );
446 OSL_TRACE("DBACCESS ORowSetBase::getBookmark() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
447 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
448 ::osl::MutexGuard aGuard( *m_pMutex );
449 checkCache();
451 if ( m_bBeforeFirst || m_bAfterLast )
452 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
454 if ( impl_rowDeleted() )
455 ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_DELETED ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
457 OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::getBookmark: bookmark has no value!" );
458 return m_aBookmark;
461 sal_Bool SAL_CALL ORowSetBase::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
463 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::moveToBookmark" );
464 OSL_TRACE("DBACCESS ORowSetBase::moveToBookmark(Any) Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
465 OSL_ENSURE(bookmark.hasValue(),"ORowSetBase::moveToBookmark bookmark has no value!");
466 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
468 if(!bookmark.hasValue() || m_nResultSetType == ResultSetType::FORWARD_ONLY)
470 if(bookmark.hasValue())
471 OSL_FAIL("MoveToBookmark is not possible when we are only forward");
472 else
473 OSL_FAIL("Bookmark is not valid");
474 throwFunctionSequenceException(*m_pMySelf);
478 checkCache();
480 sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
481 if ( bRet )
483 // check if we are inserting a row
484 sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
486 ORowSetNotifier aNotifier( this );
487 // this will call cancelRowModification on the cache if necessary
489 ORowSetRow aOldValues = getOldRow(bWasNew);
491 bRet = m_pCache->moveToBookmark(bookmark);
492 doCancelModification( );
493 if(bRet)
495 // notification order
496 // - column values
497 // - cursorMoved
498 setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
500 else
502 movementFailed();
505 // - IsModified
506 // - IsNew
507 aNotifier.fire( );
509 OSL_TRACE("DBACCESS ORowSetBase::moveToBookmark(Any) = %i Clone = %i",bRet,m_bClone);
510 return bRet;
513 sal_Bool SAL_CALL ORowSetBase::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
515 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::moveRelativeToBookmark" );
516 OSL_TRACE("DBACCESS ORowSetBase::moveRelativeToBookmark(Any,%i) Clone = %i",rows,m_bClone);
517 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
519 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
521 checkPositioningAllowed();
523 sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
524 if ( bRet )
526 // check if we are inserting a row
527 sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
529 ORowSetNotifier aNotifier( this );
530 // this will call cancelRowModification on the cache if necessary
532 ORowSetRow aOldValues = getOldRow(bWasNew);
534 bRet = m_pCache->moveRelativeToBookmark(bookmark,rows);
535 doCancelModification( );
536 if(bRet)
538 // notification order
539 // - column values
540 // - cursorMoved
541 setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
543 else
544 movementFailed();
546 // - IsModified
547 // - IsNew
548 aNotifier.fire( );
550 // RowCount/IsRowCountFinal
551 fireRowcount();
553 OSL_TRACE("DBACCESS ORowSetBase::moveRelativeToBookmark(Any,%i) = %i Clone = %i",rows,bRet,m_bClone);
554 return bRet;
557 sal_Int32 SAL_CALL ORowSetBase::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
559 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::compareBookmarks" );
560 ::osl::MutexGuard aGuard( *m_pMutex );
561 checkCache();
562 return m_pCache->compareBookmarks(_first,_second);
565 sal_Bool SAL_CALL ORowSetBase::hasOrderedBookmarks( ) throw(SQLException, RuntimeException)
567 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::hasOrderedBookmarks" );
568 ::osl::MutexGuard aGuard( *m_pMutex );
569 checkCache();
570 return m_pCache->hasOrderedBookmarks();
573 sal_Int32 SAL_CALL ORowSetBase::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
575 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::hashBookmark" );
576 ::osl::MutexGuard aGuard( *m_pMutex );
577 checkCache();
578 return m_pCache->hashBookmark(bookmark);
581 // XResultSetMetaDataSupplier
582 Reference< XResultSetMetaData > SAL_CALL ORowSetBase::getMetaData( ) throw(SQLException, RuntimeException)
584 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getMetaData" );
585 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
587 Reference< XResultSetMetaData > xMeta;
588 if(m_pCache)
589 xMeta = m_pCache->getMetaData();
591 return xMeta;
594 // XColumnLocate
595 sal_Int32 SAL_CALL ORowSetBase::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
597 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::findColumn" );
598 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
600 ::osl::MutexGuard aGuard( m_aColumnsMutex );
601 // it is possible to save some time here when we remember the names - position relation in a map
602 return m_pColumns ? m_pColumns->findColumn(columnName) : sal_Int32(0);
605 // ::com::sun::star::sdbcx::XColumnsSupplier
606 Reference< XNameAccess > SAL_CALL ORowSetBase::getColumns( ) throw(RuntimeException)
608 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getColumns" );
609 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
611 ::osl::MutexGuard aGuard( m_aColumnsMutex );
612 if(!m_pColumns)
614 if (!m_pEmptyCollection)
615 m_pEmptyCollection = new OEmptyCollection(*m_pMySelf,m_aColumnsMutex);
616 return m_pEmptyCollection;
619 return m_pColumns;
622 // XResultSet
623 sal_Bool SAL_CALL ORowSetBase::next( ) throw(SQLException, RuntimeException)
625 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::next" );
626 OSL_TRACE("DBACCESS ORowSetBase::next() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
627 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
628 checkCache();
630 sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
631 if ( bRet )
633 // check if we are inserting a row
634 sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
636 ORowSetNotifier aNotifier( this );
637 // this will call cancelRowModification on the cache if necessary
639 ORowSetRow aOldValues = getOldRow(bWasNew);
641 positionCache( MOVE_FORWARD );
642 sal_Bool bAfterLast = m_pCache->isAfterLast();
643 bRet = m_pCache->next();
644 doCancelModification( );
646 if ( bRet || bAfterLast != m_pCache->isAfterLast() )
648 // notification order
649 // - column values
650 // - cursorMoved
651 setCurrentRow( bRet, sal_True, aOldValues, aGuard );
652 OSL_ENSURE(!m_bBeforeFirst,"BeforeFirst is true. I don't know why?");
654 else
656 // moved after the last row
657 movementFailed();
658 OSL_ENSURE(m_bAfterLast,"AfterLast is false. I don't know why?");
661 // - IsModified
662 // - IsNew
663 aNotifier.fire();
665 // - RowCount/IsRowCountFinal
666 fireRowcount();
668 OSL_TRACE("DBACCESS ORowSetBase::next() = %i Clone = %i ID = %i",bRet,m_bClone,osl_getThreadIdentifier(NULL));
669 return bRet;
672 sal_Bool SAL_CALL ORowSetBase::isBeforeFirst( ) throw(SQLException, RuntimeException)
674 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isBeforeFirst" );
675 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
676 ::osl::MutexGuard aGuard( *m_pMutex );
677 checkCache();
679 OSL_TRACE("DBACCESS ORowSetBase::isBeforeFirst() = %i Clone = %i",m_bBeforeFirst,m_bClone);
681 return m_bBeforeFirst;
684 sal_Bool SAL_CALL ORowSetBase::isAfterLast( ) throw(SQLException, RuntimeException)
686 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isAfterLast" );
687 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
688 ::osl::MutexGuard aGuard( *m_pMutex );
689 checkCache();
690 OSL_TRACE("DBACCESS ORowSetBase::isAfterLast() = %i Clone = %i",m_bAfterLast,m_bClone);
692 return m_bAfterLast;
695 sal_Bool ORowSetBase::isOnFirst()
697 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isOnFirst" );
698 return isFirst();
701 sal_Bool SAL_CALL ORowSetBase::isFirst( ) throw(SQLException, RuntimeException)
703 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isFirst" );
704 OSL_TRACE("DBACCESS ORowSetBase::isFirst() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
706 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
707 ::osl::MutexGuard aGuard( *m_pMutex );
708 checkCache();
710 if ( m_bBeforeFirst || m_bAfterLast )
711 return sal_False;
713 if ( impl_rowDeleted() )
714 return ( m_nDeletedPosition == 1 );
716 sal_Bool bIsFirst = m_pCache->isFirst();
718 OSL_TRACE("DBACCESS ORowSetBase::isFirst() = %i Clone = %i",bIsFirst,m_bClone);
719 return bIsFirst;
722 sal_Bool ORowSetBase::isOnLast()
724 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isOnLast" );
725 return isLast();
728 sal_Bool SAL_CALL ORowSetBase::isLast( ) throw(SQLException, RuntimeException)
730 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isLast" );
731 OSL_TRACE("DBACCESS ORowSetBase::isLast() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
732 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
733 ::osl::MutexGuard aGuard( *m_pMutex );
734 checkCache();
736 if ( m_bBeforeFirst || m_bAfterLast )
737 return sal_False;
739 if ( impl_rowDeleted() )
741 if ( !m_pCache->m_bRowCountFinal )
742 return sal_False;
743 else
744 return ( m_nDeletedPosition == impl_getRowCount() );
747 sal_Bool bIsLast = m_pCache->isLast();
749 OSL_TRACE("DBACCESS ORowSetBase::isLast() = %i Clone = %i",bIsLast,m_bClone);
750 return bIsLast;
753 void SAL_CALL ORowSetBase::beforeFirst( ) throw(SQLException, RuntimeException)
755 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::beforeFirst" );
756 OSL_TRACE("DBACCESS ORowSetBase::beforeFirst() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
757 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
758 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
760 checkPositioningAllowed();
762 // check if we are inserting a row
763 sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
765 if((bWasNew || !m_bBeforeFirst) && notifyAllListenersCursorBeforeMove(aGuard) )
767 ORowSetNotifier aNotifier( this );
768 // this will call cancelRowModification on the cache if necessary
770 if ( !m_bBeforeFirst )
772 ORowSetRow aOldValues = getOldRow(bWasNew);
773 m_pCache->beforeFirst();
774 doCancelModification( );
776 // notification order
777 // - column values
778 // - cursorMoved
779 setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
781 // - IsModified
782 // - Isnew
783 aNotifier.fire();
785 // - RowCount/IsRowCountFinal
786 fireRowcount();
789 // to be done _after_ the notifications!
790 m_aOldRow->clearRow();
792 OSL_TRACE("DBACCESS ORowSetBase::beforeFirst() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
795 void SAL_CALL ORowSetBase::afterLast( ) throw(SQLException, RuntimeException)
797 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::afterLast" );
798 OSL_TRACE("DBACCESS ORowSetBase::afterLast() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
799 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
801 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
802 checkPositioningAllowed();
804 sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
806 if((bWasNew || !m_bAfterLast) && notifyAllListenersCursorBeforeMove(aGuard) )
808 // check if we are inserting a row
809 ORowSetNotifier aNotifier( this );
810 // this will call cancelRowModification on the cache if necessary
812 if(!m_bAfterLast)
814 ORowSetRow aOldValues = getOldRow(bWasNew);
816 m_pCache->afterLast();
817 doCancelModification( );
819 // notification order
820 // - column values
821 // - cursorMoved
822 setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
824 // - IsModified
825 // - Isnew
826 aNotifier.fire();
828 // - RowCount/IsRowCountFinal
829 fireRowcount();
832 OSL_TRACE("DBACCESS ORowSetBase::afterLast() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
835 sal_Bool SAL_CALL ORowSetBase::move( ::std::mem_fun_t<sal_Bool,ORowSetBase>& _aCheckFunctor,
836 ::std::mem_fun_t<sal_Bool,ORowSetCache>& _aMovementFunctor)
838 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::move" );
839 OSL_TRACE("DBACCESS ORowSetBase::move() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
840 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
841 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
842 checkPositioningAllowed();
844 sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
845 if( bRet )
847 // check if we are inserting a row
848 sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
850 ORowSetNotifier aNotifier( this );
851 // this will call cancelRowModification on the cache if necessary
853 ORowSetRow aOldValues = getOldRow(bWasNew);
855 sal_Bool bMoved = ( bWasNew || !_aCheckFunctor(this) );
857 bRet = _aMovementFunctor(m_pCache);
858 doCancelModification( );
860 if ( bRet )
862 // notification order
863 // - column values
864 // - cursorMoved
865 setCurrentRow( bMoved, sal_True, aOldValues, aGuard );
867 else
868 { // first goes wrong so there is no row
869 movementFailed();
872 // - IsModified
873 // - IsNew
874 aNotifier.fire();
876 // - RowCount/IsRowCountFinal
877 fireRowcount();
879 OSL_TRACE("DBACCESS ORowSetBase::move() = %i Clone = %i",bRet,m_bClone);
880 return bRet;
883 sal_Bool SAL_CALL ORowSetBase::first( ) throw(SQLException, RuntimeException)
885 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::first" );
886 OSL_TRACE("DBACCESS ORowSetBase::first() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
887 ::std::mem_fun_t<sal_Bool,ORowSetBase> ioF_tmp(&ORowSetBase::isOnFirst);
888 ::std::mem_fun_t<sal_Bool,ORowSetCache> F_tmp(&ORowSetCache::first);
889 return move(ioF_tmp,F_tmp);
892 sal_Bool SAL_CALL ORowSetBase::last( ) throw(SQLException, RuntimeException)
894 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::last" );
895 OSL_TRACE("DBACCESS ORowSetBase::last() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
896 ::std::mem_fun_t<sal_Bool,ORowSetBase> ioL_tmp(&ORowSetBase::isOnLast);
897 ::std::mem_fun_t<sal_Bool,ORowSetCache> L_tmp(&ORowSetCache::last);
898 return move(ioL_tmp,L_tmp);
901 sal_Int32 SAL_CALL ORowSetBase::getRow( ) throw(SQLException, RuntimeException)
903 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getRow" );
904 OSL_TRACE("DBACCESS ORowSetBase::getRow() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
905 ::osl::MutexGuard aGuard( *m_pMutex );
907 checkCache();
908 return impl_getRow();
911 sal_Int32 ORowSetBase::impl_getRow()
913 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getRow" );
914 sal_Int32 nPos = 0;
915 if ( m_bBeforeFirst )
916 nPos = 0;
917 else if ( m_bAfterLast )
918 nPos = impl_getRowCount() + 1;
919 else if ( impl_rowDeleted() )
920 nPos = m_nDeletedPosition;
921 else if ( !m_bClone && m_pCache->m_bNew )
922 nPos = 0;
923 else
925 if ( m_pCache->isAfterLast()
926 || m_pCache->isBeforeFirst()
927 || ( m_pCache->compareBookmarks( m_aBookmark, m_pCache->getBookmark() ) != CompareBookmark::EQUAL )
930 positionCache( MOVE_NONE_REFRESH_ONLY );
932 nPos = m_pCache->getRow();
934 OSL_TRACE("DBACCESS ORowSetBase::impl_getRow() = %i Clone = %i ID = %i",nPos,m_bClone,osl_getThreadIdentifier(NULL));
935 return nPos;
938 sal_Bool SAL_CALL ORowSetBase::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
940 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::absolute" );
941 OSL_TRACE("DBACCESS ORowSetBase::absolute(%i) Clone = %i",row,m_bClone);
942 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
943 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
944 checkPositioningAllowed();
946 sal_Bool bRet = ( row > 0 )
947 && notifyAllListenersCursorBeforeMove( aGuard );
948 if ( bRet )
950 // check if we are inserting a row
951 sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
953 ORowSetNotifier aNotifier( this );
954 // this will call cancelRowModification on the cache if necessary
956 ORowSetRow aOldValues = getOldRow(bWasNew);
958 bRet = m_pCache->absolute(row);
959 doCancelModification( );
961 if(bRet)
963 // notification order
964 // - column values
965 // - cursorMoved
966 setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
968 else
969 { // absolute movement goes wrong we stand left or right side of the rows
970 movementFailed();
973 // - IsModified
974 // - IsNew
975 aNotifier.fire();
977 // - RowCount/IsRowCountFinal
978 fireRowcount();
980 OSL_TRACE("DBACCESS ORowSetBase::absolute(%i) = %i Clone = %i",row,bRet,m_bClone);
981 return bRet;
984 sal_Bool SAL_CALL ORowSetBase::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
986 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::relative" );
987 OSL_TRACE("DBACCESS ORowSetBase::relative(%i) Clone = %i",rows,m_bClone);
988 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
990 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
992 if(!rows)
993 return sal_True; // in this case do nothing
995 checkPositioningAllowed();
997 sal_Bool bRet =
998 ( ( !m_bAfterLast || rows <= 0 )
999 && ( !m_bBeforeFirst || rows >= 0 )
1000 && notifyAllListenersCursorBeforeMove( aGuard )
1003 if ( bRet )
1005 // check if we are inserting a row
1006 sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
1008 ORowSetNotifier aNotifier( this );
1009 // this will call cancelRowModification on the cache if necessary
1011 ORowSetRow aOldValues = getOldRow(bWasNew);
1013 positionCache( rows > 0 ? MOVE_FORWARD : MOVE_BACKWARD );
1014 bRet = m_pCache->relative(rows);
1015 doCancelModification( );
1017 if(bRet)
1019 // notification order
1020 // - column values
1021 // - cursorMoved
1022 setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
1024 else
1026 movementFailed();
1029 // - IsModified
1030 // - IsNew
1031 aNotifier.fire();
1033 // - RowCount/IsRowCountFinal
1034 fireRowcount();
1036 OSL_TRACE("DBACCESS ORowSetBase::relative(%i) = %i Clone = %i",rows,bRet,m_bClone);
1037 return bRet;
1040 sal_Bool SAL_CALL ORowSetBase::previous( ) throw(SQLException, RuntimeException)
1042 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::previous" );
1043 OSL_TRACE("DBACCESS ORowSetBase::previous() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1044 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
1045 ::osl::ResettableMutexGuard aGuard( *m_pMutex );
1047 checkPositioningAllowed();
1049 sal_Bool bRet = !m_bBeforeFirst
1050 && notifyAllListenersCursorBeforeMove(aGuard);
1052 if ( bRet )
1054 // check if we are inserting a row
1055 sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
1057 ORowSetNotifier aNotifier( this );
1058 // this will call cancelRowModification on the cache if necessary
1060 ORowSetRow aOldValues = getOldRow(bWasNew);
1062 positionCache( MOVE_BACKWARD );
1063 bRet = m_pCache->previous();
1064 doCancelModification( );
1066 // if m_bBeforeFirst is false and bRet is false than we stood on the first row
1067 if(!m_bBeforeFirst || bRet)
1069 // notification order
1070 // - column values
1071 // - cursorMoved
1072 setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
1074 else
1076 OSL_FAIL( "ORowSetBase::previous: inconsistency!" );
1077 // we should never reach this place, as we should not get into this whole branch if m_bBeforeFirst
1078 // was |true| from the beginning
1079 movementFailed();
1082 // - IsModified
1083 // - IsNew
1084 aNotifier.fire();
1086 // - RowCount/IsRowCountFinal
1087 fireRowcount();
1089 OSL_TRACE("DBACCESS ORowSetBase::previous() = %i Clone = %i",bRet,m_bClone);
1090 return bRet;
1093 void ORowSetBase::setCurrentRow( sal_Bool _bMoved, sal_Bool _bDoNotify, const ORowSetRow& _rOldValues, ::osl::ResettableMutexGuard& _rGuard )
1095 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::setCurrentRow" );
1096 OSL_TRACE("DBACCESS ORowSetBase::setCurrentRow() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1097 m_bBeforeFirst = m_pCache->isBeforeFirst();
1098 m_bAfterLast = m_pCache->isAfterLast();
1100 if(!(m_bBeforeFirst || m_bAfterLast))
1102 m_aBookmark = m_pCache->getBookmark();
1103 OSL_ENSURE(m_aBookmark.hasValue(),"Bookmark has no value!");
1104 m_aCurrentRow = m_pCache->m_aMatrixIter;
1105 m_bIsInsertRow = sal_False;
1106 OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is null!");
1107 m_aCurrentRow.setBookmark(m_aBookmark);
1108 OSL_ENSURE(!m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd(),"Position of matrix iterator isn't valid!");
1109 OSL_ENSURE(m_aCurrentRow->is(),"Currentrow isn't valid");
1110 OSL_ENSURE(m_aBookmark.hasValue(),"Bookmark has no value!");
1112 m_aCurrentRow = m_pCache->m_aMatrixIter;
1113 m_bIsInsertRow = sal_False;
1114 OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!");
1115 #if OSL_DEBUG_LEVEL > 0
1116 ORowSetRow rRow = (*m_aCurrentRow);
1117 OSL_ENSURE(rRow.is() ,"Invalid size of vector!");
1118 #endif
1119 // the cache could repositioned so we need to adjust the cache
1120 if ( _bMoved && m_aCurrentRow.isNull() )
1122 positionCache( MOVE_NONE_REFRESH_ONLY );
1123 m_aCurrentRow = m_pCache->m_aMatrixIter;
1124 m_bIsInsertRow = sal_False;
1125 OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!");
1128 else
1130 m_aOldRow->clearRow();
1131 m_aCurrentRow = m_pCache->getEnd();
1132 m_aBookmark = Any();
1133 m_aCurrentRow.setBookmark(m_aBookmark);
1136 // notification order
1137 // - column values
1138 if ( _bDoNotify )
1139 firePropertyChange(_rOldValues);
1141 // TODO: can this be done before the notifications?
1142 if(!(m_bBeforeFirst || m_bAfterLast) && !m_aCurrentRow.isNull() && m_aCurrentRow->is() && m_aCurrentRow != m_pCache->getEnd())
1143 m_aOldRow->setRow(new ORowSetValueVector( *(*m_aCurrentRow) ));
1145 if ( _bMoved && _bDoNotify )
1146 // - cursorMoved
1147 notifyAllListenersCursorMoved( _rGuard );
1149 OSL_TRACE("DBACCESS ORowSetBase::setCurrentRow() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1152 void ORowSetBase::checkPositioningAllowed() throw( SQLException, RuntimeException )
1154 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::checkPositioningAllowed" );
1155 if(!m_pCache || m_nResultSetType == ResultSetType::FORWARD_ONLY)
1156 throwFunctionSequenceException(*m_pMySelf);
1159 Reference< XInterface > ORowSetBase::getStatement(void) throw( SQLException, RuntimeException )
1161 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getStatement" );
1162 return NULL;
1165 void SAL_CALL ORowSetBase::refreshRow( ) throw(SQLException, RuntimeException)
1167 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::refreshRow" );
1168 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
1169 ::osl::MutexGuard aGuard( *m_pMutex );
1170 checkCache();
1171 if ( impl_rowDeleted() )
1172 throwSQLException( "The current row is deleted", SQL_INVALID_CURSOR_STATE, Reference< XRowSet >( this ) );
1174 if(!(m_bBeforeFirst || m_bAfterLast))
1176 sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
1177 ORowSetRow aOldValues = getOldRow(bWasNew);
1178 positionCache( MOVE_NONE_REFRESH_ONLY );
1179 m_pCache->refreshRow();
1180 firePropertyChange(aOldValues);
1184 sal_Bool SAL_CALL ORowSetBase::rowUpdated( ) throw(SQLException, RuntimeException)
1186 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowUpdated" );
1187 ::osl::MutexGuard aGuard( *m_pMutex );
1188 checkCache();
1190 if ( impl_rowDeleted() )
1191 return sal_False;
1193 return m_pCache->rowUpdated();
1196 sal_Bool SAL_CALL ORowSetBase::rowInserted( ) throw(SQLException, RuntimeException)
1198 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowInserted" );
1199 ::osl::MutexGuard aGuard( *m_pMutex );
1201 checkCache();
1203 if ( impl_rowDeleted() )
1204 return sal_False;
1206 return m_pCache->rowInserted();
1209 sal_Bool SAL_CALL ORowSetBase::rowDeleted( ) throw(SQLException, RuntimeException)
1211 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowDeleted" );
1212 ::osl::MutexGuard aGuard( *m_pMutex );
1213 checkCache();
1214 return impl_rowDeleted();
1217 sal_Bool ORowSetBase::impl_rowDeleted( )
1219 return !m_aBookmark.hasValue() && !m_bBeforeFirst && !m_bAfterLast;
1222 // XWarningsSupplier
1223 Any SAL_CALL ORowSetBase::getWarnings( ) throw(SQLException, RuntimeException)
1225 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getWarnings" );
1226 ::osl::MutexGuard aGuard( *m_pMutex );
1228 if ( m_pCache )
1230 Reference< XWarningsSupplier > xWarnings( m_pCache->m_xSet.get(), UNO_QUERY );
1231 if ( xWarnings.is() )
1232 return xWarnings->getWarnings();
1235 return Any();
1238 void SAL_CALL ORowSetBase::clearWarnings( ) throw(SQLException, RuntimeException)
1240 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::clearWarnings" );
1241 ::osl::MutexGuard aGuard( *m_pMutex );
1243 if ( m_pCache )
1245 Reference< XWarningsSupplier > xWarnings( m_pCache->m_xSet.get(), UNO_QUERY );
1246 if ( xWarnings.is() )
1247 xWarnings->clearWarnings();
1251 void ORowSetBase::firePropertyChange(const ORowSetRow& _rOldRow)
1253 if (!isPropertyChangeNotificationEnabled())
1254 return;
1256 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::firePropertyChange" );
1257 OSL_TRACE("DBACCESS ORowSetBase::firePropertyChange() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1258 OSL_ENSURE(m_pColumns,"Columns can not be NULL here!");
1259 sal_Int32 i=0;
1262 TDataColumns::iterator aEnd = m_aDataColumns.end();
1263 for(TDataColumns::iterator aIter = m_aDataColumns.begin();aIter != aEnd;++aIter,++i)
1264 (*aIter)->fireValueChange(_rOldRow.is() ? (_rOldRow->get())[i+1] : ::connectivity::ORowSetValue());
1266 catch (const Exception&)
1268 OSL_FAIL("firePropertyChange: Exception");
1270 OSL_TRACE("DBACCESS ORowSetBase::firePropertyChange() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1273 void ORowSetBase::firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rOldValue)
1275 OSL_ENSURE(_nPos < (sal_Int32)m_aDataColumns.size(),"nPos is invalid!");
1276 m_aDataColumns[_nPos]->fireValueChange(_rOldValue);
1279 void ORowSetBase::fireRowcount()
1281 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::fireRowcount" );
1284 sal_Bool ORowSetBase::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& /*_rGuard*/)
1286 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListenersCursorBeforeMove" );
1287 return sal_True;
1290 void ORowSetBase::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& /*_rGuard*/)
1292 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListenersCursorMoved" );
1295 void ORowSetBase::notifyAllListeners(::osl::ResettableMutexGuard& /*_rGuard*/)
1297 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListeners" );
1300 sal_Bool ORowSetBase::isPropertyChangeNotificationEnabled() const
1302 return sal_True;
1305 void ORowSetBase::fireProperty( sal_Int32 _nProperty, sal_Bool _bNew, sal_Bool _bOld )
1307 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::fireProperty" );
1308 Any aNew = bool2any( _bNew );
1309 Any aOld = bool2any( _bOld );
1310 fire( &_nProperty, &aNew, &aOld, 1, sal_False );
1313 void ORowSetBase::positionCache( CursorMoveDirection _ePrepareForDirection )
1315 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::positionCache" );
1316 OSL_TRACE("DBACCESS ORowSetBase::positionCache() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1318 sal_Bool bSuccess = sal_False;
1319 if ( m_aBookmark.hasValue() )
1321 if ( _ePrepareForDirection == MOVE_NONE_REFRESH_ONLY ||
1322 m_pCache->compareBookmarks( m_aBookmark, m_pCache->getBookmark() ) != CompareBookmark::EQUAL )
1323 bSuccess = m_pCache->moveToBookmark( m_aBookmark );
1324 else
1325 bSuccess = sal_True;
1327 else
1329 if ( m_bBeforeFirst )
1331 bSuccess = m_pCache->beforeFirst();
1333 else if ( m_bAfterLast )
1335 bSuccess = m_pCache->afterLast();
1337 else
1339 OSL_ENSURE( m_nDeletedPosition >= 1, "ORowSetBase::positionCache: no bookmark, and no valid 'deleted position'!" );
1340 switch ( _ePrepareForDirection )
1342 case MOVE_FORWARD:
1343 if ( m_nDeletedPosition > 1 )
1344 bSuccess = m_pCache->absolute( m_nDeletedPosition - 1 );
1345 else
1347 m_pCache->beforeFirst();
1348 bSuccess = sal_True;
1350 break;
1352 case MOVE_BACKWARD:
1353 if ( m_pCache->m_bRowCountFinal && ( m_nDeletedPosition == impl_getRowCount() ) )
1355 m_pCache->afterLast();
1356 bSuccess = sal_True;
1358 else
1359 bSuccess = m_pCache->absolute( m_nDeletedPosition );
1360 break;
1362 case MOVE_NONE_REFRESH_ONLY:
1363 bSuccess = sal_False; // will be asserted below
1364 break;
1368 OSL_ENSURE( bSuccess, "ORowSetBase::positionCache: failed!" );
1369 (void)bSuccess;
1371 OSL_TRACE("DBACCESS ORowSetBase::positionCache() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1374 void ORowSetBase::checkCache()
1376 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::checkCache" );
1377 ::connectivity::checkDisposed(m_rBHelper.bDisposed);
1378 if(!m_pCache)
1379 throwFunctionSequenceException(*m_pMySelf);
1382 void ORowSetBase::movementFailed()
1384 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::movementFailed" );
1385 OSL_TRACE("DBACCESS ORowSetBase::movementFailed() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1386 m_aOldRow->clearRow();
1387 m_aCurrentRow = m_pCache->getEnd();
1388 m_bBeforeFirst = m_pCache->isBeforeFirst();
1389 m_bAfterLast = m_pCache->isAfterLast();
1390 m_aBookmark = Any();
1391 m_aCurrentRow.setBookmark(m_aBookmark);
1392 OSL_ENSURE(m_bBeforeFirst || m_bAfterLast,"BeforeFirst or AfterLast is wrong!");
1393 OSL_TRACE("DBACCESS ORowSetBase::movementFailed() Clone = %i ID = %i",m_bClone,osl_getThreadIdentifier(NULL));
1396 ORowSetRow ORowSetBase::getOldRow(sal_Bool _bWasNew)
1398 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getOldRow" );
1399 OSL_ENSURE(m_aOldRow.is(),"RowSetRowHElper isn't valid!");
1400 ORowSetRow aOldValues;
1401 if ( !_bWasNew && m_aOldRow->getRow().is() )
1402 aOldValues = new ORowSetValueVector( *(m_aOldRow->getRow())); // remember the old values
1403 return aOldValues;
1406 void ORowSetBase::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
1408 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getPropertyDefaultByHandle" );
1409 _rDefault.clear();
1412 void ORowSetBase::onDeleteRow( const Any& _rBookmark )
1414 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::onDeleteRow" );
1415 if ( rowDeleted() )
1416 // not interested in
1417 return;
1419 ::osl::MutexGuard aGuard( *m_pMutex );
1420 //OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::onDeleteRow: Bookmark isn't valid!" );
1421 if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 )
1423 positionCache( MOVE_NONE_REFRESH_ONLY );
1424 m_nDeletedPosition = m_pCache->getRow();
1428 void ORowSetBase::onDeletedRow( const Any& _rBookmark, sal_Int32 _nPos )
1430 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::onDeletedRow" );
1431 if ( rowDeleted() )
1433 // if we're a clone, and on a deleted row, and the main RowSet deleted another
1434 // row (only the main RowSet can, clones can't), which is *before* our
1435 // deleted position, then we have to adjust this position
1436 if ( m_bClone && ( _nPos < m_nDeletedPosition ) )
1437 --m_nDeletedPosition;
1438 return;
1441 ::osl::MutexGuard aGuard( *m_pMutex );
1442 if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 )
1444 m_aOldRow->clearRow();
1445 m_aCurrentRow = m_pCache->getEnd();
1446 m_aBookmark = Any();
1447 m_aCurrentRow.setBookmark( m_aBookmark );
1451 sal_Int32 ORowSetBase::impl_getRowCount() const
1453 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getRowCount" );
1454 sal_Int32 nRowCount( m_pCache->m_nRowCount );
1455 if ( const_cast< ORowSetBase* >( this )->rowDeleted() && !m_pCache->m_bNew )
1456 ++nRowCount;
1457 return nRowCount;
1459 // =============================================================================
1460 struct ORowSetNotifierImpl
1462 ::std::vector<sal_Int32> aChangedColumns;
1463 ::std::vector<Any> aChangedBookmarks;
1464 ORowSetValueVector::Vector aRow;
1467 DBG_NAME(ORowSetNotifier)
1469 ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet )
1470 :m_pRowSet( _pRowSet )
1471 ,m_bWasNew( sal_False )
1472 ,m_bWasModified( sal_False )
1473 #ifdef DBG_UTIL
1474 ,m_bNotifyCalled( sal_False )
1475 #endif
1477 DBG_CTOR(ORowSetNotifier,NULL);
1479 OSL_ENSURE( m_pRowSet, "ORowSetNotifier::ORowSetNotifier: invalid row set. This wil crash." );
1481 // remember the "inserted" and "modified" state for later firing
1482 m_bWasNew = m_pRowSet->isNew( ORowSetBase::GrantNotifierAccess() );
1483 m_bWasModified = m_pRowSet->isModified( ORowSetBase::GrantNotifierAccess() );
1485 // if the row set is on the insert row, then we need to cancel this
1486 if ( m_pRowSet->isModification( ORowSetBase::GrantNotifierAccess() ) )
1487 m_pRowSet->doCancelModification( ORowSetBase::GrantNotifierAccess() );
1490 ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet,const ORowSetValueVector::Vector& i_aRow )
1491 :m_pImpl(new ORowSetNotifierImpl)
1492 ,m_pRowSet( _pRowSet )
1493 ,m_bWasNew( sal_False )
1494 ,m_bWasModified( sal_False )
1495 #ifdef DBG_UTIL
1496 ,m_bNotifyCalled( sal_False )
1497 #endif
1499 DBG_CTOR(ORowSetNotifier,NULL);
1501 OSL_ENSURE( m_pRowSet, "ORowSetNotifier::ORowSetNotifier: invalid row set. This wil crash." );
1502 m_pImpl->aRow = i_aRow; // yes, create a copy to store the old values
1505 ORowSetNotifier::~ORowSetNotifier( )
1507 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetNotifier::~ORowSetNotifier" );
1508 DBG_DTOR(ORowSetNotifier,NULL);
1511 void ORowSetNotifier::fire()
1513 // we're not interested in firing changes FALSE->TRUE, only TRUE->FALSE.
1514 // (the former would be quite pathological, e.g. after a failed movement)
1516 if ( m_bWasModified
1517 && ( m_bWasModified != m_pRowSet->isModified( ORowSetBase::GrantNotifierAccess() ) )
1519 m_pRowSet->fireProperty( PROPERTY_ID_ISMODIFIED, sal_False, sal_True, ORowSetBase::GrantNotifierAccess() );
1521 if ( m_bWasNew
1522 && ( m_bWasNew != m_pRowSet->isNew( ORowSetBase::GrantNotifierAccess() ) )
1524 m_pRowSet->fireProperty( PROPERTY_ID_ISNEW, sal_False, sal_True, ORowSetBase::GrantNotifierAccess() );
1526 #ifdef DBG_UTIL
1527 m_bNotifyCalled = sal_True;
1528 #endif
1531 ::std::vector<sal_Int32>& ORowSetNotifier::getChangedColumns() const
1533 OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!");
1534 return m_pImpl->aChangedColumns;
1537 void ORowSetNotifier::firePropertyChange()
1539 OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!");
1540 if( m_pImpl.get() )
1542 ::std::vector<sal_Int32>::iterator aIter = m_pImpl->aChangedColumns.begin();
1543 for(;aIter != m_pImpl->aChangedColumns.end();++aIter)
1545 m_pRowSet->firePropertyChange((*aIter)-1 ,m_pImpl->aRow[(*aIter)-1], ORowSetBase::GrantNotifierAccess());
1547 if ( !m_pImpl->aChangedColumns.empty() )
1548 m_pRowSet->fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False, ORowSetBase::GrantNotifierAccess());
1551 } // namespace dbaccess
1553 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */