Branch data Line data Source code
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 : :
23 : : using namespace ::com::sun::star::sdb;
24 : : using namespace connectivity;
25 : : using namespace connectivity::dbase;
26 : : using namespace connectivity::file;
27 : : using namespace ::com::sun::star::sdb;
28 : : //==================================================================
29 : : // OIndexIterator
30 : : //==================================================================
31 : : //------------------------------------------------------------------
32 [ # # ]: 0 : OIndexIterator::~OIndexIterator()
33 : : {
34 : 0 : m_pIndex->release();
35 [ # # ]: 0 : }
36 : :
37 : : //------------------------------------------------------------------
38 : 0 : sal_uIntPtr OIndexIterator::First()
39 : : {
40 : 0 : return Find(sal_True);
41 : : }
42 : :
43 : : //------------------------------------------------------------------
44 : 0 : sal_uIntPtr OIndexIterator::Next()
45 : : {
46 : 0 : return Find(sal_False);
47 : : }
48 : : //------------------------------------------------------------------
49 : 0 : sal_uIntPtr OIndexIterator::Find(sal_Bool bFirst)
50 : : {
51 : 0 : sal_uIntPtr nRes = STRING_NOTFOUND;
52 : :
53 [ # # ]: 0 : if (bFirst)
54 : : {
55 [ # # ]: 0 : m_aRoot = m_pIndex->getRoot();
56 : 0 : m_aCurLeaf = NULL;
57 : : }
58 : :
59 [ # # ]: 0 : if (!m_pOperator)
60 : : {
61 : : // Preparation, position on the smallest element
62 [ # # ]: 0 : if (bFirst)
63 : : {
64 : 0 : ONDXPage* pPage = m_aRoot;
65 [ # # ][ # # ]: 0 : while (pPage && !pPage->IsLeaf())
[ # # ]
66 : 0 : pPage = pPage->GetChild(m_pIndex);
67 : :
68 : 0 : m_aCurLeaf = pPage;
69 : 0 : m_nCurNode = NODE_NOTFOUND;
70 : : }
71 : 0 : ONDXKey* pKey = GetNextKey();
72 [ # # ]: 0 : nRes = pKey ? pKey->GetRecord() : STRING_NOTFOUND;
73 : : }
74 [ # # ]: 0 : else if (m_pOperator->IsA(TYPE(OOp_ISNOTNULL)))
75 : 0 : nRes = GetNotNull(bFirst);
76 [ # # ]: 0 : else if (m_pOperator->IsA(TYPE(OOp_ISNULL)))
77 : 0 : nRes = GetNull(bFirst);
78 [ # # ]: 0 : else if (m_pOperator->IsA(TYPE(OOp_LIKE)))
79 : 0 : nRes = GetLike(bFirst);
80 [ # # ]: 0 : else if (m_pOperator->IsA(TYPE(OOp_COMPARE)))
81 : 0 : nRes = GetCompare(bFirst);
82 : :
83 : 0 : return nRes;
84 : : }
85 : :
86 : : //------------------------------------------------------------------
87 : 0 : ONDXKey* OIndexIterator::GetFirstKey(ONDXPage* pPage, const OOperand& rKey)
88 : : {
89 : : // searches a given key
90 : : // Speciality: At the end of the algorithm
91 : : // the actual page and the position of the node which fulfil the
92 : : // '<='-condition are saved. this is considered for inserts.
93 : : // ONDXIndex* m_pIndex = GetNDXIndex();
94 [ # # ]: 0 : OOp_COMPARE aTempOp(SQLFilterOperator::GREATER);
95 : 0 : sal_uInt16 i = 0;
96 : :
97 [ # # ]: 0 : if (pPage->IsLeaf())
98 : : {
99 : : // in the leaf the actual operation is run, otherwise temp. (>)
100 [ # # ][ # # ]: 0 : while (i < pPage->Count() && !m_pOperator->operate(&((*pPage)[i]).GetKey(),&rKey))
[ # # ][ # # ]
[ # # ]
101 : 0 : i++;
102 : : }
103 : : else
104 [ # # ][ # # ]: 0 : while (i < pPage->Count() && !aTempOp.operate(&((*pPage)[i]).GetKey(),&rKey))
[ # # ][ # # ]
[ # # ]
105 : 0 : i++;
106 : :
107 : :
108 : 0 : ONDXKey* pFoundKey = NULL;
109 [ # # ]: 0 : if (!pPage->IsLeaf())
110 : : {
111 : : // descend further
112 : 0 : ONDXPagePtr aPage = (i==0) ? pPage->GetChild(m_pIndex)
113 [ # # ][ # # ]: 0 : : ((*pPage)[i-1]).GetChild(m_pIndex, pPage);
[ # # ][ # # ]
[ # # ]
114 [ # # ][ # # ]: 0 : pFoundKey = aPage.Is() ? GetFirstKey(aPage, rKey) : NULL;
[ # # ]
115 : : }
116 [ # # ]: 0 : else if (i == pPage->Count())
117 : : {
118 : 0 : pFoundKey = NULL;
119 : : }
120 : : else
121 : : {
122 [ # # ]: 0 : pFoundKey = &(*pPage)[i].GetKey();
123 [ # # ][ # # ]: 0 : if (!m_pOperator->operate(pFoundKey,&rKey))
124 : 0 : pFoundKey = NULL;
125 : :
126 [ # # ]: 0 : m_aCurLeaf = pPage;
127 [ # # ]: 0 : m_nCurNode = pFoundKey ? i : i - 1;
128 : : }
129 [ # # ]: 0 : return pFoundKey;
130 : : }
131 : :
132 : : //------------------------------------------------------------------
133 : 0 : sal_uIntPtr OIndexIterator::GetCompare(sal_Bool bFirst)
134 : : {
135 : 0 : ONDXKey* pKey = NULL;
136 [ # # ][ # # ]: 0 : sal_Int32 ePredicateType = PTR_CAST(file::OOp_COMPARE,m_pOperator)->getPredicateType();
137 : :
138 [ # # ]: 0 : if (bFirst)
139 : : {
140 : : // Preparation, position on the smallest element
141 : 0 : ONDXPage* pPage = m_aRoot;
142 [ # # ]: 0 : switch (ePredicateType)
143 : : {
144 : : case SQLFilterOperator::NOT_EQUAL:
145 : : case SQLFilterOperator::LESS:
146 : : case SQLFilterOperator::LESS_EQUAL:
147 [ # # ][ # # ]: 0 : while (pPage && !pPage->IsLeaf())
[ # # ]
148 : 0 : pPage = pPage->GetChild(m_pIndex);
149 : :
150 : 0 : m_aCurLeaf = pPage;
151 : 0 : m_nCurNode = NODE_NOTFOUND;
152 : : }
153 : :
154 : :
155 [ # # # # : 0 : switch (ePredicateType)
# # ]
156 : : {
157 : : case SQLFilterOperator::NOT_EQUAL:
158 [ # # ][ # # ]: 0 : while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand)) ;
[ # # ]
159 : 0 : break;
160 : : case SQLFilterOperator::LESS:
161 [ # # ][ # # ]: 0 : while ( ( ( pKey = GetNextKey() ) != NULL ) && pKey->getValue().isNull()) ;
[ # # ]
162 : 0 : break;
163 : : case SQLFilterOperator::LESS_EQUAL:
164 [ # # ]: 0 : while ( ( pKey = GetNextKey() ) != NULL ) ;
165 : 0 : break;
166 : : case SQLFilterOperator::GREATER_EQUAL:
167 : : case SQLFilterOperator::EQUAL:
168 : 0 : pKey = GetFirstKey(m_aRoot,*m_pOperand);
169 : 0 : break;
170 : : case SQLFilterOperator::GREATER:
171 : 0 : pKey = GetFirstKey(m_aRoot,*m_pOperand);
172 [ # # ]: 0 : if ( !pKey )
173 [ # # ][ # # ]: 0 : while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand)) ;
[ # # ]
174 : : }
175 : : }
176 : : else
177 : : {
178 [ # # # # ]: 0 : switch (ePredicateType)
179 : : {
180 : : case SQLFilterOperator::NOT_EQUAL:
181 [ # # ][ # # ]: 0 : while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand))
[ # # ]
182 : : ;
183 : 0 : break;
184 : : case SQLFilterOperator::LESS:
185 : : case SQLFilterOperator::LESS_EQUAL:
186 : : case SQLFilterOperator::EQUAL:
187 [ # # ][ # # ]: 0 : if ( ( ( pKey = GetNextKey() ) == NULL ) || !m_pOperator->operate(pKey,m_pOperand))
[ # # ]
188 : : {
189 : 0 : pKey = NULL;
190 : 0 : m_aCurLeaf = NULL;
191 : : }
192 : 0 : break;
193 : : case SQLFilterOperator::GREATER_EQUAL:
194 : : case SQLFilterOperator::GREATER:
195 : 0 : pKey = GetNextKey();
196 : : }
197 : : }
198 : :
199 [ # # ]: 0 : return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
200 : : }
201 : :
202 : : //------------------------------------------------------------------
203 : 0 : sal_uIntPtr OIndexIterator::GetLike(sal_Bool bFirst)
204 : : {
205 [ # # ]: 0 : if (bFirst)
206 : : {
207 : 0 : ONDXPage* pPage = m_aRoot;
208 : :
209 [ # # ][ # # ]: 0 : while (pPage && !pPage->IsLeaf())
[ # # ]
210 : 0 : pPage = pPage->GetChild(m_pIndex);
211 : :
212 : 0 : m_aCurLeaf = pPage;
213 : 0 : m_nCurNode = NODE_NOTFOUND;
214 : : }
215 : :
216 : : ONDXKey* pKey;
217 [ # # ][ # # ]: 0 : while ( ( ( pKey = GetNextKey() ) != NULL ) && !m_pOperator->operate(pKey,m_pOperand))
[ # # ]
218 : : ;
219 [ # # ]: 0 : return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
220 : : }
221 : :
222 : : //------------------------------------------------------------------
223 : 0 : sal_uIntPtr OIndexIterator::GetNull(sal_Bool bFirst)
224 : : {
225 [ # # ]: 0 : if (bFirst)
226 : : {
227 : 0 : ONDXPage* pPage = m_aRoot;
228 [ # # ][ # # ]: 0 : while (pPage && !pPage->IsLeaf())
[ # # ]
229 : 0 : pPage = pPage->GetChild(m_pIndex);
230 : :
231 : 0 : m_aCurLeaf = pPage;
232 : 0 : m_nCurNode = NODE_NOTFOUND;
233 : : }
234 : :
235 : : ONDXKey* pKey;
236 [ # # ][ # # ]: 0 : if ( ( ( pKey = GetNextKey() ) == NULL ) || !pKey->getValue().isNull())
[ # # ]
237 : : {
238 : 0 : pKey = NULL;
239 : 0 : m_aCurLeaf = NULL;
240 : : }
241 [ # # ]: 0 : return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
242 : : }
243 : :
244 : : //------------------------------------------------------------------
245 : 0 : sal_uIntPtr OIndexIterator::GetNotNull(sal_Bool bFirst)
246 : : {
247 : : ONDXKey* pKey;
248 [ # # ]: 0 : if (bFirst)
249 : : {
250 : : // go through all NULL values first
251 [ # # ]: 0 : for (sal_uIntPtr nRec = GetNull(bFirst);
252 : : nRec != STRING_NOTFOUND;
253 : : nRec = GetNull(sal_False))
254 : : ;
255 [ # # ]: 0 : pKey = m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
256 : : }
257 : : else
258 : 0 : pKey = GetNextKey();
259 : :
260 [ # # ]: 0 : return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
261 : : }
262 : :
263 : : //------------------------------------------------------------------
264 : 0 : ONDXKey* OIndexIterator::GetNextKey()
265 : : {
266 [ # # ][ # # ]: 0 : if (m_aCurLeaf.Is() && ((++m_nCurNode) >= m_aCurLeaf->Count()))
[ # # ]
267 : : {
268 : 0 : ONDXPage* pPage = m_aCurLeaf;
269 : : // search next page
270 [ # # ]: 0 : while (pPage)
271 : : {
272 : 0 : ONDXPage* pParentPage = pPage->GetParent();
273 [ # # ]: 0 : if (pParentPage)
274 : : {
275 : 0 : sal_uInt16 nPos = pParentPage->Search(pPage);
276 [ # # ]: 0 : if (nPos != pParentPage->Count() - 1)
277 : : { // page found
278 : 0 : pPage = (*pParentPage)[nPos+1].GetChild(m_pIndex,pParentPage);
279 : 0 : break;
280 : : }
281 : : }
282 : 0 : pPage = pParentPage;
283 : : }
284 : :
285 : : // now go on with leaf
286 [ # # ][ # # ]: 0 : while (pPage && !pPage->IsLeaf())
[ # # ]
287 : 0 : pPage = pPage->GetChild(m_pIndex);
288 : :
289 : 0 : m_aCurLeaf = pPage;
290 : 0 : m_nCurNode = 0;
291 : : }
292 [ # # ]: 0 : return m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
293 : : }
294 : :
295 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|