1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9b5730f6SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9b5730f6SAndrew Rist  * distributed with this work for additional information
6*9b5730f6SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9b5730f6SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist  * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9b5730f6SAndrew Rist  *
11*9b5730f6SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9b5730f6SAndrew Rist  *
13*9b5730f6SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist  * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9b5730f6SAndrew Rist  * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist  * under the License.
19*9b5730f6SAndrew Rist  *
20*9b5730f6SAndrew Rist  *************************************************************/
21*9b5730f6SAndrew Rist 
22*9b5730f6SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir #include "dbase/DIndexIter.hxx"
27cdf0e10cSrcweir #include <com/sun/star/sdb/SQLFilterOperator.hpp>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir using namespace ::com::sun::star::sdb;
30cdf0e10cSrcweir using namespace connectivity;
31cdf0e10cSrcweir using namespace connectivity::dbase;
32cdf0e10cSrcweir using namespace connectivity::file;
33cdf0e10cSrcweir using namespace ::com::sun::star::sdb;
34cdf0e10cSrcweir //==================================================================
35cdf0e10cSrcweir // OIndexIterator
36cdf0e10cSrcweir //==================================================================
37cdf0e10cSrcweir //------------------------------------------------------------------
~OIndexIterator()38cdf0e10cSrcweir OIndexIterator::~OIndexIterator()
39cdf0e10cSrcweir {
40cdf0e10cSrcweir 	//	m_pIndex->UnLock();
41cdf0e10cSrcweir 	m_pIndex->release();
42cdf0e10cSrcweir }
43cdf0e10cSrcweir 
44cdf0e10cSrcweir //------------------------------------------------------------------
First()45cdf0e10cSrcweir sal_uIntPtr OIndexIterator::First()
46cdf0e10cSrcweir {
47cdf0e10cSrcweir 	return Find(sal_True);
48cdf0e10cSrcweir }
49cdf0e10cSrcweir 
50cdf0e10cSrcweir //------------------------------------------------------------------
Next()51cdf0e10cSrcweir sal_uIntPtr OIndexIterator::Next()
52cdf0e10cSrcweir {
53cdf0e10cSrcweir 	return Find(sal_False);
54cdf0e10cSrcweir }
55cdf0e10cSrcweir //------------------------------------------------------------------
Find(sal_Bool bFirst)56cdf0e10cSrcweir sal_uIntPtr OIndexIterator::Find(sal_Bool bFirst)
57cdf0e10cSrcweir {
58cdf0e10cSrcweir 	//	ONDXIndex* m_pIndex = GetNDXIndex();
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 	sal_uIntPtr nRes = STRING_NOTFOUND;
61cdf0e10cSrcweir //	if (!m_pIndex->IsOpen())
62cdf0e10cSrcweir //		return nRes;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 	if (bFirst)
65cdf0e10cSrcweir 	{
66cdf0e10cSrcweir 		m_aRoot = m_pIndex->getRoot();
67cdf0e10cSrcweir 		m_aCurLeaf = NULL;
68cdf0e10cSrcweir 	}
69cdf0e10cSrcweir 
70cdf0e10cSrcweir 	if (!m_pOperator)
71cdf0e10cSrcweir 	{
72cdf0e10cSrcweir 		// Vorbereitung , auf kleinstes Element positionieren
73cdf0e10cSrcweir 		if (bFirst)
74cdf0e10cSrcweir 		{
75cdf0e10cSrcweir 			ONDXPage* pPage = m_aRoot;
76cdf0e10cSrcweir 			while (pPage && !pPage->IsLeaf())
77cdf0e10cSrcweir 				pPage = pPage->GetChild(m_pIndex);
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 			m_aCurLeaf = pPage;
80cdf0e10cSrcweir 			m_nCurNode = NODE_NOTFOUND;
81cdf0e10cSrcweir 		}
82cdf0e10cSrcweir 		ONDXKey* pKey = GetNextKey();
83cdf0e10cSrcweir 		nRes = pKey ? pKey->GetRecord() : STRING_NOTFOUND;
84cdf0e10cSrcweir 	}
85cdf0e10cSrcweir 	else if (m_pOperator->IsA(TYPE(OOp_ISNOTNULL)))
86cdf0e10cSrcweir 		nRes = GetNotNull(bFirst);
87cdf0e10cSrcweir 	else if (m_pOperator->IsA(TYPE(OOp_ISNULL)))
88cdf0e10cSrcweir 		nRes = GetNull(bFirst);
89cdf0e10cSrcweir 	else if (m_pOperator->IsA(TYPE(OOp_LIKE)))
90cdf0e10cSrcweir 		nRes = GetLike(bFirst);
91cdf0e10cSrcweir 	else if (m_pOperator->IsA(TYPE(OOp_COMPARE)))
92cdf0e10cSrcweir 		nRes = GetCompare(bFirst);
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 	return nRes;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir //------------------------------------------------------------------
GetFirstKey(ONDXPage * pPage,const OOperand & rKey)98cdf0e10cSrcweir ONDXKey* OIndexIterator::GetFirstKey(ONDXPage* pPage, const OOperand& rKey)
99cdf0e10cSrcweir {
100cdf0e10cSrcweir 	// sucht den vorgegeben key
101cdf0e10cSrcweir 	// Besonderheit: gelangt der Algorithmus ans Ende
102cdf0e10cSrcweir 	// wird immer die aktuelle Seite und die Knotenposition vermerkt
103cdf0e10cSrcweir 	// auf die die Bedingung <= zutrifft
104cdf0e10cSrcweir 	// dieses findet beim Insert besondere Beachtung
105cdf0e10cSrcweir 	//	ONDXIndex* m_pIndex = GetNDXIndex();
106cdf0e10cSrcweir 	OOp_COMPARE aTempOp(SQLFilterOperator::GREATER);
107cdf0e10cSrcweir 	sal_uInt16 i = 0;
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 	if (pPage->IsLeaf())
110cdf0e10cSrcweir 	{
111cdf0e10cSrcweir 		// im blatt wird die eigentliche Operation ausgefuehrt, sonst die temp. (>)
112cdf0e10cSrcweir 		while (i < pPage->Count() && !m_pOperator->operate(&((*pPage)[i]).GetKey(),&rKey))
113cdf0e10cSrcweir 			   i++;
114cdf0e10cSrcweir 	}
115cdf0e10cSrcweir 	else
116cdf0e10cSrcweir 		while (i < pPage->Count() && !aTempOp.operate(&((*pPage)[i]).GetKey(),&rKey))
117cdf0e10cSrcweir 			   i++;
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 	ONDXKey* pFoundKey = NULL;
121cdf0e10cSrcweir 	if (!pPage->IsLeaf())
122cdf0e10cSrcweir 	{
123cdf0e10cSrcweir 		// weiter absteigen
124cdf0e10cSrcweir 		ONDXPagePtr aPage = (i==0) ? pPage->GetChild(m_pIndex)
125cdf0e10cSrcweir 									 : ((*pPage)[i-1]).GetChild(m_pIndex, pPage);
126cdf0e10cSrcweir 		pFoundKey = aPage.Is() ? GetFirstKey(aPage, rKey) : NULL;
127cdf0e10cSrcweir 	}
128cdf0e10cSrcweir 	else if (i == pPage->Count())
129cdf0e10cSrcweir 	{
130cdf0e10cSrcweir 		pFoundKey = NULL;
131cdf0e10cSrcweir 	}
132cdf0e10cSrcweir 	else
133cdf0e10cSrcweir 	{
134cdf0e10cSrcweir 		pFoundKey = &(*pPage)[i].GetKey();
135cdf0e10cSrcweir 		if (!m_pOperator->operate(pFoundKey,&rKey))
136cdf0e10cSrcweir 			pFoundKey = NULL;
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 		m_aCurLeaf = pPage;
139cdf0e10cSrcweir 		m_nCurNode = pFoundKey ? i : i - 1;
140cdf0e10cSrcweir 	}
141cdf0e10cSrcweir 	return pFoundKey;
142cdf0e10cSrcweir }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir //------------------------------------------------------------------
GetCompare(sal_Bool bFirst)145cdf0e10cSrcweir sal_uIntPtr OIndexIterator::GetCompare(sal_Bool bFirst)
146cdf0e10cSrcweir {
147cdf0e10cSrcweir 	ONDXKey* pKey = NULL;
148cdf0e10cSrcweir 	//	ONDXIndex* m_pIndex = GetNDXIndex();
149cdf0e10cSrcweir 	sal_Int32 ePredicateType = PTR_CAST(file::OOp_COMPARE,m_pOperator)->getPredicateType();
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 	if (bFirst)
152cdf0e10cSrcweir 	{
153cdf0e10cSrcweir 		// Vorbereitung , auf kleinstes Element positionieren
154cdf0e10cSrcweir 		ONDXPage* pPage = m_aRoot;
155cdf0e10cSrcweir 		switch (ePredicateType)
156cdf0e10cSrcweir 		{
157cdf0e10cSrcweir 			case SQLFilterOperator::NOT_EQUAL:
158cdf0e10cSrcweir 			case SQLFilterOperator::LESS:
159cdf0e10cSrcweir 			case SQLFilterOperator::LESS_EQUAL:
160cdf0e10cSrcweir 				while (pPage && !pPage->IsLeaf())
161cdf0e10cSrcweir 					pPage = pPage->GetChild(m_pIndex);
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 				m_aCurLeaf = pPage;
164cdf0e10cSrcweir 				m_nCurNode = NODE_NOTFOUND;
165cdf0e10cSrcweir 		}
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 		switch (ePredicateType)
169cdf0e10cSrcweir 		{
170cdf0e10cSrcweir 			case SQLFilterOperator::NOT_EQUAL:
171cdf0e10cSrcweir 				while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand)) ;
172cdf0e10cSrcweir 				break;
173cdf0e10cSrcweir 			case SQLFilterOperator::LESS:
174cdf0e10cSrcweir                 while ( ( ( pKey = GetNextKey() ) != NULL ) && pKey->getValue().isNull()) ;
175cdf0e10cSrcweir 				break;
176cdf0e10cSrcweir 			case SQLFilterOperator::LESS_EQUAL:
177cdf0e10cSrcweir                 while ( ( pKey = GetNextKey() ) != NULL ) ;
178cdf0e10cSrcweir 				break;
179cdf0e10cSrcweir 			case SQLFilterOperator::GREATER_EQUAL:
180cdf0e10cSrcweir 			case SQLFilterOperator::EQUAL:
181cdf0e10cSrcweir 				pKey = GetFirstKey(m_aRoot,*m_pOperand);
182cdf0e10cSrcweir 				break;
183cdf0e10cSrcweir 			case SQLFilterOperator::GREATER:
184cdf0e10cSrcweir                 pKey = GetFirstKey(m_aRoot,*m_pOperand);
185cdf0e10cSrcweir                 if ( !pKey )
186cdf0e10cSrcweir                     while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand)) ;
187cdf0e10cSrcweir 		}
188cdf0e10cSrcweir 	}
189cdf0e10cSrcweir 	else
190cdf0e10cSrcweir 	{
191cdf0e10cSrcweir 		switch (ePredicateType)
192cdf0e10cSrcweir 		{
193cdf0e10cSrcweir 			case SQLFilterOperator::NOT_EQUAL:
194cdf0e10cSrcweir 				while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand))
195cdf0e10cSrcweir 					;
196cdf0e10cSrcweir 				break;
197cdf0e10cSrcweir 			case SQLFilterOperator::LESS:
198cdf0e10cSrcweir 			case SQLFilterOperator::LESS_EQUAL:
199cdf0e10cSrcweir 			case SQLFilterOperator::EQUAL:
200cdf0e10cSrcweir 				if ( ( ( pKey = GetNextKey() ) == NULL )  || !m_pOperator->operate(pKey,m_pOperand))
201cdf0e10cSrcweir 				{
202cdf0e10cSrcweir 					pKey = NULL;
203cdf0e10cSrcweir 					m_aCurLeaf = NULL;
204cdf0e10cSrcweir 				}
205cdf0e10cSrcweir 				break;
206cdf0e10cSrcweir 			case SQLFilterOperator::GREATER_EQUAL:
207cdf0e10cSrcweir 			case SQLFilterOperator::GREATER:
208cdf0e10cSrcweir 				pKey = GetNextKey();
209cdf0e10cSrcweir 		}
210cdf0e10cSrcweir 	}
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 	return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
213cdf0e10cSrcweir }
214cdf0e10cSrcweir 
215cdf0e10cSrcweir //------------------------------------------------------------------
GetLike(sal_Bool bFirst)216cdf0e10cSrcweir sal_uIntPtr OIndexIterator::GetLike(sal_Bool bFirst)
217cdf0e10cSrcweir {
218cdf0e10cSrcweir 	//	ONDXIndex* m_pIndex = GetNDXIndex();
219cdf0e10cSrcweir 	if (bFirst)
220cdf0e10cSrcweir 	{
221cdf0e10cSrcweir 		ONDXPage* pPage = m_aRoot;
222cdf0e10cSrcweir 
223cdf0e10cSrcweir 		while (pPage && !pPage->IsLeaf())
224cdf0e10cSrcweir 			pPage = pPage->GetChild(m_pIndex);
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 		m_aCurLeaf = pPage;
227cdf0e10cSrcweir 		m_nCurNode = NODE_NOTFOUND;
228cdf0e10cSrcweir 	}
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 	ONDXKey* pKey;
231cdf0e10cSrcweir 	while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand))
232cdf0e10cSrcweir 		;
233cdf0e10cSrcweir 	return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir //------------------------------------------------------------------
GetNull(sal_Bool bFirst)237cdf0e10cSrcweir sal_uIntPtr OIndexIterator::GetNull(sal_Bool bFirst)
238cdf0e10cSrcweir {
239cdf0e10cSrcweir 	//	ONDXIndex* m_pIndex = GetNDXIndex();
240cdf0e10cSrcweir 	if (bFirst)
241cdf0e10cSrcweir 	{
242cdf0e10cSrcweir 		ONDXPage* pPage = m_aRoot;
243cdf0e10cSrcweir 		while (pPage && !pPage->IsLeaf())
244cdf0e10cSrcweir 			pPage = pPage->GetChild(m_pIndex);
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 		m_aCurLeaf = pPage;
247cdf0e10cSrcweir 		m_nCurNode = NODE_NOTFOUND;
248cdf0e10cSrcweir 	}
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	ONDXKey* pKey;
251cdf0e10cSrcweir 	if ( ( ( pKey = GetNextKey() ) == NULL ) || !pKey->getValue().isNull())
252cdf0e10cSrcweir 	{
253cdf0e10cSrcweir 		pKey = NULL;
254cdf0e10cSrcweir 		m_aCurLeaf = NULL;
255cdf0e10cSrcweir 	}
256cdf0e10cSrcweir 	return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir //------------------------------------------------------------------
GetNotNull(sal_Bool bFirst)260cdf0e10cSrcweir sal_uIntPtr OIndexIterator::GetNotNull(sal_Bool bFirst)
261cdf0e10cSrcweir {
262cdf0e10cSrcweir 	ONDXKey* pKey;
263cdf0e10cSrcweir 	//	ONDXIndex* m_pIndex = GetNDXIndex();
264cdf0e10cSrcweir 	if (bFirst)
265cdf0e10cSrcweir 	{
266cdf0e10cSrcweir 		// erst alle NULL werte abklappern
267cdf0e10cSrcweir 		for (sal_uIntPtr nRec = GetNull(bFirst);
268cdf0e10cSrcweir 			 nRec != STRING_NOTFOUND;
269cdf0e10cSrcweir 			 nRec = GetNull(sal_False))
270cdf0e10cSrcweir 				 ;
271cdf0e10cSrcweir 		pKey = m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
272cdf0e10cSrcweir 	}
273cdf0e10cSrcweir 	else
274cdf0e10cSrcweir 		pKey = GetNextKey();
275cdf0e10cSrcweir 
276cdf0e10cSrcweir 	return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir //------------------------------------------------------------------
GetNextKey()280cdf0e10cSrcweir ONDXKey* OIndexIterator::GetNextKey()
281cdf0e10cSrcweir {
282cdf0e10cSrcweir 	//	ONDXIndex* m_pIndex = GetNDXIndex();
283cdf0e10cSrcweir 	if (m_aCurLeaf.Is() && ((++m_nCurNode) >= m_aCurLeaf->Count()))
284cdf0e10cSrcweir 	{
285cdf0e10cSrcweir 		ONDXPage* pPage = m_aCurLeaf;
286cdf0e10cSrcweir 		// naechste Seite suchen
287cdf0e10cSrcweir 		while (pPage)
288cdf0e10cSrcweir 		{
289cdf0e10cSrcweir 			ONDXPage* pParentPage = pPage->GetParent();
290cdf0e10cSrcweir 			if (pParentPage)
291cdf0e10cSrcweir 			{
292cdf0e10cSrcweir 				sal_uInt16 nPos = pParentPage->Search(pPage);
293cdf0e10cSrcweir 				if (nPos != pParentPage->Count() - 1)
294cdf0e10cSrcweir 				{	// Seite gefunden
295cdf0e10cSrcweir 					pPage = (*pParentPage)[nPos+1].GetChild(m_pIndex,pParentPage);
296cdf0e10cSrcweir 					break;
297cdf0e10cSrcweir 				}
298cdf0e10cSrcweir 			}
299cdf0e10cSrcweir 			pPage = pParentPage;
300cdf0e10cSrcweir 		}
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 		// jetzt wieder zum Blatt
303cdf0e10cSrcweir 		while (pPage && !pPage->IsLeaf())
304cdf0e10cSrcweir 			pPage = pPage->GetChild(m_pIndex);
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 		m_aCurLeaf = pPage;
307cdf0e10cSrcweir 		m_nCurNode = 0;
308cdf0e10cSrcweir 	}
309cdf0e10cSrcweir 	return m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
312