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