1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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 //==================================================================
43 //==================================================================
44 //------------------------------------------------------------------
45 OIndexIterator::~OIndexIterator()
47 // m_pIndex->UnLock();
51 //------------------------------------------------------------------
52 ULONG
OIndexIterator::First()
57 //------------------------------------------------------------------
58 ULONG
OIndexIterator::Next()
62 //------------------------------------------------------------------
63 ULONG
OIndexIterator::Find(BOOL bFirst
)
65 // ONDXIndex* m_pIndex = GetNDXIndex();
67 ULONG nRes
= STRING_NOTFOUND
;
68 // if (!m_pIndex->IsOpen())
73 m_aRoot
= m_pIndex
->getRoot();
79 // Vorbereitung , auf kleinstes Element positionieren
82 ONDXPage
* pPage
= m_aRoot
;
83 while (pPage
&& !pPage
->IsLeaf())
84 pPage
= pPage
->GetChild(m_pIndex
);
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
);
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
);
118 // im blatt wird die eigentliche Operation ausgefuehrt, sonst die temp. (>)
119 while (i
< pPage
->Count() && !m_pOperator
->operate(&((*pPage
)[i
]).GetKey(),&rKey
))
123 while (i
< pPage
->Count() && !aTempOp
.operate(&((*pPage
)[i
]).GetKey(),&rKey
))
127 ONDXKey
* pFoundKey
= NULL
;
128 if (!pPage
->IsLeaf())
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())
141 pFoundKey
= &(*pPage
)[i
].GetKey();
142 if (!m_pOperator
->operate(pFoundKey
,&rKey
))
146 m_nCurNode
= pFoundKey
? i
: i
- 1;
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();
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
);
171 m_nCurNode
= NODE_NOTFOUND
;
175 switch (ePredicateType
)
177 case SQLFilterOperator::NOT_EQUAL
:
178 while ( ( ( pKey
= GetNextKey() ) != NULL
) && !m_pOperator
->operate(pKey
,m_pOperand
)) ;
180 case SQLFilterOperator::LESS
:
181 while ( ( ( pKey
= GetNextKey() ) != NULL
) && pKey
->getValue().isNull()) ;
183 case SQLFilterOperator::LESS_EQUAL
:
184 while ( ( pKey
= GetNextKey() ) != NULL
) ;
186 case SQLFilterOperator::GREATER_EQUAL
:
187 case SQLFilterOperator::EQUAL
:
188 pKey
= GetFirstKey(m_aRoot
,*m_pOperand
);
190 case SQLFilterOperator::GREATER
:
191 pKey
= GetFirstKey(m_aRoot
,*m_pOperand
);
193 while ( ( ( pKey
= GetNextKey() ) != NULL
) && !m_pOperator
->operate(pKey
,m_pOperand
)) ;
198 switch (ePredicateType
)
200 case SQLFilterOperator::NOT_EQUAL
:
201 while ( ( ( pKey
= GetNextKey() ) != NULL
) && !m_pOperator
->operate(pKey
,m_pOperand
))
204 case SQLFilterOperator::LESS
:
205 case SQLFilterOperator::LESS_EQUAL
:
206 case SQLFilterOperator::EQUAL
:
207 if ( ( ( pKey
= GetNextKey() ) == NULL
) || !m_pOperator
->operate(pKey
,m_pOperand
))
213 case SQLFilterOperator::GREATER_EQUAL
:
214 case SQLFilterOperator::GREATER
:
219 return pKey
? pKey
->GetRecord() : STRING_NOTFOUND
;
222 //------------------------------------------------------------------
223 ULONG
OIndexIterator::GetLike(BOOL bFirst
)
225 // ONDXIndex* m_pIndex = GetNDXIndex();
228 ONDXPage
* pPage
= m_aRoot
;
230 while (pPage
&& !pPage
->IsLeaf())
231 pPage
= pPage
->GetChild(m_pIndex
);
234 m_nCurNode
= NODE_NOTFOUND
;
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();
249 ONDXPage
* pPage
= m_aRoot
;
250 while (pPage
&& !pPage
->IsLeaf())
251 pPage
= pPage
->GetChild(m_pIndex
);
254 m_nCurNode
= NODE_NOTFOUND
;
258 if ( ( ( pKey
= GetNextKey() ) == NULL
) || !pKey
->getValue().isNull())
263 return pKey
? pKey
->GetRecord() : STRING_NOTFOUND
;
266 //------------------------------------------------------------------
267 ULONG
OIndexIterator::GetNotNull(BOOL bFirst
)
270 // ONDXIndex* m_pIndex = GetNDXIndex();
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
;
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
296 ONDXPage
* pParentPage
= pPage
->GetParent();
299 USHORT nPos
= pParentPage
->Search(pPage
);
300 if (nPos
!= pParentPage
->Count() - 1)
302 pPage
= (*pParentPage
)[nPos
+1].GetChild(m_pIndex
,pParentPage
);
309 // jetzt wieder zum Blatt
310 while (pPage
&& !pPage
->IsLeaf())
311 pPage
= pPage
->GetChild(m_pIndex
);
316 return m_aCurLeaf
.Is() ? &(*m_aCurLeaf
)[m_nCurNode
].GetKey() : NULL
;