1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _CONNECTIVITY_DBASE_INDEXNODE_HXX_
24 #define _CONNECTIVITY_DBASE_INDEXNODE_HXX_
25 
26 #include "file/fcode.hxx"
27 #include "file/FTable.hxx"
28 #include "dbase/DIndexPage.hxx"
29 #include "connectivity/FValue.hxx"
30 #include <tools/ref.hxx>
31 
32 #define NODE_NOTFOUND 0xFFFF
33 #define PAGE_SIZE 512
34 
35 namespace connectivity
36 {
37 	namespace dbase
38 	{
39 
40 		class ONDXNode;
41 		class ODbaseIndex;
42 		//==================================================================
43 		// Index Key
44 		//==================================================================
45 		typedef file::OOperand ONDXKey_BASE;
46 		class ONDXKey : public ONDXKey_BASE
47 		{
48 			friend class ONDXNode;
49 			sal_uInt32			nRecord;				/* Satzzeiger				*/
50 			ORowSetValue	xValue;					/* Schluesselwert			*/
51 
52 		public:
53 			ONDXKey(sal_uInt32 nRec=0);
54 			ONDXKey(const ORowSetValue& rVal, sal_Int32 eType, sal_uInt32 nRec);
55 			ONDXKey(const rtl::OUString& aStr, sal_uInt32 nRec = 0);
56 			ONDXKey(double aVal, sal_uInt32 nRec = 0);
57 
58 			inline ONDXKey(const ONDXKey& rKey);
59 
60 			inline ONDXKey& operator= (const ONDXKey& rKey);
61 			virtual void setValue(const ORowSetValue& _rVal);
62 
63 			virtual const ORowSetValue& getValue() const;
64 
GetRecord() const65 			sal_uInt32 GetRecord() const		{ return nRecord;	}
setRecord(sal_uInt32 _nRec)66 			void setRecord(sal_uInt32 _nRec)	{ nRecord = _nRec;	}
ResetRecord()67 			void   ResetRecord()			{ nRecord = 0;		}
68 
69 			sal_Bool operator == (const ONDXKey& rKey) const;
70 			sal_Bool operator != (const ONDXKey& rKey) const;
71 			sal_Bool operator <	 (const ONDXKey& rKey) const;
72 			sal_Bool operator <= (const ONDXKey& rKey) const;
73 			sal_Bool operator >  (const ONDXKey& rKey) const;
74 			sal_Bool operator >= (const ONDXKey& rKey) const;
75 
76 			sal_Bool Load (SvFileStream& rStream, sal_Bool bText);
77 			sal_Bool Write(SvFileStream& rStream, sal_Bool bText);
78 
79 			static sal_Bool IsText(sal_Int32 eType);
80 
81 		private:
82 			StringCompare Compare(const ONDXKey& rKey) const;
83 		};
84 
85 
86 
87 
88 		//==================================================================
89 		// Index Seitenverweis
90 		//==================================================================
91 		SV_DECL_REF(ONDXPage) // Basisklasse da weitere Informationen gehalten werden muessen
92 
93 
94 		class ONDXPagePtr : public ONDXPageRef
95 		{
96 			friend  SvStream& operator << (SvStream &rStream, const ONDXPagePtr&);
97 			friend  SvStream& operator >> (SvStream &rStream, ONDXPagePtr&);
98 
99 			sal_uInt32	nPagePos;		// Position in der Indexdatei
100 
101 		public:
ONDXPagePtr(sal_uInt32 nPos=0)102 			ONDXPagePtr(sal_uInt32 nPos = 0):nPagePos(nPos){}
103 			ONDXPagePtr(const ONDXPagePtr& rRef);
104 			ONDXPagePtr(ONDXPage* pRefPage);
105 
106 			ONDXPagePtr& operator=(const ONDXPagePtr& rRef);
107 			ONDXPagePtr& operator=(ONDXPage* pPageRef);
108 
GetPagePos() const109 			sal_uInt32 GetPagePos() const {return nPagePos;}
HasPage() const110 			sal_Bool HasPage() const {return nPagePos != 0;}
111 			//	sal_Bool Is() const { return isValid(); }
112 		};
113 		//==================================================================
114 		// Index Seite
115 		//==================================================================
116 		class ONDXPage : public SvRefBase
117 		{
118 			friend class ODbaseIndex;
119 
120 			friend  SvStream& operator << (SvStream &rStream, const ONDXPage&);
121 			friend  SvStream& operator >> (SvStream &rStream, ONDXPage&);
122 
123 			sal_uInt32		nPagePos;				// Position in der Indexdatei
124 			sal_Bool		bModified : 1;
125 			sal_uInt16		nCount;
126 
127 			ONDXPagePtr	aParent,			// VaterSeite
128 						aChild;				// Zeiger auf rechte ChildPage
129 			ODbaseIndex& rIndex;
130 			ONDXNode*  ppNodes;				// array von Knoten
131 
132 		public:
133 			// Knoten Operationen
Count() const134 			sal_uInt16	Count() const {return nCount;}
135 
136 			sal_Bool	Insert(ONDXNode& rNode, sal_uInt32 nRowsLeft = 0);
137 			sal_Bool	Insert(sal_uInt16 nIndex, ONDXNode& rNode);
138 			sal_Bool	Append(ONDXNode& rNode);
139 			sal_Bool	Delete(sal_uInt16);
140 			void	Remove(sal_uInt16);
141 			void	Release(sal_Bool bSave = sal_True);
142 			void	ReleaseFull(sal_Bool bSave = sal_True);
143 
144 			// Aufteilen und Zerlegen
145 			ONDXNode Split(ONDXPage& rPage);
146 			void Merge(sal_uInt16 nParentNodePos, ONDXPagePtr xPage);
147 
148 			// Zugriffsoperationen
149 			ONDXNode& operator[] (sal_uInt16 nPos);
150 			const ONDXNode& operator[] (sal_uInt16 nPos) const;
151 
152 			sal_Bool IsRoot() const;
153 			sal_Bool IsLeaf() const;
154 			sal_Bool IsModified() const;
155 			sal_Bool HasParent();
156 			sal_Bool HasChild() const;
157 
158 			sal_Bool IsFull() const;
159 
GetPagePos() const160 			sal_uInt32 GetPagePos() const {return nPagePos;}
161 			ONDXPagePtr& GetChild(ODbaseIndex* pIndex = 0);
162 
163 			// Parent braucht nicht nachgeladen zu werden
164 			ONDXPagePtr GetParent();
GetIndex()165 			ODbaseIndex& GetIndex() {return rIndex;}
GetIndex() const166 			const ODbaseIndex& GetIndex() const {return rIndex;}
167 
168 			// Setzen des Childs, ueber Referenz, um die PagePos zu erhalten
169 			void SetChild(ONDXPagePtr aCh);
170 			void SetParent(ONDXPagePtr aPa);
171 
172 			sal_uInt16 Search(const ONDXKey& rSearch);
173 			sal_uInt16 Search(const ONDXPage* pPage);
174 			void   SearchAndReplace(const ONDXKey& rSearch, ONDXKey& rReplace);
175 
176 		protected:
177 			ONDXPage(ODbaseIndex& rIndex, sal_uInt32 nPos, ONDXPage* = NULL);
178 			~ONDXPage();
179 
180 			virtual void QueryDelete();
181 
SetModified(sal_Bool bMod)182 			void SetModified(sal_Bool bMod) {bModified = bMod;}
SetPagePos(sal_uInt32 nPage)183 			void SetPagePos(sal_uInt32 nPage) {nPagePos = nPage;}
184 
185 			sal_Bool Find(const ONDXKey&);	// rek. Abstieg
186 			sal_uInt16 FindPos(const ONDXKey& rKey) const;
187 
188 #if OSL_DEBUG_LEVEL > 1
189 			void PrintPage();
190 #endif
191 		};
192 
193 		SV_IMPL_REF(ONDXPage);
194 
195 		SvStream& operator << (SvStream &rStream, const ONDXPagePtr&);
196 		SvStream& operator >> (SvStream &rStream, ONDXPagePtr&);
197 
IsRoot() const198 		inline sal_Bool ONDXPage::IsRoot() const {return !aParent.Is();}
IsLeaf() const199 		inline sal_Bool ONDXPage::IsLeaf() const {return !aChild.HasPage();}
IsModified() const200 		inline sal_Bool ONDXPage::IsModified() const {return bModified;}
HasParent()201 		inline sal_Bool ONDXPage::HasParent() {return aParent.Is();}
HasChild() const202 		inline sal_Bool ONDXPage::HasChild() const {return aChild.HasPage();}
GetParent()203 		inline ONDXPagePtr ONDXPage::GetParent() {return aParent;}
204 
SetParent(ONDXPagePtr aPa=ONDXPagePtr ())205 		inline void ONDXPage::SetParent(ONDXPagePtr aPa = ONDXPagePtr())
206 		{
207 			aParent = aPa;
208 		}
209 
SetChild(ONDXPagePtr aCh=ONDXPagePtr ())210 		inline void ONDXPage::SetChild(ONDXPagePtr aCh = ONDXPagePtr())
211 		{
212 			aChild = aCh;
213 			if (aChild.Is())
214 				aChild->SetParent(this);
215 		}
216 		SvStream& operator >> (SvStream &rStream, ONDXPage& rPage);
217 		SvStream& operator << (SvStream &rStream, const ONDXPage& rPage);
218 
219 
220 		typedef ::std::vector<ONDXPage*>	ONDXPageList;
221 
222 		//==================================================================
223 		// Index Knoten
224 		//==================================================================
225 		class ONDXNode
226 		{
227 			friend class ONDXPage;
228 			ONDXPagePtr aChild;				/* naechster Seitenverweis	*/
229 			ONDXKey	  aKey;
230 
231 		public:
ONDXNode()232 			ONDXNode(){}
ONDXNode(const ONDXKey & rKey,ONDXPagePtr aPagePtr=ONDXPagePtr ())233 			ONDXNode(const ONDXKey& rKey,
234 					   ONDXPagePtr aPagePtr = ONDXPagePtr())
235                        :aChild(aPagePtr),aKey(rKey) {}
236 
237 			// verweist der Knoten auf eine Seite
HasChild() const238 			sal_Bool			HasChild() const {return aChild.HasPage();}
239 			// Ist ein Index angegeben, kann gegebenfalls die Seite nachgeladen werden
240 			ONDXPagePtr&	GetChild(ODbaseIndex* pIndex = NULL, ONDXPage* = NULL);
241 
GetKey() const242 			const ONDXKey& GetKey() const	{ return aKey;}
GetKey()243 			ONDXKey&	   GetKey()			{ return aKey;}
244 
245 			// Setzen des Childs, ueber Referenz, um die PagePos zu erhalten
246 			void			SetChild(ONDXPagePtr aCh = ONDXPagePtr(), ONDXPage* = NULL);
SetKey(ONDXKey & rKey)247 			void			SetKey(ONDXKey& rKey) {aKey = rKey;}
248 
249 			void Write(SvStream &rStream, const ONDXPage& rPage) const;
250 			void Read(SvStream &rStream, ODbaseIndex&);
251 		};
252 		//==================================================================
253 		// inline implementation
254 		//==================================================================
255 //		inline ONDXKey::ONDXKey(const ORowSetValue& rVal, sal_Int32 eType, sal_uInt32 nRec)
256 //			: ONDXKey_BASE(eType)
257 //			, nRecord(nRec),xValue(rVal)
258 //		{
259 //		}
260 
261 
262 //		inline ONDXKey::ONDXKey(const rtl::OUString& aStr, sal_uInt32 nRec)
263 //					: ONDXKey_BASE(::com::sun::star::sdbc::DataType::VARCHAR)
264 //					 ,nRecord(nRec)
265 //		{
266 //			if (aStr.len())
267 //				xValue = aStr;
268 //		}
269 
270 //		inline ONDXKey::ONDXKey(double aVal, sal_uInt32 nRec)
271 //					 : ONDXKey_BASE(::com::sun::star::sdbc::DataType::DOUBLE)
272 //					 ,nRecord(nRec)
273 //					 ,xValue(aVal)
274 //		{
275 //		}
276 
277 //		inline ONDXKey::ONDXKey(sal_uInt32 nRec)
278 //					 :nRecord(nRec)
279 //		{
280 //		}
281 
ONDXKey(const ONDXKey & rKey)282 		inline ONDXKey::ONDXKey(const ONDXKey& rKey)
283 					 : ONDXKey_BASE(rKey.getDBType())
284 					 ,nRecord(rKey.nRecord)
285 					 ,xValue(rKey.xValue)
286 		{
287 		}
288 
operator =(const ONDXKey & rKey)289 		inline ONDXKey& ONDXKey::operator=(const ONDXKey& rKey)
290 		{
291 			if(&rKey == this)
292 				return *this;
293 
294 			xValue = rKey.xValue;
295 			nRecord = rKey.nRecord;
296 			m_eDBType = rKey.getDBType();
297 			return *this;
298 		}
299 
operator ==(const ONDXKey & rKey) const300 		inline sal_Bool ONDXKey::operator == (const ONDXKey& rKey) const
301 		{
302 			if(&rKey == this)
303 				return sal_True;
304 			return Compare(rKey) == COMPARE_EQUAL;
305 		}
operator !=(const ONDXKey & rKey) const306 		inline sal_Bool ONDXKey::operator != (const ONDXKey& rKey) const
307 		{
308 			return !operator== (rKey);
309 		}
operator <(const ONDXKey & rKey) const310 		inline sal_Bool ONDXKey::operator <  (const ONDXKey& rKey) const
311 		{
312 			return Compare(rKey) == COMPARE_LESS;
313 		}
operator >(const ONDXKey & rKey) const314 		inline sal_Bool ONDXKey::operator >  (const ONDXKey& rKey) const
315 		{
316 			return Compare(rKey) == COMPARE_GREATER;
317 		}
operator <=(const ONDXKey & rKey) const318 		inline sal_Bool ONDXKey::operator <= (const ONDXKey& rKey) const
319 		{
320 			return !operator > (rKey);
321 		}
operator >=(const ONDXKey & rKey) const322 		inline sal_Bool ONDXKey::operator >= (const ONDXKey& rKey) const
323 		{
324 			return !operator< (rKey);
325 		}
326 
SetChild(ONDXPagePtr aCh,ONDXPage * pParent)327 		inline void ONDXNode::SetChild(ONDXPagePtr aCh, ONDXPage* pParent)
328 		{
329 			aChild = aCh;
330 			if (aChild.Is())
331 				aChild->SetParent(pParent);
332 		}
333 
334 	}
335 
336 }
337 
338 
339 
340 
341 #endif // _CONNECTIVITY_DBASE_INDEXNODE_HXX_
342 
343 
344