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 
30 using namespace connectivity;
31 // -----------------------------------------------------------------------------
32 OSkipDeletedSet::OSkipDeletedSet(IResultSetHelper* _pHelper)
33 	: m_pHelper(_pHelper)
34     ,m_bDeletedVisible(false)
35 {
36     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::OSkipDeletedSet" );
37     m_aBookmarksPositions.reserve(256);
38 }
39 // -----------------------------------------------------------------------------
40 OSkipDeletedSet::~OSkipDeletedSet()
41 {
42 	m_aBookmarksPositions.clear();
43 	//m_aBookmarks.clear();
44 }
45 // -----------------------------------------------------------------------------
46 sal_Bool OSkipDeletedSet::skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData)
47 {
48     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::skipDeleted" );
49 	OSL_ENSURE(_eCursorPosition != IResultSetHelper::BOOKMARK,"OSkipDeletedSet::SkipDeleted can't be called for BOOKMARK");
50 
51 	IResultSetHelper::Movement eDelPosition = _eCursorPosition;
52 	sal_Int32 nDelOffset = abs(_nOffset);
53 
54 	switch (_eCursorPosition)
55 	{
56 		case IResultSetHelper::ABSOLUTE:
57             return moveAbsolute(_nOffset,_bRetrieveData);
58 		case IResultSetHelper::FIRST:					// set the movement when positioning failed
59 			eDelPosition = IResultSetHelper::NEXT;
60 			nDelOffset = 1;
61 			break;
62 		case IResultSetHelper::LAST:
63 			eDelPosition = IResultSetHelper::PRIOR; // lsat row is invalid so position before
64 			nDelOffset = 1;
65 			break;
66 		case IResultSetHelper::RELATIVE:
67 			eDelPosition = (_nOffset >= 0) ? IResultSetHelper::NEXT : IResultSetHelper::PRIOR;
68 			break;
69         default:
70             break;
71 	}
72 
73 	sal_Bool bDone			= sal_True;
74 	sal_Bool bDataFound		= sal_False;
75 
76 	if (_eCursorPosition == IResultSetHelper::LAST)
77 	{
78         RTL_LOGFILE_CONTEXT_TRACE( aLogger, "OSkipDeletedSet::skipDeleted: last" );
79 		sal_Int32 nBookmark = 0;
80 		// first position on the last known row
81 		if ( m_aBookmarksPositions.empty() )
82 		{
83 			bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData);
84 			if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
85 				//m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
86                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
87 		}
88 		else
89 		{
90 			// I already have a bookmark so we can positioned on that and look if it is the last one
91 			nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
92 
93 			bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
94 			OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"A bookmark should not be deleted!");
95 		}
96 
97 
98 		// and than move forward until we are after the last row
99 		while(bDataFound)
100 		{
101 			bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, sal_False); // we don't need the data here
102 			if( bDataFound && ( m_bDeletedVisible || !m_pHelper->isRowDeleted()) )
103 			{	// we weren't on the last row we remember it and move on
104                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
105 				//m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
106 			}
107 			else if(!bDataFound && !m_aBookmarksPositions.empty() )
108 			{
109 				// i already know the last bookmark :-)
110 				// now we only have to repositioning us to the last row
111 				nBookmark = (*m_aBookmarksPositions.rbegin())/*->first*/;
112 				bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK, nBookmark, _bRetrieveData);
113 				break;
114 			}
115 		}
116 		return bDataFound;
117 	}
118 	else if (_eCursorPosition != IResultSetHelper::RELATIVE)
119 	{
120 		bDataFound = m_pHelper->move(_eCursorPosition, _nOffset, _bRetrieveData);
121 		bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
122 	}
123 	else
124 	{
125 		bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
126 		if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
127 		{
128             bDone = (--nDelOffset) == 0;
129             if ( !bDone )
130                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
131 			//m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
132 		}
133 		else
134 			bDone = sal_False;
135 	}
136 
137     while (bDataFound && !bDone)            // solange iterieren bis man auf einem gueltigen Satz ist
138 	{
139 		bDataFound = m_pHelper->move(eDelPosition, 1, _bRetrieveData);
140 		if (_eCursorPosition != IResultSetHelper::RELATIVE)
141 			bDone = bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted());
142 		else if (bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
143 		{
144             bDone = (--nDelOffset) == 0;
145             if ( !bDone )
146                 m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
147 			//m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
148 		}
149 		else
150 			bDone = sal_False;
151 	}
152 
153 	if(bDataFound && bDone)
154 	{
155         const sal_Int32 nDriverPos = m_pHelper->getDriverPos();
156         if ( m_bDeletedVisible )
157         {
158             if ( nDriverPos > (sal_Int32)m_aBookmarksPositions.size() )
159                 m_aBookmarksPositions.push_back(nDriverPos);
160         }
161         else if ( ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),nDriverPos) == m_aBookmarksPositions.end() )
162             m_aBookmarksPositions.push_back(nDriverPos);
163 		/*sal_Int32 nDriverPos = m_pHelper->getDriverPos();
164 		if(m_aBookmarks.find(nDriverPos) == m_aBookmarks.end())
165 			m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(nDriverPos,m_aBookmarksPositions.size()+1)).first);*/
166 	}
167 
168 	return bDataFound;
169 }
170 // -------------------------------------------------------------------------
171 sal_Bool OSkipDeletedSet::moveAbsolute(sal_Int32 _nPos,sal_Bool _bRetrieveData)
172 {
173     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::moveAbsolute" );
174 	sal_Bool bDataFound = sal_False;
175 	sal_Int32 nNewPos = _nPos;
176 	if(nNewPos > 0)
177 	{
178 		if((sal_Int32)m_aBookmarksPositions.size() < nNewPos)
179 		{
180 			// bookmark isn't known yet
181 			// start at the last known position
182 			sal_Int32 nCurPos = 0,nLastBookmark = 1;
183 			if ( m_aBookmarksPositions.empty() )
184             {
185 				bDataFound = m_pHelper->move(IResultSetHelper::FIRST, 0, _bRetrieveData );
186 				if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
187 				{
188 					++nCurPos;
189                     m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
190 					//m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
191 					--nNewPos;
192 				}
193 			} // if ( m_aBookmarksPositions.empty() )
194             else
195 			{
196 				nLastBookmark	= (*m_aBookmarksPositions.rbegin())/*->first*/;
197 				nCurPos			= /*(**/m_aBookmarksPositions.size()/*->second*/;
198 				nNewPos		    = nNewPos - nCurPos;
199 				bDataFound		= m_pHelper->move(IResultSetHelper::BOOKMARK, nLastBookmark, _bRetrieveData);
200 			}
201 
202 			// now move to that row we need and don't count deleted rows
203 			while (bDataFound && nNewPos)
204 			{
205 				bDataFound = m_pHelper->move(IResultSetHelper::NEXT, 1, _bRetrieveData);
206 				if(bDataFound && (m_bDeletedVisible || !m_pHelper->isRowDeleted()))
207 				{
208 					++nCurPos;
209                     m_aBookmarksPositions.push_back(m_pHelper->getDriverPos());
210 					//m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(m_pHelper->getDriverPos(),m_aBookmarksPositions.size()+1)).first);
211 					--nNewPos;
212 				}
213 			}
214 		}
215 		else
216 		{
217 			const sal_Int32 nBookmark = m_aBookmarksPositions[nNewPos-1]/*->first*/;
218 			bDataFound = m_pHelper->move(IResultSetHelper::BOOKMARK,nBookmark, _bRetrieveData);
219 			OSL_ENSURE((m_bDeletedVisible || !m_pHelper->isRowDeleted()),"moveAbsolute: row can't be deleted!");
220 		}
221 	}
222 	else
223 	{
224 		++nNewPos;
225 		bDataFound = skipDeleted(IResultSetHelper::LAST,0,nNewPos == 0);
226 
227 		for(sal_Int32 i=nNewPos+1;bDataFound && i <= 0;++i)
228 			bDataFound = skipDeleted(IResultSetHelper::PRIOR,1,i == 0);
229 
230 	}
231 	return bDataFound;
232 }
233 // -----------------------------------------------------------------------------
234 void OSkipDeletedSet::clear()
235 {
236     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::clear" );
237 	::std::vector<sal_Int32>().swap(m_aBookmarksPositions);
238 	//TInt2IntMap().swap(m_aBookmarks);
239 }
240 // -----------------------------------------------------------------------------
241 sal_Int32 OSkipDeletedSet::getMappedPosition(sal_Int32 _nPos) const
242 {
243     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::getMappedPosition" );
244     ::std::vector<sal_Int32>::const_iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos);
245     if ( aFind !=  m_aBookmarksPositions.end() )
246         return (aFind - m_aBookmarksPositions.begin()) + 1;
247 	/*TInt2IntMap::const_iterator aFind = m_aBookmarks.find(_nPos);
248 	OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::getMappedPosition() invalid bookmark!");
249 	return aFind->second;*/
250     OSL_ENSURE(0,"Why!");
251     return -1;
252 }
253 // -----------------------------------------------------------------------------
254 void OSkipDeletedSet::insertNewPosition(sal_Int32 _nPos)
255 {
256     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::insertNewPosition" );
257 	//OSL_ENSURE(m_aBookmarks.find(_nPos) == m_aBookmarks.end(),"OSkipDeletedSet::insertNewPosition: Invalid position");
258 	//m_aBookmarksPositions.push_back(m_aBookmarks.insert(TInt2IntMap::value_type(_nPos,m_aBookmarksPositions.size()+1)).first);
259     //OSL_ENSURE(::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nPos) == m_aBookmarksPositions.end(),"Invalid driver pos");
260     m_aBookmarksPositions.push_back(_nPos);
261 }
262 // -----------------------------------------------------------------------------
263 void OSkipDeletedSet::deletePosition(sal_Int32 _nBookmark)
264 {
265     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "commontools", "Ocke.Janssen@sun.com", "OSkipDeletedSet::deletePosition" );
266     ::std::vector<sal_Int32>::iterator aFind = ::std::find(m_aBookmarksPositions.begin(),m_aBookmarksPositions.end(),_nBookmark);
267     if ( aFind !=  m_aBookmarksPositions.end() )
268     {
269 	//TInt2IntMap::iterator aFind = m_aBookmarks.find(_nPos);
270 	//OSL_ENSURE(aFind != m_aBookmarks.end(),"OSkipDeletedSet::deletePosition() bookmark not found!");
271 	//TInt2IntMap::iterator aIter = aFind;
272         m_aBookmarksPositions.erase(aFind);
273 	    //for (; aFind != m_aBookmarksPositions.end() ; ++aIter)
274 		   // --(aFind->second);
275     } // if ( aFind !=  m_aBookmarksPositions.end() )
276 	//m_aBookmarksPositions.erase(m_aBookmarksPositions.begin() + aFind->second-1);
277 	//m_aBookmarks.erase(_nPos);
278 }
279 // -----------------------------------------------------------------------------
280