Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "TSkipDeletedSet.hxx"
21 : #include <osl/diagnose.h>
22 : #include <sal/log.hxx>
23 : #include <algorithm>
24 :
25 : using namespace connectivity;
26 :
27 29 : OSkipDeletedSet::OSkipDeletedSet(IResultSetHelper* _pHelper)
28 : : m_pHelper(_pHelper)
29 29 : ,m_bDeletedVisible(false)
30 : {
31 29 : m_aBookmarksPositions.reserve(256);
32 29 : }
33 :
34 58 : OSkipDeletedSet::~OSkipDeletedSet()
35 : {
36 29 : m_aBookmarksPositions.clear();
37 : //m_aBookmarks.clear();
38 29 : }
39 :
40 473 : bool OSkipDeletedSet::skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, bool _bRetrieveData)
41 : {
42 : OSL_ENSURE(_eCursorPosition != IResultSetHelper::BOOKMARK,"OSkipDeletedSet::SkipDeleted can't be called for BOOKMARK");
43 :
44 473 : IResultSetHelper::Movement eDelPosition = _eCursorPosition;
45 473 : sal_Int32 nDelOffset = abs(_nOffset);
46 :
47 473 : switch (_eCursorPosition)
48 : {
49 : case IResultSetHelper::ABSOLUTE1:
50 82 : return moveAbsolute(_nOffset,_bRetrieveData);
51 : case IResultSetHelper::FIRST: // set the movement when positioning failed
52 77 : eDelPosition = IResultSetHelper::NEXT;
53 77 : nDelOffset = 1;
54 77 : break;
55 : case IResultSetHelper::LAST:
56 10 : eDelPosition = IResultSetHelper::PRIOR; // last row is invalid so position before
57 10 : nDelOffset = 1;
58 10 : break;
59 : case IResultSetHelper::RELATIVE1:
60 0 : eDelPosition = (_nOffset >= 0) ? IResultSetHelper::NEXT : IResultSetHelper::PRIOR;
61 0 : break;
62 : default:
63 304 : break;
64 : }
65 :
66 391 : bool bDone = true;
67 391 : bool bDataFound = false;
68 :
69 391 : if (_eCursorPosition == IResultSetHelper::LAST)
70 : {
71 : SAL_INFO( "connectivity.commontools", "OSkipDeletedSet::skipDeleted: last" );
72 10 : sal_Int32 nBookmark = 0;
73 : // first position on the last known row
74 10 : if ( m_aBookmarksPositions.empty() )
75 : {
76 0 : bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData);
77 0 : if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
78 : //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
79 0 : m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
80 : }
81 : else
82 : {
83 : // I already have a bookmark so we can positioned on that and look if it is the last one
84 10 : nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
85 :
86 10 : bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
87 : OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"A bookmark should not be deleted!");
88 : }
89 :
90 :
91 : // and then move forward until we are after the last row
92 20 : while(bDataFound)
93 : {
94 10 : bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, false); // we don't need the data here
95 10 : if( bDataFound && ( m_bDeletedVisible || !m_pHelper->isRowDeleted()) )
96 : { // we weren't on the last row we remember it and move on
97 0 : m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
98 : //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
99 : }
100 10 : else if(!bDataFound && !m_aBookmarksPositions.empty() )
101 : {
102 : // i already know the last bookmark :-)
103 : // now we only have to repositioning us to the last row
104 10 : nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
105 10 : bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
106 10 : break;
107 : }
108 : }
109 10 : return bDataFound;
110 : }
111 381 : else if (_eCursorPosition != IResultSetHelper::RELATIVE1)
112 : {
113 381 : bDataFound = m_pHelper->move(_eCursorPosition, _nOffset, _bRetrieveData);
114 381 : bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
115 : }
116 : else
117 : {
118 0 : bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
119 0 : if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
120 : {
121 0 : bDone = (--nDelOffset) == 0;
122 0 : if ( !bDone )
123 0 : m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
124 : //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
125 : }
126 : else
127 0 : bDone = false;
128 : }
129 :
130 2471 : while (bDataFound && !bDone) // Iterate until we are at the valid set
131 : {
132 1709 : bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
133 1709 : if (_eCursorPosition != IResultSetHelper::RELATIVE1)
134 1709 : bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
135 0 : else if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
136 : {
137 0 : bDone = (--nDelOffset) == 0;
138 0 : if ( !bDone )
139 0 : m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
140 : //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
141 : }
142 : else
143 0 : bDone = false;
144 : }
145 :
146 381 : if(bDataFound && bDone)
147 : {
148 300 : const sal_Int32 nDriverPos = m_pHelper->getDriverPos();
149 300 : if ( m_bDeletedVisible )
150 : {
151 0 : if ( nDriverPos > (sal_Int32)m_aBookmarksPositions.size() )
152 0 : m_aBookmarksPositions.push_back(nDriverPos);
153 : }
154 300 : else if ( ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),nDriverPos) == m_aBookmarksPositions.end() )
155 230 : m_aBookmarksPositions.push_back(nDriverPos);
156 : /*sal_Int32 nDriverPos = m_pHelper->getDriverPos();
157 : if(m_aBookmarks.find(nDriverPos) == m_aBookmarks.end())
158 : m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(nDriverPos,m_aBookmarksPositions.size()+1)).first);*/
159 : }
160 :
161 381 : return bDataFound;
162 : }
163 :
164 82 : bool OSkipDeletedSet::moveAbsolute(sal_Int32 _nPos,bool _bRetrieveData)
165 : {
166 82 : bool bDataFound = false;
167 82 : sal_Int32 nNewPos = _nPos;
168 82 : if(nNewPos > 0)
169 : {
170 82 : if((sal_Int32)m_aBookmarksPositions.size() < nNewPos)
171 : {
172 : // bookmark isn't known yet
173 : // start at the last known position
174 25 : sal_Int32 nCurPos = 0,nLastBookmark = 1;
175 25 : if ( m_aBookmarksPositions.empty() )
176 : {
177 9 : bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData );
178 9 : if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
179 : {
180 1 : ++nCurPos;
181 1 : m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
182 : //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
183 1 : --nNewPos;
184 : }
185 : } // if ( m_aBookmarksPositions.empty() )
186 : else
187 : {
188 16 : nLastBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
189 16 : nCurPos = /*(**/m_aBookmarksPositions.size()/*->second*/;
190 16 : nNewPos = nNewPos - nCurPos;
191 16 : bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nLastBookmark, _bRetrieveData);
192 : }
193 :
194 : // now move to that row we need and don't count deleted rows
195 66 : while (bDataFound && nNewPos)
196 : {
197 16 : bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, _bRetrieveData);
198 16 : if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
199 : {
200 0 : ++nCurPos;
201 0 : m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
202 : //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
203 0 : --nNewPos;
204 : }
205 : }
206 : }
207 : else
208 : {
209 57 : const sal_Int32 nBookmark = m_aBookmarksPositions[nNewPos-1]/*->first*/;
210 57 : bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK,nBookmark, _bRetrieveData);
211 : OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"moveAbsolute: row can't be deleted!");
212 : }
213 : }
214 : else
215 : {
216 0 : ++nNewPos;
217 0 : bDataFound = skipDeleted(IResultSetHelper::LAST,0,nNewPos == 0);
218 :
219 0 : for(sal_Int32 i=nNewPos+1;bDataFound && i <= 0;++i)
220 0 : bDataFound = skipDeleted(IResultSetHelper::PRIOR,1,i == 0);
221 :
222 : }
223 82 : return bDataFound;
224 : }
225 :
226 58 : void OSkipDeletedSet::clear()
227 : {
228 58 : ::std::vector<sal_Int32>().swap(m_aBookmarksPositions);
229 : //TInt2IntMap().swap(m_aBookmarks);
230 58 : }
231 :
232 40 : sal_Int32 OSkipDeletedSet::getMappedPosition(sal_Int32 _nPos) const
233 : {
234 40 : ::std::vector<sal_Int32>::const_iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos);
235 40 : if ( aFind != m_aBookmarksPositions.end() )
236 40 : return (aFind - m_aBookmarksPositions.begin()) + 1;
237 : /*TInt2IntMap::const_iterator aFind = m_aBookmarks.find(_nPos);
238 : OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::getMappedPosition() invalid bookmark!");
239 : return aFind->second;*/
240 : OSL_FAIL("Why!");
241 0 : return -1;
242 : }
243 :
244 1 : void OSkipDeletedSet::insertNewPosition(sal_Int32 _nPos)
245 : {
246 : //OSL_ENSURE(m_aBookmarks.find(_nPos) == m_aBookmarks.end(),"OSkipDeletedSet::insertNewPosition: Invalid position");
247 : //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(_nPos,m_aBookmarksPositions.size()+1)).first);
248 : //OSL_ENSURE(::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos) == m_aBookmarksPositions.end(),"Invalid driver pos");
249 1 : m_aBookmarksPositions.push_back(_nPos);
250 1 : }
251 :
252 1 : void OSkipDeletedSet::deletePosition(sal_Int32 _nBookmark)
253 : {
254 1 : ::std::vector<sal_Int32>::iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nBookmark);
255 1 : if ( aFind != m_aBookmarksPositions.end() )
256 : {
257 : //TInt2IntMap::iterator aFind = m_aBookmarks.find(_nPos);
258 : //OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::deletePosition() bookmark not found!");
259 : //TInt2IntMap::iterator aIter = aFind;
260 1 : m_aBookmarksPositions.erase(aFind);
261 : //for (; aFind != m_aBookmarksPositions.end() ; ++aIter)
262 : // --(aFind->second);
263 : } // if ( aFind != m_aBookmarksPositions.end() )
264 : //m_aBookmarksPositions.erase(m_aBookmarksPositions.begin() + aFind->second-1);
265 : //m_aBookmarks.erase(_nPos);
266 1 : }
267 :
268 :
269 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|