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 #ifndef DBACCESS_CORE_API_ROWSETBASE_HXX
28 #define DBACCESS_CORE_API_ROWSETBASE_HXX
29 
30 #ifndef _CPPUHELPER_IMPLBASE10_HXX_
31 #include <cppuhelper/implbase10.hxx>
32 #endif
33 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_
34 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
35 #endif
36 #ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
37 #include <com/sun/star/sdbc/XRow.hpp>
38 #endif
39 #ifndef _COM_SUN_STAR_SDBC_XCOLUMNLOCATE_HPP_
40 #include <com/sun/star/sdbc/XColumnLocate.hpp>
41 #endif
42 #ifndef _COM_SUN_STAR_SDBC_XCLOSEABLE_HPP_
43 #include <com/sun/star/sdbc/XCloseable.hpp>
44 #endif
45 #ifndef _COM_SUN_STAR_SDBCX_XROWLOCATE_HPP_
46 #include <com/sun/star/sdbcx/XRowLocate.hpp>
47 #endif
48 #ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_
49 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
50 #endif
51 #ifndef _COM_SUN_STAR_SDBC_XWARNINGSSUPPLIER_HPP_
52 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
53 #endif
54 #ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
55 #include <com/sun/star/lang/XServiceInfo.hpp>
56 #endif
57 #ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
58 #include <com/sun/star/lang/XUnoTunnel.hpp>
59 #endif
60 #ifndef _CPPUHELPER_INTERFACECONTAINER_H_
61 #include <cppuhelper/interfacecontainer.h>
62 #endif
63 #ifndef CONNECTIVITY_SQLERROR_HXX
64 #include <connectivity/sqlerror.hxx>
65 #endif
66 #ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
67 #include <connectivity/CommonTools.hxx>
68 #endif
69 #ifndef COMPHELPER_PROPERTYSTATECONTAINER_HXX
70 #include <comphelper/propertystatecontainer.hxx>
71 #endif
72 #ifndef _COMPHELPER_PROPERTY_ARRAY_HELPER_HXX_
73 #include <comphelper/proparrhlp.hxx>
74 #endif
75 #ifndef _COM_SUN_STAR_SDBC_XROWSET_HPP_
76 #include <com/sun/star/sdbc/XRowSet.hpp>
77 #endif
78 #ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTYPES_HPP_
79 #include <com/sun/star/util/XNumberFormatTypes.hpp>
80 #endif
81 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
82 #include <com/sun/star/container/XNameAccess.hpp>
83 #endif
84 #ifndef DBACCESS_CORE_API_ROWSETROW_HXX
85 #include "RowSetRow.hxx"
86 #endif
87 #ifndef _COMPHELPER_BROADCASTHELPER_HXX_
88 #include <comphelper/broadcasthelper.hxx>
89 #endif
90 #ifndef DBACCESS_ROWSETCACHEITERATOR_HXX
91 #include "RowSetCacheIterator.hxx"
92 #endif
93 #include "core_resource.hxx"
94 #include <comphelper/componentcontext.hxx>
95 
96 #include <functional>
97 
98 
99 namespace com { namespace sun { namespace star {
100 	namespace sdb { struct RowChangeEvent; }
101 	namespace lang { struct Locale; }
102 } } }
103 
104 namespace dbaccess
105 {
106 	class OEmptyCollection;
107 
108 	typedef ::cppu::ImplHelper10<				::com::sun::star::sdbcx::XRowLocate,
109 												::com::sun::star::sdbc::XRow,
110 												::com::sun::star::sdbc::XResultSetMetaDataSupplier,
111 												::com::sun::star::sdbc::XWarningsSupplier,
112 												::com::sun::star::sdbc::XColumnLocate,
113 												::com::sun::star::sdbcx::XColumnsSupplier,
114 												::com::sun::star::lang::XServiceInfo,
115 												::com::sun::star::sdbc::XRowSet,
116 												::com::sun::star::sdbc::XCloseable,
117 												::com::sun::star::lang::XUnoTunnel> ORowSetBase_BASE;
118 
119 	class ORowSetCache;
120 	class ORowSetDataColumns;
121 	class ORowSetCacheIterator;
122 	class ORowSetDataColumn;
123 	class ORowSetBase : public ORowSetBase_BASE,
124 						public ::comphelper::OPropertyStateContainer,
125 						public ::comphelper::OPropertyArrayUsageHelper<ORowSetBase> // this class hold the static property info
126 	{
127         OModuleClient                           m_aModuleClient;
128 	protected:
129 		typedef ::std::vector<ORowSetDataColumn*>	TDataColumns;
130 		::osl::Mutex*							m_pMutex;			// this the mutex form the rowset itself
131 		::osl::Mutex							m_aRowCountMutex, // mutex for rowcount changes
132 												// we need a extra mutex for columns to prevend deadlock when setting new values
133 												// for a row
134 												m_aColumnsMutex;
135 
136 		::com::sun::star::uno::Any				m_aBookmark;
137 		ORowSetCacheIterator					m_aCurrentRow;		// contains the actual fetched row
138 		TORowSetOldRowHelperRef					m_aOldRow;
139 		TDataColumns							m_aDataColumns;		// holds the columns as m_pColumns but know the implementation class
140 		connectivity::ORowSetValue				m_aEmptyValue;		// only for error case
141 
142 		::cppu::OWeakObject*					m_pMySelf;			// set by derived classes
143 		ORowSetCache*							m_pCache;			// the cache is used by the rowset and his clone (shared)
144 		ORowSetDataColumns*						m_pColumns;			// represent the select columns
145 		::cppu::OBroadcastHelper&				m_rBHelper;			// must be set from the derived classes
146 		// is used when the formatkey for database types is set
147 		::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatTypes>	m_xNumberFormatTypes;
148 		OEmptyCollection*																m_pEmptyCollection;
149 
150         ::comphelper::ComponentContext          m_aContext;
151         ::connectivity::SQLError                m_aErrors;
152 
153 		sal_Int32								m_nLastColumnIndex;	// the last column ask for, used for wasNull()
154 		sal_Int32								m_nDeletedPosition; // is set only when a row was deleted
155 		sal_Int32								m_nResultSetType;	// fetch property
156         sal_Int32                               m_nResultSetConcurrency;
157 		sal_Bool								m_bClone;			// I'm clone or not
158 		sal_Bool								m_bIgnoreResult ;
159 		sal_Bool								m_bBeforeFirst	: 1;
160 		sal_Bool								m_bAfterLast	: 1;
161 		sal_Bool								m_bIsInsertRow	: 1;
162 
163 	protected:
164 		ORowSetBase(
165             const ::comphelper::ComponentContext& _rContext,
166             ::cppu::OBroadcastHelper& _rBHelper,
167             ::osl::Mutex* _pMutex
168         );
169 
170 		// fire a notification for all that are listening on column::VALUE property
171 		void firePropertyChange(const ORowSetRow& _rOldRow);
172         // fire a change for one column
173 		// _nPos starts at zero
174         void firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rNewValue);
175 
176         // fire if rowcount changed
177 		virtual void fireRowcount();
178         // notify row changed
179 		virtual sal_Bool notifyAllListenersCursorBeforeMove(::osl::ResettableMutexGuard& _rGuard);
180         // notify cursor moved
181 		virtual void notifyAllListenersCursorMoved(::osl::ResettableMutexGuard& _rGuard);
182         // notify all that rowset changed
183 		virtual void notifyAllListeners(::osl::ResettableMutexGuard& _rGuard);
184 
185 		// cancel the insertion, if necessary (means if we're on the insert row)
186 		virtual void		doCancelModification( ) = 0;
187 		// return <TRUE/> if and only if we're using the insert row (means: we're updating _or_ inserting)
188 		virtual sal_Bool	isModification( ) = 0;
189 		// return <TRUE/> if and only if the current row is modified
190 		// TODO: isn't this the same as isModification?
191 		virtual sal_Bool	isModified( ) = 0;
192 		// return <TRUE/> if and only if the current row is the insert row
193 		virtual sal_Bool	isNew( ) = 0;
194 		// notify the change of a boolean property
195 		void fireProperty( sal_Int32 _nProperty, sal_Bool _bNew, sal_Bool _bOld );
196 
197 	// OPropertyStateContainer
198 		virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, ::com::sun::star::uno::Any& _rDefault ) const;
199 		virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue,sal_Int32 nHandle) const;
200 
201         enum CursorMoveDirection
202         {
203             /// denotes a cursor move forward
204             MOVE_FORWARD,
205             /// denotes a cursor  move backwards
206             MOVE_BACKWARD,
207             /// denotes no cursor move at all, used when the current row is to be refreshed only
208             MOVE_NONE_REFRESH_ONLY
209         };
210         /** positions the cache in preparation of a cursor move
211 
212             Normally, the cache is simply moved to our bookmark (m_aBookmark). If however the current
213             row is deleted, then the cache is properly positioned for a following cursor movement in the
214             given direction.
215 
216             @param _ePrepareForDirection
217                 the direction into which the cursor should be moved after the call. If we're currently not on
218                 a deleted row, this parameter is ignored, since in this case the cache is simply moved to
219                 m_aBookmark.</br>
220                 If, however, we're currently on a deleted row, this is used to properly position the cache
221                 using <member>m_nDeletedPosition</member>.<br/>
222                 In this case, MOVE_NONE_REFRESH_ONLY is not supported. This is because the deleted row
223                 (to which the RowSet currently points to) is not present in the cache. So, you cannot move the
224                 cache to this row.
225         */
226 		void positionCache( CursorMoveDirection _ePrepareForDirection );
227 
228         // returns a value of a column of the current row
229 		const connectivity::ORowSetValue& getValue(sal_Int32 columnIndex);
230         // the cache has to be checked before calling this method
231         const connectivity::ORowSetValue& impl_getValue(sal_Int32 columnIndex);
232 		// sets the current and the bookmark
233 		void setCurrentRow( sal_Bool _bMoved, sal_Bool _bDoNotify, const ORowSetRow& _rOldValues, ::osl::ResettableMutexGuard& _rGuard);
234 		void checkPositioningAllowed() throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
235 		// checks  if the cache is null
236 		void checkCache();
237 		// sets the bookmark to Any()
238 		// m_aCurrentRow to end of matrix
239 		// m_aOldRow to NULL
240 		void movementFailed();
241 
242 		ORowSetRow getOldRow(sal_Bool _bWasNew);
243 		/** move the cache the postion defined by the member functor
244 			@param	_aCheckFunctor
245 				Return <TRUE/> when we already stand on the row we want to.
246 			@param	_aMovementFunctor
247 				The mehtod used to move.
248 			@return
249 				<TRUE/> if movement was successful.
250 		*/
251 		sal_Bool SAL_CALL move(	::std::mem_fun_t<sal_Bool,ORowSetBase>& _aCheckFunctor,
252 								::std::mem_fun_t<sal_Bool,ORowSetCache>& _aMovementFunctor);
253 
254 		/** same meaning as isFirst. Only need by mem_fun
255 			@return
256 				<TRUE/> if so.
257 		*/
258 		sal_Bool isOnFirst();
259 		/** same meaning as isLast. Only need by mem_fun
260 			@return
261 				<TRUE/> if so.
262 		*/
263 		sal_Bool isOnLast();
264 
265         /** returns the current row count
266 
267             This function takes into account that we might actually be positioned on a
268             deleted row, so that m_pCache->m_nRowCount does not really reflect the actual
269             count.
270 
271             @precond
272                 Our mutext is locked.
273         */
274         sal_Int32   impl_getRowCount() const;
275 
276         // the checkCache has to be called before calling this methods
277         sal_Bool    impl_wasNull();
278         sal_Int32   impl_getRow();
279         sal_Bool    impl_rowDeleted();
280 
281     public:
282 		virtual ~ORowSetBase();
283 
284 	// OComponentHelper
285 		virtual void SAL_CALL disposing(void);
286 
287 	// com::sun::star::beans::XPropertySet
288 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException)
289 		{
290 			return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
291 		}
292 
293 	// comphelper::OPropertyArrayUsageHelper
294 		virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
295 
296 	// cppu::OPropertySetHelper
297 		virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
298 
299 	// com::sun::star::lang::XTypeProvider
300 		virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
301 
302 	// com::sun::star::uno::XInterface
303 		virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException);
304 
305 	// ::com::sun::star::sdbc::XWarningsSupplier
306 		virtual ::com::sun::star::uno::Any SAL_CALL getWarnings(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
307 		virtual void SAL_CALL clearWarnings(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
308 
309 	// ::com::sun::star::sdbc::XResultSetMetaDataSupplier
310 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL getMetaData(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
311 
312 	// ::com::sun::star::sdbc::XColumnLocate
313 		virtual sal_Int32 SAL_CALL findColumn( const ::rtl::OUString& columnName ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
314 
315 	// ::com::sun::star::sdbcx::XColumnsSupplier
316 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getColumns(  ) throw(::com::sun::star::uno::RuntimeException);
317 
318 	// ::com::sun::star::sdbc::XRow
319 		virtual sal_Bool SAL_CALL wasNull(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
320 		virtual ::rtl::OUString SAL_CALL getString( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
321 		virtual sal_Bool SAL_CALL getBoolean( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
322 		virtual sal_Int8 SAL_CALL getByte( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
323 		virtual sal_Int16 SAL_CALL getShort( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
324 		virtual sal_Int32 SAL_CALL getInt( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
325 		virtual sal_Int64 SAL_CALL getLong( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
326 		virtual float SAL_CALL getFloat( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
327 		virtual double SAL_CALL getDouble( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
328 		virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getBytes( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
329 		virtual ::com::sun::star::util::Date SAL_CALL getDate( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
330 		virtual ::com::sun::star::util::Time SAL_CALL getTime( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
331 		virtual ::com::sun::star::util::DateTime SAL_CALL getTimestamp( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
332 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getBinaryStream( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
333 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getCharacterStream( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
334 		virtual ::com::sun::star::uno::Any SAL_CALL getObject( sal_Int32 columnIndex, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& typeMap ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
335 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRef > SAL_CALL getRef( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
336 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XBlob > SAL_CALL getBlob( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
337 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XClob > SAL_CALL getClob( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
338 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XArray > SAL_CALL getArray( sal_Int32 columnIndex ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
339 
340 	// ::com::sun::star::sdbcx::XRowLocate
341 		virtual ::com::sun::star::uno::Any SAL_CALL getBookmark(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
342 		virtual sal_Bool SAL_CALL moveToBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
343 		virtual sal_Bool SAL_CALL moveRelativeToBookmark( const ::com::sun::star::uno::Any& bookmark, sal_Int32 rows ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
344 		virtual sal_Int32 SAL_CALL compareBookmarks( const ::com::sun::star::uno::Any& first, const ::com::sun::star::uno::Any& second ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
345 		virtual sal_Bool SAL_CALL hasOrderedBookmarks(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
346 		virtual sal_Int32 SAL_CALL hashBookmark( const ::com::sun::star::uno::Any& bookmark ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
347 
348 	// ::com::sun::star::sdbc::XResultSet
349 		virtual sal_Bool SAL_CALL next(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
350 		virtual sal_Bool SAL_CALL isBeforeFirst(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
351 		virtual sal_Bool SAL_CALL isAfterLast(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
352 		virtual sal_Bool SAL_CALL isFirst(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
353 		virtual sal_Bool SAL_CALL isLast(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
354 		virtual void SAL_CALL beforeFirst(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
355 		virtual void SAL_CALL afterLast(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
356 		virtual sal_Bool SAL_CALL first(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
357 		virtual sal_Bool SAL_CALL last(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
358 		virtual sal_Int32 SAL_CALL getRow(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
359 		virtual sal_Bool SAL_CALL absolute( sal_Int32 row ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
360 		virtual sal_Bool SAL_CALL relative( sal_Int32 rows ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
361 		virtual sal_Bool SAL_CALL previous(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
362 		virtual void SAL_CALL refreshRow(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
363 		virtual sal_Bool SAL_CALL rowUpdated(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
364 		virtual sal_Bool SAL_CALL rowInserted(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
365 		virtual sal_Bool SAL_CALL rowDeleted(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
366 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getStatement(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
367 
368 	// ::com::sun::star::sdbc::XRowSet
369 		virtual void SAL_CALL execute(  ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException) = 0;
370 		virtual void SAL_CALL addRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) = 0;
371 		virtual void SAL_CALL removeRowSetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSetListener >& listener ) throw(::com::sun::star::uno::RuntimeException) = 0;
372 
373 		// is called when the rowset is going to delete this bookmark _rBookmark
374 		void onDeleteRow( const ::com::sun::star::uno::Any& _rBookmark );
375 		// is called when the rowset has deleted this bookmark _rBookmark
376 		void onDeletedRow( const ::com::sun::star::uno::Any& _rBookmark, sal_Int32 _nPos );
377 
378 		// ==========================================================
379 		// granular access control
380 		struct GrantNotifierAccess { friend class ORowSetNotifier; private: GrantNotifierAccess () { } };
381 
382 		// cancel the insertion, if necessary (means if we're on the insert row)
383 		inline	void		doCancelModification( const GrantNotifierAccess& ) { doCancelModification(); }
384 		inline	sal_Bool	isModification( const GrantNotifierAccess& ) { return isModification(); }
385 		inline	sal_Bool	isModified( const GrantNotifierAccess& ) { return isModified(); }
386 		inline	sal_Bool	isNew( const GrantNotifierAccess& ) { return isNew(); }
387 		inline	sal_Bool	isInsertRow() { return m_bIsInsertRow; } // isNew() || isModified(); }
388 		inline	void		fireProperty( sal_Int32 _nProperty, sal_Bool _bNew, sal_Bool _bOld, const GrantNotifierAccess& )
389 		{
390 			fireProperty( _nProperty, _bNew, _bOld );
391 		}
392         inline	void firePropertyChange(sal_Int32 _nPos,const ::connectivity::ORowSetValue& _rNewValue, const GrantNotifierAccess& )
393 		{
394 			firePropertyChange(_nPos,_rNewValue);
395 		}
396         using ::comphelper::OPropertyStateContainer::getFastPropertyValue;
397 
398 		::osl::Mutex*	getMutex() const { return m_pMutex; }
399 	};
400 
401 	// ========================================================================
402 	/** eases the handling of the doCancelModification and notifyCancelInsert methods
403 
404 		<p>The class can only be used on the stack, within a method of ORowSetBase (or derivees)</p>
405 	*/
406     struct ORowSetNotifierImpl;
407 	class ORowSetNotifier
408 	{
409 	private:
410         ::std::auto_ptr<ORowSetNotifierImpl> m_pImpl;
411 		ORowSetBase*	m_pRowSet;
412 			// not aquired! This is not necessary because this class here is to be used on the stack within
413 			// a method of ORowSetBase (or derivees)
414 		sal_Bool		m_bWasNew;
415 		sal_Bool		m_bWasModified;
416 
417 #ifdef DBG_UTIL
418 		sal_Bool		m_bNotifyCalled;
419 #endif
420 
421 	public:
422 		/** constructs the object, and cancels the insertion
423 
424 			@see ORowSetBase::doCancelModification
425 		*/
426 		ORowSetNotifier( ORowSetBase* m_pRowSet );
427 
428         /** use this one to consturct an vector for change value notification
429         */
430         ORowSetNotifier( ORowSetBase* m_pRowSet,const ORowSetValueVector::Vector& i_aRow );
431 
432 		// destructs the object. <member>fire</member> has to be called before.
433 		~ORowSetNotifier( );
434 
435 		/** notifies the insertion
436 
437 			<p>This has <em>not</em> been put into the destructor by intention!<br/>
438 
439 			The destructor is called during stack unwinding in case of an exception, so if we would do
440 			listener notification there, this would have the potential of another exception during stack
441 			unwinding, which would terminate the application.</p>
442 
443 			@see ORowSetBase::notifyCancelInsert
444 		*/
445 		void	fire();
446 
447         /** notifies value change events and notifies IsModified
448             @param  i_aChangedColumns   the index of the changed value columns
449             @param  i_aRow              the old values
450             @see ORowSetBase::notifyCancelInsert
451         */
452         void    firePropertyChange();
453 
454         /** use this one to store the inde of the changed column values
455         */
456         ::std::vector<sal_Int32>& getChangedColumns() const;
457         ::std::vector<com::sun::star::uno::Any>& getChangedBookmarks() const;
458 
459 	};
460 
461 } // end of namespace
462 
463 #endif // DBACCESS_CORE_API_ROWSETBASE_HXX
464 
465