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