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