1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 
27 #include "RowSetBase.hxx"
28 #include "CRowSetDataColumn.hxx"
29 #include <connectivity/sdbcx/VCollection.hxx>
30 #include "RowSetCache.hxx"
31 #include "dbastrings.hrc"
32 #include "core_resource.hrc"
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/sdbcx/CompareBookmark.hpp>
36 #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
37 #include <com/sun/star/lang/Locale.hpp>
38 #include <com/sun/star/util/NumberFormat.hpp>
39 #include <comphelper/sequence.hxx>
40 #include <comphelper/extract.hxx>
41 #include <comphelper/seqstream.hxx>
42 #include <connectivity/dbexception.hxx>
43 #include <osl/thread.h>
44 #include <tools/debug.hxx>
45 #include <rtl/logfile.hxx>
46 
47 using namespace dbaccess;
48 using namespace connectivity;
49 using namespace connectivity::sdbcx;
50 using namespace comphelper;
51 using namespace dbtools;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::beans;
54 using namespace ::com::sun::star::sdbc;
55 using namespace ::com::sun::star::sdb;
56 using namespace ::com::sun::star::sdbcx;
57 using namespace ::com::sun::star::container;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star::util;
60 using namespace ::cppu;
61 using namespace ::osl;
62 
63 namespace dbaccess
64 {
65 
66 // =========================================================================
67 // = OEmptyCollection
68 // =========================================================================
69 // -------------------------------------------------------------------------
70 class OEmptyCollection : public sdbcx::OCollection
71 {
72 protected:
73 	virtual void impl_refresh() throw(RuntimeException);
74     virtual connectivity::sdbcx::ObjectType createObject(const ::rtl::OUString& _rName);
75 public:
76 	OEmptyCollection(::cppu::OWeakObject& _rParent,::osl::Mutex& _rMutex) : OCollection(_rParent,sal_True,_rMutex,::std::vector< ::rtl::OUString>()){}
77 };
78 // -----------------------------------------------------------------------------
79 void OEmptyCollection::impl_refresh() throw(RuntimeException)
80 {
81 }
82 // -----------------------------------------------------------------------------
83 connectivity::sdbcx::ObjectType OEmptyCollection::createObject(const ::rtl::OUString& /*_rName*/)
84 {
85 	return connectivity::sdbcx::ObjectType();
86 }
87 // -----------------------------------------------------------------------------
88 
89 // =========================================================================
90 // = ORowSetBase
91 // =========================================================================
92 DBG_NAME(ORowSetBase)
93 // -------------------------------------------------------------------------
94 ORowSetBase::ORowSetBase( const ::comphelper::ComponentContext& _rContext, ::cppu::OBroadcastHelper& _rBHelper, ::osl::Mutex* _pMutex )
95 	:OPropertyStateContainer(_rBHelper)
96 	,m_pMutex(_pMutex)
97 	,m_pCache(NULL)
98 	,m_pColumns(NULL)
99     ,m_rBHelper(_rBHelper)
100 	,m_pEmptyCollection( NULL )
101     ,m_aContext( _rContext )
102     ,m_aErrors( _rContext )
103 	,m_nLastColumnIndex(-1)
104 	,m_nDeletedPosition(-1)
105     ,m_nResultSetType( ResultSetType::FORWARD_ONLY )
106     ,m_nResultSetConcurrency( ResultSetConcurrency::READ_ONLY )
107 	,m_bClone(sal_False)
108 	,m_bIgnoreResult(sal_False)
109     ,m_bBeforeFirst(sal_True) // changed from sal_False
110 	,m_bAfterLast(sal_False)
111 	,m_bIsInsertRow(sal_False)
112 {
113     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::ORowSetBase" );
114     DBG_CTOR(ORowSetBase,NULL);
115 
116 	sal_Int32 nRBT	= PropertyAttribute::READONLY	| PropertyAttribute::BOUND		| PropertyAttribute::TRANSIENT;
117 
118     sal_Int32 nInitialRowCountValue = 0;
119     sal_Bool bInitialRowCountFinalValue( sal_False );
120     registerPropertyNoMember( PROPERTY_ROWCOUNT,        PROPERTY_ID_ROWCOUNT,        nRBT, ::getCppuType( &nInitialRowCountValue ), &nInitialRowCountValue );
121     registerPropertyNoMember( PROPERTY_ISROWCOUNTFINAL, PROPERTY_ID_ISROWCOUNTFINAL, nRBT, ::getBooleanCppuType(),                  &bInitialRowCountFinalValue );
122 }
123 // -----------------------------------------------------------------------------
124 ORowSetBase::~ORowSetBase()
125 {
126 	if(m_pColumns)
127 	{
128 		TDataColumns().swap(m_aDataColumns);
129 		m_pColumns->acquire();
130 		m_pColumns->disposing();
131 		delete m_pColumns;
132 		m_pColumns = NULL;
133 	}
134 
135 	if ( m_pEmptyCollection )
136 		delete m_pEmptyCollection;
137 
138     DBG_DTOR(ORowSetBase,NULL);
139 }
140 // com::sun::star::lang::XTypeProvider
141 //--------------------------------------------------------------------------
142 Sequence< Type > ORowSetBase::getTypes() throw (RuntimeException)
143 {
144     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTypes" );
145 	return ::comphelper::concatSequences(ORowSetBase_BASE::getTypes(),OPropertyStateContainer::getTypes());
146 }
147 // com::sun::star::uno::XInterface
148 //--------------------------------------------------------------------------
149 Any ORowSetBase::queryInterface( const Type & rType ) throw (RuntimeException)
150 {
151     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::queryInterface" );
152 	Any aRet = ORowSetBase_BASE::queryInterface(rType);
153 	if(!aRet.hasValue())
154 		aRet = OPropertyStateContainer::queryInterface(rType);
155 	return aRet;
156 }
157 // -------------------------------------------------------------------------
158 void SAL_CALL ORowSetBase::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
159 {
160     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getFastPropertyValue" );
161 	if(m_pCache)
162 	{
163 		switch(nHandle)
164 		{
165 		case PROPERTY_ID_ROWCOUNT:
166 			rValue <<= impl_getRowCount();
167 			break;
168 		case PROPERTY_ID_ISROWCOUNTFINAL:
169 			rValue.setValue(&m_pCache->m_bRowCountFinal,::getCppuBooleanType());
170 			break;
171 		default:
172 			OPropertyStateContainer::getFastPropertyValue(rValue,nHandle);
173 		};
174 	}
175 	else
176 		OPropertyStateContainer::getFastPropertyValue(rValue,nHandle);
177 }
178 // -------------------------------------------------------------------------
179 // OComponentHelper
180 void SAL_CALL ORowSetBase::disposing(void)
181 {
182     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::disposing" );
183 	MutexGuard aGuard(*m_pMutex);
184 
185 	if ( m_pColumns )
186 	{
187 		TDataColumns().swap(m_aDataColumns);
188 		m_pColumns->disposing();
189 	}
190 	if ( m_pCache )
191     {
192 		m_pCache->deregisterOldRow(m_aOldRow);
193         m_pCache->deleteIterator(this);
194     }
195 	m_pCache = NULL;
196 }
197 // -------------------------------------------------------------------------
198 // comphelper::OPropertyArrayUsageHelper
199 ::cppu::IPropertyArrayHelper* ORowSetBase::createArrayHelper( ) const
200 {
201     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::createArrayHelper" );
202 	Sequence< Property > aProps;
203 	describeProperties(aProps);
204 	return new ::cppu::OPropertyArrayHelper(aProps);
205 }
206 // -------------------------------------------------------------------------
207 // cppu::OPropertySetHelper
208 ::cppu::IPropertyArrayHelper& SAL_CALL ORowSetBase::getInfoHelper()
209 {
210     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getInfoHelper" );
211 	return *const_cast<ORowSetBase*>(this)->getArrayHelper();
212 }
213 // -------------------------------------------------------------------------
214 // XRow
215 sal_Bool SAL_CALL ORowSetBase::wasNull(  ) throw(SQLException, RuntimeException)
216 {
217     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::wasNull" );
218 	::osl::MutexGuard aGuard( *m_pMutex );
219 	checkCache();
220 	return impl_wasNull();
221 }
222 // -----------------------------------------------------------------------------
223 sal_Bool ORowSetBase::impl_wasNull()
224 {
225     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_wasNull" );
226 	return ((m_nLastColumnIndex != -1) && !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid()) ? ((*m_aCurrentRow)->get())[m_nLastColumnIndex].isNull() : sal_True;
227 }
228 
229 // -----------------------------------------------------------------------------
230 const ORowSetValue& ORowSetBase::getValue(sal_Int32 columnIndex)
231 {
232     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getValue" );
233 	checkCache();
234     return impl_getValue(columnIndex);
235 }
236 // -----------------------------------------------------------------------------
237 const ORowSetValue& ORowSetBase::impl_getValue(sal_Int32 columnIndex)
238 {
239     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getValue" );
240 	if ( m_bBeforeFirst || m_bAfterLast )
241 	{
242 		OSL_ENSURE(0,"ORowSetBase::getValue: Illegal call here (we're before first or after last)!");
243         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
244 	}
245 
246     if ( impl_rowDeleted() )
247 	{
248         return m_aEmptyValue;
249 	}
250 
251     bool bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
252     if ( !bValidCurrentRow )
253     {
254         // currentrow is null when the clone moves the window
255 		positionCache( MOVE_NONE_REFRESH_ONLY );
256 		m_aCurrentRow	= m_pCache->m_aMatrixIter;
257 		m_bIsInsertRow	= sal_False;
258 		OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getValue: we don't stand on a valid row! Row is null.");
259 
260         bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
261 	}
262 
263     if ( bValidCurrentRow )
264 	{
265 #if OSL_DEBUG_LEVEL > 0
266 		ORowSetMatrix::iterator aCacheEnd;
267 		ORowSetMatrix::iterator aCurrentRow;
268         aCacheEnd = m_pCache->getEnd();
269         aCurrentRow = m_aCurrentRow;
270         ORowSetCacheMap::iterator aCacheIter = m_aCurrentRow.getIter();
271         sal_Int32 n = aCacheIter->first;
272         n = n;
273         ORowSetCacheIterator_Helper aHelper = aCacheIter->second;
274         ORowSetMatrix::iterator k = aHelper.aIterator;
275         for (; k != m_pCache->getEnd(); ++k)
276         {
277             ORowSetValueVector* pTemp = k->getBodyPtr();
278             OSL_ENSURE( pTemp != (void*)0xfeeefeee,"HALT!" );
279         }
280 #endif
281 		OSL_ENSURE(!m_aCurrentRow.isNull() && m_aCurrentRow < m_pCache->getEnd() && aCacheIter != m_pCache->m_aCacheIterators.end(),"Invalid iterator set for currentrow!");
282 #if OSL_DEBUG_LEVEL > 0
283         ORowSetRow rRow = (*m_aCurrentRow);
284         OSL_ENSURE(rRow.isValid() && static_cast<sal_uInt16>(columnIndex) < (rRow->get()).size(),"Invalid size of vector!");
285 #endif
286 		return ((*m_aCurrentRow)->get())[m_nLastColumnIndex = columnIndex];
287 	}
288 
289     // we should normally never reach this
290 	return m_aEmptyValue;
291 }
292 // -------------------------------------------------------------------------
293 ::rtl::OUString SAL_CALL ORowSetBase::getString( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
294 {
295     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getString" );
296 	::osl::MutexGuard aGuard( *m_pMutex );
297 	return getValue(columnIndex);
298 }
299 // -------------------------------------------------------------------------
300 sal_Bool SAL_CALL ORowSetBase::getBoolean( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
301 {
302     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBoolean" );
303 	::osl::MutexGuard aGuard( *m_pMutex );
304 	return getValue(columnIndex);
305 }
306 // -------------------------------------------------------------------------
307 sal_Int8 SAL_CALL ORowSetBase::getByte( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
308 {
309     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getByte" );
310 	::osl::MutexGuard aGuard( *m_pMutex );
311 	return getValue(columnIndex);
312 }
313 // -------------------------------------------------------------------------
314 sal_Int16 SAL_CALL ORowSetBase::getShort( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
315 {
316     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getShort" );
317 	::osl::MutexGuard aGuard( *m_pMutex );
318 	return getValue(columnIndex);
319 }
320 // -------------------------------------------------------------------------
321 sal_Int32 SAL_CALL ORowSetBase::getInt( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
322 {
323     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getInt" );
324 	::osl::MutexGuard aGuard( *m_pMutex );
325 	return getValue(columnIndex);
326 }
327 // -------------------------------------------------------------------------
328 sal_Int64 SAL_CALL ORowSetBase::getLong( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
329 {
330     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getLong" );
331 	::osl::MutexGuard aGuard( *m_pMutex );
332 	return getValue(columnIndex);
333 }
334 // -------------------------------------------------------------------------
335 float SAL_CALL ORowSetBase::getFloat( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
336 {
337     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getFloat" );
338 	::osl::MutexGuard aGuard( *m_pMutex );
339 	return getValue(columnIndex);
340 }
341 // -------------------------------------------------------------------------
342 double SAL_CALL ORowSetBase::getDouble( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
343 {
344     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getDouble" );
345 	::osl::MutexGuard aGuard( *m_pMutex );
346 	return getValue(columnIndex);
347 }
348 // -------------------------------------------------------------------------
349 Sequence< sal_Int8 > SAL_CALL ORowSetBase::getBytes( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
350 {
351     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBytes" );
352 	::osl::MutexGuard aGuard( *m_pMutex );
353 	return getValue(columnIndex);
354 }
355 // -------------------------------------------------------------------------
356 ::com::sun::star::util::Date SAL_CALL ORowSetBase::getDate( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
357 {
358     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getDate" );
359 	::osl::MutexGuard aGuard( *m_pMutex );
360 	return getValue(columnIndex);
361 }
362 // -------------------------------------------------------------------------
363 ::com::sun::star::util::Time SAL_CALL ORowSetBase::getTime( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
364 {
365     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTime" );
366 	::osl::MutexGuard aGuard( *m_pMutex );
367 	return getValue(columnIndex);
368 }
369 // -------------------------------------------------------------------------
370 ::com::sun::star::util::DateTime SAL_CALL ORowSetBase::getTimestamp( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
371 {
372     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getTimestamp" );
373 	::osl::MutexGuard aGuard( *m_pMutex );
374 	return getValue(columnIndex);
375 }
376 // -------------------------------------------------------------------------
377 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSetBase::getBinaryStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
378 {
379     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBinaryStream" );
380 	::osl::MutexGuard aGuard( *m_pMutex );
381 	checkCache();
382 
383 	if ( m_bBeforeFirst || m_bAfterLast )
384 	{
385 		OSL_ENSURE(0,"ORowSetBase::getBinaryStream: Illegal call here (we're before first or after last)!");
386         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_CURSOR_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
387 	}
388 
389     if ( impl_rowDeleted() )
390 	{
391         return NULL;
392 	}
393 
394     bool bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
395     if ( !bValidCurrentRow )
396 	{
397         positionCache( MOVE_NONE_REFRESH_ONLY );
398 		m_aCurrentRow	= m_pCache->m_aMatrixIter;
399 		m_bIsInsertRow	= sal_False;
400 		OSL_ENSURE(!m_aCurrentRow.isNull(),"ORowSetBase::getBinaryStream: we don't stand on a valid row! Row is null.");
401 
402         bValidCurrentRow = ( !m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd() && m_aCurrentRow->isValid() );
403 	}
404 
405     if ( bValidCurrentRow )
406 		return new ::comphelper::SequenceInputStream(((*m_aCurrentRow)->get())[m_nLastColumnIndex = columnIndex].getSequence());
407 
408     // we should normally never reach this
409 	return Reference< ::com::sun::star::io::XInputStream >();
410 }
411 // -------------------------------------------------------------------------
412 Reference< ::com::sun::star::io::XInputStream > SAL_CALL ORowSetBase::getCharacterStream( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
413 {
414     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getCharacterStream" );
415 	return getBinaryStream(columnIndex);
416 }
417 // -------------------------------------------------------------------------
418 Any SAL_CALL ORowSetBase::getObject( sal_Int32 columnIndex, const Reference< XNameAccess >& /*typeMap*/ ) throw(SQLException, RuntimeException)
419 {
420     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getObject" );
421 	::osl::MutexGuard aGuard( *m_pMutex );
422 	checkCache();
423 
424 	return getValue(columnIndex).makeAny();
425 }
426 // -------------------------------------------------------------------------
427 Reference< XRef > SAL_CALL ORowSetBase::getRef( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
428 {
429     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getRef" );
430     ::dbtools::throwFeatureNotImplementedException( "XRow::getRef", *m_pMySelf );
431     return NULL;
432 }
433 // -------------------------------------------------------------------------
434 Reference< XBlob > SAL_CALL ORowSetBase::getBlob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
435 {
436     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBlob" );
437     return Reference< XBlob >(getValue(columnIndex).makeAny(),UNO_QUERY);
438 }
439 // -------------------------------------------------------------------------
440 Reference< XClob > SAL_CALL ORowSetBase::getClob( sal_Int32 columnIndex ) throw(SQLException, RuntimeException)
441 {
442     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getClob" );
443     return Reference< XClob >(getValue(columnIndex).makeAny(),UNO_QUERY);
444 }
445 // -------------------------------------------------------------------------
446 Reference< XArray > SAL_CALL ORowSetBase::getArray( sal_Int32 /*columnIndex*/ ) throw(SQLException, RuntimeException)
447 {
448     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getArray" );
449     ::dbtools::throwFeatureNotImplementedException( "XRow::getArray", *m_pMySelf );
450     return NULL;
451 }
452 // -------------------------------------------------------------------------
453 // ::com::sun::star::sdbcx::XRowLocate
454 Any SAL_CALL ORowSetBase::getBookmark(  ) throw(SQLException, RuntimeException)
455 {
456     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getBookmark" );
457 	DBG_TRACE2("DBACCESS ORowSetBase::getBookmark() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
458 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
459 	::osl::MutexGuard aGuard( *m_pMutex );
460     checkCache();
461 
462 	if ( m_bBeforeFirst || m_bAfterLast )
463         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_BEFORE_OR_AFTER ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
464 
465     if ( impl_rowDeleted() )
466         ::dbtools::throwSQLException( DBACORE_RESSTRING( RID_STR_NO_BOOKMARK_DELETED ), SQL_INVALID_CURSOR_POSITION, *m_pMySelf );
467 
468     OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::getBookmark: bookmark has no value!" );
469 	return m_aBookmark;
470 }
471 // -------------------------------------------------------------------------
472 sal_Bool SAL_CALL ORowSetBase::moveToBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
473 {
474     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::moveToBookmark" );
475 	DBG_TRACE2("DBACCESS ORowSetBase::moveToBookmark(Any) Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
476 	OSL_ENSURE(bookmark.hasValue(),"ORowSetBase::moveToBookmark bookmark has no value!");
477 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
478 
479 	if(!bookmark.hasValue() || m_nResultSetType == ResultSetType::FORWARD_ONLY)
480 	{
481 		if(bookmark.hasValue())
482 			OSL_ENSURE(0,"MoveToBookmark is not possible when we are only forward");
483 		else
484 			OSL_ENSURE(0,"Bookmark is not valid");
485 		throwFunctionSequenceException(*m_pMySelf);
486 	}
487 
488 
489 	checkCache();
490 
491     sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
492 	if ( bRet )
493 	{
494 		// check if we are inserting a row
495 		sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
496 
497 		ORowSetNotifier aNotifier( this );
498 			// this will call cancelRowModification on the cache if necessary
499 
500 		ORowSetRow aOldValues = getOldRow(bWasNew);
501 
502 		bRet = m_pCache->moveToBookmark(bookmark);
503 		doCancelModification( );
504 		if(bRet)
505 		{
506 			// notification order
507 			// - column values
508 			// - cursorMoved
509 			setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
510 		}
511 		else
512 		{
513 			movementFailed();
514 		}
515 
516 		// - IsModified
517 		// - IsNew
518 		aNotifier.fire( );
519 	}
520 	DBG_TRACE2("DBACCESS ORowSetBase::moveToBookmark(Any) = %i Clone = %i\n",bRet,m_bClone);
521 	return bRet;
522 }
523 // -------------------------------------------------------------------------
524 sal_Bool SAL_CALL ORowSetBase::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows ) throw(SQLException, RuntimeException)
525 {
526     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::moveRelativeToBookmark" );
527 	DBG_TRACE2("DBACCESS ORowSetBase::moveRelativeToBookmark(Any,%i) Clone = %i\n",rows,m_bClone);
528 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
529 
530 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
531 
532 	checkPositioningAllowed();
533 
534 	sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
535 	if ( bRet )
536 	{
537 		// check if we are inserting a row
538 		sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
539 
540 		ORowSetNotifier aNotifier( this );
541 			// this will call cancelRowModification on the cache if necessary
542 
543 		ORowSetRow aOldValues = getOldRow(bWasNew);
544 
545 		bRet = m_pCache->moveRelativeToBookmark(bookmark,rows);
546 		doCancelModification( );
547 		if(bRet)
548 		{
549 			// notification order
550 			// - column values
551 			// - cursorMoved
552 			setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
553 		}
554 		else
555 			movementFailed();
556 
557 		// - IsModified
558 		// - IsNew
559 		aNotifier.fire( );
560 
561 		// RowCount/IsRowCountFinal
562 		fireRowcount();
563 	}
564 	DBG_TRACE3("DBACCESS ORowSetBase::moveRelativeToBookmark(Any,%i) = %i Clone = %i\n",rows,bRet,m_bClone);
565 	return bRet;
566 }
567 // -------------------------------------------------------------------------
568 sal_Int32 SAL_CALL ORowSetBase::compareBookmarks( const Any& _first, const Any& _second ) throw(SQLException, RuntimeException)
569 {
570     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::compareBookmarks" );
571 	::osl::MutexGuard aGuard( *m_pMutex );
572 	checkCache();
573 	return m_pCache->compareBookmarks(_first,_second);
574 }
575 // -------------------------------------------------------------------------
576 sal_Bool SAL_CALL ORowSetBase::hasOrderedBookmarks(  ) throw(SQLException, RuntimeException)
577 {
578     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::hasOrderedBookmarks" );
579 	::osl::MutexGuard aGuard( *m_pMutex );
580 	checkCache();
581 	return m_pCache->hasOrderedBookmarks();
582 }
583 // -------------------------------------------------------------------------
584 sal_Int32 SAL_CALL ORowSetBase::hashBookmark( const Any& bookmark ) throw(SQLException, RuntimeException)
585 {
586     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::hashBookmark" );
587 	::osl::MutexGuard aGuard( *m_pMutex );
588 	checkCache();
589 	return m_pCache->hashBookmark(bookmark);
590 }
591 // -------------------------------------------------------------------------
592 // -------------------------------------------------------------------------
593 // XResultSetMetaDataSupplier
594 Reference< XResultSetMetaData > SAL_CALL ORowSetBase::getMetaData(  ) throw(SQLException, RuntimeException)
595 {
596     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getMetaData" );
597 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
598 
599 	Reference< XResultSetMetaData > xMeta;
600 	if(m_pCache)
601 		xMeta = m_pCache->getMetaData();
602 
603 	return xMeta;
604 }
605 // -------------------------------------------------------------------------
606 
607 // XColumnLocate
608 sal_Int32 SAL_CALL ORowSetBase::findColumn( const ::rtl::OUString& columnName ) throw(SQLException, RuntimeException)
609 {
610     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::findColumn" );
611 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
612 
613 	::osl::MutexGuard aGuard( m_aColumnsMutex );
614 	// it is possible to save some time her when we remember the names - position relation in a map
615 	return m_pColumns ? m_pColumns->findColumn(columnName) : sal_Int32(0);
616 }
617 // -------------------------------------------------------------------------
618 
619 // ::com::sun::star::sdbcx::XColumnsSupplier
620 Reference< XNameAccess > SAL_CALL ORowSetBase::getColumns(  ) throw(RuntimeException)
621 {
622     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getColumns" );
623 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
624 
625 	::osl::MutexGuard aGuard( m_aColumnsMutex );
626 	if(!m_pColumns)
627 	{
628 		if (!m_pEmptyCollection)
629 			m_pEmptyCollection = new OEmptyCollection(*m_pMySelf,m_aColumnsMutex);
630 		return m_pEmptyCollection;
631 	}
632 
633 	return m_pColumns;
634 }
635 // -------------------------------------------------------------------------
636 // XResultSet
637 sal_Bool SAL_CALL ORowSetBase::next(  ) throw(SQLException, RuntimeException)
638 {
639     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::next" );
640 	DBG_TRACE2("DBACCESS ORowSetBase::next() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
641 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
642 	checkCache();
643 
644 	sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
645 	if ( bRet )
646 	{
647 		// check if we are inserting a row
648 		sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
649 
650 		ORowSetNotifier aNotifier( this );
651 			// this will call cancelRowModification on the cache if necessary
652 
653 		ORowSetRow aOldValues = getOldRow(bWasNew);
654 
655         positionCache( MOVE_FORWARD );
656         sal_Bool bAfterLast = m_pCache->isAfterLast();
657 		bRet = m_pCache->next();
658 		doCancelModification( );
659 
660 
661 		if ( bRet || bAfterLast != m_pCache->isAfterLast() )
662 		{
663 			// notification order
664 			// - column values
665 			// - cursorMoved
666 			setCurrentRow( bRet, sal_True, aOldValues, aGuard );
667 			OSL_ENSURE(!m_bBeforeFirst,"BeforeFirst is true. I don't know why?");
668 		}
669 		else
670 		{
671 			// moved after the last row
672 			movementFailed();
673 			OSL_ENSURE(m_bAfterLast,"AfterLast is false. I don't know why?");
674 		}
675 
676 		// - IsModified
677 		// - IsNew
678 		aNotifier.fire();
679 
680 		// - RowCount/IsRowCountFinal
681 		fireRowcount();
682 	}
683 	DBG_TRACE3("DBACCESS ORowSetBase::next() = %i Clone = %i ID = %i\n",bRet,m_bClone,osl_getThreadIdentifier(NULL));
684 	return bRet;
685 }
686 // -------------------------------------------------------------------------
687 sal_Bool SAL_CALL ORowSetBase::isBeforeFirst(  ) throw(SQLException, RuntimeException)
688 {
689     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isBeforeFirst" );
690     ::connectivity::checkDisposed(m_rBHelper.bDisposed);
691 	::osl::MutexGuard aGuard( *m_pMutex );
692 	checkCache();
693 
694 	DBG_TRACE2("DBACCESS ORowSetBase::isBeforeFirst() = %i Clone = %i\n",m_bBeforeFirst,m_bClone);
695 
696 	return m_bBeforeFirst;
697 }
698 // -------------------------------------------------------------------------
699 sal_Bool SAL_CALL ORowSetBase::isAfterLast(  ) throw(SQLException, RuntimeException)
700 {
701     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isAfterLast" );
702 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
703 	::osl::MutexGuard aGuard( *m_pMutex );
704 	checkCache();
705 	DBG_TRACE2("DBACCESS ORowSetBase::isAfterLast() = %i Clone = %i\n",m_bAfterLast,m_bClone);
706 
707 	return m_bAfterLast;
708 }
709 // -------------------------------------------------------------------------
710 sal_Bool ORowSetBase::isOnFirst()
711 {
712     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isOnFirst" );
713 	return isFirst();
714 }
715 // -------------------------------------------------------------------------
716 sal_Bool SAL_CALL ORowSetBase::isFirst(  ) throw(SQLException, RuntimeException)
717 {
718     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isFirst" );
719 	DBG_TRACE2("DBACCESS ORowSetBase::isFirst() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
720 
721 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
722 	::osl::MutexGuard aGuard( *m_pMutex );
723 	checkCache();
724 
725     if ( m_bBeforeFirst || m_bAfterLast )
726         return sal_False;
727 
728     if ( impl_rowDeleted() )
729         return ( m_nDeletedPosition == 1 );
730 
731 	positionCache( MOVE_NONE_REFRESH_ONLY );
732 	sal_Bool bIsFirst = m_pCache->isFirst();
733 
734 	DBG_TRACE2("DBACCESS ORowSetBase::isFirst() = %i Clone = %i\n",bIsFirst,m_bClone);
735 	return bIsFirst;
736 }
737 // -------------------------------------------------------------------------
738 sal_Bool ORowSetBase::isOnLast()
739 {
740     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isOnLast" );
741 	return isLast();
742 }
743 // -----------------------------------------------------------------------------
744 sal_Bool SAL_CALL ORowSetBase::isLast(  ) throw(SQLException, RuntimeException)
745 {
746     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::isLast" );
747 	DBG_TRACE2("DBACCESS ORowSetBase::isLast() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
748 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
749 	::osl::MutexGuard aGuard( *m_pMutex );
750 	checkCache();
751 
752     if ( m_bBeforeFirst || m_bAfterLast )
753         return sal_False;
754 
755     if ( impl_rowDeleted() )
756     {
757         if ( !m_pCache->m_bRowCountFinal )
758             return sal_False;
759         else
760             return ( m_nDeletedPosition == impl_getRowCount() );
761     }
762 
763 	positionCache( MOVE_NONE_REFRESH_ONLY );
764 	sal_Bool bIsLast = m_pCache->isLast();
765 
766     DBG_TRACE2("DBACCESS ORowSetBase::isLast() = %i Clone = %i\n",bIsLast,m_bClone);
767 	return bIsLast;
768 }
769 // -------------------------------------------------------------------------
770 void SAL_CALL ORowSetBase::beforeFirst(  ) throw(SQLException, RuntimeException)
771 {
772     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::beforeFirst" );
773 	DBG_TRACE2("DBACCESS ORowSetBase::beforeFirst() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
774 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
775 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
776 
777 	checkPositioningAllowed();
778 
779 	// check if we are inserting a row
780 	sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
781 
782 	if((bWasNew || !m_bBeforeFirst) && notifyAllListenersCursorBeforeMove(aGuard) )
783 	{
784 		ORowSetNotifier aNotifier( this );
785 			// this will call cancelRowModification on the cache if necessary
786 
787 		if ( !m_bBeforeFirst )
788 		{
789             ORowSetRow aOldValues = getOldRow(bWasNew);
790 			m_pCache->beforeFirst();
791 			doCancelModification( );
792 
793 			// notification order
794 			// - column values
795 			// - cursorMoved
796 			setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
797 
798 			// - IsModified
799 			// - Isnew
800 			aNotifier.fire();
801 
802 			// - RowCount/IsRowCountFinal
803 			fireRowcount();
804 		}
805 
806 		// to be done _after_ the notifications!
807 		m_aOldRow->clearRow();
808 	}
809 	DBG_TRACE2("DBACCESS ORowSetBase::beforeFirst() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
810 }
811 // -------------------------------------------------------------------------
812 void SAL_CALL ORowSetBase::afterLast(  ) throw(SQLException, RuntimeException)
813 {
814     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::afterLast" );
815 	DBG_TRACE2("DBACCESS ORowSetBase::afterLast() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
816 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
817 
818 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
819 	checkPositioningAllowed();
820 
821 	sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
822 
823 	if((bWasNew || !m_bAfterLast) && notifyAllListenersCursorBeforeMove(aGuard) )
824 	{
825 		// check if we are inserting a row
826 		ORowSetNotifier aNotifier( this );
827 			// this will call cancelRowModification on the cache if necessary
828 
829 		if(!m_bAfterLast)
830 		{
831 			ORowSetRow aOldValues = getOldRow(bWasNew);
832 
833 			m_pCache->afterLast();
834 			doCancelModification( );
835 
836 			// notification order
837 			// - column values
838 			// - cursorMoved
839 			setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
840 
841 			// - IsModified
842 			// - Isnew
843 			aNotifier.fire();
844 
845 			// - RowCount/IsRowCountFinal
846 			fireRowcount();
847 		}
848 	}
849 	DBG_TRACE2("DBACCESS ORowSetBase::afterLast() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
850 }
851 // -----------------------------------------------------------------------------
852 sal_Bool SAL_CALL ORowSetBase::move(	::std::mem_fun_t<sal_Bool,ORowSetBase>& _aCheckFunctor,
853 										::std::mem_fun_t<sal_Bool,ORowSetCache>& _aMovementFunctor)
854 {
855     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::move" );
856 	DBG_TRACE2("DBACCESS ORowSetBase::move() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
857 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
858 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
859 	checkPositioningAllowed();
860 
861 	sal_Bool bRet( notifyAllListenersCursorBeforeMove( aGuard ) );
862 	if( bRet )
863 	{
864 		// check if we are inserting a row
865 		sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
866 
867 		ORowSetNotifier aNotifier( this );
868 			// this will call cancelRowModification on the cache if necessary
869 
870 		ORowSetRow aOldValues = getOldRow(bWasNew);
871 
872 		sal_Bool bMoved = ( bWasNew || !_aCheckFunctor(this) );
873 
874 		bRet = _aMovementFunctor(m_pCache);
875 		doCancelModification( );
876 
877 		if ( bRet )
878 		{
879 			// notification order
880 			// - column values
881 			// - cursorMoved
882 			setCurrentRow( bMoved, sal_True, aOldValues, aGuard );
883 		}
884 		else
885 		{	// first goes wrong so there is no row
886 			movementFailed();
887 		}
888 
889 		// - IsModified
890 		// - IsNew
891 		aNotifier.fire();
892 
893 		// - RowCount/IsRowCountFinal
894 		fireRowcount();
895 	}
896 	DBG_TRACE2("DBACCESS ORowSetBase::move() = %i Clone = %i\n",bRet,m_bClone);
897 	return bRet;
898 }
899 // -------------------------------------------------------------------------
900 sal_Bool SAL_CALL ORowSetBase::first(  ) throw(SQLException, RuntimeException)
901 {
902     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::first" );
903 	DBG_TRACE2("DBACCESS ORowSetBase::first() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
904 	::std::mem_fun_t<sal_Bool,ORowSetBase> ioF_tmp(&ORowSetBase::isOnFirst);
905 	::std::mem_fun_t<sal_Bool,ORowSetCache> F_tmp(&ORowSetCache::first);
906 	return move(ioF_tmp,F_tmp);
907 }
908 // -------------------------------------------------------------------------
909 sal_Bool SAL_CALL ORowSetBase::last(  ) throw(SQLException, RuntimeException)
910 {
911     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::last" );
912 	DBG_TRACE2("DBACCESS ORowSetBase::last() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
913 	::std::mem_fun_t<sal_Bool,ORowSetBase> ioL_tmp(&ORowSetBase::isOnLast);
914 	::std::mem_fun_t<sal_Bool,ORowSetCache> L_tmp(&ORowSetCache::last);
915 	return move(ioL_tmp,L_tmp);
916 }
917 // -------------------------------------------------------------------------
918 sal_Int32 SAL_CALL ORowSetBase::getRow(  ) throw(SQLException, RuntimeException)
919 {
920     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getRow" );
921 	DBG_TRACE2("DBACCESS ORowSetBase::getRow() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
922 	::osl::MutexGuard aGuard( *m_pMutex );
923 
924 	checkCache();
925     return impl_getRow();
926 }
927 // -------------------------------------------------------------------------
928 sal_Int32 ORowSetBase::impl_getRow()
929 {
930     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getRow" );
931 	sal_Int32  nPos = 0;
932     if ( m_bBeforeFirst )
933         nPos = 0;
934     else if ( m_bAfterLast )
935         nPos = impl_getRowCount() + 1;
936     else if ( impl_rowDeleted() )
937         nPos = m_nDeletedPosition;
938     else if ( !m_bClone && m_pCache->m_bNew )
939         nPos = 0;
940     else
941     {
942         if  (   m_pCache->isAfterLast()
943             ||  m_pCache->isBeforeFirst()
944             ||  ( m_pCache->compareBookmarks( m_aBookmark, m_pCache->getBookmark() ) != CompareBookmark::EQUAL )
945             )
946 		{
947             positionCache( MOVE_NONE_REFRESH_ONLY );
948 		}
949 		nPos = m_pCache->getRow();
950     }
951 	DBG_TRACE3("DBACCESS ORowSetBase::impl_getRow() = %i Clone = %i ID = %i\n",nPos,m_bClone,osl_getThreadIdentifier(NULL));
952 	return nPos;
953 }
954 // -------------------------------------------------------------------------
955 sal_Bool SAL_CALL ORowSetBase::absolute( sal_Int32 row ) throw(SQLException, RuntimeException)
956 {
957     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::absolute" );
958 	DBG_TRACE2("DBACCESS ORowSetBase::absolute(%i) Clone = %i\n",row,m_bClone);
959 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
960 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
961 	checkPositioningAllowed();
962 
963 	sal_Bool bRet = ( row > 0 )
964                 &&  notifyAllListenersCursorBeforeMove( aGuard );
965 	if ( bRet )
966 	{
967 		// check if we are inserting a row
968 		sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
969 
970 		ORowSetNotifier aNotifier( this );
971 			// this will call cancelRowModification on the cache if necessary
972 
973 		ORowSetRow aOldValues = getOldRow(bWasNew);
974 
975 		bRet = m_pCache->absolute(row);
976 		doCancelModification( );
977 
978 		if(bRet)
979 		{
980 			// notification order
981 			// - column values
982 			// - cursorMoved
983 			setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
984 		}
985 		else
986 		{ // absolute movement goes wrong we stand left or right side of the rows
987 			movementFailed();
988 		}
989 
990 		// - IsModified
991 		// - IsNew
992 		aNotifier.fire();
993 
994 		// - RowCount/IsRowCountFinal
995 		fireRowcount();
996 	}
997 	DBG_TRACE3("DBACCESS ORowSetBase::absolute(%i) = %i Clone = %i\n",row,bRet,m_bClone);
998 	return bRet;
999 }
1000 // -------------------------------------------------------------------------
1001 sal_Bool SAL_CALL ORowSetBase::relative( sal_Int32 rows ) throw(SQLException, RuntimeException)
1002 {
1003     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::relative" );
1004 	DBG_TRACE2("DBACCESS ORowSetBase::relative(%i) Clone = %i\n",rows,m_bClone);
1005 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
1006 
1007 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
1008 
1009 	if(!rows)
1010 		return sal_True; // in this case do nothing
1011 
1012 	checkPositioningAllowed();
1013 
1014 	sal_Bool bRet =
1015             (  ( !m_bAfterLast || rows <= 0 )
1016             && ( !m_bBeforeFirst || rows >= 0 )
1017             && notifyAllListenersCursorBeforeMove( aGuard )
1018             );
1019 
1020 	if ( bRet )
1021 	{
1022 		// check if we are inserting a row
1023 		sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
1024 
1025 		ORowSetNotifier aNotifier( this );
1026 			// this will call cancelRowModification on the cache if necessary
1027 
1028 		ORowSetRow aOldValues = getOldRow(bWasNew);
1029 
1030         positionCache( rows > 0 ? MOVE_FORWARD : MOVE_BACKWARD );
1031 		bRet = m_pCache->relative(rows);
1032 		doCancelModification( );
1033 
1034 		if(bRet)
1035 		{
1036 			// notification order
1037 			// - column values
1038 			// - cursorMoved
1039 			setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
1040 		}
1041 		else
1042 		{
1043 			movementFailed();
1044 		}
1045 
1046 		// - IsModified
1047 		// - IsNew
1048 		aNotifier.fire();
1049 
1050 		// - RowCount/IsRowCountFinal
1051 		fireRowcount();
1052 	}
1053 	DBG_TRACE3("DBACCESS ORowSetBase::relative(%i) = %i Clone = %i\n",rows,bRet,m_bClone);
1054 	return bRet;
1055 }
1056 // -------------------------------------------------------------------------
1057 sal_Bool SAL_CALL ORowSetBase::previous(  ) throw(SQLException, RuntimeException)
1058 {
1059     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::previous" );
1060 	DBG_TRACE2("DBACCESS ORowSetBase::previous() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1061 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
1062 	::osl::ResettableMutexGuard aGuard( *m_pMutex );
1063 
1064 	checkPositioningAllowed();
1065 
1066 	sal_Bool bRet = !m_bBeforeFirst
1067                 &&  notifyAllListenersCursorBeforeMove(aGuard);
1068 
1069 	if ( bRet )
1070 	{
1071 		// check if we are inserting a row
1072 		sal_Bool bWasNew = m_pCache->m_bNew || rowDeleted();
1073 
1074 		ORowSetNotifier aNotifier( this );
1075 			// this will call cancelRowModification on the cache if necessary
1076 
1077 		ORowSetRow aOldValues = getOldRow(bWasNew);
1078 
1079 		positionCache( MOVE_BACKWARD );
1080 		bRet = m_pCache->previous();
1081 		doCancelModification( );
1082 
1083 		// if m_bBeforeFirst is false and bRet is false than we stood on the first row
1084 		if(!m_bBeforeFirst || bRet)
1085 		{
1086 			// notification order
1087 			// - column values
1088 			// - cursorMoved
1089 			setCurrentRow( sal_True, sal_True, aOldValues, aGuard );
1090 		}
1091 		else
1092 		{
1093             DBG_ERROR( "ORowSetBase::previous: inconsistency!" );
1094                 // we should never reach this place, as we should not get into this whole branch if m_bBeforeFirst
1095                 // was |true| from the beginning
1096 			movementFailed();
1097 		}
1098 
1099 		// - IsModified
1100 		// - IsNew
1101 		aNotifier.fire();
1102 
1103 		// - RowCount/IsRowCountFinal
1104 		fireRowcount();
1105 	}
1106 	DBG_TRACE2("DBACCESS ORowSetBase::previous() = %i Clone = %i\n",bRet,m_bClone);
1107 	return bRet;
1108 }
1109 // -----------------------------------------------------------------------------
1110 void ORowSetBase::setCurrentRow( sal_Bool _bMoved, sal_Bool _bDoNotify, const ORowSetRow& _rOldValues, ::osl::ResettableMutexGuard& _rGuard )
1111 {
1112     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::setCurrentRow" );
1113 	DBG_TRACE2("DBACCESS ORowSetBase::setCurrentRow() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1114 	m_bBeforeFirst	= m_pCache->isBeforeFirst();
1115 	m_bAfterLast	= m_pCache->isAfterLast();
1116 	//m_pCache->resetInsertRow(sal_True);
1117 
1118 	if(!(m_bBeforeFirst || m_bAfterLast))
1119 	{
1120 		m_aBookmark		= m_pCache->getBookmark();
1121 		OSL_ENSURE(m_aBookmark.hasValue(),"Bookmark has no value!");
1122 		m_aCurrentRow	= m_pCache->m_aMatrixIter;
1123 		m_bIsInsertRow	= sal_False;
1124 		OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is null!");
1125 		m_aCurrentRow.setBookmark(m_aBookmark);
1126 		OSL_ENSURE(!m_aCurrentRow.isNull() && m_aCurrentRow != m_pCache->getEnd(),"Position of matrix iterator isn't valid!");
1127 		OSL_ENSURE(m_aCurrentRow->isValid(),"Currentrow isn't valid");
1128 		OSL_ENSURE(m_aBookmark.hasValue(),"Bookmark has no value!");
1129 
1130 #if OSL_DEBUG_LEVEL > 0
1131 		sal_Int32 nOldRow = m_pCache->getRow();
1132 #endif
1133 		positionCache( MOVE_NONE_REFRESH_ONLY );
1134 #if OSL_DEBUG_LEVEL > 0
1135 		sal_Int32 nNewRow = m_pCache->getRow();
1136 #endif
1137 		OSL_ENSURE(nOldRow == nNewRow,"Old position is not equal to new postion");
1138 		m_aCurrentRow	= m_pCache->m_aMatrixIter;
1139 		m_bIsInsertRow	= sal_False;
1140 		OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!");
1141 #if OSL_DEBUG_LEVEL > 0
1142         ORowSetRow rRow = (*m_aCurrentRow);
1143         OSL_ENSURE(rRow.isValid() ,"Invalid size of vector!");
1144 #endif
1145 		// the cache could repositioned so we need to adjust the cache
1146 		// #104144# OJ
1147         if ( _bMoved && m_aCurrentRow.isNull() )
1148 	    {
1149 			positionCache( MOVE_NONE_REFRESH_ONLY );
1150 			m_aCurrentRow	= m_pCache->m_aMatrixIter;
1151 			m_bIsInsertRow	= sal_False;
1152 			OSL_ENSURE(!m_aCurrentRow.isNull(),"CurrentRow is nul after positionCache!");
1153 	    }
1154 	}
1155 	else
1156 	{
1157 		m_aOldRow->clearRow();
1158 		m_aCurrentRow	= m_pCache->getEnd();
1159 		m_aBookmark		= Any();
1160 		m_aCurrentRow.setBookmark(m_aBookmark);
1161 	}
1162 
1163 	// notification order
1164 	// - column values
1165     if ( _bDoNotify )
1166 	    firePropertyChange(_rOldValues);
1167 
1168 	// TODO: can this be done before the notifications?
1169 	if(!(m_bBeforeFirst || m_bAfterLast) && !m_aCurrentRow.isNull() && m_aCurrentRow->isValid() && m_aCurrentRow != m_pCache->getEnd())
1170 		m_aOldRow->setRow(new ORowSetValueVector(m_aCurrentRow->getBody()));
1171 
1172 	if ( _bMoved && _bDoNotify )
1173 		// - cursorMoved
1174 		notifyAllListenersCursorMoved( _rGuard );
1175 
1176 	DBG_TRACE2("DBACCESS ORowSetBase::setCurrentRow() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1177 }
1178 // -----------------------------------------------------------------------------
1179 void ORowSetBase::checkPositioningAllowed() throw( SQLException, RuntimeException )
1180 {
1181     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::checkPositioningAllowed" );
1182 	if(!m_pCache || m_nResultSetType == ResultSetType::FORWARD_ONLY)
1183 		throwFunctionSequenceException(*m_pMySelf);
1184 }
1185 //------------------------------------------------------------------------------
1186 Reference< XInterface >  ORowSetBase::getStatement(void) throw( SQLException, RuntimeException )
1187 {
1188     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getStatement" );
1189 	return NULL;
1190 }
1191 // -------------------------------------------------------------------------
1192 void SAL_CALL ORowSetBase::refreshRow(  ) throw(SQLException, RuntimeException)
1193 {
1194     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::refreshRow" );
1195 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
1196 	::osl::MutexGuard aGuard( *m_pMutex );
1197 	checkCache();
1198     if ( impl_rowDeleted() )
1199         throwSQLException( "The current row is deleted", SQL_INVALID_CURSOR_STATE, Reference< XRowSet >( this ) );
1200 
1201 	if(!(m_bBeforeFirst || m_bAfterLast))
1202 	{
1203         sal_Bool bWasNew = m_pCache->m_bNew || impl_rowDeleted();
1204         ORowSetRow aOldValues = getOldRow(bWasNew);
1205 		positionCache( MOVE_NONE_REFRESH_ONLY );
1206 		m_pCache->refreshRow();
1207         firePropertyChange(aOldValues);
1208 	}
1209 }
1210 // -------------------------------------------------------------------------
1211 sal_Bool SAL_CALL ORowSetBase::rowUpdated(  ) throw(SQLException, RuntimeException)
1212 {
1213     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowUpdated" );
1214 	::osl::MutexGuard aGuard( *m_pMutex );
1215 	checkCache();
1216 
1217     if ( impl_rowDeleted() )
1218         return sal_False;
1219 
1220 	return m_pCache->rowUpdated();
1221 }
1222 // -------------------------------------------------------------------------
1223 sal_Bool SAL_CALL ORowSetBase::rowInserted(  ) throw(SQLException, RuntimeException)
1224 {
1225     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowInserted" );
1226 	::osl::MutexGuard aGuard( *m_pMutex );
1227 
1228 	checkCache();
1229 
1230     if ( impl_rowDeleted() )
1231         return sal_False;
1232 
1233 	return m_pCache->rowInserted();
1234 }
1235 // -------------------------------------------------------------------------
1236 sal_Bool SAL_CALL ORowSetBase::rowDeleted(  ) throw(SQLException, RuntimeException)
1237 {
1238     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::rowDeleted" );
1239 	::osl::MutexGuard aGuard( *m_pMutex );
1240 	checkCache();
1241     return impl_rowDeleted();
1242 }
1243 // -------------------------------------------------------------------------
1244 sal_Bool ORowSetBase::impl_rowDeleted(  )
1245 {
1246     return !m_aBookmark.hasValue() && !m_bBeforeFirst && !m_bAfterLast;
1247 }
1248 // -------------------------------------------------------------------------
1249 // XWarningsSupplier
1250 Any SAL_CALL ORowSetBase::getWarnings(  ) throw(SQLException, RuntimeException)
1251 {
1252     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getWarnings" );
1253 	::osl::MutexGuard aGuard( *m_pMutex );
1254 
1255     if ( m_pCache )
1256     {
1257         Reference< XWarningsSupplier > xWarnings( m_pCache->m_xSet.get(), UNO_QUERY );
1258         if ( xWarnings.is() )
1259             return xWarnings->getWarnings();
1260     }
1261 
1262     return Any();
1263 }
1264 // -------------------------------------------------------------------------
1265 void SAL_CALL ORowSetBase::clearWarnings(  ) throw(SQLException, RuntimeException)
1266 {
1267     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::clearWarnings" );
1268 	::osl::MutexGuard aGuard( *m_pMutex );
1269 
1270     if ( m_pCache )
1271     {
1272         Reference< XWarningsSupplier > xWarnings( m_pCache->m_xSet.get(), UNO_QUERY );
1273         if ( xWarnings.is() )
1274             xWarnings->clearWarnings();
1275     }
1276 }
1277 // -------------------------------------------------------------------------
1278 void ORowSetBase::firePropertyChange(const ORowSetRow& _rOldRow)
1279 {
1280     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::firePropertyChange" );
1281 	DBG_TRACE2("DBACCESS ORowSetBase::firePropertyChange() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1282 	OSL_ENSURE(m_pColumns,"Columns can not be NULL here!");
1283 #if OSL_DEBUG_LEVEL > 1
1284 	sal_Bool bNull;
1285 	ORowSetMatrix::iterator atest;
1286     bNull = m_aCurrentRow.isNull();
1287     atest = m_aCurrentRow;
1288 #endif
1289 	sal_Int32 i=0;
1290 	try
1291 	{
1292         TDataColumns::iterator aEnd = m_aDataColumns.end();
1293 		for(TDataColumns::iterator aIter = m_aDataColumns.begin();aIter != aEnd;++aIter,++i) // #104278# OJ ++i inserted
1294 			(*aIter)->fireValueChange(_rOldRow.isValid() ? (_rOldRow->get())[i+1] : ::connectivity::ORowSetValue());
1295 	}
1296 	catch(Exception&)
1297 	{
1298 		OSL_ENSURE(0,"firePropertyChange: Exception");
1299 	}
1300 	DBG_TRACE2("DBACCESS ORowSetBase::firePropertyChange() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1301 }
1302 // -------------------------------------------------------------------------
1303 void ORowSetBase::firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rOldValue)
1304 {
1305 	OSL_ENSURE(_nPos < (sal_Int32)m_aDataColumns.size(),"nPos is invalid!");
1306 	m_aDataColumns[_nPos]->fireValueChange(_rOldValue);
1307 }
1308 // -----------------------------------------------------------------------------
1309 void ORowSetBase::fireRowcount()
1310 {
1311     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::fireRowcount" );
1312 }
1313 
1314 // -----------------------------------------------------------------------------
1315 sal_Bool ORowSetBase::notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& /*_rGuard*/)
1316 {
1317     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListenersCursorBeforeMove" );
1318     return sal_True;
1319 }
1320 
1321 // -----------------------------------------------------------------------------
1322 void ORowSetBase::notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& /*_rGuard*/)
1323 {
1324     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListenersCursorMoved" );
1325 }
1326 
1327 // -----------------------------------------------------------------------------
1328 void ORowSetBase::notifyAllListeners(::osl::ResettableMutexGuard& /*_rGuard*/)
1329 {
1330     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::notifyAllListeners" );
1331 }
1332 
1333 // -----------------------------------------------------------------------------
1334 void ORowSetBase::fireProperty( sal_Int32 _nProperty, sal_Bool _bNew, sal_Bool _bOld )
1335 {
1336     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::fireProperty" );
1337 	Any aNew = bool2any( _bNew );
1338 	Any aOld = bool2any( _bOld );
1339 	fire( &_nProperty, &aNew, &aOld, 1, sal_False );
1340 }
1341 
1342 // -----------------------------------------------------------------------------
1343 void ORowSetBase::positionCache( CursorMoveDirection _ePrepareForDirection )
1344 {
1345     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::positionCache" );
1346 	DBG_TRACE2("DBACCESS ORowSetBase::positionCache() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1347 
1348     sal_Bool bSuccess = sal_False;
1349 	if ( m_aBookmark.hasValue() )
1350 	{
1351 		bSuccess = m_pCache->moveToBookmark( m_aBookmark );
1352 	}
1353 	else
1354     {
1355         if ( m_bBeforeFirst )
1356         {
1357             bSuccess = m_pCache->beforeFirst();
1358         }
1359         else if ( m_bAfterLast )
1360         {
1361             bSuccess = m_pCache->afterLast();
1362         }
1363         else
1364         {
1365             OSL_ENSURE( m_nDeletedPosition >= 1, "ORowSetBase::positionCache: no bookmark, and no valid 'deleted position'!" );
1366             switch ( _ePrepareForDirection )
1367             {
1368             case MOVE_FORWARD:
1369                 if ( m_nDeletedPosition > 1 )
1370                     bSuccess = m_pCache->absolute( m_nDeletedPosition - 1 );
1371                 else
1372                 {
1373                     m_pCache->beforeFirst();
1374                     bSuccess = sal_True;
1375                 }
1376                 break;
1377 
1378             case MOVE_BACKWARD:
1379                 if ( m_pCache->m_bRowCountFinal && ( m_nDeletedPosition == impl_getRowCount() ) )
1380                 {
1381                     m_pCache->afterLast();
1382                     bSuccess = sal_True;
1383                 }
1384                 else
1385                     bSuccess = m_pCache->absolute( m_nDeletedPosition );
1386                 break;
1387 
1388             case MOVE_NONE_REFRESH_ONLY:
1389                 bSuccess = sal_False;   // will be asserted below
1390                 break;
1391             }
1392         }
1393     }
1394 	OSL_ENSURE( bSuccess, "ORowSetBase::positionCache: failed!" );
1395 
1396     DBG_TRACE2("DBACCESS ORowSetBase::positionCache() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1397 }
1398 // -----------------------------------------------------------------------------
1399 void ORowSetBase::checkCache()
1400 {
1401     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::checkCache" );
1402 	::connectivity::checkDisposed(m_rBHelper.bDisposed);
1403 	if(!m_pCache)
1404 		throwFunctionSequenceException(*m_pMySelf);
1405 }
1406 // -----------------------------------------------------------------------------
1407 void ORowSetBase::movementFailed()
1408 {
1409     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::movementFailed" );
1410 	DBG_TRACE2("DBACCESS ORowSetBase::movementFailed() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1411 	m_aOldRow->clearRow();
1412 	m_aCurrentRow	= m_pCache->getEnd();
1413 	m_bBeforeFirst	= m_pCache->isBeforeFirst();
1414 	m_bAfterLast	= m_pCache->isAfterLast();
1415 	m_aBookmark		= Any();
1416 	m_aCurrentRow.setBookmark(m_aBookmark);
1417 	OSL_ENSURE(m_bBeforeFirst || m_bAfterLast,"BeforeFirst or AfterLast is wrong!");
1418 	DBG_TRACE2("DBACCESS ORowSetBase::movementFailed() Clone = %i ID = %i\n",m_bClone,osl_getThreadIdentifier(NULL));
1419 }
1420 // -----------------------------------------------------------------------------
1421 ORowSetRow ORowSetBase::getOldRow(sal_Bool _bWasNew)
1422 {
1423     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getOldRow" );
1424 	OSL_ENSURE(m_aOldRow.isValid(),"RowSetRowHElper isn't valid!");
1425 	ORowSetRow aOldValues;
1426 	if ( !_bWasNew && m_aOldRow->getRow().isValid() )
1427 		aOldValues = new ORowSetValueVector( m_aOldRow->getRow().getBody());	 // remember the old values
1428 	return aOldValues;
1429 }
1430 // -----------------------------------------------------------------------------
1431 void ORowSetBase::getPropertyDefaultByHandle( sal_Int32 /*_nHandle*/, Any& _rDefault ) const
1432 {
1433     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::getPropertyDefaultByHandle" );
1434 	_rDefault.clear();
1435 }
1436 // -----------------------------------------------------------------------------
1437 void ORowSetBase::onDeleteRow( const Any& _rBookmark )
1438 {
1439     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::onDeleteRow" );
1440     if ( rowDeleted() )
1441         // not interested in
1442         return;
1443 
1444 	::osl::MutexGuard aGuard( *m_pMutex );
1445 	//OSL_ENSURE( m_aBookmark.hasValue(), "ORowSetBase::onDeleteRow: Bookmark isn't valid!" );
1446 	if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 )
1447     {
1448         positionCache( MOVE_NONE_REFRESH_ONLY );
1449 		m_nDeletedPosition = m_pCache->getRow();
1450     }
1451 }
1452 // -----------------------------------------------------------------------------
1453 void ORowSetBase::onDeletedRow( const Any& _rBookmark, sal_Int32 _nPos )
1454 {
1455     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::onDeletedRow" );
1456     if ( rowDeleted() )
1457     {
1458         // if we're a clone, and on a deleted row, and the main RowSet deleted another
1459         // row (only the main RowSet can, clones can't), which is *before* our
1460         // deleted position, then we have to adjust this position
1461         if ( m_bClone && ( _nPos < m_nDeletedPosition ) )
1462             --m_nDeletedPosition;
1463         return;
1464     }
1465 
1466 	::osl::MutexGuard aGuard( *m_pMutex );
1467 	if ( compareBookmarks( _rBookmark, m_aBookmark ) == 0 )
1468 	{
1469 		m_aOldRow->clearRow();
1470 		m_aCurrentRow	= m_pCache->getEnd();
1471 		m_aBookmark		= Any();
1472 		m_aCurrentRow.setBookmark( m_aBookmark );
1473 	}
1474 }
1475 // -----------------------------------------------------------------------------
1476 sal_Int32 ORowSetBase::impl_getRowCount() const
1477 {
1478     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetBase::impl_getRowCount" );
1479     sal_Int32 nRowCount( m_pCache->m_nRowCount );
1480     if ( const_cast< ORowSetBase* >( this )->rowDeleted() && !m_pCache->m_bNew )
1481         ++nRowCount;
1482     return nRowCount;
1483 }
1484 // =============================================================================
1485 struct ORowSetNotifierImpl
1486 {
1487     ::std::vector<sal_Int32>    aChangedColumns;
1488     ::std::vector<Any>          aChangedBookmarks;
1489     ORowSetValueVector::Vector  aRow;
1490 
1491 };
1492 DBG_NAME(ORowSetNotifier)
1493 // -----------------------------------------------------------------------------
1494 ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet )
1495 	:m_pRowSet( _pRowSet )
1496 	,m_bWasNew( sal_False )
1497 	,m_bWasModified( sal_False )
1498 #ifdef DBG_UTIL
1499 	,m_bNotifyCalled( sal_False )
1500 #endif
1501 {
1502     DBG_CTOR(ORowSetNotifier,NULL);
1503 
1504 	OSL_ENSURE( m_pRowSet, "ORowSetNotifier::ORowSetNotifier: invalid row set. This wil crash." );
1505 
1506 	// remember the "inserted" and "modified" state for later firing
1507 	m_bWasNew		= m_pRowSet->isNew( ORowSetBase::GrantNotifierAccess() );
1508 	m_bWasModified	= m_pRowSet->isModified( ORowSetBase::GrantNotifierAccess() );
1509 
1510 	// if the row set is on the insert row, then we need to cancel this
1511 	if ( m_pRowSet->isModification( ORowSetBase::GrantNotifierAccess() ) )
1512 		m_pRowSet->doCancelModification( ORowSetBase::GrantNotifierAccess() );
1513 }
1514 // -----------------------------------------------------------------------------
1515 ORowSetNotifier::ORowSetNotifier( ORowSetBase* _pRowSet,const ORowSetValueVector::Vector& i_aRow )
1516     :m_pImpl(new ORowSetNotifierImpl)
1517     ,m_pRowSet( _pRowSet )
1518 	,m_bWasNew( sal_False )
1519 	,m_bWasModified( sal_False )
1520 #ifdef DBG_UTIL
1521 	,m_bNotifyCalled( sal_False )
1522 #endif
1523 {
1524     DBG_CTOR(ORowSetNotifier,NULL);
1525 
1526 	OSL_ENSURE( m_pRowSet, "ORowSetNotifier::ORowSetNotifier: invalid row set. This wil crash." );
1527     m_pImpl->aRow = i_aRow; // yes, create a copy to store the old values
1528 }
1529 // -----------------------------------------------------------------------------
1530 ORowSetNotifier::~ORowSetNotifier( )
1531 {
1532     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ORowSetNotifier::~ORowSetNotifier" );
1533     DBG_DTOR(ORowSetNotifier,NULL);
1534 }
1535 
1536 // -----------------------------------------------------------------------------
1537 void ORowSetNotifier::fire()
1538 {
1539 	// we're not interested in firing changes FALSE->TRUE, only TRUE->FALSE.
1540 	// (the former would be quite pathological, e.g. after a failed movement)
1541 
1542 	if	(	m_bWasModified
1543 		&&	( m_bWasModified != m_pRowSet->isModified( ORowSetBase::GrantNotifierAccess() ) )
1544 		)
1545 		m_pRowSet->fireProperty( PROPERTY_ID_ISMODIFIED, sal_False, sal_True, ORowSetBase::GrantNotifierAccess() );
1546 
1547 	if	(	m_bWasNew
1548 		&&	( m_bWasNew != m_pRowSet->isNew( ORowSetBase::GrantNotifierAccess() ) )
1549 		)
1550 		m_pRowSet->fireProperty( PROPERTY_ID_ISNEW, sal_False, sal_True, ORowSetBase::GrantNotifierAccess() );
1551 
1552 #ifdef DBG_UTIL
1553 	m_bNotifyCalled = sal_True;
1554 #endif
1555 }
1556 // -----------------------------------------------------------------------------
1557 ::std::vector<sal_Int32>& ORowSetNotifier::getChangedColumns() const
1558 {
1559     OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!");
1560     return m_pImpl->aChangedColumns;
1561 }
1562 // -----------------------------------------------------------------------------
1563 ::std::vector<Any>& ORowSetNotifier::getChangedBookmarks() const
1564 {
1565     OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!");
1566     return m_pImpl->aChangedBookmarks;
1567 }
1568 // -----------------------------------------------------------------------------
1569 void ORowSetNotifier::firePropertyChange()
1570 {
1571     OSL_ENSURE(m_pImpl.get(),"Illegal CTor call, use the other one!");
1572     if( m_pImpl.get() )
1573     {
1574         ::std::vector<sal_Int32>::iterator aIter = m_pImpl->aChangedColumns.begin();
1575         for(;aIter != m_pImpl->aChangedColumns.end();++aIter)
1576         {
1577             m_pRowSet->firePropertyChange((*aIter)-1 ,m_pImpl->aRow[(*aIter)-1], ORowSetBase::GrantNotifierAccess());
1578         }
1579 		if ( !m_pImpl->aChangedColumns.empty() )
1580 			m_pRowSet->fireProperty(PROPERTY_ID_ISMODIFIED,sal_True,sal_False, ORowSetBase::GrantNotifierAccess());
1581     }
1582 }
1583 }	// namespace dbaccess
1584