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