LibreOffice Module connectivity (master) 1
DIndexIter.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <dbase/DIndexIter.hxx>
21#include <com/sun/star/sdb/SQLFilterOperator.hpp>
22
23using namespace ::com::sun::star::sdb;
24using namespace connectivity;
25using namespace connectivity::dbase;
26using namespace connectivity::file;
27
28// OIndexIterator
29
30OIndexIterator::~OIndexIterator() {}
31
32sal_uInt32 OIndexIterator::First() { return Find(true); }
33
34sal_uInt32 OIndexIterator::Next() { return Find(false); }
35
36sal_uInt32 OIndexIterator::Find(bool bFirst)
37{
38 sal_uInt32 nRes = NODE_NOTFOUND;
39
40 if (bFirst)
41 {
42 m_aRoot = m_xIndex->getRoot();
44 }
45
46 if (!m_pOperator)
47 {
48 // Preparation, position on the smallest element
49 if (bFirst)
50 {
51 ONDXPage* pPage = m_aRoot;
52 while (pPage && !pPage->IsLeaf())
53 pPage = pPage->GetChild(m_xIndex.get());
54
55 m_aCurLeaf = pPage;
57 }
58 ONDXKey* pKey = GetNextKey();
59 nRes = pKey ? pKey->GetRecord() : NODE_NOTFOUND;
60 }
61 else if (dynamic_cast<const OOp_ISNOTNULL*>(m_pOperator) != nullptr)
62 nRes = GetNotNull(bFirst);
63 else if (dynamic_cast<const OOp_ISNULL*>(m_pOperator) != nullptr)
64 nRes = GetNull(bFirst);
65 else if (dynamic_cast<const OOp_LIKE*>(m_pOperator) != nullptr)
66 nRes = GetLike(bFirst);
67 else if (dynamic_cast<const OOp_COMPARE*>(m_pOperator) != nullptr)
68 nRes = GetCompare(bFirst);
69
70 return nRes;
71}
72
74{
75 // searches a given key
76 // Speciality: At the end of the algorithm
77 // the actual page and the position of the node which fulfil the
78 // '<='-condition are saved. this is considered for inserts.
79 // ONDXIndex* m_pIndex = GetNDXIndex();
80 OOp_COMPARE aTempOp(SQLFilterOperator::GREATER);
81 sal_uInt16 i = 0;
82
83 if (pPage->IsLeaf())
84 {
85 // in the leaf the actual operation is run, otherwise temp. (>)
86 while (i < pPage->Count() && !m_pOperator->operate(&((*pPage)[i]).GetKey(), &rKey))
87 i++;
88 }
89 else
90 while (i < pPage->Count() && !aTempOp.operate(&((*pPage)[i]).GetKey(), &rKey))
91 i++;
92
93 ONDXKey* pFoundKey = nullptr;
94 if (!pPage->IsLeaf())
95 {
96 // descend further
97 ONDXPagePtr aPage = (i == 0) ? pPage->GetChild(m_xIndex.get())
98 : ((*pPage)[i - 1]).GetChild(m_xIndex.get(), pPage);
99 pFoundKey = aPage.Is() ? GetFirstKey(aPage, rKey) : nullptr;
100 }
101 else if (i == pPage->Count())
102 {
103 pFoundKey = nullptr;
104 }
105 else
106 {
107 pFoundKey = &(*pPage)[i].GetKey();
108 if (!m_pOperator->operate(pFoundKey, &rKey))
109 pFoundKey = nullptr;
110
111 m_aCurLeaf = pPage;
112 m_nCurNode = pFoundKey ? i : i - 1;
113 }
114 return pFoundKey;
115}
116
117sal_uInt32 OIndexIterator::GetCompare(bool bFirst)
118{
119 ONDXKey* pKey = nullptr;
120 sal_Int32 ePredicateType = dynamic_cast<file::OOp_COMPARE&>(*m_pOperator).getPredicateType();
121
122 if (bFirst)
123 {
124 // Preparation, position on the smallest element
125 ONDXPage* pPage = m_aRoot;
126 switch (ePredicateType)
127 {
128 case SQLFilterOperator::NOT_EQUAL:
129 case SQLFilterOperator::LESS:
130 case SQLFilterOperator::LESS_EQUAL:
131 while (pPage && !pPage->IsLeaf())
132 pPage = pPage->GetChild(m_xIndex.get());
133
134 m_aCurLeaf = pPage;
136 }
137
138 switch (ePredicateType)
139 {
140 case SQLFilterOperator::NOT_EQUAL:
141 while ((pKey = GetNextKey()) != nullptr)
142 if (m_pOperator->operate(pKey, m_pOperand))
143 break;
144 break;
145 case SQLFilterOperator::LESS:
146 while ((pKey = GetNextKey()) != nullptr)
147 if (!pKey->getValue().isNull())
148 break;
149 break;
150 case SQLFilterOperator::LESS_EQUAL:
151 while ((pKey = GetNextKey()) != nullptr)
152 ;
153 break;
154 case SQLFilterOperator::GREATER_EQUAL:
155 case SQLFilterOperator::EQUAL:
157 break;
158 case SQLFilterOperator::GREATER:
160 if (!pKey)
161 while ((pKey = GetNextKey()) != nullptr)
162 if (m_pOperator->operate(pKey, m_pOperand))
163 break;
164 }
165 }
166 else
167 {
168 switch (ePredicateType)
169 {
170 case SQLFilterOperator::NOT_EQUAL:
171 while ((pKey = GetNextKey()) != nullptr)
172 if (m_pOperator->operate(pKey, m_pOperand))
173 break;
174 break;
175 case SQLFilterOperator::LESS:
176 case SQLFilterOperator::LESS_EQUAL:
177 case SQLFilterOperator::EQUAL:
178 pKey = GetNextKey();
179 if (pKey == nullptr || !m_pOperator->operate(pKey, m_pOperand))
180 {
181 pKey = nullptr;
183 }
184 break;
185 case SQLFilterOperator::GREATER_EQUAL:
186 case SQLFilterOperator::GREATER:
187 pKey = GetNextKey();
188 }
189 }
190
191 return pKey ? pKey->GetRecord() : NODE_NOTFOUND;
192}
193
194sal_uInt32 OIndexIterator::GetLike(bool bFirst)
195{
196 if (bFirst)
197 {
198 ONDXPage* pPage = m_aRoot;
199
200 while (pPage && !pPage->IsLeaf())
201 pPage = pPage->GetChild(m_xIndex.get());
202
203 m_aCurLeaf = pPage;
205 }
206
207 ONDXKey* pKey;
208 while ((pKey = GetNextKey()) != nullptr)
209 if (m_pOperator->operate(pKey, m_pOperand))
210 break;
211 return pKey ? pKey->GetRecord() : NODE_NOTFOUND;
212}
213
214sal_uInt32 OIndexIterator::GetNull(bool bFirst)
215{
216 if (bFirst)
217 {
218 ONDXPage* pPage = m_aRoot;
219 while (pPage && !pPage->IsLeaf())
220 pPage = pPage->GetChild(m_xIndex.get());
221
222 m_aCurLeaf = pPage;
224 }
225
226 ONDXKey* pKey = GetNextKey();
227 if (pKey == nullptr || !pKey->getValue().isNull())
228 {
229 pKey = nullptr;
231 }
232 return pKey ? pKey->GetRecord() : NODE_NOTFOUND;
233}
234
235sal_uInt32 OIndexIterator::GetNotNull(bool bFirst)
236{
237 ONDXKey* pKey;
238 if (bFirst)
239 {
240 // go through all NULL values first
241 for (sal_uInt32 nRec = GetNull(bFirst); nRec != NODE_NOTFOUND; nRec = GetNull(false))
242 ;
243 pKey = m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : nullptr;
244 }
245 else
246 pKey = GetNextKey();
247
248 return pKey ? pKey->GetRecord() : NODE_NOTFOUND;
249}
250
252{
253 if (m_aCurLeaf.Is() && ((++m_nCurNode) >= m_aCurLeaf->Count()))
254 {
255 ONDXPage* pPage = m_aCurLeaf;
256 // search next page
257 while (pPage)
258 {
259 ONDXPage* pParentPage = pPage->GetParent();
260 if (pParentPage)
261 {
262 sal_uInt16 nPos = pParentPage->Search(pPage);
263 if (nPos != pParentPage->Count() - 1)
264 { // page found
265 pPage = (*pParentPage)[nPos + 1].GetChild(m_xIndex.get(), pParentPage);
266 break;
267 }
268 }
269 pPage = pParentPage;
270 }
271
272 // now go on with leaf
273 while (pPage && !pPage->IsLeaf())
274 pPage = pPage->GetChild(m_xIndex.get());
275
276 m_aCurLeaf = pPage;
277 m_nCurNode = 0;
278 }
279 return m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : nullptr;
280}
281
282/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 GetCompare(bool bFirst)
Definition: DIndexIter.cxx:117
file::OBoolOperator * m_pOperator
Definition: DIndexIter.hxx:33
sal_uInt32 GetNull(bool bFirst)
Definition: DIndexIter.cxx:214
sal_uInt32 GetNotNull(bool bFirst)
Definition: DIndexIter.cxx:235
ONDXKey * GetFirstKey(ONDXPage *pPage, const file::OOperand &rKey)
Definition: DIndexIter.cxx:73
sal_uInt32 GetLike(bool bFirst)
Definition: DIndexIter.cxx:194
sal_uInt32 Find(bool bFirst)
Definition: DIndexIter.cxx:36
const file::OOperand * m_pOperand
Definition: DIndexIter.hxx:34
rtl::Reference< ODbaseIndex > m_xIndex
Definition: DIndexIter.hxx:35
virtual const ORowSetValue & getValue() const override
Definition: dindexnode.cxx:787
sal_uInt32 GetRecord() const
Definition: dindexnode.hxx:58
ONDXPagePtr & GetChild(ODbaseIndex const *pIndex=nullptr)
Definition: dindexnode.cxx:129
sal_uInt16 Search(const ONDXKey &rSearch)
Definition: dindexnode.cxx:973
sal_uInt16 Count() const
Definition: dindexnode.hxx:132
const ONDXPagePtr & GetParent() const
Definition: dindexnode.hxx:210
virtual bool operate(const OOperand *, const OOperand *) const
Definition: fcode.cxx:123
virtual bool operate(const OOperand *, const OOperand *) const override
Definition: fcode.cxx:216
sal_Int32 getPredicateType() const
Definition: fcode.hxx:255
#define NODE_NOTFOUND
Definition: dindexnode.hxx:25
sal_uInt16 nPos
int i
Count