196de5490SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
396de5490SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
496de5490SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
596de5490SAndrew Rist  * distributed with this work for additional information
696de5490SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
796de5490SAndrew Rist  * to you under the Apache License, Version 2.0 (the
896de5490SAndrew Rist  * "License"); you may not use this file except in compliance
996de5490SAndrew Rist  * with the License.  You may obtain a copy of the License at
1096de5490SAndrew Rist  *
1196de5490SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1296de5490SAndrew Rist  *
1396de5490SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1496de5490SAndrew Rist  * software distributed under the License is distributed on an
1596de5490SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1696de5490SAndrew Rist  * KIND, either express or implied.  See the License for the
1796de5490SAndrew Rist  * specific language governing permissions and limitations
1896de5490SAndrew Rist  * under the License.
1996de5490SAndrew Rist  *
2096de5490SAndrew Rist  *************************************************************/
2196de5490SAndrew Rist 
2296de5490SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_dbaccess.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "BookmarkSet.hxx"
29cdf0e10cSrcweir #include "CRowSetColumn.hxx"
30cdf0e10cSrcweir #include "CRowSetDataColumn.hxx"
31cdf0e10cSrcweir #include "KeySet.hxx"
32cdf0e10cSrcweir #include "OptimisticSet.hxx"
33cdf0e10cSrcweir #include "RowSetBase.hxx"
34cdf0e10cSrcweir #include "RowSetCache.hxx"
35cdf0e10cSrcweir #include "StaticSet.hxx"
36cdf0e10cSrcweir #include "WrappedResultSet.hxx"
37cdf0e10cSrcweir #include "core_resource.hrc"
38cdf0e10cSrcweir #include "core_resource.hxx"
39cdf0e10cSrcweir #include "dbastrings.hrc"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir /** === begin UNO includes === **/
42cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
43cdf0e10cSrcweir #include <com/sun/star/sdbc/ResultSetConcurrency.hpp>
44cdf0e10cSrcweir #include <com/sun/star/sdbcx/CompareBookmark.hpp>
45cdf0e10cSrcweir #include <com/sun/star/sdbcx/KeyType.hpp>
46cdf0e10cSrcweir #include <com/sun/star/sdbcx/Privilege.hpp>
47cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
48cdf0e10cSrcweir #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
49cdf0e10cSrcweir #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
50cdf0e10cSrcweir /** === end UNO includes === **/
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #include <comphelper/extract.hxx>
53cdf0e10cSrcweir #include <comphelper/property.hxx>
54cdf0e10cSrcweir #include <comphelper/seqstream.hxx>
55cdf0e10cSrcweir #include <comphelper/uno3.hxx>
56cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
57cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
58cdf0e10cSrcweir #include <connectivity/sqliterator.hxx>
59cdf0e10cSrcweir #include <connectivity/sqlnode.hxx>
60cdf0e10cSrcweir #include <connectivity/sqlparse.hxx>
61cdf0e10cSrcweir #include <tools/debug.hxx>
62cdf0e10cSrcweir #include <tools/diagnose_ex.h>
63cdf0e10cSrcweir 
64cdf0e10cSrcweir #include <algorithm>
65cdf0e10cSrcweir 
66cdf0e10cSrcweir using namespace dbaccess;
67cdf0e10cSrcweir using namespace dbtools;
68cdf0e10cSrcweir using namespace connectivity;
69cdf0e10cSrcweir using namespace ::com::sun::star::uno;
70cdf0e10cSrcweir using namespace ::com::sun::star::beans;
71cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
72cdf0e10cSrcweir using namespace ::com::sun::star::sdb;
73cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx;
74cdf0e10cSrcweir using namespace ::com::sun::star::container;
75cdf0e10cSrcweir using namespace ::com::sun::star::lang;
76cdf0e10cSrcweir using namespace ::cppu;
77cdf0e10cSrcweir using namespace ::osl;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir #define CHECK_MATRIX_POS(M) OSL_ENSURE(((M) >= static_cast<ORowSetMatrix::difference_type>(0)) && ((M) < static_cast<sal_Int32>(m_pMatrix->size())),"Position is invalid!")
80cdf0e10cSrcweir 
DBG_NAME(ORowSetCache)81cdf0e10cSrcweir DBG_NAME(ORowSetCache)
82cdf0e10cSrcweir // -------------------------------------------------------------------------
83cdf0e10cSrcweir ORowSetCache::ORowSetCache(const Reference< XResultSet >& _xRs,
84cdf0e10cSrcweir 						   const Reference< XSingleSelectQueryAnalyzer >& _xAnalyzer,
85cdf0e10cSrcweir                            const ::comphelper::ComponentContext& _rContext,
86cdf0e10cSrcweir 						   const ::rtl::OUString& _rUpdateTableName,
87cdf0e10cSrcweir 						   sal_Bool&	_bModified,
88cdf0e10cSrcweir 						   sal_Bool&	_bNew,
89cdf0e10cSrcweir                            const ORowSetValueVector& _aParameterValueForCache,
90cdf0e10cSrcweir                            const ::rtl::OUString& i_sRowSetFilter,
91cdf0e10cSrcweir                            sal_Int32 i_nMaxRows)
92cdf0e10cSrcweir 	:m_xSet(_xRs)
93cdf0e10cSrcweir 	,m_xMetaData(Reference< XResultSetMetaDataSupplier >(_xRs,UNO_QUERY)->getMetaData())
94cdf0e10cSrcweir 	,m_aContext( _rContext )
95cdf0e10cSrcweir     ,m_pCacheSet(NULL)
96cdf0e10cSrcweir 	,m_pMatrix(NULL)
97cdf0e10cSrcweir 	,m_pInsertMatrix(NULL)
98cdf0e10cSrcweir     ,m_nLastColumnIndex(0)
99cdf0e10cSrcweir 	,m_nFetchSize(0)
100cdf0e10cSrcweir 	,m_nRowCount(0)
101cdf0e10cSrcweir     ,m_nPrivileges( Privilege::SELECT )
102cdf0e10cSrcweir 	,m_nPosition(0)
103cdf0e10cSrcweir     ,m_nStartPos(0)
104cdf0e10cSrcweir 	,m_nEndPos(0)
105cdf0e10cSrcweir 	,m_bRowCountFinal(sal_False)
106cdf0e10cSrcweir     ,m_bBeforeFirst(sal_True)
107cdf0e10cSrcweir 	,m_bAfterLast( sal_False )
108cdf0e10cSrcweir 	,m_bUpdated(sal_False)
109cdf0e10cSrcweir 	,m_bModified(_bModified)
110cdf0e10cSrcweir 	,m_bNew(_bNew)
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     DBG_CTOR(ORowSetCache,NULL);
113cdf0e10cSrcweir 
114cdf0e10cSrcweir     // first try if the result can be used to do inserts and updates
115cdf0e10cSrcweir     Reference< XPropertySet> xProp(_xRs,UNO_QUERY);
116cdf0e10cSrcweir     Reference< XPropertySetInfo > xPropInfo = xProp->getPropertySetInfo();
117cdf0e10cSrcweir 	sal_Bool bBookmarkable = sal_False;
118cdf0e10cSrcweir     try
119cdf0e10cSrcweir     {
120cdf0e10cSrcweir         Reference< XResultSetUpdate> xUp(_xRs,UNO_QUERY_THROW);
121cdf0e10cSrcweir 	    bBookmarkable = xPropInfo->hasPropertyByName(PROPERTY_ISBOOKMARKABLE) &&
122cdf0e10cSrcweir 							    any2bool(xProp->getPropertyValue(PROPERTY_ISBOOKMARKABLE)) && Reference< XRowLocate >(_xRs, UNO_QUERY).is();
123cdf0e10cSrcweir         if ( bBookmarkable )
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir             xUp->moveToInsertRow();
126cdf0e10cSrcweir             xUp->cancelRowUpdates();
127cdf0e10cSrcweir             _xRs->beforeFirst();
128cdf0e10cSrcweir             m_nPrivileges = Privilege::SELECT|Privilege::DELETE|Privilege::INSERT|Privilege::UPDATE;
129cdf0e10cSrcweir             m_pCacheSet = new WrappedResultSet(i_nMaxRows);
130cdf0e10cSrcweir             m_xCacheSet = m_pCacheSet;
131cdf0e10cSrcweir 		    m_pCacheSet->construct(_xRs,i_sRowSetFilter);
132cdf0e10cSrcweir             return;
133cdf0e10cSrcweir         }
134cdf0e10cSrcweir     }
135cdf0e10cSrcweir     catch(const Exception& ex)
136cdf0e10cSrcweir     {
137cdf0e10cSrcweir         (void)ex;
138cdf0e10cSrcweir     }
139cdf0e10cSrcweir     try
140cdf0e10cSrcweir     {
141cdf0e10cSrcweir         if ( xPropInfo->hasPropertyByName(PROPERTY_RESULTSETTYPE) &&
142cdf0e10cSrcweir 							::comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETTYPE)) != ResultSetType::FORWARD_ONLY)
143cdf0e10cSrcweir             _xRs->beforeFirst();
144cdf0e10cSrcweir     }
145cdf0e10cSrcweir     catch(const SQLException& e)
146cdf0e10cSrcweir     {
147cdf0e10cSrcweir         (void)e;
148cdf0e10cSrcweir     }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir 	// check if all keys of the updateable table are fetched
151cdf0e10cSrcweir 	sal_Bool bAllKeysFound = sal_False;
152cdf0e10cSrcweir 	sal_Int32 nTablesCount = 0;
153cdf0e10cSrcweir 
154cdf0e10cSrcweir 	sal_Bool bNeedKeySet = !bBookmarkable || (xPropInfo->hasPropertyByName(PROPERTY_RESULTSETCONCURRENCY) &&
155cdf0e10cSrcweir 							::comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETCONCURRENCY)) == ResultSetConcurrency::READ_ONLY);
156cdf0e10cSrcweir 
157cdf0e10cSrcweir     Reference< XIndexAccess> xUpdateTableKeys;
158cdf0e10cSrcweir 	::rtl::OUString aUpdateTableName = _rUpdateTableName;
159cdf0e10cSrcweir 	Reference< XConnection> xConnection;
160cdf0e10cSrcweir     // first we need a connection
161cdf0e10cSrcweir 	Reference< XStatement> xStmt(_xRs->getStatement(),UNO_QUERY);
162cdf0e10cSrcweir 	if(xStmt.is())
163cdf0e10cSrcweir 		xConnection = xStmt->getConnection();
164cdf0e10cSrcweir 	else
165cdf0e10cSrcweir 	{
166cdf0e10cSrcweir 		Reference< XPreparedStatement> xPrepStmt(_xRs->getStatement(),UNO_QUERY);
167cdf0e10cSrcweir 		xConnection = xPrepStmt->getConnection();
168cdf0e10cSrcweir 	}
169cdf0e10cSrcweir 	OSL_ENSURE(xConnection.is(),"No connection!");
170cdf0e10cSrcweir 	if(_xAnalyzer.is())
171cdf0e10cSrcweir 	{
172cdf0e10cSrcweir 		try
173cdf0e10cSrcweir 		{
174cdf0e10cSrcweir 			Reference<XTablesSupplier> xTabSup(_xAnalyzer,UNO_QUERY);
175cdf0e10cSrcweir 			OSL_ENSURE(xTabSup.is(),"ORowSet::execute composer isn't a tablesupplier!");
176cdf0e10cSrcweir 			Reference<XNameAccess> xTables = xTabSup->getTables();
177cdf0e10cSrcweir             Sequence< ::rtl::OUString> aTableNames = xTables->getElementNames();
178cdf0e10cSrcweir             if ( aTableNames.getLength() > 1 && !_rUpdateTableName.getLength() && bNeedKeySet )
179cdf0e10cSrcweir             {// here we have a join or union and nobody told us which table to update, so we update them all
180cdf0e10cSrcweir                 m_nPrivileges = Privilege::SELECT|Privilege::DELETE|Privilege::INSERT|Privilege::UPDATE;
181cdf0e10cSrcweir                 OptimisticSet* pCursor = new OptimisticSet(m_aContext,xConnection,_xAnalyzer,_aParameterValueForCache,i_nMaxRows,m_nRowCount);
182cdf0e10cSrcweir                 m_pCacheSet = pCursor;
183cdf0e10cSrcweir                 m_xCacheSet = m_pCacheSet;
184cdf0e10cSrcweir                 try
185cdf0e10cSrcweir                 {
186cdf0e10cSrcweir 		            m_pCacheSet->construct(_xRs,i_sRowSetFilter);
187cdf0e10cSrcweir                     if ( pCursor->isReadOnly() )
188cdf0e10cSrcweir                         m_nPrivileges = Privilege::SELECT;
189cdf0e10cSrcweir                     m_aKeyColumns = pCursor->getJoinedKeyColumns();
190cdf0e10cSrcweir                     return;
191cdf0e10cSrcweir                 }
192cdf0e10cSrcweir                 catch(const Exception&)
193cdf0e10cSrcweir                 {
194cdf0e10cSrcweir                     // DBG_UNHANDLED_EXCEPTION();
195cdf0e10cSrcweir                 }
196cdf0e10cSrcweir                 m_pCacheSet = NULL;
197cdf0e10cSrcweir                 m_xCacheSet.clear();
198cdf0e10cSrcweir             }
199cdf0e10cSrcweir             else
200cdf0e10cSrcweir             {
201cdf0e10cSrcweir 			    if(_rUpdateTableName.getLength() && xTables->hasByName(_rUpdateTableName))
202cdf0e10cSrcweir 				    xTables->getByName(_rUpdateTableName) >>= m_aUpdateTable;
203cdf0e10cSrcweir 			    else if(xTables->getElementNames().getLength())
204cdf0e10cSrcweir 			    {
205cdf0e10cSrcweir 				    aUpdateTableName = xTables->getElementNames()[0];
206cdf0e10cSrcweir 				    xTables->getByName(aUpdateTableName) >>= m_aUpdateTable;
207cdf0e10cSrcweir 			    }
208cdf0e10cSrcweir 			    Reference<XIndexAccess> xIndexAccess(xTables,UNO_QUERY);
209cdf0e10cSrcweir 			    if(xIndexAccess.is())
210cdf0e10cSrcweir 				    nTablesCount = xIndexAccess->getCount();
211cdf0e10cSrcweir 			    else
212cdf0e10cSrcweir 				    nTablesCount = xTables->getElementNames().getLength();
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 			    if(m_aUpdateTable.is() && nTablesCount < 3) // for we can't handle more than 2 tables in our keyset
215cdf0e10cSrcweir 			    {
216cdf0e10cSrcweir                     Reference<XPropertySet> xSet(m_aUpdateTable,UNO_QUERY);
217cdf0e10cSrcweir                     const Reference<XNameAccess> xPrimaryKeyColumns = dbtools::getPrimaryKeyColumns_throw(xSet);
218cdf0e10cSrcweir                     if ( xPrimaryKeyColumns.is() )
219cdf0e10cSrcweir                     {
220cdf0e10cSrcweir 					    Reference<XColumnsSupplier> xColSup(_xAnalyzer,UNO_QUERY);
221cdf0e10cSrcweir 					    if ( xColSup.is() )
222cdf0e10cSrcweir 					    {
223cdf0e10cSrcweir 						    Reference<XNameAccess> xSelColumns = xColSup->getColumns();
224cdf0e10cSrcweir 						    Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
225cdf0e10cSrcweir                             SelectColumnsMetaData aColumnNames(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() ? true : false);
226cdf0e10cSrcweir 						    ::dbaccess::getColumnPositions(xSelColumns,xPrimaryKeyColumns->getElementNames(),aUpdateTableName,aColumnNames);
227cdf0e10cSrcweir 						    bAllKeysFound = !aColumnNames.empty() && sal_Int32(aColumnNames.size()) == xPrimaryKeyColumns->getElementNames().getLength();
228cdf0e10cSrcweir 					    }
229cdf0e10cSrcweir 				    }
230cdf0e10cSrcweir 			    }
231cdf0e10cSrcweir             }
232cdf0e10cSrcweir 		}
233cdf0e10cSrcweir 		catch(Exception&)
234cdf0e10cSrcweir 		{
235cdf0e10cSrcweir 		}
236cdf0e10cSrcweir 	}
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 	// first check if resultset is bookmarkable
239cdf0e10cSrcweir 	if(!bNeedKeySet)
240cdf0e10cSrcweir 	{
241cdf0e10cSrcweir 		try
242cdf0e10cSrcweir 		{
243cdf0e10cSrcweir 			m_pCacheSet = new OBookmarkSet(i_nMaxRows);
244cdf0e10cSrcweir 			m_xCacheSet = m_pCacheSet;
245cdf0e10cSrcweir 			m_pCacheSet->construct(_xRs,i_sRowSetFilter);
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 			// check privileges
248cdf0e10cSrcweir 			m_nPrivileges = Privilege::SELECT;
249cdf0e10cSrcweir 			if(Reference<XResultSetUpdate>(_xRs,UNO_QUERY).is())  // this interface is optional so we have to check it
250cdf0e10cSrcweir 			{
251cdf0e10cSrcweir 				Reference<XPropertySet> xTable(m_aUpdateTable,UNO_QUERY);
252cdf0e10cSrcweir 				if(xTable.is() && xTable->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES))
253cdf0e10cSrcweir 				{
254cdf0e10cSrcweir 					m_nPrivileges = 0;
255cdf0e10cSrcweir 					xTable->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
256cdf0e10cSrcweir 					if(!m_nPrivileges)
257cdf0e10cSrcweir 						m_nPrivileges = Privilege::SELECT;
258cdf0e10cSrcweir 				}
259cdf0e10cSrcweir 			}
260cdf0e10cSrcweir 		}
261cdf0e10cSrcweir 		catch(const SQLException&)
262cdf0e10cSrcweir 		{
263cdf0e10cSrcweir 			bNeedKeySet = sal_True;
264cdf0e10cSrcweir 		}
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 	}
267cdf0e10cSrcweir 	if(bNeedKeySet)
268cdf0e10cSrcweir 	{
269cdf0e10cSrcweir 		// need to check if we could handle this select clause
270cdf0e10cSrcweir 		bAllKeysFound = bAllKeysFound && (nTablesCount == 1 || checkJoin(xConnection,_xAnalyzer,aUpdateTableName));
271cdf0e10cSrcweir 
272cdf0e10cSrcweir 		// || !(comphelper::hasProperty(PROPERTY_CANUPDATEINSERTEDROWS,xProp) && any2bool(xProp->getPropertyValue(PROPERTY_CANUPDATEINSERTEDROWS)))
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 		// oj removed because keyset uses only the next// || (xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_RESULTSETTYPE) && comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETTYPE)) == ResultSetType::FORWARD_ONLY)
275cdf0e10cSrcweir 		if(!bAllKeysFound )
276cdf0e10cSrcweir 		{
277cdf0e10cSrcweir 			if ( bBookmarkable )
278cdf0e10cSrcweir 			{
279cdf0e10cSrcweir 				// here I know that we have a read only bookmarable cursor
280cdf0e10cSrcweir 				_xRs->beforeFirst();
281cdf0e10cSrcweir 				m_nPrivileges = Privilege::SELECT;
282cdf0e10cSrcweir 				m_pCacheSet = new WrappedResultSet(i_nMaxRows);
283cdf0e10cSrcweir 				m_xCacheSet = m_pCacheSet;
284cdf0e10cSrcweir 				m_pCacheSet->construct(_xRs,i_sRowSetFilter);
285cdf0e10cSrcweir 				return;
286cdf0e10cSrcweir 			}
287cdf0e10cSrcweir 			m_pCacheSet = new OStaticSet(i_nMaxRows);
288cdf0e10cSrcweir 			m_xCacheSet = m_pCacheSet;
289cdf0e10cSrcweir 			m_pCacheSet->construct(_xRs,i_sRowSetFilter);
290cdf0e10cSrcweir 			m_nPrivileges = Privilege::SELECT;
291cdf0e10cSrcweir 		}
292cdf0e10cSrcweir 		else
293cdf0e10cSrcweir 		{
294cdf0e10cSrcweir 			Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
295cdf0e10cSrcweir             SelectColumnsMetaData aColumnNames(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() ? true : false);
296cdf0e10cSrcweir 			Reference<XColumnsSupplier> xColSup(_xAnalyzer,UNO_QUERY);
297cdf0e10cSrcweir 			Reference<XNameAccess> xSelColumns	= xColSup->getColumns();
298cdf0e10cSrcweir 			Reference<XNameAccess> xColumns		= m_aUpdateTable->getColumns();
299cdf0e10cSrcweir 			::dbaccess::getColumnPositions(xSelColumns,xColumns->getElementNames(),aUpdateTableName,aColumnNames);
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 			// check privileges
302cdf0e10cSrcweir 			m_nPrivileges = Privilege::SELECT;
303cdf0e10cSrcweir 			sal_Bool bNoInsert = sal_False;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 			Sequence< ::rtl::OUString> aNames(xColumns->getElementNames());
306cdf0e10cSrcweir 			const ::rtl::OUString* pIter	= aNames.getConstArray();
307cdf0e10cSrcweir 			const ::rtl::OUString* pEnd		= pIter + aNames.getLength();
308cdf0e10cSrcweir 			for(;pIter != pEnd;++pIter)
309cdf0e10cSrcweir 			{
310cdf0e10cSrcweir 				Reference<XPropertySet> xColumn(xColumns->getByName(*pIter),UNO_QUERY);
311cdf0e10cSrcweir 				OSL_ENSURE(xColumn.is(),"Column in table is null!");
312cdf0e10cSrcweir 				if(xColumn.is())
313cdf0e10cSrcweir 				{
314cdf0e10cSrcweir 					sal_Int32 nNullable = 0;
315cdf0e10cSrcweir 					xColumn->getPropertyValue(PROPERTY_ISNULLABLE) >>= nNullable;
316cdf0e10cSrcweir 					if(nNullable == ColumnValue::NO_NULLS && aColumnNames.find(*pIter) == aColumnNames.end())
317cdf0e10cSrcweir 					{ // we found a column where null is not allowed so we can't insert new values
318cdf0e10cSrcweir 						bNoInsert = sal_True;
319cdf0e10cSrcweir 						break; // one column is enough
320cdf0e10cSrcweir 					}
321cdf0e10cSrcweir 				}
322cdf0e10cSrcweir 			}
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 			OKeySet* pKeySet = new OKeySet(m_aUpdateTable,xUpdateTableKeys,aUpdateTableName ,_xAnalyzer,_aParameterValueForCache,i_nMaxRows,m_nRowCount);
325cdf0e10cSrcweir 			try
326cdf0e10cSrcweir 			{
327cdf0e10cSrcweir 				m_pCacheSet = pKeySet;
328cdf0e10cSrcweir 				m_xCacheSet = m_pCacheSet;
329cdf0e10cSrcweir 				pKeySet->construct(_xRs,i_sRowSetFilter);
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 				if(Reference<XResultSetUpdate>(_xRs,UNO_QUERY).is())  // this interface is optional so we have to check it
332cdf0e10cSrcweir 				{
333cdf0e10cSrcweir 					Reference<XPropertySet> xTable(m_aUpdateTable,UNO_QUERY);
334cdf0e10cSrcweir 					if(xTable.is() && xTable->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES))
335cdf0e10cSrcweir 					{
336cdf0e10cSrcweir 						m_nPrivileges = 0;
337cdf0e10cSrcweir 						xTable->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
338cdf0e10cSrcweir 						if(!m_nPrivileges)
339cdf0e10cSrcweir 							m_nPrivileges = Privilege::SELECT;
340cdf0e10cSrcweir 					}
341cdf0e10cSrcweir 				}
342cdf0e10cSrcweir 				if(bNoInsert)
343cdf0e10cSrcweir 					m_nPrivileges |= ~Privilege::INSERT; // remove the insert privilege
344cdf0e10cSrcweir 			}
345cdf0e10cSrcweir 			catch(const SQLException&)
346cdf0e10cSrcweir 			{
347cdf0e10cSrcweir 				// we couldn't create a keyset here so we have to create a static cache
348cdf0e10cSrcweir 				if ( m_pCacheSet )
349cdf0e10cSrcweir 					m_pCacheSet = NULL;
350cdf0e10cSrcweir 				m_xCacheSet = NULL;
351cdf0e10cSrcweir 				m_pCacheSet = new OStaticSet(i_nMaxRows);
352cdf0e10cSrcweir 				m_xCacheSet = m_pCacheSet;
353cdf0e10cSrcweir 				m_pCacheSet->construct(_xRs,i_sRowSetFilter);
354cdf0e10cSrcweir 				m_nPrivileges = Privilege::SELECT;
355cdf0e10cSrcweir 			}
356cdf0e10cSrcweir 		}
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 	}
359cdf0e10cSrcweir 	// last check
360cdf0e10cSrcweir 	if(!bAllKeysFound && xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_RESULTSETCONCURRENCY) &&
361cdf0e10cSrcweir 		::comphelper::getINT32(xProp->getPropertyValue(PROPERTY_RESULTSETCONCURRENCY)) == ResultSetConcurrency::READ_ONLY)
362cdf0e10cSrcweir 		m_nPrivileges = Privilege::SELECT;
363cdf0e10cSrcweir }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir // -------------------------------------------------------------------------
~ORowSetCache()366cdf0e10cSrcweir ORowSetCache::~ORowSetCache()
367cdf0e10cSrcweir {
368cdf0e10cSrcweir 	m_pCacheSet = NULL;
369cdf0e10cSrcweir 	m_xCacheSet = NULL;
370cdf0e10cSrcweir 	if(m_pMatrix)
371cdf0e10cSrcweir 	{
372cdf0e10cSrcweir 		m_pMatrix->clear();
373cdf0e10cSrcweir 		delete m_pMatrix;
374cdf0e10cSrcweir 	}
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 	if(m_pInsertMatrix)
377cdf0e10cSrcweir 	{
378cdf0e10cSrcweir 		m_pInsertMatrix->clear();
379cdf0e10cSrcweir 		delete m_pInsertMatrix;
380cdf0e10cSrcweir 	}
381cdf0e10cSrcweir 	m_xSet			= WeakReference< XResultSet>();
382cdf0e10cSrcweir 	m_xMetaData		= NULL;
383cdf0e10cSrcweir 	m_aUpdateTable	= NULL;
384cdf0e10cSrcweir 
385cdf0e10cSrcweir     DBG_DTOR(ORowSetCache,NULL);
386cdf0e10cSrcweir }
387cdf0e10cSrcweir 
388cdf0e10cSrcweir // -------------------------------------------------------------------------
setFetchSize(sal_Int32 _nSize)389cdf0e10cSrcweir void ORowSetCache::setFetchSize(sal_Int32 _nSize)
390cdf0e10cSrcweir {
391cdf0e10cSrcweir 	if(_nSize == m_nFetchSize)
392cdf0e10cSrcweir 		return;
393cdf0e10cSrcweir 
394cdf0e10cSrcweir 	m_nFetchSize = _nSize;
395cdf0e10cSrcweir 	if(!m_pMatrix)
396cdf0e10cSrcweir 	{
397cdf0e10cSrcweir 		m_pMatrix = new ORowSetMatrix(_nSize);
398cdf0e10cSrcweir 		m_aMatrixIter = m_pMatrix->end();
399cdf0e10cSrcweir 		m_aMatrixEnd = m_pMatrix->end();
400cdf0e10cSrcweir 
401cdf0e10cSrcweir 		m_pInsertMatrix = new ORowSetMatrix(1); // a little bit overkill but ??? :-)
402cdf0e10cSrcweir 		m_aInsertRow	= m_pInsertMatrix->end();
403cdf0e10cSrcweir 	}
404cdf0e10cSrcweir 	else
405cdf0e10cSrcweir 	{
406cdf0e10cSrcweir 		// now correct the iterator in our iterator vector
407cdf0e10cSrcweir 		::std::vector<sal_Int32> aPositions;
408cdf0e10cSrcweir 		::std::map<sal_Int32,sal_Bool> aCacheIterToChange;
409cdf0e10cSrcweir 		// first get the positions where they stand now
410cdf0e10cSrcweir 		ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
411cdf0e10cSrcweir         ORowSetCacheMap::iterator aCacheEnd = m_aCacheIterators.end();
412cdf0e10cSrcweir 		for(;aCacheIter != aCacheEnd;++aCacheIter)
413cdf0e10cSrcweir 		{
414cdf0e10cSrcweir 			aCacheIterToChange[aCacheIter->first] = sal_False;
415cdf0e10cSrcweir 			if ( !aCacheIter->second.pRowSet->isInsertRow()
416cdf0e10cSrcweir 				/*&& aCacheIter->second.aIterator != m_pMatrix->end()*/ && !m_bModified )
417cdf0e10cSrcweir 			{
418cdf0e10cSrcweir 				ptrdiff_t nDist = (aCacheIter->second.aIterator - m_pMatrix->begin());
419cdf0e10cSrcweir 				aPositions.push_back(nDist);
420cdf0e10cSrcweir 				aCacheIterToChange[aCacheIter->first] = sal_True;
421cdf0e10cSrcweir 			}
422cdf0e10cSrcweir 		}
423cdf0e10cSrcweir 		sal_Int32 nKeyPos = (m_aMatrixIter - m_pMatrix->begin());
424cdf0e10cSrcweir 		m_pMatrix->resize(_nSize);
425cdf0e10cSrcweir 
426cdf0e10cSrcweir         if ( nKeyPos < _nSize )
427cdf0e10cSrcweir 		    m_aMatrixIter = m_pMatrix->begin() + nKeyPos;
428cdf0e10cSrcweir         else
429cdf0e10cSrcweir             m_aMatrixIter = m_pMatrix->end();
430cdf0e10cSrcweir 		m_aMatrixEnd = m_pMatrix->end();
431cdf0e10cSrcweir 
432cdf0e10cSrcweir 		// now adjust their positions because a resize invalid all iterators
433cdf0e10cSrcweir 		::std::vector<sal_Int32>::const_iterator aIter = aPositions.begin();
434cdf0e10cSrcweir 		::std::map<sal_Int32,sal_Bool>::const_iterator aPosChangeIter = aCacheIterToChange.begin();
435cdf0e10cSrcweir 		for(	aCacheIter = m_aCacheIterators.begin();
436cdf0e10cSrcweir 				aPosChangeIter != aCacheIterToChange.end();
437cdf0e10cSrcweir 				++aPosChangeIter,++aCacheIter)
438cdf0e10cSrcweir 		{
439cdf0e10cSrcweir 			if ( aPosChangeIter->second )
440cdf0e10cSrcweir             {
441cdf0e10cSrcweir                 CHECK_MATRIX_POS(*aIter);
442cdf0e10cSrcweir                 if ( *aIter < _nSize )
443cdf0e10cSrcweir 				    aCacheIter->second.aIterator = m_pMatrix->begin() + *aIter++;
444cdf0e10cSrcweir                 else
445cdf0e10cSrcweir                     aCacheIter->second.aIterator = m_pMatrix->end();
446cdf0e10cSrcweir             }
447cdf0e10cSrcweir 		}
448cdf0e10cSrcweir 	}
449cdf0e10cSrcweir 	if(!m_nPosition)
450cdf0e10cSrcweir 	{
451cdf0e10cSrcweir 		sal_Int32 nNewSt = 1;
452cdf0e10cSrcweir 		fillMatrix(nNewSt,_nSize+1);
453cdf0e10cSrcweir 		m_nStartPos = 0;
454cdf0e10cSrcweir 		m_nEndPos = _nSize;
455cdf0e10cSrcweir 	}
456cdf0e10cSrcweir     else if (m_nStartPos < m_nPosition && m_nPosition < m_nEndPos)
457cdf0e10cSrcweir     {
458cdf0e10cSrcweir         sal_Int32 nNewSt = -1;
459cdf0e10cSrcweir         fillMatrix(nNewSt,_nSize+1);
460cdf0e10cSrcweir 		m_nStartPos = 0;
461cdf0e10cSrcweir 		m_nEndPos = _nSize;
462cdf0e10cSrcweir     }
463cdf0e10cSrcweir }
464cdf0e10cSrcweir // -------------------------------------------------------------------------
465cdf0e10cSrcweir 
466cdf0e10cSrcweir // XResultSetMetaDataSupplier
getMetaData()467cdf0e10cSrcweir Reference< XResultSetMetaData > ORowSetCache::getMetaData(  )
468cdf0e10cSrcweir {
469cdf0e10cSrcweir 	return m_xMetaData;
470cdf0e10cSrcweir }
471cdf0e10cSrcweir // -------------------------------------------------------------------------
lcl_getBookmark(ORowSetValue & i_aValue,OCacheSet * i_pCacheSet)472cdf0e10cSrcweir Any lcl_getBookmark(ORowSetValue& i_aValue,OCacheSet* i_pCacheSet)
473cdf0e10cSrcweir {
474cdf0e10cSrcweir     switch ( i_aValue.getTypeKind() )
475cdf0e10cSrcweir 	{
476cdf0e10cSrcweir 		case DataType::TINYINT:
477cdf0e10cSrcweir 		case DataType::SMALLINT:
478cdf0e10cSrcweir 		case DataType::INTEGER:
479cdf0e10cSrcweir 			return makeAny((sal_Int32)i_aValue);
480cdf0e10cSrcweir 		default:
481cdf0e10cSrcweir 			if ( i_pCacheSet && i_aValue.isNull())
482cdf0e10cSrcweir 				i_aValue = i_pCacheSet->getBookmark();
483cdf0e10cSrcweir 			return i_aValue.getAny();
484cdf0e10cSrcweir 	}
485cdf0e10cSrcweir }
486cdf0e10cSrcweir // -------------------------------------------------------------------------
487cdf0e10cSrcweir // ::com::sun::star::sdbcx::XRowLocate
getBookmark()488cdf0e10cSrcweir Any ORowSetCache::getBookmark(  )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir 
491cdf0e10cSrcweir 	if(m_bAfterLast)
492cdf0e10cSrcweir 		throwFunctionSequenceException(m_xSet.get());
493cdf0e10cSrcweir 
494cdf0e10cSrcweir 	if ( m_aMatrixIter >= m_pMatrix->end() || m_aMatrixIter < m_pMatrix->begin() || !(*m_aMatrixIter).isValid())
495cdf0e10cSrcweir 	{
496cdf0e10cSrcweir 		return Any(); // this is allowed here because the rowset knowns what it is doing
497cdf0e10cSrcweir 	}
498cdf0e10cSrcweir 
499cdf0e10cSrcweir 	return lcl_getBookmark(((*m_aMatrixIter)->get())[0],m_pCacheSet);
500cdf0e10cSrcweir }
501cdf0e10cSrcweir // -------------------------------------------------------------------------
moveToBookmark(const Any & bookmark)502cdf0e10cSrcweir sal_Bool ORowSetCache::moveToBookmark( const Any& bookmark )
503cdf0e10cSrcweir {
504cdf0e10cSrcweir 	if ( m_pCacheSet->moveToBookmark(bookmark) )
505cdf0e10cSrcweir 	{
506cdf0e10cSrcweir 		m_bBeforeFirst = sal_False;
507cdf0e10cSrcweir 		m_nPosition	= m_pCacheSet->getRow();
508cdf0e10cSrcweir 
509cdf0e10cSrcweir 		checkPositionFlags();
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 		if(!m_bAfterLast)
512cdf0e10cSrcweir 		{
513cdf0e10cSrcweir 			moveWindow();
514cdf0e10cSrcweir 			checkPositionFlags();
515cdf0e10cSrcweir 			if ( !m_bAfterLast )
516cdf0e10cSrcweir 			{
517cdf0e10cSrcweir 				m_aMatrixIter = calcPosition();
518cdf0e10cSrcweir 				OSL_ENSURE(m_aMatrixIter->isValid(),"Iterator after moveToBookmark not valid");
519cdf0e10cSrcweir 			}
520cdf0e10cSrcweir 			else
521cdf0e10cSrcweir 				m_aMatrixIter = m_pMatrix->end();
522cdf0e10cSrcweir 		}
523cdf0e10cSrcweir 		else
524cdf0e10cSrcweir 			m_aMatrixIter = m_pMatrix->end();
525cdf0e10cSrcweir 	}
526cdf0e10cSrcweir 	else
527cdf0e10cSrcweir 		return sal_False;
528cdf0e10cSrcweir 
529cdf0e10cSrcweir 	return m_aMatrixIter != m_pMatrix->end() && (*m_aMatrixIter).isValid();
530cdf0e10cSrcweir }
531cdf0e10cSrcweir // -------------------------------------------------------------------------
moveRelativeToBookmark(const Any & bookmark,sal_Int32 rows)532cdf0e10cSrcweir sal_Bool ORowSetCache::moveRelativeToBookmark( const Any& bookmark, sal_Int32 rows )
533cdf0e10cSrcweir {
534cdf0e10cSrcweir 	sal_Bool bRet( moveToBookmark( bookmark ) );
535cdf0e10cSrcweir 	if ( bRet )
536cdf0e10cSrcweir 	{
537cdf0e10cSrcweir 		m_nPosition = m_pCacheSet->getRow() + rows;
538cdf0e10cSrcweir 		absolute(m_nPosition);
539cdf0e10cSrcweir 		//	for(sal_Int32 i=0;i<rows && m_aMatrixIter != m_pMatrix->end();++i,++m_aMatrixIter) ;
540cdf0e10cSrcweir 
541cdf0e10cSrcweir 		bRet = m_aMatrixIter != m_pMatrix->end() && (*m_aMatrixIter).isValid();
542cdf0e10cSrcweir 	}
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 	return bRet;
545cdf0e10cSrcweir }
546cdf0e10cSrcweir // -------------------------------------------------------------------------
compareBookmarks(const Any & _first,const Any & _second)547cdf0e10cSrcweir sal_Int32 ORowSetCache::compareBookmarks( const Any& _first, const Any& _second )
548cdf0e10cSrcweir {
549cdf0e10cSrcweir 	return (!_first.hasValue() || !_second.hasValue()) ? CompareBookmark::NOT_COMPARABLE : m_pCacheSet->compareBookmarks(_first,_second);
550cdf0e10cSrcweir }
551cdf0e10cSrcweir // -------------------------------------------------------------------------
hasOrderedBookmarks()552cdf0e10cSrcweir sal_Bool ORowSetCache::hasOrderedBookmarks(  )
553cdf0e10cSrcweir {
554cdf0e10cSrcweir 	return m_pCacheSet->hasOrderedBookmarks();
555cdf0e10cSrcweir }
556cdf0e10cSrcweir // -------------------------------------------------------------------------
hashBookmark(const Any & bookmark)557cdf0e10cSrcweir sal_Int32 ORowSetCache::hashBookmark( const Any& bookmark )
558cdf0e10cSrcweir {
559cdf0e10cSrcweir 	return m_pCacheSet->hashBookmark(bookmark);
560cdf0e10cSrcweir }
561cdf0e10cSrcweir // XRowUpdate
562cdf0e10cSrcweir // -----------------------------------------------------------------------------
updateNull(sal_Int32 columnIndex,ORowSetValueVector::Vector & io_aRow,::std::vector<sal_Int32> & o_ChangedColumns)563cdf0e10cSrcweir void ORowSetCache::updateNull(sal_Int32 columnIndex,ORowSetValueVector::Vector& io_aRow
564cdf0e10cSrcweir                               ,::std::vector<sal_Int32>& o_ChangedColumns
565cdf0e10cSrcweir                               )
566cdf0e10cSrcweir {
567cdf0e10cSrcweir 	checkUpdateConditions(columnIndex);
568cdf0e10cSrcweir 
569cdf0e10cSrcweir     ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get());
570cdf0e10cSrcweir 	if ( !rInsert[columnIndex].isNull() )
571cdf0e10cSrcweir 	{
572cdf0e10cSrcweir 		rInsert[columnIndex].setBound(sal_True);
573cdf0e10cSrcweir 		rInsert[columnIndex].setNull();
574cdf0e10cSrcweir 		rInsert[columnIndex].setModified();
575cdf0e10cSrcweir     	io_aRow[columnIndex].setNull();
576cdf0e10cSrcweir 
577cdf0e10cSrcweir 	    m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns);
578cdf0e10cSrcweir     	impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns);
579cdf0e10cSrcweir 	}
580cdf0e10cSrcweir }
581cdf0e10cSrcweir // -----------------------------------------------------------------------------
updateValue(sal_Int32 columnIndex,const ORowSetValue & x,ORowSetValueVector::Vector & io_aRow,::std::vector<sal_Int32> & o_ChangedColumns)582cdf0e10cSrcweir void ORowSetCache::updateValue(sal_Int32 columnIndex,const ORowSetValue& x
583cdf0e10cSrcweir                                ,ORowSetValueVector::Vector& io_aRow
584cdf0e10cSrcweir                                ,::std::vector<sal_Int32>& o_ChangedColumns
585cdf0e10cSrcweir                                )
586cdf0e10cSrcweir {
587cdf0e10cSrcweir 	checkUpdateConditions(columnIndex);
588cdf0e10cSrcweir 
589cdf0e10cSrcweir     ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get());
590cdf0e10cSrcweir 	if ( rInsert[columnIndex] != x )
591cdf0e10cSrcweir 	{
592cdf0e10cSrcweir 		rInsert[columnIndex].setBound(sal_True);
593cdf0e10cSrcweir 		rInsert[columnIndex] = x;
594cdf0e10cSrcweir 		rInsert[columnIndex].setModified();
595cdf0e10cSrcweir 		io_aRow[columnIndex] = rInsert[columnIndex];
596cdf0e10cSrcweir 
597cdf0e10cSrcweir 		m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns);
598cdf0e10cSrcweir 		impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns);
599cdf0e10cSrcweir 	}
600cdf0e10cSrcweir }
601cdf0e10cSrcweir // -------------------------------------------------------------------------
updateCharacterStream(sal_Int32 columnIndex,const Reference<::com::sun::star::io::XInputStream> & x,sal_Int32 length,ORowSetValueVector::Vector & io_aRow,::std::vector<sal_Int32> & o_ChangedColumns)602cdf0e10cSrcweir void ORowSetCache::updateCharacterStream( sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x
603cdf0e10cSrcweir                                          , sal_Int32 length,ORowSetValueVector::Vector& io_aRow
604cdf0e10cSrcweir                                          ,::std::vector<sal_Int32>& o_ChangedColumns
605cdf0e10cSrcweir                                          )
606cdf0e10cSrcweir {
607cdf0e10cSrcweir 	checkUpdateConditions(columnIndex);
608cdf0e10cSrcweir 
609cdf0e10cSrcweir 	Sequence<sal_Int8> aSeq;
610cdf0e10cSrcweir 	if(x.is())
611cdf0e10cSrcweir 		x->readBytes(aSeq,length);
612cdf0e10cSrcweir 
613cdf0e10cSrcweir     ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get());
614cdf0e10cSrcweir     rInsert[columnIndex].setBound(sal_True);
615cdf0e10cSrcweir 	rInsert[columnIndex] = aSeq;
616cdf0e10cSrcweir 	rInsert[columnIndex].setModified();
617cdf0e10cSrcweir     io_aRow[columnIndex] = makeAny(x);
618cdf0e10cSrcweir 
619cdf0e10cSrcweir     m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns);
620cdf0e10cSrcweir     impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns);
621cdf0e10cSrcweir }
622cdf0e10cSrcweir // -------------------------------------------------------------------------
updateObject(sal_Int32 columnIndex,const Any & x,ORowSetValueVector::Vector & io_aRow,::std::vector<sal_Int32> & o_ChangedColumns)623cdf0e10cSrcweir void ORowSetCache::updateObject( sal_Int32 columnIndex, const Any& x
624cdf0e10cSrcweir                                 ,ORowSetValueVector::Vector& io_aRow
625cdf0e10cSrcweir                                 ,::std::vector<sal_Int32>& o_ChangedColumns
626cdf0e10cSrcweir                                 )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir 	checkUpdateConditions(columnIndex);
629cdf0e10cSrcweir 
630cdf0e10cSrcweir     ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get());
631cdf0e10cSrcweir 	ORowSetValue aTemp;
632cdf0e10cSrcweir 	aTemp.fill(x);
633cdf0e10cSrcweir 	if ( rInsert[columnIndex] != aTemp )
634cdf0e10cSrcweir 	{
635cdf0e10cSrcweir 		rInsert[columnIndex].setBound(sal_True);
636cdf0e10cSrcweir 		rInsert[columnIndex] = aTemp;
637cdf0e10cSrcweir 		rInsert[columnIndex].setModified();
638cdf0e10cSrcweir     	io_aRow[columnIndex] = rInsert[columnIndex];
639cdf0e10cSrcweir 
640cdf0e10cSrcweir 	    m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns);
641cdf0e10cSrcweir     	impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns);
642cdf0e10cSrcweir 	}
643cdf0e10cSrcweir }
644cdf0e10cSrcweir // -------------------------------------------------------------------------
updateNumericObject(sal_Int32 columnIndex,const Any & x,sal_Int32,ORowSetValueVector::Vector & io_aRow,::std::vector<sal_Int32> & o_ChangedColumns)645cdf0e10cSrcweir void ORowSetCache::updateNumericObject( sal_Int32 columnIndex, const Any& x, sal_Int32 /*scale*/
646cdf0e10cSrcweir                                        ,ORowSetValueVector::Vector& io_aRow
647cdf0e10cSrcweir                                        ,::std::vector<sal_Int32>& o_ChangedColumns
648cdf0e10cSrcweir                                        )
649cdf0e10cSrcweir {
650cdf0e10cSrcweir 	checkUpdateConditions(columnIndex);
651cdf0e10cSrcweir 
652cdf0e10cSrcweir     ORowSetValueVector::Vector& rInsert = ((*m_aInsertRow)->get());
653cdf0e10cSrcweir 	ORowSetValue aTemp;
654cdf0e10cSrcweir 	aTemp.fill(x);
655cdf0e10cSrcweir 	if ( rInsert[columnIndex] != aTemp )
656cdf0e10cSrcweir 	{
657cdf0e10cSrcweir 		rInsert[columnIndex].setBound(sal_True);
658cdf0e10cSrcweir 		rInsert[columnIndex] = aTemp;
659cdf0e10cSrcweir 		rInsert[columnIndex].setModified();
660cdf0e10cSrcweir     	io_aRow[columnIndex] = rInsert[columnIndex];
661cdf0e10cSrcweir 
662cdf0e10cSrcweir 	    m_pCacheSet->mergeColumnValues(columnIndex,rInsert,io_aRow,o_ChangedColumns);
663cdf0e10cSrcweir     	impl_updateRowFromCache_throw(io_aRow,o_ChangedColumns);
664cdf0e10cSrcweir 	}
665cdf0e10cSrcweir }
666cdf0e10cSrcweir // -------------------------------------------------------------------------
667cdf0e10cSrcweir // XResultSet
next()668cdf0e10cSrcweir sal_Bool ORowSetCache::next(  )
669cdf0e10cSrcweir {
670cdf0e10cSrcweir 	if(!isAfterLast())
671cdf0e10cSrcweir 	{
672cdf0e10cSrcweir 		m_bBeforeFirst = sal_False;
673cdf0e10cSrcweir         ++m_nPosition;
674cdf0e10cSrcweir 
675cdf0e10cSrcweir 		// after we increment the position we have to check if we are already after the last row
676cdf0e10cSrcweir 		checkPositionFlags();
677cdf0e10cSrcweir 		if(!m_bAfterLast)
678cdf0e10cSrcweir 		{
679cdf0e10cSrcweir 			moveWindow();
680cdf0e10cSrcweir 
681cdf0e10cSrcweir 			OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
682cdf0e10cSrcweir 			m_aMatrixIter = calcPosition();
683cdf0e10cSrcweir 			checkPositionFlags();
684cdf0e10cSrcweir 		}
685cdf0e10cSrcweir 	}
686cdf0e10cSrcweir 
687cdf0e10cSrcweir 	return !m_bAfterLast;
688cdf0e10cSrcweir }
689cdf0e10cSrcweir // -------------------------------------------------------------------------
isBeforeFirst()690cdf0e10cSrcweir sal_Bool ORowSetCache::isBeforeFirst(  )
691cdf0e10cSrcweir {
692cdf0e10cSrcweir 	return m_bBeforeFirst;
693cdf0e10cSrcweir }
694cdf0e10cSrcweir // -------------------------------------------------------------------------
isAfterLast()695cdf0e10cSrcweir sal_Bool ORowSetCache::isAfterLast(  )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir 	return m_bAfterLast;
698cdf0e10cSrcweir }
699cdf0e10cSrcweir // -------------------------------------------------------------------------
isFirst()700cdf0e10cSrcweir sal_Bool ORowSetCache::isFirst(  )
701cdf0e10cSrcweir {
702cdf0e10cSrcweir 	return m_nPosition == 1; // ask resultset for
703cdf0e10cSrcweir }
704cdf0e10cSrcweir // -------------------------------------------------------------------------
isLast()705cdf0e10cSrcweir sal_Bool ORowSetCache::isLast(  )
706cdf0e10cSrcweir {
707cdf0e10cSrcweir 	return m_nPosition == m_nRowCount;
708cdf0e10cSrcweir }
709cdf0e10cSrcweir // -------------------------------------------------------------------------
beforeFirst()710cdf0e10cSrcweir sal_Bool ORowSetCache::beforeFirst(  )
711cdf0e10cSrcweir {
712cdf0e10cSrcweir 	if(!m_bBeforeFirst)
713cdf0e10cSrcweir 	{
714cdf0e10cSrcweir 		m_bAfterLast	= sal_False;
715cdf0e10cSrcweir 		m_nPosition		= 0;
716cdf0e10cSrcweir 		m_bBeforeFirst	= sal_True;
717cdf0e10cSrcweir 		m_pCacheSet->beforeFirst();
718cdf0e10cSrcweir 		moveWindow();
719cdf0e10cSrcweir 		m_aMatrixIter = m_pMatrix->end();
720cdf0e10cSrcweir 	}
721cdf0e10cSrcweir     return sal_True;
722cdf0e10cSrcweir }
723cdf0e10cSrcweir // -------------------------------------------------------------------------
afterLast()724cdf0e10cSrcweir sal_Bool ORowSetCache::afterLast(  )
725cdf0e10cSrcweir {
726cdf0e10cSrcweir 	if(!m_bAfterLast)
727cdf0e10cSrcweir 	{
728cdf0e10cSrcweir 		m_bBeforeFirst = sal_False;
729cdf0e10cSrcweir 		m_bAfterLast = sal_True;
730cdf0e10cSrcweir 
731cdf0e10cSrcweir 		if(!m_bRowCountFinal)
732cdf0e10cSrcweir 		{
733cdf0e10cSrcweir 			m_pCacheSet->last_checked(sal_False);
734cdf0e10cSrcweir 			m_bRowCountFinal = sal_True;
735cdf0e10cSrcweir 			m_nRowCount = m_pCacheSet->getRow();// + 1 removed
736cdf0e10cSrcweir 		}
737cdf0e10cSrcweir 		m_pCacheSet->afterLast();
738cdf0e10cSrcweir 
739cdf0e10cSrcweir 		m_nPosition = 0;
740cdf0e10cSrcweir 		m_aMatrixIter = m_pMatrix->end();
741cdf0e10cSrcweir 	}
742cdf0e10cSrcweir     return sal_True;
743cdf0e10cSrcweir }
744cdf0e10cSrcweir // -------------------------------------------------------------------------
fillMatrix(sal_Int32 & _nNewStartPos,sal_Int32 _nNewEndPos)745cdf0e10cSrcweir sal_Bool ORowSetCache::fillMatrix(sal_Int32& _nNewStartPos,sal_Int32 _nNewEndPos)
746cdf0e10cSrcweir {
747cdf0e10cSrcweir 	OSL_ENSURE(_nNewStartPos != _nNewEndPos,"ORowSetCache::fillMatrix: StartPos and EndPos can not be equal!");
748cdf0e10cSrcweir 	// fill the whole window with new data
749cdf0e10cSrcweir     ORowSetMatrix::iterator aIter;
750cdf0e10cSrcweir     sal_Int32 i;
751cdf0e10cSrcweir     sal_Bool bCheck;
752cdf0e10cSrcweir     if ( _nNewStartPos == -1 )
753cdf0e10cSrcweir     {
754cdf0e10cSrcweir 	    aIter = m_pMatrix->begin() + m_nEndPos;
755cdf0e10cSrcweir         i = m_nEndPos+1;
756cdf0e10cSrcweir     }
757cdf0e10cSrcweir     else
758cdf0e10cSrcweir     {
759cdf0e10cSrcweir         aIter = m_pMatrix->begin();
760cdf0e10cSrcweir         i = _nNewStartPos;
761cdf0e10cSrcweir     }
762cdf0e10cSrcweir     bCheck = m_pCacheSet->absolute(i); // -1 no need to
763cdf0e10cSrcweir 
764cdf0e10cSrcweir 
765cdf0e10cSrcweir 	for(;i<_nNewEndPos;++i,++aIter)
766cdf0e10cSrcweir 	{
767cdf0e10cSrcweir 		if(bCheck)
768cdf0e10cSrcweir 		{
769cdf0e10cSrcweir 			if(!aIter->isValid())
770cdf0e10cSrcweir 				*aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
771cdf0e10cSrcweir 			m_pCacheSet->fillValueRow(*aIter,i);
772cdf0e10cSrcweir 			if(!m_bRowCountFinal)
773cdf0e10cSrcweir                 ++m_nRowCount;
774cdf0e10cSrcweir 		}
775cdf0e10cSrcweir 		else
776cdf0e10cSrcweir 		{	// there are no more rows found so we can fetch some before start
777cdf0e10cSrcweir 
778cdf0e10cSrcweir 			if(!m_bRowCountFinal)
779cdf0e10cSrcweir 			{
780cdf0e10cSrcweir 				if(m_pCacheSet->previous_checked(sal_False)) // because we stand after the last row
781cdf0e10cSrcweir 					m_nRowCount = m_pCacheSet->getRow(); // here we have the row count
782cdf0e10cSrcweir 				if(!m_nRowCount)
783cdf0e10cSrcweir 					m_nRowCount = i-1; // it can be that getRow return zero
784cdf0e10cSrcweir 				m_bRowCountFinal = sal_True;
785cdf0e10cSrcweir 			}
786cdf0e10cSrcweir 			if(m_nRowCount > m_nFetchSize)
787cdf0e10cSrcweir 			{
788cdf0e10cSrcweir 				ORowSetMatrix::iterator aEnd = aIter;
789cdf0e10cSrcweir                 ORowSetMatrix::iterator aRealEnd = m_pMatrix->end();
790cdf0e10cSrcweir 				sal_Int32 nPos = m_nRowCount - m_nFetchSize + 1;
791cdf0e10cSrcweir 				_nNewStartPos = nPos;
792cdf0e10cSrcweir 				bCheck = m_pCacheSet->absolute(_nNewStartPos);
793cdf0e10cSrcweir 
794cdf0e10cSrcweir 				for(;bCheck && aIter != aRealEnd;++aIter)
795cdf0e10cSrcweir 				{
796cdf0e10cSrcweir 					if(bCheck)
797cdf0e10cSrcweir 					{
798cdf0e10cSrcweir 						if(!aIter->isValid())
799cdf0e10cSrcweir 							*aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
800cdf0e10cSrcweir 						m_pCacheSet->fillValueRow(*aIter,nPos++);
801cdf0e10cSrcweir 					}
802cdf0e10cSrcweir 					bCheck = m_pCacheSet->next();
803cdf0e10cSrcweir 				}
804cdf0e10cSrcweir 				if(aIter != aEnd)
805cdf0e10cSrcweir 					::std::rotate(m_pMatrix->begin(),aEnd,aRealEnd);
806cdf0e10cSrcweir 			}
807cdf0e10cSrcweir 			break;
808cdf0e10cSrcweir 		}
809cdf0e10cSrcweir         if ( i < (_nNewEndPos-1) )
810cdf0e10cSrcweir 		    bCheck = m_pCacheSet->next();
811cdf0e10cSrcweir 	}
812cdf0e10cSrcweir 	//	m_nStartPos = _nNewStartPos;
813cdf0e10cSrcweir 	// we have to read one row forward to ensure that we know when we are on last row
814cdf0e10cSrcweir 	// but only when we don't know it already
815cdf0e10cSrcweir     /*
816cdf0e10cSrcweir 	if(!m_bRowCountFinal)
817cdf0e10cSrcweir 	{
818cdf0e10cSrcweir 		if(!m_pCacheSet->next())
819cdf0e10cSrcweir 		{
820cdf0e10cSrcweir 			if(m_pCacheSet->previous_checked(sal_False)) // because we stand after the last row
821cdf0e10cSrcweir 				m_nRowCount = m_pCacheSet->getRow(); // here we have the row count
822cdf0e10cSrcweir 			m_bRowCountFinal = sal_True;
823cdf0e10cSrcweir 		}
824cdf0e10cSrcweir 		else
825cdf0e10cSrcweir 		   m_nRowCount = std::max(i,m_nRowCount);
826cdf0e10cSrcweir 
827cdf0e10cSrcweir 	}
828cdf0e10cSrcweir     */
829cdf0e10cSrcweir 	return bCheck;
830cdf0e10cSrcweir }
831cdf0e10cSrcweir // -------------------------------------------------------------------------
moveWindow()832cdf0e10cSrcweir sal_Bool ORowSetCache::moveWindow()
833cdf0e10cSrcweir {
834cdf0e10cSrcweir 
835cdf0e10cSrcweir 	sal_Bool bRet = sal_True;
836cdf0e10cSrcweir 
837cdf0e10cSrcweir 	sal_Int32 nDiff = (sal_Int32)(m_nFetchSize*0.5 -0.5);
838cdf0e10cSrcweir 	sal_Int32 nNewStartPos	= (m_nPosition - nDiff);
839cdf0e10cSrcweir 	//	sal_Int32 nNewEndPos	= (m_nPosition+m_nFetchSize*0.5);
840cdf0e10cSrcweir 	sal_Int32 nNewEndPos	= nNewStartPos + m_nFetchSize;
841cdf0e10cSrcweir 
842cdf0e10cSrcweir 	if ( m_nPosition <= m_nStartPos )
843cdf0e10cSrcweir 	{	// the window is behind the new start pos
844cdf0e10cSrcweir 		if(!m_nStartPos)
845cdf0e10cSrcweir 			return sal_False;
846cdf0e10cSrcweir 		// the new position should be the nPos - nFetchSize/2
847cdf0e10cSrcweir 		if ( nNewEndPos > m_nStartPos )
848cdf0e10cSrcweir 		{	// but the two regions are overlapping
849cdf0e10cSrcweir 			// fill the rows behind the new end
850cdf0e10cSrcweir 
851cdf0e10cSrcweir 			ORowSetMatrix::iterator aEnd; // the iterator we need for rotate
852cdf0e10cSrcweir 			ORowSetMatrix::iterator aIter; // the iterator we fill with new values
853cdf0e10cSrcweir 
854cdf0e10cSrcweir 			sal_Bool bCheck = sal_True;
855cdf0e10cSrcweir 			if ( nNewStartPos < 1 )
856cdf0e10cSrcweir 			{
857cdf0e10cSrcweir 				bCheck = m_pCacheSet->first();
858cdf0e10cSrcweir 				OSL_ENSURE((nNewEndPos - m_nStartPos - nNewStartPos) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
859cdf0e10cSrcweir 				aEnd = m_pMatrix->begin() + (nNewEndPos - m_nStartPos - nNewStartPos);
860cdf0e10cSrcweir 				aIter = aEnd;
861cdf0e10cSrcweir 				m_nStartPos = 0;
862cdf0e10cSrcweir 			}
863cdf0e10cSrcweir 			else
864cdf0e10cSrcweir 			{
865cdf0e10cSrcweir 				OSL_ENSURE((nNewEndPos - m_nStartPos -1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
866cdf0e10cSrcweir 				aEnd = m_pMatrix->begin() + ((nNewEndPos - m_nStartPos)-1);
867cdf0e10cSrcweir 				aIter = m_pMatrix->begin() + ((nNewEndPos - m_nStartPos)-1);
868cdf0e10cSrcweir 				bCheck = m_pCacheSet->absolute(nNewStartPos);
869cdf0e10cSrcweir 				m_nStartPos = nNewStartPos -1;
870cdf0e10cSrcweir 			}
871cdf0e10cSrcweir 
872cdf0e10cSrcweir 			if ( bCheck )
873cdf0e10cSrcweir 			{
874cdf0e10cSrcweir 				sal_Int32 nPos = m_nStartPos;
875cdf0e10cSrcweir 				bCheck = fill(aIter,m_pMatrix->end(),nPos,bCheck);
876cdf0e10cSrcweir 
877cdf0e10cSrcweir 				::std::rotate(m_pMatrix->begin(),aEnd,m_pMatrix->end());
878cdf0e10cSrcweir 				// now correct the iterator in our iterator vector
879cdf0e10cSrcweir 				//	rotateCacheIterator(aEnd-m_pMatrix->begin()); //can't be used because they decrement and here we need to increment
880cdf0e10cSrcweir 				ptrdiff_t nNewDist = aEnd - m_pMatrix->begin();
881cdf0e10cSrcweir 				ptrdiff_t nOffSet = m_pMatrix->end() - aEnd;
882cdf0e10cSrcweir 				ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
883cdf0e10cSrcweir 				ORowSetCacheMap::iterator aCacheEnd  = m_aCacheIterators.end();
884cdf0e10cSrcweir 		        for(;aCacheIter != aCacheEnd;++aCacheIter)
885cdf0e10cSrcweir 				{
886cdf0e10cSrcweir 					if ( !aCacheIter->second.pRowSet->isInsertRow()
887cdf0e10cSrcweir 						&& aCacheIter->second.aIterator != m_pMatrix->end() && !m_bModified )
888cdf0e10cSrcweir 					{
889cdf0e10cSrcweir 						ptrdiff_t nDist = (aCacheIter->second.aIterator - m_pMatrix->begin());
890cdf0e10cSrcweir 						if ( nDist >= nNewDist )
891cdf0e10cSrcweir 						{
892cdf0e10cSrcweir 							aCacheIter->second.aIterator = m_pMatrix->end();
893cdf0e10cSrcweir 						}
894cdf0e10cSrcweir 						else
895cdf0e10cSrcweir 						{
896cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
897cdf0e10cSrcweir 							ORowSetMatrix::iterator aOldPos;
898cdf0e10cSrcweir                             aOldPos = aCacheIter->second.aIterator;
899cdf0e10cSrcweir #endif
900cdf0e10cSrcweir                             CHECK_MATRIX_POS( ((aOldPos - m_pMatrix->begin()) + nOffSet) );
901cdf0e10cSrcweir 							aCacheIter->second.aIterator += nOffSet;
902cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
903cdf0e10cSrcweir 							ORowSetMatrix::iterator aCurrentPos;
904cdf0e10cSrcweir                             aCurrentPos = aCacheIter->second.aIterator;
905cdf0e10cSrcweir #endif
906cdf0e10cSrcweir 							OSL_ENSURE(aCacheIter->second.aIterator >= m_pMatrix->begin()
907cdf0e10cSrcweir 									&& aCacheIter->second.aIterator < m_pMatrix->end(),"Iterator out of area!");
908cdf0e10cSrcweir 						}
909cdf0e10cSrcweir 					}
910cdf0e10cSrcweir 				}
911cdf0e10cSrcweir 			}
912cdf0e10cSrcweir 			else
913e9faf1d9Smseidel 			{ // normally this should never happen
914cdf0e10cSrcweir 				OSL_ENSURE(0,"What the hell is happen here!");
915cdf0e10cSrcweir 				return sal_False;
916cdf0e10cSrcweir 			}
917cdf0e10cSrcweir 		}
918cdf0e10cSrcweir 		else
919cdf0e10cSrcweir 		{// no rows can be reused so fill again
920cdf0e10cSrcweir 			if(nNewStartPos < 1) // special case
921cdf0e10cSrcweir 			{
922cdf0e10cSrcweir 				m_nStartPos = 0;
923cdf0e10cSrcweir 
924cdf0e10cSrcweir 				rotateCacheIterator(static_cast<sal_Int16>(m_nFetchSize+1)); // static_cast<sal_Int16>(m_nFetchSize+1)
925cdf0e10cSrcweir 
926cdf0e10cSrcweir 				m_pCacheSet->beforeFirst();
927cdf0e10cSrcweir 
928cdf0e10cSrcweir 				sal_Bool bCheck;
929cdf0e10cSrcweir 				ORowSetMatrix::iterator aIter = m_pMatrix->begin();
930cdf0e10cSrcweir 				for(sal_Int32 i=0;i<m_nFetchSize;++i,++aIter)
931cdf0e10cSrcweir 				{
932cdf0e10cSrcweir                     bCheck = m_pCacheSet->next();
933cdf0e10cSrcweir 					if ( bCheck )
934cdf0e10cSrcweir 					{
935cdf0e10cSrcweir 						if(!aIter->isValid())
936cdf0e10cSrcweir 							*aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
937cdf0e10cSrcweir 						m_pCacheSet->fillValueRow(*aIter,i+1);
938cdf0e10cSrcweir 					}
939cdf0e10cSrcweir 					else
940cdf0e10cSrcweir 						*aIter = NULL;
941cdf0e10cSrcweir 				}
942cdf0e10cSrcweir 			}
943cdf0e10cSrcweir 			else
944cdf0e10cSrcweir 				bRet = reFillMatrix(nNewStartPos,nNewEndPos);
945cdf0e10cSrcweir 		}
946cdf0e10cSrcweir 	}
947cdf0e10cSrcweir 	else if(m_nPosition > m_nStartPos)
948cdf0e10cSrcweir 	{	// the new start pos is above the startpos of the window
949cdf0e10cSrcweir 
950cdf0e10cSrcweir 		if(m_nPosition <= (m_nStartPos+m_nFetchSize))
951cdf0e10cSrcweir 		{	// position in window
952cdf0e10cSrcweir 			OSL_ENSURE((m_nPosition - m_nStartPos -1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
953cdf0e10cSrcweir 			m_aMatrixIter = calcPosition();
954cdf0e10cSrcweir 			if(!m_aMatrixIter->isValid())
955cdf0e10cSrcweir 			{
956cdf0e10cSrcweir 				sal_Bool bOk( m_pCacheSet->absolute( m_nPosition ) );
957cdf0e10cSrcweir 				if ( bOk )
958cdf0e10cSrcweir 				{
959cdf0e10cSrcweir 					*m_aMatrixIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
960cdf0e10cSrcweir 					m_pCacheSet->fillValueRow(*m_aMatrixIter,m_nPosition);
961cdf0e10cSrcweir 					// we have to read one row forward to ensure that we know when we are on last row
962cdf0e10cSrcweir 					// but only when we don't know it already
963cdf0e10cSrcweir 					if ( !m_bRowCountFinal )
964cdf0e10cSrcweir                     {
965cdf0e10cSrcweir                         bOk = m_pCacheSet->absolute_checked( m_nPosition + 1,sal_False );
966cdf0e10cSrcweir                         if ( bOk )
967cdf0e10cSrcweir 						    m_nRowCount = std::max(sal_Int32(m_nPosition+1),m_nRowCount);
968cdf0e10cSrcweir                     }
969cdf0e10cSrcweir 				}
970cdf0e10cSrcweir 				if(!bOk && !m_bRowCountFinal)
971cdf0e10cSrcweir 				{
972cdf0e10cSrcweir 					// because we stand after the last row
973cdf0e10cSrcweir 					m_nRowCount = m_pCacheSet->previous_checked(sal_False) ? m_pCacheSet->getRow() : 0;//  + 1 removed
974cdf0e10cSrcweir 					m_bRowCountFinal = sal_True;
975cdf0e10cSrcweir 				}
976cdf0e10cSrcweir 			}
977cdf0e10cSrcweir 		}
978cdf0e10cSrcweir 		else if(nNewStartPos < (m_nStartPos+m_nFetchSize))
979cdf0e10cSrcweir 		{	// position behind window but the region is overlapping
980cdf0e10cSrcweir 			// the rows from begin() to (begin + nNewStartPos - m_nStartPos) can be refilled with the new rows
981cdf0e10cSrcweir 			// the rows behind this can be reused
982cdf0e10cSrcweir 			ORowSetMatrix::iterator aIter = m_pMatrix->begin();
983cdf0e10cSrcweir             CHECK_MATRIX_POS(nNewStartPos - m_nStartPos - 1);
984cdf0e10cSrcweir 			ORowSetMatrix::iterator aEnd  = m_pMatrix->begin() + (nNewStartPos - m_nStartPos - 1);
985cdf0e10cSrcweir 
986cdf0e10cSrcweir 			sal_Int32 nPos = m_nStartPos + m_nFetchSize + 1;
987cdf0e10cSrcweir 			sal_Bool bCheck = m_pCacheSet->absolute(nPos);
988cdf0e10cSrcweir 			bCheck = fill(aIter,aEnd,nPos,bCheck); // refill the region wew don't need anymore
989cdf0e10cSrcweir 
990d0dd8695Smseidel 			// we have to read one row forward to ensure that we know when we are on last row
991cdf0e10cSrcweir 			// but only when we don't know it already
992cdf0e10cSrcweir 			sal_Bool bOk = sal_True;
993cdf0e10cSrcweir 			if(bCheck && !m_bRowCountFinal)
994cdf0e10cSrcweir 				bOk = m_pCacheSet->next();
995cdf0e10cSrcweir 			// bind end to front
996cdf0e10cSrcweir 			if(bCheck)
997cdf0e10cSrcweir 			{	// rotate the end to the front
998cdf0e10cSrcweir 				::std::rotate(m_pMatrix->begin(),aIter,m_pMatrix->end());
999cdf0e10cSrcweir 				// now correct the iterator in our iterator vector
1000cdf0e10cSrcweir 				rotateCacheIterator( (sal_Int16)( aIter - m_pMatrix->begin() ) );
1001cdf0e10cSrcweir 				m_nStartPos = nNewStartPos - 1; // must be -1
1002cdf0e10cSrcweir 				// now I can say how many rows we have
1003cdf0e10cSrcweir 				if(!bOk)
1004cdf0e10cSrcweir 				{
1005cdf0e10cSrcweir 					m_pCacheSet->previous_checked(sal_False); // because we stand after the last row
1006cdf0e10cSrcweir 					m_nRowCount		 = nPos; // here we have the row count
1007cdf0e10cSrcweir 					m_bRowCountFinal = sal_True;
1008cdf0e10cSrcweir 				}
1009cdf0e10cSrcweir 				else if(!m_bRowCountFinal)
1010cdf0e10cSrcweir 					m_nRowCount = std::max(++nPos,m_nRowCount);
1011cdf0e10cSrcweir 			}
1012cdf0e10cSrcweir 			else
1013cdf0e10cSrcweir 			{	// the end was reached before end() so we can set the start before nNewStartPos
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir 				m_nStartPos += (aIter - m_pMatrix->begin());
1016cdf0e10cSrcweir 				//	m_nStartPos = (aIter - m_pMatrix->begin());
1017cdf0e10cSrcweir 				::std::rotate(m_pMatrix->begin(),aIter,m_pMatrix->end());
1018cdf0e10cSrcweir 				// now correct the iterator in our iterator vector
1019cdf0e10cSrcweir 				rotateCacheIterator( (sal_Int16)( aIter - m_pMatrix->begin() ) );
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir 				if ( !m_bRowCountFinal )
1022cdf0e10cSrcweir 				{
1023cdf0e10cSrcweir 					m_pCacheSet->previous_checked(sal_False);					// because we stand after the last row
1024cdf0e10cSrcweir 					m_nRowCount		 = std::max(m_nRowCount,--nPos);	// here we have the row count
1025cdf0e10cSrcweir 					OSL_ENSURE(nPos == m_pCacheSet->getRow(),"nPos isn't valid!");
1026cdf0e10cSrcweir 					m_bRowCountFinal = sal_True;
1027cdf0e10cSrcweir 				}
1028cdf0e10cSrcweir 				// TODO check
1029cdf0e10cSrcweir 				//	m_nStartPos = (nNewStartPos+m_nRowCount) - m_nFetchSize ;
1030cdf0e10cSrcweir 				if(m_nStartPos < 0)
1031cdf0e10cSrcweir 					m_nStartPos = 0;
1032cdf0e10cSrcweir 			}
103307a3d7f1SPedro Giffuni 			// here we need only to check if the beginning row is valid. If not we have to fetch it.
1034cdf0e10cSrcweir 			if(!m_pMatrix->begin()->isValid())
1035cdf0e10cSrcweir 			{
1036cdf0e10cSrcweir 				aIter = m_pMatrix->begin();
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir 				nPos	= m_nStartPos;
1039cdf0e10cSrcweir 				bCheck	= m_pCacheSet->absolute_checked(m_nStartPos,sal_False);
1040cdf0e10cSrcweir 				for(; !aIter->isValid() && bCheck;++aIter)
1041cdf0e10cSrcweir 				{
1042cdf0e10cSrcweir                     OSL_ENSURE(aIter != m_pMatrix->end(),"Invalid iterator");
1043cdf0e10cSrcweir                     bCheck = m_pCacheSet->next();
1044cdf0e10cSrcweir 					if ( bCheck ) // resultset stands on right position
1045cdf0e10cSrcweir 					{
1046cdf0e10cSrcweir 						*aIter = new ORowSetValueVector(m_xMetaData->getColumnCount());
1047cdf0e10cSrcweir 						m_pCacheSet->fillValueRow(*aIter,++nPos);
1048cdf0e10cSrcweir 					}
1049cdf0e10cSrcweir 				}
1050cdf0e10cSrcweir 			}
1051cdf0e10cSrcweir 		}
1052cdf0e10cSrcweir 		else // no rows can be reused so fill again
1053cdf0e10cSrcweir 			bRet = reFillMatrix(nNewStartPos,nNewEndPos);
1054cdf0e10cSrcweir 	}
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir 	if(!m_bRowCountFinal)
1057cdf0e10cSrcweir 	   m_nRowCount = std::max(m_nPosition,m_nRowCount);
1058cdf0e10cSrcweir 	OSL_ENSURE(m_nStartPos >= 0,"ORowSetCache::moveWindow: m_nStartPos is less than 0!");
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 	return bRet;
1061cdf0e10cSrcweir }
1062cdf0e10cSrcweir // -------------------------------------------------------------------------
first()1063cdf0e10cSrcweir sal_Bool ORowSetCache::first(  )
1064cdf0e10cSrcweir {
1065cdf0e10cSrcweir 	// first move to the first row
106607a3d7f1SPedro Giffuni 	// then check if the cache window is at the beginning
1067*ebe15e47SJohn Bampton 	// when not, position the window and fill it with data
1068cdf0e10cSrcweir 	// smart moving of the window -> clear only the rows whom are out of range
1069cdf0e10cSrcweir 	sal_Bool bRet = m_pCacheSet->first();
1070cdf0e10cSrcweir 	if(bRet)
1071cdf0e10cSrcweir 	{
1072cdf0e10cSrcweir 		m_bBeforeFirst	= m_bAfterLast = sal_False;
1073cdf0e10cSrcweir 		m_nPosition		= 1;
1074cdf0e10cSrcweir 		moveWindow();
1075cdf0e10cSrcweir 		m_aMatrixIter	= m_pMatrix->begin();
1076cdf0e10cSrcweir 	}
1077cdf0e10cSrcweir 	else
1078cdf0e10cSrcweir 	{
1079cdf0e10cSrcweir 		m_bRowCountFinal = m_bBeforeFirst = m_bAfterLast = sal_True;
1080cdf0e10cSrcweir 		m_nRowCount = m_nPosition = 0;
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir 		OSL_ENSURE(m_bBeforeFirst || m_bNew,"ORowSetCache::first return false and BeforeFirst isn't true");
1083cdf0e10cSrcweir 		m_aMatrixIter = m_pMatrix->end();
1084cdf0e10cSrcweir 	}
1085cdf0e10cSrcweir 	return bRet;
1086cdf0e10cSrcweir }
1087cdf0e10cSrcweir // -------------------------------------------------------------------------
last()1088cdf0e10cSrcweir sal_Bool ORowSetCache::last(  )
1089cdf0e10cSrcweir {
1090cdf0e10cSrcweir 	sal_Bool bRet = m_pCacheSet->last();
1091cdf0e10cSrcweir 	if(bRet)
1092cdf0e10cSrcweir 	{
1093cdf0e10cSrcweir 		m_bBeforeFirst = m_bAfterLast = sal_False;
1094cdf0e10cSrcweir 		if(!m_bRowCountFinal)
1095cdf0e10cSrcweir 		{
1096cdf0e10cSrcweir 			m_bRowCountFinal = sal_True;
1097cdf0e10cSrcweir 			m_nRowCount = m_nPosition = m_pCacheSet->getRow(); // not  + 1
1098cdf0e10cSrcweir 		}
1099cdf0e10cSrcweir 		m_nPosition = m_pCacheSet->getRow();
1100cdf0e10cSrcweir 		moveWindow();
1101cdf0e10cSrcweir 		// we have to repositioning because moveWindow can modify the cache
1102cdf0e10cSrcweir 		m_pCacheSet->last();
1103cdf0e10cSrcweir //		if(m_nPosition > m_nFetchSize)
1104cdf0e10cSrcweir //			m_aMatrixIter = m_pMatrix->end() -1;
1105cdf0e10cSrcweir //		else
1106cdf0e10cSrcweir //			m_aMatrixIter = m_pMatrix->begin() + m_nPosition - 1;
1107cdf0e10cSrcweir 		OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
1108cdf0e10cSrcweir 		m_aMatrixIter = calcPosition();
1109cdf0e10cSrcweir 	}
1110cdf0e10cSrcweir 	else
1111cdf0e10cSrcweir 	{
1112cdf0e10cSrcweir 		m_bRowCountFinal = m_bBeforeFirst = m_bAfterLast = sal_True;
1113cdf0e10cSrcweir 		m_nRowCount = m_nPosition = 0;
1114cdf0e10cSrcweir 		OSL_ENSURE(m_bBeforeFirst,"ORowSetCache::last return false and BeforeFirst isn't true");
1115cdf0e10cSrcweir 		m_aMatrixIter = m_pMatrix->end();
1116cdf0e10cSrcweir 	}
1117cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1118cdf0e10cSrcweir 	if(bRet)
1119cdf0e10cSrcweir 	{
1120cdf0e10cSrcweir 		OSL_ENSURE((*m_aMatrixIter).isValid(),"ORowSetCache::last: Row not valid!");
1121cdf0e10cSrcweir 	}
1122cdf0e10cSrcweir #endif
1123cdf0e10cSrcweir 
1124cdf0e10cSrcweir 	return bRet;
1125cdf0e10cSrcweir }
1126cdf0e10cSrcweir // -------------------------------------------------------------------------
getRow()1127cdf0e10cSrcweir sal_Int32 ORowSetCache::getRow(  )
1128cdf0e10cSrcweir {
1129cdf0e10cSrcweir 	return (isBeforeFirst() || isAfterLast()) ? 0 : m_nPosition;
1130cdf0e10cSrcweir }
1131cdf0e10cSrcweir // -------------------------------------------------------------------------
absolute(sal_Int32 row)1132cdf0e10cSrcweir sal_Bool ORowSetCache::absolute( sal_Int32 row )
1133cdf0e10cSrcweir {
1134cdf0e10cSrcweir 	if(!row )
1135cdf0e10cSrcweir 		throw SQLException(DBACORE_RESSTRING(RID_STR_NO_ABS_ZERO),NULL,SQLSTATE_GENERAL,1000,Any() );
1136cdf0e10cSrcweir 
1137cdf0e10cSrcweir 	if(row < 0)
1138cdf0e10cSrcweir 	{
1139cdf0e10cSrcweir 		// here we have to scroll from the last row to backward so we have to go to last row and
1140cdf0e10cSrcweir 		// and two the previous
1141cdf0e10cSrcweir 		if(m_bRowCountFinal || last())
1142cdf0e10cSrcweir 		{
1143cdf0e10cSrcweir 			m_nPosition = m_nRowCount + row + 1; // + row because row is negative and +1 because row==-1 means last row
1144cdf0e10cSrcweir 			if(m_nPosition < 1)
1145cdf0e10cSrcweir 			{
1146cdf0e10cSrcweir 				m_bBeforeFirst = sal_True;
1147cdf0e10cSrcweir 				m_bAfterLast = sal_False;
1148cdf0e10cSrcweir 				m_aMatrixIter = m_pMatrix->end();
1149cdf0e10cSrcweir 			}
1150cdf0e10cSrcweir 			else
1151cdf0e10cSrcweir 			{
1152cdf0e10cSrcweir 				m_bBeforeFirst	= sal_False;
1153cdf0e10cSrcweir 				m_bAfterLast	= m_nPosition > m_nRowCount;
1154cdf0e10cSrcweir 				moveWindow();
1155cdf0e10cSrcweir 				OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
1156cdf0e10cSrcweir 				m_aMatrixIter = calcPosition();
1157cdf0e10cSrcweir 			}
1158cdf0e10cSrcweir 		}
1159cdf0e10cSrcweir 		else
1160cdf0e10cSrcweir 			m_aMatrixIter = m_pMatrix->end();
1161cdf0e10cSrcweir 	}
1162cdf0e10cSrcweir 	else
1163cdf0e10cSrcweir 	{
1164cdf0e10cSrcweir 		m_nPosition = row;
1165cdf0e10cSrcweir 		// the position flags
1166cdf0e10cSrcweir 		m_bBeforeFirst	= sal_False;
1167cdf0e10cSrcweir 		checkPositionFlags();
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir 		if(!m_bAfterLast)
1170cdf0e10cSrcweir 		{
1171cdf0e10cSrcweir 			moveWindow();
1172cdf0e10cSrcweir 			checkPositionFlags();
1173cdf0e10cSrcweir 			if(!m_bAfterLast)
1174cdf0e10cSrcweir 				m_aMatrixIter = calcPosition();
1175cdf0e10cSrcweir 			else
1176cdf0e10cSrcweir 				m_aMatrixIter = m_pMatrix->end();
1177cdf0e10cSrcweir 		}
1178cdf0e10cSrcweir 		else
1179cdf0e10cSrcweir 			m_aMatrixIter = m_pMatrix->end();
1180cdf0e10cSrcweir 	}
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir 	return !(m_bAfterLast || m_bBeforeFirst);
1183cdf0e10cSrcweir }
1184cdf0e10cSrcweir // -------------------------------------------------------------------------
relative(sal_Int32 rows)1185cdf0e10cSrcweir sal_Bool ORowSetCache::relative( sal_Int32 rows )
1186cdf0e10cSrcweir {
1187cdf0e10cSrcweir 	sal_Bool bErg = sal_True;
1188cdf0e10cSrcweir 	if(rows)
1189cdf0e10cSrcweir 	{
1190cdf0e10cSrcweir         sal_Int32 nNewPosition = m_nPosition + rows;
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir         if ( m_bBeforeFirst && rows > 0 )
1193cdf0e10cSrcweir             nNewPosition = rows;
1194cdf0e10cSrcweir         else if ( m_bRowCountFinal && m_bAfterLast && rows < 0 )
1195cdf0e10cSrcweir             nNewPosition = m_nRowCount + 1 + rows;
1196cdf0e10cSrcweir         else
1197cdf0e10cSrcweir 		    if ( m_bBeforeFirst || ( m_bRowCountFinal && m_bAfterLast ) )
1198cdf0e10cSrcweir 			    throw SQLException( DBACORE_RESSTRING( RID_STR_NO_RELATIVE ), NULL, SQLSTATE_GENERAL, 1000, Any() );
1199cdf0e10cSrcweir 		if ( nNewPosition )
1200cdf0e10cSrcweir 		{
1201cdf0e10cSrcweir 			bErg = absolute( nNewPosition );
1202cdf0e10cSrcweir 			bErg = bErg && !isAfterLast() && !isBeforeFirst();
1203cdf0e10cSrcweir 		}
1204cdf0e10cSrcweir 		else
1205cdf0e10cSrcweir         {
1206cdf0e10cSrcweir             m_bBeforeFirst = sal_True;
1207cdf0e10cSrcweir 			bErg = sal_False;
1208cdf0e10cSrcweir         }
1209cdf0e10cSrcweir 	}
1210cdf0e10cSrcweir 	return bErg;
1211cdf0e10cSrcweir }
1212cdf0e10cSrcweir // -------------------------------------------------------------------------
previous()1213cdf0e10cSrcweir sal_Bool ORowSetCache::previous(  )
1214cdf0e10cSrcweir {
1215cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
1216cdf0e10cSrcweir 	if(!isBeforeFirst())
1217cdf0e10cSrcweir 	{
1218cdf0e10cSrcweir 		if(m_bAfterLast)   // we stand after the last row so one before is the last row
1219cdf0e10cSrcweir 			bRet = last();
1220cdf0e10cSrcweir 		else
1221cdf0e10cSrcweir 		{
1222cdf0e10cSrcweir 			m_bAfterLast = sal_False;
1223cdf0e10cSrcweir 			--m_nPosition;
1224cdf0e10cSrcweir 			moveWindow();
1225cdf0e10cSrcweir 			OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir 			checkPositionFlags();
1228cdf0e10cSrcweir 
1229cdf0e10cSrcweir 			if(!m_nPosition)
1230cdf0e10cSrcweir 			{
1231cdf0e10cSrcweir 				m_bBeforeFirst = sal_True;
1232cdf0e10cSrcweir 				m_aMatrixIter = m_pMatrix->end();
1233cdf0e10cSrcweir 			}
1234cdf0e10cSrcweir 			else
1235cdf0e10cSrcweir 			{
1236cdf0e10cSrcweir 				m_aMatrixIter = calcPosition();
1237cdf0e10cSrcweir 				bRet = (*m_aMatrixIter).isValid();
1238cdf0e10cSrcweir 			}
1239cdf0e10cSrcweir 		}
1240cdf0e10cSrcweir 	}
1241cdf0e10cSrcweir 	return bRet;
1242cdf0e10cSrcweir }
1243cdf0e10cSrcweir // -------------------------------------------------------------------------
refreshRow()1244cdf0e10cSrcweir void ORowSetCache::refreshRow(  )
1245cdf0e10cSrcweir {
1246cdf0e10cSrcweir 	if(isAfterLast())
1247cdf0e10cSrcweir 		throw SQLException(DBACORE_RESSTRING(RID_STR_NO_REFESH_AFTERLAST),NULL,SQLSTATE_GENERAL,1000,Any() );
1248cdf0e10cSrcweir 	OSL_ENSURE(m_aMatrixIter != m_pMatrix->end(),"refreshRow() called for invalid row!");
1249cdf0e10cSrcweir 	m_pCacheSet->refreshRow();
1250cdf0e10cSrcweir 	m_pCacheSet->fillValueRow(*m_aMatrixIter,m_nPosition);
1251cdf0e10cSrcweir 	if ( m_bNew )
1252cdf0e10cSrcweir 	{
1253cdf0e10cSrcweir 		cancelRowModification();
1254cdf0e10cSrcweir 	}
1255cdf0e10cSrcweir }
1256cdf0e10cSrcweir // -------------------------------------------------------------------------
rowUpdated()1257cdf0e10cSrcweir sal_Bool ORowSetCache::rowUpdated(  )
1258cdf0e10cSrcweir {
1259cdf0e10cSrcweir 	return m_pCacheSet->rowUpdated();
1260cdf0e10cSrcweir }
1261cdf0e10cSrcweir // -------------------------------------------------------------------------
rowInserted()1262cdf0e10cSrcweir sal_Bool ORowSetCache::rowInserted(  )
1263cdf0e10cSrcweir {
1264cdf0e10cSrcweir 	return m_pCacheSet->rowInserted();
1265cdf0e10cSrcweir }
1266cdf0e10cSrcweir // -------------------------------------------------------------------------
1267cdf0e10cSrcweir // XResultSetUpdate
insertRow(::std::vector<Any> & o_aBookmarks)1268cdf0e10cSrcweir sal_Bool ORowSetCache::insertRow(::std::vector< Any >& o_aBookmarks)
1269cdf0e10cSrcweir {
1270cdf0e10cSrcweir 	if ( !m_bNew || !m_aInsertRow->isValid() )
1271cdf0e10cSrcweir 		throw SQLException(DBACORE_RESSTRING(RID_STR_NO_MOVETOINSERTROW_CALLED),NULL,SQLSTATE_GENERAL,1000,Any() );
1272cdf0e10cSrcweir 
1273cdf0e10cSrcweir 	m_pCacheSet->insertRow(*m_aInsertRow,m_aUpdateTable);
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir 	sal_Bool bRet( rowInserted() );
1276cdf0e10cSrcweir 	if ( bRet )
1277cdf0e10cSrcweir 	{
1278cdf0e10cSrcweir 		++m_nRowCount;
1279cdf0e10cSrcweir 		Any aBookmark = ((*m_aInsertRow)->get())[0].makeAny();
1280cdf0e10cSrcweir 		m_bAfterLast = m_bBeforeFirst = sal_False;
1281cdf0e10cSrcweir 		if(aBookmark.hasValue())
1282cdf0e10cSrcweir         {
1283cdf0e10cSrcweir 			moveToBookmark(aBookmark);
1284cdf0e10cSrcweir             // update the cached values
1285cdf0e10cSrcweir             ORowSetValueVector::Vector& rCurrentRow = ((*m_aMatrixIter))->get();
1286cdf0e10cSrcweir             ORowSetMatrix::iterator aIter = m_pMatrix->begin();
1287cdf0e10cSrcweir             for(;aIter != m_pMatrix->end();++aIter)
1288cdf0e10cSrcweir             {
1289cdf0e10cSrcweir                 if ( m_aMatrixIter != aIter && aIter->isValid() && m_pCacheSet->columnValuesUpdated((*aIter)->get(),rCurrentRow) )
1290cdf0e10cSrcweir                 {
1291cdf0e10cSrcweir                     o_aBookmarks.push_back(lcl_getBookmark((*aIter)->get()[0],m_pCacheSet));
1292cdf0e10cSrcweir                 }
1293cdf0e10cSrcweir             }
1294cdf0e10cSrcweir         }
1295cdf0e10cSrcweir 		else
1296cdf0e10cSrcweir 		{
1297cdf0e10cSrcweir 			OSL_ENSURE(0,"There must be a bookmark after the row was inserted!");
1298cdf0e10cSrcweir 		}
1299cdf0e10cSrcweir 	}
1300cdf0e10cSrcweir 	return bRet;
1301cdf0e10cSrcweir }
1302cdf0e10cSrcweir // -------------------------------------------------------------------------
resetInsertRow(sal_Bool _bClearInsertRow)1303cdf0e10cSrcweir void ORowSetCache::resetInsertRow(sal_Bool _bClearInsertRow)
1304cdf0e10cSrcweir {
1305cdf0e10cSrcweir 	if ( _bClearInsertRow )
1306cdf0e10cSrcweir 		clearInsertRow();
1307cdf0e10cSrcweir 	m_bNew		= sal_False;
1308cdf0e10cSrcweir 	m_bModified = sal_False;
1309cdf0e10cSrcweir }
1310cdf0e10cSrcweir // -------------------------------------------------------------------------
cancelRowModification()1311cdf0e10cSrcweir void ORowSetCache::cancelRowModification()
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir 	// clear the insertrow references	-> implies that the current row of the rowset changes as well
1314cdf0e10cSrcweir 	ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
1315cdf0e10cSrcweir 	ORowSetCacheMap::iterator aCacheEnd = m_aCacheIterators.end();
1316cdf0e10cSrcweir 	for(;aCacheIter != aCacheEnd;++aCacheIter)
1317cdf0e10cSrcweir 	{
1318cdf0e10cSrcweir 		if ( aCacheIter->second.pRowSet->isInsertRow() && aCacheIter->second.aIterator == m_aInsertRow )
1319cdf0e10cSrcweir 			aCacheIter->second.aIterator = m_pMatrix->end();
1320cdf0e10cSrcweir 	} // for(;aCacheIter != aCacheEnd;++aCacheIter)
1321cdf0e10cSrcweir 	resetInsertRow(sal_False);
1322cdf0e10cSrcweir }
1323cdf0e10cSrcweir // -------------------------------------------------------------------------
updateRow(ORowSetMatrix::iterator & _rUpdateRow,::std::vector<Any> & o_aBookmarks)1324cdf0e10cSrcweir void ORowSetCache::updateRow( ORowSetMatrix::iterator& _rUpdateRow,::std::vector< Any >& o_aBookmarks )
1325cdf0e10cSrcweir {
1326cdf0e10cSrcweir 	if(isAfterLast() || isBeforeFirst())
1327cdf0e10cSrcweir 		throw SQLException(DBACORE_RESSTRING(RID_STR_NO_UPDATEROW),NULL,SQLSTATE_GENERAL,1000,Any() );
1328cdf0e10cSrcweir 
1329cdf0e10cSrcweir 	Any aBookmark = ((*_rUpdateRow)->get())[0].makeAny();
1330cdf0e10cSrcweir 	OSL_ENSURE(aBookmark.hasValue(),"Bookmark must have a value!");
1331cdf0e10cSrcweir 	// here we don't have to reposition our CacheSet, when we try to update a row,
1332cdf0e10cSrcweir 	// the row was already fetched
1333cdf0e10cSrcweir 	moveToBookmark(aBookmark);
1334cdf0e10cSrcweir 	m_pCacheSet->updateRow(*_rUpdateRow,*m_aMatrixIter,m_aUpdateTable);
1335cdf0e10cSrcweir 	// refetch the whole row
1336cdf0e10cSrcweir 	(*m_aMatrixIter) = NULL;
1337cdf0e10cSrcweir 
1338cdf0e10cSrcweir 	if ( moveToBookmark(aBookmark) )
1339cdf0e10cSrcweir     {
1340cdf0e10cSrcweir         // update the cached values
1341cdf0e10cSrcweir         ORowSetValueVector::Vector& rCurrentRow = ((*m_aMatrixIter))->get();
1342cdf0e10cSrcweir         ORowSetMatrix::iterator aIter = m_pMatrix->begin();
1343cdf0e10cSrcweir         for(;aIter != m_pMatrix->end();++aIter)
1344cdf0e10cSrcweir         {
1345cdf0e10cSrcweir             if ( m_aMatrixIter != aIter && aIter->isValid() && m_pCacheSet->columnValuesUpdated((*aIter)->get(),rCurrentRow) )
1346cdf0e10cSrcweir             {
1347cdf0e10cSrcweir                 o_aBookmarks.push_back(lcl_getBookmark((*aIter)->get()[0],m_pCacheSet));
1348cdf0e10cSrcweir             }
1349cdf0e10cSrcweir         }
1350cdf0e10cSrcweir     }
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir 	m_bModified = sal_False;
1353cdf0e10cSrcweir }
1354cdf0e10cSrcweir // -------------------------------------------------------------------------
deleteRow()1355cdf0e10cSrcweir bool ORowSetCache::deleteRow(  )
1356cdf0e10cSrcweir {
1357cdf0e10cSrcweir 	if(isAfterLast() || isBeforeFirst())
1358cdf0e10cSrcweir 		throw SQLException(DBACORE_RESSTRING(RID_STR_NO_DELETEROW),NULL,SQLSTATE_GENERAL,1000,Any() );
1359cdf0e10cSrcweir 
1360cdf0e10cSrcweir 	//	m_pCacheSet->absolute(m_nPosition);
1361cdf0e10cSrcweir 	m_pCacheSet->deleteRow(*m_aMatrixIter,m_aUpdateTable);
1362cdf0e10cSrcweir     if ( !m_pCacheSet->rowDeleted() )
1363cdf0e10cSrcweir         return false;
1364cdf0e10cSrcweir 
1365cdf0e10cSrcweir     --m_nRowCount;
1366cdf0e10cSrcweir     OSL_ENSURE(((m_nPosition - m_nStartPos) - 1) < (sal_Int32)m_pMatrix->size(),"Position is behind end()!");
1367cdf0e10cSrcweir     ORowSetMatrix::iterator aPos = calcPosition();
1368cdf0e10cSrcweir     (*aPos)	  = NULL;
1369cdf0e10cSrcweir 
1370cdf0e10cSrcweir     ORowSetMatrix::iterator aEnd = m_pMatrix->end();
1371cdf0e10cSrcweir     for(++aPos;aPos != aEnd && aPos->isValid();++aPos)
1372cdf0e10cSrcweir     {
1373cdf0e10cSrcweir         *(aPos-1) = *aPos;
1374cdf0e10cSrcweir         (*aPos)	  = NULL;
1375cdf0e10cSrcweir     }
1376cdf0e10cSrcweir     m_aMatrixIter = m_pMatrix->end();
1377cdf0e10cSrcweir 
1378cdf0e10cSrcweir     --m_nPosition;
1379cdf0e10cSrcweir     return true;
1380cdf0e10cSrcweir }
1381cdf0e10cSrcweir // -------------------------------------------------------------------------
cancelRowUpdates()1382cdf0e10cSrcweir void ORowSetCache::cancelRowUpdates(  )
1383cdf0e10cSrcweir {
1384cdf0e10cSrcweir 	m_bNew = m_bModified = sal_False;
1385cdf0e10cSrcweir 	if(!m_nPosition)
1386cdf0e10cSrcweir 	{
1387cdf0e10cSrcweir 		OSL_ENSURE(0,"cancelRowUpdates:Invalid positions pos == 0");
1388cdf0e10cSrcweir 		::dbtools::throwFunctionSequenceException(NULL);
1389cdf0e10cSrcweir 	}
1390cdf0e10cSrcweir 
1391cdf0e10cSrcweir 	if(m_pCacheSet->absolute(m_nPosition))
1392cdf0e10cSrcweir 		m_pCacheSet->fillValueRow(*m_aMatrixIter,m_nPosition);
1393cdf0e10cSrcweir 	else
1394cdf0e10cSrcweir 	{
1395cdf0e10cSrcweir 		OSL_ENSURE(0,"cancelRowUpdates couldn't position right with absolute");
1396cdf0e10cSrcweir 		::dbtools::throwFunctionSequenceException(NULL);
1397cdf0e10cSrcweir 	}
1398cdf0e10cSrcweir }
1399cdf0e10cSrcweir // -------------------------------------------------------------------------
moveToInsertRow()1400cdf0e10cSrcweir void ORowSetCache::moveToInsertRow(  )
1401cdf0e10cSrcweir {
1402cdf0e10cSrcweir 	m_bNew		= sal_True;
1403cdf0e10cSrcweir 	m_bUpdated	= m_bAfterLast = sal_False;
1404cdf0e10cSrcweir 
1405cdf0e10cSrcweir 	m_aInsertRow = m_pInsertMatrix->begin();
1406cdf0e10cSrcweir 	if(!m_aInsertRow->isValid())
1407cdf0e10cSrcweir 		*m_aInsertRow = new ORowSetValueVector(m_xMetaData->getColumnCount());
1408cdf0e10cSrcweir 
1409cdf0e10cSrcweir 	// we don't unbound the bookmark column
1410cdf0e10cSrcweir 	ORowSetValueVector::Vector::iterator aIter = (*m_aInsertRow)->get().begin()+1;
1411cdf0e10cSrcweir     ORowSetValueVector::Vector::iterator aEnd = (*m_aInsertRow)->get().end();
1412cdf0e10cSrcweir 	for(sal_Int32 i = 1;aIter != aEnd;++aIter,++i)
1413cdf0e10cSrcweir 	{
1414cdf0e10cSrcweir 		aIter->setBound(sal_False);
1415cdf0e10cSrcweir 		aIter->setModified(sal_False);
1416cdf0e10cSrcweir 		aIter->setNull();
1417cdf0e10cSrcweir         aIter->setTypeKind(m_xMetaData->getColumnType(i));
1418cdf0e10cSrcweir 	}
1419cdf0e10cSrcweir }
1420cdf0e10cSrcweir // -------------------------------------------------------------------------
createIterator(ORowSetBase * _pRowSet)1421cdf0e10cSrcweir ORowSetCacheIterator ORowSetCache::createIterator(ORowSetBase* _pRowSet)
1422cdf0e10cSrcweir {
1423cdf0e10cSrcweir 
1424cdf0e10cSrcweir 	ORowSetCacheIterator_Helper aHelper;
1425cdf0e10cSrcweir 	aHelper.aIterator = m_pMatrix->end();
1426cdf0e10cSrcweir     aHelper.pRowSet = _pRowSet;
1427cdf0e10cSrcweir     return ORowSetCacheIterator(m_aCacheIterators.insert(m_aCacheIterators.begin(),ORowSetCacheMap::value_type(m_aCacheIterators.size()+1,aHelper)),this,_pRowSet);
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir // -----------------------------------------------------------------------------
deleteIterator(const ORowSetBase * _pRowSet)1430cdf0e10cSrcweir void ORowSetCache::deleteIterator(const ORowSetBase* _pRowSet)
1431cdf0e10cSrcweir {
1432cdf0e10cSrcweir     ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
1433cdf0e10cSrcweir 	for(;aCacheIter != m_aCacheIterators.end();)
1434cdf0e10cSrcweir     {
1435cdf0e10cSrcweir         if ( aCacheIter->second.pRowSet == _pRowSet )
1436cdf0e10cSrcweir         {
1437cdf0e10cSrcweir             m_aCacheIterators.erase(aCacheIter);
1438cdf0e10cSrcweir             aCacheIter = m_aCacheIterators.begin();
1439cdf0e10cSrcweir         } // if ( aCacheIter->second.pRowSet == _pRowSet )
1440cdf0e10cSrcweir         else
1441cdf0e10cSrcweir             ++aCacheIter;
1442cdf0e10cSrcweir     }
1443cdf0e10cSrcweir }
1444cdf0e10cSrcweir // -----------------------------------------------------------------------------
rotateCacheIterator(ORowSetMatrix::difference_type _nDist)1445cdf0e10cSrcweir void ORowSetCache::rotateCacheIterator(ORowSetMatrix::difference_type _nDist)
1446cdf0e10cSrcweir {
1447cdf0e10cSrcweir 	if(_nDist)
1448cdf0e10cSrcweir 	{
1449cdf0e10cSrcweir 		// now correct the iterator in our iterator vector
1450cdf0e10cSrcweir 		ORowSetCacheMap::iterator aCacheIter = m_aCacheIterators.begin();
1451cdf0e10cSrcweir         ORowSetCacheMap::iterator aCacheEnd  = m_aCacheIterators.end();
1452cdf0e10cSrcweir 		for(;aCacheIter != aCacheEnd;++aCacheIter)
1453cdf0e10cSrcweir 		{
1454cdf0e10cSrcweir 			if ( !aCacheIter->second.pRowSet->isInsertRow()
1455cdf0e10cSrcweir 				&& aCacheIter->second.aIterator != m_pMatrix->end() && !m_bModified )
1456cdf0e10cSrcweir 			{
1457cdf0e10cSrcweir 				ptrdiff_t nDist = (aCacheIter->second.aIterator - m_pMatrix->begin());
1458cdf0e10cSrcweir 				if(nDist < _nDist)
1459cdf0e10cSrcweir 				{
1460cdf0e10cSrcweir 					aCacheIter->second.aIterator = m_pMatrix->end();
1461cdf0e10cSrcweir 				}
1462cdf0e10cSrcweir 				else
1463cdf0e10cSrcweir 				{
1464cdf0e10cSrcweir                     OSL_ENSURE((aCacheIter->second.aIterator - m_pMatrix->begin()) >= _nDist,"Invalid Dist value!");
1465cdf0e10cSrcweir 					aCacheIter->second.aIterator -= _nDist;
1466cdf0e10cSrcweir 					OSL_ENSURE(aCacheIter->second.aIterator >= m_pMatrix->begin()
1467cdf0e10cSrcweir 							&& aCacheIter->second.aIterator < m_pMatrix->end(),"Iterator out of area!");
1468cdf0e10cSrcweir 				}
1469cdf0e10cSrcweir 			}
1470cdf0e10cSrcweir 		}
1471cdf0e10cSrcweir 	}
1472cdf0e10cSrcweir }
1473cdf0e10cSrcweir // -------------------------------------------------------------------------
setUpdateIterator(const ORowSetMatrix::iterator & _rOriginalRow)1474cdf0e10cSrcweir void ORowSetCache::setUpdateIterator(const ORowSetMatrix::iterator& _rOriginalRow)
1475cdf0e10cSrcweir {
1476cdf0e10cSrcweir 	m_aInsertRow = m_pInsertMatrix->begin();
1477cdf0e10cSrcweir 	if(!m_aInsertRow->isValid())
1478cdf0e10cSrcweir 		*m_aInsertRow = new ORowSetValueVector(m_xMetaData->getColumnCount());
1479cdf0e10cSrcweir 
1480cdf0e10cSrcweir 	(*(*m_aInsertRow)) = (*(*_rOriginalRow));
1481cdf0e10cSrcweir 	// we don't unbound the bookmark column
1482cdf0e10cSrcweir 	ORowSetValueVector::Vector::iterator aIter = (*m_aInsertRow)->get().begin();
1483cdf0e10cSrcweir     ORowSetValueVector::Vector::iterator aEnd = (*m_aInsertRow)->get().end();
1484cdf0e10cSrcweir 	for(;aIter != aEnd;++aIter)
1485cdf0e10cSrcweir 		aIter->setModified(sal_False);
1486cdf0e10cSrcweir }
1487cdf0e10cSrcweir // -----------------------------------------------------------------------------
checkPositionFlags()1488cdf0e10cSrcweir void ORowSetCache::checkPositionFlags()
1489cdf0e10cSrcweir {
1490cdf0e10cSrcweir 	if(m_bRowCountFinal)
1491cdf0e10cSrcweir 	{
1492cdf0e10cSrcweir 		m_bAfterLast	= m_nPosition > m_nRowCount;
1493cdf0e10cSrcweir 		if(m_bAfterLast)
1494cdf0e10cSrcweir 			m_nPosition = 0;//m_nRowCount;
1495cdf0e10cSrcweir 	}
1496cdf0e10cSrcweir }
1497cdf0e10cSrcweir // -----------------------------------------------------------------------------
checkUpdateConditions(sal_Int32 columnIndex)1498cdf0e10cSrcweir void ORowSetCache::checkUpdateConditions(sal_Int32 columnIndex)
1499cdf0e10cSrcweir {
1500cdf0e10cSrcweir 	if(m_bAfterLast || columnIndex >= (sal_Int32)(*m_aInsertRow)->get().size())
1501cdf0e10cSrcweir 		throwFunctionSequenceException(m_xSet.get());
1502cdf0e10cSrcweir }
1503cdf0e10cSrcweir //------------------------------------------------------------------------------
checkInnerJoin(const::connectivity::OSQLParseNode * pNode,const Reference<XConnection> & _xConnection,const::rtl::OUString & _sUpdateTableName)1504cdf0e10cSrcweir sal_Bool ORowSetCache::checkInnerJoin(const ::connectivity::OSQLParseNode *pNode,const Reference< XConnection>& _xConnection,const ::rtl::OUString& _sUpdateTableName)
1505cdf0e10cSrcweir {
1506cdf0e10cSrcweir 	sal_Bool bOk = sal_False;
1507cdf0e10cSrcweir 	if (pNode->count() == 3 &&	// Ausdruck is geklammert
1508cdf0e10cSrcweir 		SQL_ISPUNCTUATION(pNode->getChild(0),"(") &&
1509cdf0e10cSrcweir 		SQL_ISPUNCTUATION(pNode->getChild(2),")"))
1510cdf0e10cSrcweir 	{
1511cdf0e10cSrcweir 		bOk = checkInnerJoin(pNode->getChild(1),_xConnection,_sUpdateTableName);
1512cdf0e10cSrcweir 	}
1513cdf0e10cSrcweir 	else if ((SQL_ISRULE(pNode,search_condition) || SQL_ISRULE(pNode,boolean_term))	&&			// AND/OR-Verknuepfung:
1514cdf0e10cSrcweir 				pNode->count() == 3)
1515cdf0e10cSrcweir 	{
1516*ebe15e47SJohn Bampton 		// nur AND Verknüpfung zulassen
1517cdf0e10cSrcweir 		if ( SQL_ISTOKEN(pNode->getChild(1),AND) )
1518cdf0e10cSrcweir             bOk = checkInnerJoin(pNode->getChild(0),_xConnection,_sUpdateTableName)
1519cdf0e10cSrcweir                 && checkInnerJoin(pNode->getChild(2),_xConnection,_sUpdateTableName);
1520cdf0e10cSrcweir 	}
1521cdf0e10cSrcweir 	else if (SQL_ISRULE(pNode,comparison_predicate))
1522cdf0e10cSrcweir 	{
1523cdf0e10cSrcweir 		// only the comparison of columns is allowed
1524cdf0e10cSrcweir 		DBG_ASSERT(pNode->count() == 3,"checkInnerJoin: Fehler im Parse Tree");
1525cdf0e10cSrcweir 		if (!(SQL_ISRULE(pNode->getChild(0),column_ref) &&
1526cdf0e10cSrcweir 				SQL_ISRULE(pNode->getChild(2),column_ref) &&
1527cdf0e10cSrcweir 				pNode->getChild(1)->getNodeType() == SQL_NODE_EQUAL))
1528cdf0e10cSrcweir 		{
1529cdf0e10cSrcweir 			bOk = sal_False;
1530cdf0e10cSrcweir 		}
1531cdf0e10cSrcweir 		::rtl::OUString sColumnName,sTableRange;
1532cdf0e10cSrcweir 		OSQLParseTreeIterator::getColumnRange( pNode->getChild(0), _xConnection, sColumnName, sTableRange );
1533cdf0e10cSrcweir         bOk = sTableRange == _sUpdateTableName;
1534cdf0e10cSrcweir 		if ( !bOk )
1535cdf0e10cSrcweir 		{
1536cdf0e10cSrcweir 			OSQLParseTreeIterator::getColumnRange( pNode->getChild(2), _xConnection, sColumnName, sTableRange );
1537cdf0e10cSrcweir 			bOk =  sTableRange == _sUpdateTableName;
1538cdf0e10cSrcweir 		}
1539cdf0e10cSrcweir 	}
1540cdf0e10cSrcweir 	return bOk;
1541cdf0e10cSrcweir }
1542cdf0e10cSrcweir // -----------------------------------------------------------------------------
checkJoin(const Reference<XConnection> & _xConnection,const Reference<XSingleSelectQueryAnalyzer> & _xAnalyzer,const::rtl::OUString & _sUpdateTableName)1543cdf0e10cSrcweir sal_Bool ORowSetCache::checkJoin(const Reference< XConnection>& _xConnection,
1544cdf0e10cSrcweir 								 const Reference< XSingleSelectQueryAnalyzer >& _xAnalyzer,
1545cdf0e10cSrcweir 								 const ::rtl::OUString& _sUpdateTableName )
1546cdf0e10cSrcweir {
1547cdf0e10cSrcweir 	sal_Bool bOk = sal_False;
1548cdf0e10cSrcweir 	::rtl::OUString sSql = _xAnalyzer->getQuery();
1549cdf0e10cSrcweir 	::rtl::OUString sErrorMsg;
1550cdf0e10cSrcweir 	::connectivity::OSQLParser aSqlParser( m_aContext.getLegacyServiceFactory() );
1551cdf0e10cSrcweir 	::std::auto_ptr< ::connectivity::OSQLParseNode> pSqlParseNode( aSqlParser.parseTree(sErrorMsg,sSql));
1552cdf0e10cSrcweir 	if ( pSqlParseNode.get() && SQL_ISRULE(pSqlParseNode, select_statement) )
1553cdf0e10cSrcweir 	{
1554cdf0e10cSrcweir 		OSQLParseNode* pTableRefCommalist = pSqlParseNode->getByRule(::connectivity::OSQLParseNode::table_ref_commalist);
1555cdf0e10cSrcweir 		OSL_ENSURE(pTableRefCommalist,"NO tables why!?");
1556cdf0e10cSrcweir 		if(pTableRefCommalist && pTableRefCommalist->count() == 1)
1557cdf0e10cSrcweir 		{
1558cdf0e10cSrcweir 			// we found only one element so it must some kind of join here
1559cdf0e10cSrcweir 			OSQLParseNode* pJoin = pTableRefCommalist->getByRule(::connectivity::OSQLParseNode::qualified_join);
1560cdf0e10cSrcweir 			if(pJoin)
1561cdf0e10cSrcweir 			{ // we are only intereseted in qualified joins like RIGHT or LEFT
1562cdf0e10cSrcweir 				OSQLParseNode* pJoinType	= pJoin->getChild(1);
1563cdf0e10cSrcweir 				OSQLParseNode* pOuterType	= NULL;
1564cdf0e10cSrcweir 				if(SQL_ISRULE(pJoinType,join_type) && pJoinType->count() == 2)
1565cdf0e10cSrcweir 					pOuterType = pJoinType->getChild(0);
1566cdf0e10cSrcweir 				else if(SQL_ISRULE(pJoinType,outer_join_type))
1567cdf0e10cSrcweir 					pOuterType = pJoinType;
1568cdf0e10cSrcweir 
1569cdf0e10cSrcweir 				sal_Bool bCheck		= sal_False;
1570cdf0e10cSrcweir 				sal_Bool bLeftSide	= sal_False;
1571cdf0e10cSrcweir 				if(pOuterType)
1572cdf0e10cSrcweir 				{ // found outer join
1573cdf0e10cSrcweir 					bLeftSide = SQL_ISTOKEN(pOuterType->getChild(0),LEFT);
1574cdf0e10cSrcweir 					bCheck = bLeftSide || SQL_ISTOKEN(pOuterType->getChild(0),RIGHT);
1575cdf0e10cSrcweir 				}
1576cdf0e10cSrcweir 
1577cdf0e10cSrcweir 				if(bCheck)
1578cdf0e10cSrcweir 				{ // here we know that we have to check on which side our table resides
1579cdf0e10cSrcweir 					const OSQLParseNode* pTableRef = pJoin->getByRule(::connectivity::OSQLParseNode::qualified_join);
1580cdf0e10cSrcweir 					if(bLeftSide)
1581cdf0e10cSrcweir 						pTableRef = pJoin->getChild(0);
1582cdf0e10cSrcweir 					else
1583cdf0e10cSrcweir 						pTableRef = pJoin->getChild(3);
1584cdf0e10cSrcweir 					OSL_ENSURE(SQL_ISRULE(pTableRef,table_ref),"Must be a tableref here!");
1585cdf0e10cSrcweir 
1586cdf0e10cSrcweir                     ::rtl::OUString sTableRange = OSQLParseNode::getTableRange(pTableRef);
1587cdf0e10cSrcweir 					if(!sTableRange.getLength())
1588cdf0e10cSrcweir 						pTableRef->getChild(0)->parseNodeToStr( sTableRange, _xConnection, NULL, sal_False, sal_False );
1589cdf0e10cSrcweir 					bOk =  sTableRange == _sUpdateTableName;
1590cdf0e10cSrcweir 				}
1591cdf0e10cSrcweir 			}
1592cdf0e10cSrcweir 		}
1593cdf0e10cSrcweir 		else
1594cdf0e10cSrcweir 		{
1595cdf0e10cSrcweir 			OSQLParseNode* pWhereOpt = pSqlParseNode->getChild(3)->getChild(1);
1596cdf0e10cSrcweir 			if ( pWhereOpt && !pWhereOpt->isLeaf() )
1597cdf0e10cSrcweir 				bOk = checkInnerJoin(pWhereOpt->getChild(1),_xConnection,_sUpdateTableName);
1598cdf0e10cSrcweir 		}
1599cdf0e10cSrcweir 	}
1600cdf0e10cSrcweir 	return bOk;
1601cdf0e10cSrcweir }
1602cdf0e10cSrcweir // -----------------------------------------------------------------------------
clearInsertRow()1603cdf0e10cSrcweir void ORowSetCache::clearInsertRow()
1604cdf0e10cSrcweir {
1605cdf0e10cSrcweir 	// we don't unbound the bookmark column
1606cdf0e10cSrcweir 	if ( m_aInsertRow != m_pInsertMatrix->end() && m_aInsertRow->isValid() )
1607cdf0e10cSrcweir 	{
1608cdf0e10cSrcweir 		ORowSetValueVector::Vector::iterator aIter = (*m_aInsertRow)->get().begin()+1;
1609cdf0e10cSrcweir 		ORowSetValueVector::Vector::iterator aEnd = (*m_aInsertRow)->get().end();
1610cdf0e10cSrcweir 		for(;aIter != aEnd;++aIter)
1611cdf0e10cSrcweir 		{
1612cdf0e10cSrcweir 			aIter->setBound(sal_False);
1613cdf0e10cSrcweir 			aIter->setModified(sal_False);
1614cdf0e10cSrcweir 			aIter->setNull();
1615cdf0e10cSrcweir 		} // for(;aIter != (*m_aInsertRow)->end();++aIter)
1616cdf0e10cSrcweir 	}
1617cdf0e10cSrcweir }
1618cdf0e10cSrcweir // -----------------------------------------------------------------------------
calcPosition() const1619cdf0e10cSrcweir ORowSetMatrix::iterator	ORowSetCache::calcPosition() const
1620cdf0e10cSrcweir {
1621cdf0e10cSrcweir 	sal_Int32 nValue = (m_nPosition - m_nStartPos) - 1;
1622cdf0e10cSrcweir     CHECK_MATRIX_POS(nValue);
1623cdf0e10cSrcweir 	return ( nValue < 0 || nValue >= static_cast<sal_Int32>(m_pMatrix->size()) ) ? m_pMatrix->end() : (m_pMatrix->begin() + nValue);
1624cdf0e10cSrcweir }
1625cdf0e10cSrcweir // -----------------------------------------------------------------------------
1626cdf0e10cSrcweir 
registerOldRow()1627cdf0e10cSrcweir TORowSetOldRowHelperRef ORowSetCache::registerOldRow()
1628cdf0e10cSrcweir {
1629cdf0e10cSrcweir 	TORowSetOldRowHelperRef pRef = new ORowSetOldRowHelper(ORowSetRow());
1630cdf0e10cSrcweir 	m_aOldRows.push_back(pRef);
1631cdf0e10cSrcweir 	return pRef;
1632cdf0e10cSrcweir }
1633cdf0e10cSrcweir // -----------------------------------------------------------------------------
deregisterOldRow(const TORowSetOldRowHelperRef & _rRow)1634cdf0e10cSrcweir void ORowSetCache::deregisterOldRow(const TORowSetOldRowHelperRef& _rRow)
1635cdf0e10cSrcweir {
1636cdf0e10cSrcweir     TOldRowSetRows::iterator aOldRowEnd = m_aOldRows.end();
1637cdf0e10cSrcweir 	for (TOldRowSetRows::iterator aOldRowIter = m_aOldRows.begin(); aOldRowIter != aOldRowEnd; ++aOldRowIter)
1638cdf0e10cSrcweir 	{
1639cdf0e10cSrcweir 		if ( aOldRowIter->getBodyPtr() == _rRow.getBodyPtr() )
1640cdf0e10cSrcweir 		{
1641cdf0e10cSrcweir 			m_aOldRows.erase(aOldRowIter);
1642cdf0e10cSrcweir 			break;
1643cdf0e10cSrcweir 		}
1644cdf0e10cSrcweir 
1645cdf0e10cSrcweir 	}
1646cdf0e10cSrcweir }
1647cdf0e10cSrcweir // -----------------------------------------------------------------------------
reFillMatrix(sal_Int32 _nNewStartPos,sal_Int32 _nNewEndPos)1648cdf0e10cSrcweir sal_Bool ORowSetCache::reFillMatrix(sal_Int32 _nNewStartPos,sal_Int32 _nNewEndPos)
1649cdf0e10cSrcweir {
1650cdf0e10cSrcweir     TOldRowSetRows::iterator aOldRowEnd = m_aOldRows.end();
1651cdf0e10cSrcweir 	for (TOldRowSetRows::iterator aOldRowIter = m_aOldRows.begin(); aOldRowIter != aOldRowEnd; ++aOldRowIter)
1652cdf0e10cSrcweir 	{
1653cdf0e10cSrcweir 		if ( aOldRowIter->isValid() && aOldRowIter->getBody().getRow().isValid() )
1654cdf0e10cSrcweir 			aOldRowIter->getBody().setRow(new ORowSetValueVector(aOldRowIter->getBody().getRow().getBody()) );
1655cdf0e10cSrcweir 	}
1656cdf0e10cSrcweir 	sal_Int32 nNewSt = _nNewStartPos;
1657cdf0e10cSrcweir 	sal_Bool bRet = fillMatrix(nNewSt,_nNewEndPos);
1658cdf0e10cSrcweir 	m_nStartPos = nNewSt - 1;
1659cdf0e10cSrcweir 	rotateCacheIterator(static_cast<sal_Int16>(m_nFetchSize+1)); // forces that every iterator will be set to null
1660cdf0e10cSrcweir 	return bRet;
1661cdf0e10cSrcweir }
1662cdf0e10cSrcweir // -----------------------------------------------------------------------------
fill(ORowSetMatrix::iterator & _aIter,const ORowSetMatrix::iterator & _aEnd,sal_Int32 & _nPos,sal_Bool _bCheck)1663cdf0e10cSrcweir sal_Bool ORowSetCache::fill(ORowSetMatrix::iterator& _aIter,const ORowSetMatrix::iterator& _aEnd,sal_Int32& _nPos,sal_Bool _bCheck)
1664cdf0e10cSrcweir {
1665cdf0e10cSrcweir 	sal_Int32 nColumnCount = m_xMetaData->getColumnCount();
1666cdf0e10cSrcweir 	for(; _bCheck && _aIter != _aEnd;)
1667cdf0e10cSrcweir 	{
1668cdf0e10cSrcweir 		if ( !_aIter->isValid() )
1669cdf0e10cSrcweir 			*_aIter = new ORowSetValueVector(nColumnCount);
1670cdf0e10cSrcweir 		else
1671cdf0e10cSrcweir 		{
1672cdf0e10cSrcweir             TOldRowSetRows::iterator aOldRowEnd = m_aOldRows.end();
1673cdf0e10cSrcweir 	        for (TOldRowSetRows::iterator aOldRowIter = m_aOldRows.begin(); aOldRowIter != aOldRowEnd; ++aOldRowIter)
1674cdf0e10cSrcweir 			{
1675cdf0e10cSrcweir 				if ( aOldRowIter->getBody().getRow().isEqualBody(*_aIter) )
1676cdf0e10cSrcweir 					*_aIter = new ORowSetValueVector(nColumnCount);
1677cdf0e10cSrcweir 			}
1678cdf0e10cSrcweir 		}
1679cdf0e10cSrcweir 		m_pCacheSet->fillValueRow(*_aIter++,++_nPos);
1680cdf0e10cSrcweir 		_bCheck = m_pCacheSet->next();
1681cdf0e10cSrcweir 	}
1682cdf0e10cSrcweir 	return _bCheck;
1683cdf0e10cSrcweir }
1684cdf0e10cSrcweir // -----------------------------------------------------------------------------
isResultSetChanged() const1685cdf0e10cSrcweir bool ORowSetCache::isResultSetChanged() const
1686cdf0e10cSrcweir {
1687cdf0e10cSrcweir     return m_pCacheSet->isResultSetChanged();
1688cdf0e10cSrcweir }
1689cdf0e10cSrcweir // -----------------------------------------------------------------------------
reset(const Reference<XResultSet> & _xDriverSet)1690cdf0e10cSrcweir void ORowSetCache::reset(const Reference< XResultSet>& _xDriverSet)
1691cdf0e10cSrcweir {
1692cdf0e10cSrcweir     m_xMetaData.set(Reference< XResultSetMetaDataSupplier >(_xDriverSet,UNO_QUERY)->getMetaData());
1693cdf0e10cSrcweir     m_pCacheSet->reset(_xDriverSet);
1694cdf0e10cSrcweir 
1695cdf0e10cSrcweir     m_bRowCountFinal = sal_False;
1696cdf0e10cSrcweir     m_nRowCount = 0;
1697cdf0e10cSrcweir 	reFillMatrix(m_nStartPos+1,m_nEndPos+1);
1698cdf0e10cSrcweir }
1699cdf0e10cSrcweir // -----------------------------------------------------------------------------
impl_updateRowFromCache_throw(ORowSetValueVector::Vector & io_aRow,::std::vector<sal_Int32> & o_ChangedColumns)1700cdf0e10cSrcweir void ORowSetCache::impl_updateRowFromCache_throw(ORowSetValueVector::Vector& io_aRow
1701cdf0e10cSrcweir                                            ,::std::vector<sal_Int32>& o_ChangedColumns)
1702cdf0e10cSrcweir {
1703cdf0e10cSrcweir     if ( o_ChangedColumns.size() > 1 )
1704cdf0e10cSrcweir     {
1705cdf0e10cSrcweir         ORowSetMatrix::iterator aIter = m_pMatrix->begin();
1706cdf0e10cSrcweir         for(;aIter != m_pMatrix->end();++aIter)
1707cdf0e10cSrcweir         {
1708cdf0e10cSrcweir             if ( aIter->isValid() && m_pCacheSet->updateColumnValues((*aIter)->get(),io_aRow,o_ChangedColumns))
1709cdf0e10cSrcweir             {
1710cdf0e10cSrcweir                 break;
1711cdf0e10cSrcweir             }
1712cdf0e10cSrcweir         }
1713cdf0e10cSrcweir 
1714cdf0e10cSrcweir         if ( aIter == m_pMatrix->end() )
1715cdf0e10cSrcweir         {
1716cdf0e10cSrcweir             m_pCacheSet->fillMissingValues(io_aRow);
1717cdf0e10cSrcweir         }
1718cdf0e10cSrcweir     }
1719cdf0e10cSrcweir }
1720cdf0e10cSrcweir // -----------------------------------------------------------------------------
1721