merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / dbase / DIndexIter.cxx
blob364d4daafc3eeae43bdf07434b539ebff5e90da9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DIndexIter.cxx,v $
10 * $Revision: 1.9.66.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "dbase/DIndexIter.hxx"
34 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
36 using namespace ::com::sun::star::sdb;
37 using namespace connectivity;
38 using namespace connectivity::dbase;
39 using namespace connectivity::file;
40 using namespace ::com::sun::star::sdb;
41 //==================================================================
42 // OIndexIterator
43 //==================================================================
44 //------------------------------------------------------------------
45 OIndexIterator::~OIndexIterator()
47 // m_pIndex->UnLock();
48 m_pIndex->release();
51 //------------------------------------------------------------------
52 ULONG OIndexIterator::First()
54 return Find(TRUE);
57 //------------------------------------------------------------------
58 ULONG OIndexIterator::Next()
60 return Find(FALSE);
62 //------------------------------------------------------------------
63 ULONG OIndexIterator::Find(BOOL bFirst)
65 // ONDXIndex* m_pIndex = GetNDXIndex();
67 ULONG nRes = STRING_NOTFOUND;
68 // if (!m_pIndex->IsOpen())
69 // return nRes;
71 if (bFirst)
73 m_aRoot = m_pIndex->getRoot();
74 m_aCurLeaf = NULL;
77 if (!m_pOperator)
79 // Vorbereitung , auf kleinstes Element positionieren
80 if (bFirst)
82 ONDXPage* pPage = m_aRoot;
83 while (pPage && !pPage->IsLeaf())
84 pPage = pPage->GetChild(m_pIndex);
86 m_aCurLeaf = pPage;
87 m_nCurNode = NODE_NOTFOUND;
89 ONDXKey* pKey = GetNextKey();
90 nRes = pKey ? pKey->GetRecord() : STRING_NOTFOUND;
92 else if (m_pOperator->IsA(TYPE(OOp_ISNOTNULL)))
93 nRes = GetNotNull(bFirst);
94 else if (m_pOperator->IsA(TYPE(OOp_ISNULL)))
95 nRes = GetNull(bFirst);
96 else if (m_pOperator->IsA(TYPE(OOp_LIKE)))
97 nRes = GetLike(bFirst);
98 else if (m_pOperator->IsA(TYPE(OOp_COMPARE)))
99 nRes = GetCompare(bFirst);
101 return nRes;
104 //------------------------------------------------------------------
105 ONDXKey* OIndexIterator::GetFirstKey(ONDXPage* pPage, const OOperand& rKey)
107 // sucht den vorgegeben key
108 // Besonderheit: gelangt der Algorithmus ans Ende
109 // wird immer die aktuelle Seite und die Knotenposition vermerkt
110 // auf die die Bedingung <= zutrifft
111 // dieses findet beim Insert besondere Beachtung
112 // ONDXIndex* m_pIndex = GetNDXIndex();
113 OOp_COMPARE aTempOp(SQLFilterOperator::GREATER);
114 USHORT i = 0;
116 if (pPage->IsLeaf())
118 // im blatt wird die eigentliche Operation ausgefuehrt, sonst die temp. (>)
119 while (i < pPage->Count() && !m_pOperator->operate(&((*pPage)[i]).GetKey(),&rKey))
120 i++;
122 else
123 while (i < pPage->Count() && !aTempOp.operate(&((*pPage)[i]).GetKey(),&rKey))
124 i++;
127 ONDXKey* pFoundKey = NULL;
128 if (!pPage->IsLeaf())
130 // weiter absteigen
131 ONDXPagePtr aPage = (i==0) ? pPage->GetChild(m_pIndex)
132 : ((*pPage)[i-1]).GetChild(m_pIndex, pPage);
133 pFoundKey = aPage.Is() ? GetFirstKey(aPage, rKey) : NULL;
135 else if (i == pPage->Count())
137 pFoundKey = NULL;
139 else
141 pFoundKey = &(*pPage)[i].GetKey();
142 if (!m_pOperator->operate(pFoundKey,&rKey))
143 pFoundKey = NULL;
145 m_aCurLeaf = pPage;
146 m_nCurNode = pFoundKey ? i : i - 1;
148 return pFoundKey;
151 //------------------------------------------------------------------
152 ULONG OIndexIterator::GetCompare(BOOL bFirst)
154 ONDXKey* pKey = NULL;
155 // ONDXIndex* m_pIndex = GetNDXIndex();
156 sal_Int32 ePredicateType = PTR_CAST(file::OOp_COMPARE,m_pOperator)->getPredicateType();
158 if (bFirst)
160 // Vorbereitung , auf kleinstes Element positionieren
161 ONDXPage* pPage = m_aRoot;
162 switch (ePredicateType)
164 case SQLFilterOperator::NOT_EQUAL:
165 case SQLFilterOperator::LESS:
166 case SQLFilterOperator::LESS_EQUAL:
167 while (pPage && !pPage->IsLeaf())
168 pPage = pPage->GetChild(m_pIndex);
170 m_aCurLeaf = pPage;
171 m_nCurNode = NODE_NOTFOUND;
175 switch (ePredicateType)
177 case SQLFilterOperator::NOT_EQUAL:
178 while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand)) ;
179 break;
180 case SQLFilterOperator::LESS:
181 while ( ( ( pKey = GetNextKey() ) != NULL ) && pKey->getValue().isNull()) ;
182 break;
183 case SQLFilterOperator::LESS_EQUAL:
184 while ( ( pKey = GetNextKey() ) != NULL ) ;
185 break;
186 case SQLFilterOperator::GREATER_EQUAL:
187 case SQLFilterOperator::EQUAL:
188 pKey = GetFirstKey(m_aRoot,*m_pOperand);
189 break;
190 case SQLFilterOperator::GREATER:
191 pKey = GetFirstKey(m_aRoot,*m_pOperand);
192 if ( !pKey )
193 while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand)) ;
196 else
198 switch (ePredicateType)
200 case SQLFilterOperator::NOT_EQUAL:
201 while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand))
203 break;
204 case SQLFilterOperator::LESS:
205 case SQLFilterOperator::LESS_EQUAL:
206 case SQLFilterOperator::EQUAL:
207 if ( ( ( pKey = GetNextKey() ) == NULL ) || !m_pOperator->operate(pKey,m_pOperand))
209 pKey = NULL;
210 m_aCurLeaf = NULL;
212 break;
213 case SQLFilterOperator::GREATER_EQUAL:
214 case SQLFilterOperator::GREATER:
215 pKey = GetNextKey();
219 return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
222 //------------------------------------------------------------------
223 ULONG OIndexIterator::GetLike(BOOL bFirst)
225 // ONDXIndex* m_pIndex = GetNDXIndex();
226 if (bFirst)
228 ONDXPage* pPage = m_aRoot;
230 while (pPage && !pPage->IsLeaf())
231 pPage = pPage->GetChild(m_pIndex);
233 m_aCurLeaf = pPage;
234 m_nCurNode = NODE_NOTFOUND;
237 ONDXKey* pKey;
238 while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand))
240 return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
243 //------------------------------------------------------------------
244 ULONG OIndexIterator::GetNull(BOOL bFirst)
246 // ONDXIndex* m_pIndex = GetNDXIndex();
247 if (bFirst)
249 ONDXPage* pPage = m_aRoot;
250 while (pPage && !pPage->IsLeaf())
251 pPage = pPage->GetChild(m_pIndex);
253 m_aCurLeaf = pPage;
254 m_nCurNode = NODE_NOTFOUND;
257 ONDXKey* pKey;
258 if ( ( ( pKey = GetNextKey() ) == NULL ) || !pKey->getValue().isNull())
260 pKey = NULL;
261 m_aCurLeaf = NULL;
263 return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
266 //------------------------------------------------------------------
267 ULONG OIndexIterator::GetNotNull(BOOL bFirst)
269 ONDXKey* pKey;
270 // ONDXIndex* m_pIndex = GetNDXIndex();
271 if (bFirst)
273 // erst alle NULL werte abklappern
274 for (ULONG nRec = GetNull(bFirst);
275 nRec != STRING_NOTFOUND;
276 nRec = GetNull(FALSE))
278 pKey = m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
280 else
281 pKey = GetNextKey();
283 return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
286 //------------------------------------------------------------------
287 ONDXKey* OIndexIterator::GetNextKey()
289 // ONDXIndex* m_pIndex = GetNDXIndex();
290 if (m_aCurLeaf.Is() && ((++m_nCurNode) >= m_aCurLeaf->Count()))
292 ONDXPage* pPage = m_aCurLeaf;
293 // naechste Seite suchen
294 while (pPage)
296 ONDXPage* pParentPage = pPage->GetParent();
297 if (pParentPage)
299 USHORT nPos = pParentPage->Search(pPage);
300 if (nPos != pParentPage->Count() - 1)
301 { // Seite gefunden
302 pPage = (*pParentPage)[nPos+1].GetChild(m_pIndex,pParentPage);
303 break;
306 pPage = pParentPage;
309 // jetzt wieder zum Blatt
310 while (pPage && !pPage->IsLeaf())
311 pPage = pPage->GetChild(m_pIndex);
313 m_aCurLeaf = pPage;
314 m_nCurNode = 0;
316 return m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;