xref: /trunk/main/connectivity/source/commontools/TSkipDeletedSet.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
30 #include "TSkipDeletedSet.hxx"
31 #include <osl/diagnose.h>
32 #include <rtl/logfile.hxx>
33 
34 using namespace connectivity;
35 // -----------------------------------------------------------------------------
36 OSkipDeletedSet::OSkipDeletedSet(IResultSetHelper* _pHelper)
37     : m_pHelper(_pHelper)
38     ,m_bDeletedVisible(false)
39 {
40     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::OSkipDeletedSet" );
41     m_aBookmarksPositions.reserve(256);
42 }
43 // -----------------------------------------------------------------------------
44 OSkipDeletedSet::~OSkipDeletedSet()
45 {
46     m_aBookmarksPositions.clear();
47     //m_aBookmarks.clear();
48 }
49 // -----------------------------------------------------------------------------
50 sal_Bool OSkipDeletedSet::skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData)
51 {
52     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::skipDeleted" );
53     OSL_ENSURE(_eCursorPosition != IResultSetHelper::BOOKMARK,"OSkipDeletedSet::SkipDeleted can't be called for BOOKMARK");
54 
55     IResultSetHelper::Movement eDelPosition = _eCursorPosition;
56     sal_Int32 nDelOffset = abs(_nOffset);
57 
58     switch (_eCursorPosition)
59     {
60         case IResultSetHelper::ABSOLUTE:
61             return moveAbsolute(_nOffset,_bRetrieveData);
62         case IResultSetHelper::FIRST:                   // set the movement when positioning failed
63             eDelPosition = IResultSetHelper::NEXT;
64             nDelOffset = 1;
65             break;
66         case IResultSetHelper::LAST:
67             eDelPosition = IResultSetHelper::PRIOR; // lsat row is invalid so position before
68             nDelOffset = 1;
69             break;
70         case IResultSetHelper::RELATIVE:
71             eDelPosition = (_nOffset >= 0) ? IResultSetHelper::NEXT : IResultSetHelper::PRIOR;
72             break;
73         default:
74             break;
75     }
76 
77     sal_Bool bDone          = sal_True;
78     sal_Bool bDataFound     = sal_False;
79 
80     if (_eCursorPosition == IResultSetHelper::LAST)
81     {
82         RTL_LOGFILE_CONTEXT_TRACE( aLogger, "OSkipDeletedSet::skipDeleted: last" );
83         sal_Int32 nBookmark = 0;
84         // first position on the last known row
85         if ( m_aBookmarksPositions.empty() )
86         {
87             bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData);
88             if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
89                 //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
90                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
91         }
92         else
93         {
94             // I already have a bookmark so we can positioned on that and look if it is the last one
95             nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
96 
97             bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
98             OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"A bookmark should not be deleted!");
99         }
100 
101 
102         // and than move forward until we are after the last row
103         while(bDataFound)
104         {
105             bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, sal_False); // we don't need the data here
106             if( bDataFound && ( m_bDeletedVisible || !m_pHelper->isRowDeleted()) )
107             {   // we weren't on the last row we remember it and move on
108                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
109                 //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
110             }
111             else if(!bDataFound && !m_aBookmarksPositions.empty() )
112             {
113                 // i already know the last bookmark :-)
114                 // now we only have to repositioning us to the last row
115                 nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
116                 bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
117                 break;
118             }
119         }
120         return bDataFound;
121     }
122     else if (_eCursorPosition != IResultSetHelper::RELATIVE)
123     {
124         bDataFound = m_pHelper->move(_eCursorPosition, _nOffset, _bRetrieveData);
125         bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
126     }
127     else
128     {
129         bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
130         if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
131         {
132             bDone = (--nDelOffset) == 0;
133             if ( !bDone )
134                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
135             //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
136         }
137         else
138             bDone = sal_False;
139     }
140 
141     while (bDataFound && !bDone)            // solange iterieren bis man auf einem gueltigen Satz ist
142     {
143         bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
144         if (_eCursorPosition != IResultSetHelper::RELATIVE)
145             bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
146         else if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
147         {
148             bDone = (--nDelOffset) == 0;
149             if ( !bDone )
150                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
151             //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
152         }
153         else
154             bDone = sal_False;
155     }
156 
157     if(bDataFound && bDone)
158     {
159         const sal_Int32 nDriverPos = m_pHelper->getDriverPos();
160         if ( m_bDeletedVisible )
161         {
162             if ( nDriverPos > (sal_Int32)m_aBookmarksPositions.size() )
163                 m_aBookmarksPositions.push_back(nDriverPos);
164         }
165         else if ( ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),nDriverPos) == m_aBookmarksPositions.end() )
166             m_aBookmarksPositions.push_back(nDriverPos);
167         /*sal_Int32 nDriverPos = m_pHelper->getDriverPos();
168         if(m_aBookmarks.find(nDriverPos) == m_aBookmarks.end())
169             m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(nDriverPos,m_aBookmarksPositions.size()+1)).first);*/
170     }
171 
172     return bDataFound;
173 }
174 // -------------------------------------------------------------------------
175 sal_Bool OSkipDeletedSet::moveAbsolute(sal_Int32 _nPos,sal_Bool _bRetrieveData)
176 {
177     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::moveAbsolute" );
178     sal_Bool bDataFound = sal_False;
179     sal_Int32 nNewPos = _nPos;
180     if(nNewPos > 0)
181     {
182         if((sal_Int32)m_aBookmarksPositions.size() < nNewPos)
183         {
184             // bookmark isn't known yet
185             // start at the last known position
186             sal_Int32 nCurPos = 0,nLastBookmark = 1;
187             if ( m_aBookmarksPositions.empty() )
188             {
189                 bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData );
190                 if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
191                 {
192                     ++nCurPos;
193                     m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
194                     //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
195                     --nNewPos;
196                 }
197             } // if ( m_aBookmarksPositions.empty() )
198             else
199             {
200                 nLastBookmark   = (*m_aBookmarksPositions.rbegin())/*->first*/;
201                 nCurPos         = /*(**/m_aBookmarksPositions.size()/*->second*/;
202                 nNewPos         = nNewPos - nCurPos;
203                 bDataFound      = m_pHelper->move(IResultSetHelper::BOOKMARK, nLastBookmark, _bRetrieveData);
204             }
205 
206             // now move to that row we need and don't count deleted rows
207             while (bDataFound && nNewPos)
208             {
209                 bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, _bRetrieveData);
210                 if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
211                 {
212                     ++nCurPos;
213                     m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
214                     //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
215                     --nNewPos;
216                 }
217             }
218         }
219         else
220         {
221             const sal_Int32 nBookmark = m_aBookmarksPositions[nNewPos-1]/*->first*/;
222             bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK,nBookmark, _bRetrieveData);
223             OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"moveAbsolute: row can't be deleted!");
224         }
225     }
226     else
227     {
228         ++nNewPos;
229         bDataFound = skipDeleted(IResultSetHelper::LAST,0,nNewPos == 0);
230 
231         for(sal_Int32 i=nNewPos+1;bDataFound && i <= 0;++i)
232             bDataFound = skipDeleted(IResultSetHelper::PRIOR,1,i == 0);
233 
234     }
235     return bDataFound;
236 }
237 // -----------------------------------------------------------------------------
238 void OSkipDeletedSet::clear()
239 {
240     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::clear" );
241     ::std::vector<sal_Int32>().swap(m_aBookmarksPositions);
242     //TInt2IntMap().swap(m_aBookmarks);
243 }
244 // -----------------------------------------------------------------------------
245 sal_Int32 OSkipDeletedSet::getMappedPosition(sal_Int32 _nPos) const
246 {
247     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::getMappedPosition" );
248     ::std::vector<sal_Int32>::const_iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos);
249     if ( aFind !=  m_aBookmarksPositions.end() )
250         return (aFind - m_aBookmarksPositions.begin()) + 1;
251     /*TInt2IntMap::const_iterator aFind = m_aBookmarks.find(_nPos);
252     OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::getMappedPosition() invalid bookmark!");
253     return aFind->second;*/
254     OSL_ENSURE(0,"Why!");
255     return -1;
256 }
257 // -----------------------------------------------------------------------------
258 void OSkipDeletedSet::insertNewPosition(sal_Int32 _nPos)
259 {
260     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::insertNewPosition" );
261     //OSL_ENSURE(m_aBookmarks.find(_nPos) == m_aBookmarks.end(),"OSkipDeletedSet::insertNewPosition: Invalid position");
262     //m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(_nPos,m_aBookmarksPositions.size()+1)).first);
263     //OSL_ENSURE(::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos) == m_aBookmarksPositions.end(),"Invalid driver pos");
264     m_aBookmarksPositions.push_back(_nPos);
265 }
266 // -----------------------------------------------------------------------------
267 void OSkipDeletedSet::deletePosition(sal_Int32 _nBookmark)
268 {
269     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::deletePosition" );
270     ::std::vector<sal_Int32>::iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nBookmark);
271     if ( aFind !=  m_aBookmarksPositions.end() )
272     {
273     //TInt2IntMap::iterator aFind = m_aBookmarks.find(_nPos);
274     //OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::deletePosition() bookmark not found!");
275     //TInt2IntMap::iterator aIter = aFind;
276         m_aBookmarksPositions.erase(aFind);
277         //for (; aFind != m_aBookmarksPositions.end() ; ++aIter)
278            // --(aFind->second);
279     } // if ( aFind !=  m_aBookmarksPositions.end() )
280     //m_aBookmarksPositions.erase(m_aBookmarksPositions.begin() + aFind->second-1);
281     //m_aBookmarks.erase(_nPos);
282 }
283 // -----------------------------------------------------------------------------
284