1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // CegoBTreeObject.cc
4 // ------------------
5 // Cego btree object class implementation
6 //
7 // Design and Implementation by Bjoern Lemke
8 //
9 // (C)opyright 2000-2019 Bjoern Lemke
10 //
11 // IMPLEMENTATION MODULE
12 //
13 // Class: CegoBTreeObject
14 //
15 // Description: Binary tree index structure
16 //
17 // Status: CLEAN
18 //
19 ///////////////////////////////////////////////////////////////////////////////
20 
21 // CEGO INCLUDES
22 #include "CegoBTreeObject.h"
23 #include "CegoXMLHelper.h"
24 #include "CegoTypeConverter.h"
25 #include "CegoXMLdef.h"
26 
27 // POSIX INCLUDES
28 #include <string.h>
29 #include <stdlib.h>
30 
CegoBTreeObject()31 CegoBTreeObject::CegoBTreeObject()
32 {
33 }
34 
CegoBTreeObject(Element * pTO)35 CegoBTreeObject::CegoBTreeObject(Element *pTO)
36 {
37     putElement(pTO);
38 }
39 
CegoBTreeObject(const CegoBTreeObject & oe)40 CegoBTreeObject::CegoBTreeObject(const CegoBTreeObject& oe) : CegoContentObject(oe)
41 {
42     _pageId = oe._pageId;
43     _relevance = oe._relevance;
44 }
45 
CegoBTreeObject(int tabSetId,CegoObject::ObjectType type,const Chain & objName)46 CegoBTreeObject::CegoBTreeObject(int tabSetId, CegoObject::ObjectType type, const Chain& objName ) : CegoContentObject(tabSetId, type, objName)
47 {
48     _pageId = 0;
49     _relevance = 0;
50 }
51 
CegoBTreeObject(int tabSetId,CegoObject::ObjectType type,const Chain & objName,const ListT<CegoField> & schema,const Chain & tabName)52 CegoBTreeObject::CegoBTreeObject(int tabSetId, CegoObject::ObjectType type,  const Chain& objName, const ListT<CegoField>& schema, const Chain& tabName) : CegoContentObject(tabSetId, type, objName, tabName, schema)
53 {
54     _pageId = 0;
55     _relevance=0;
56 }
57 
~CegoBTreeObject()58 CegoBTreeObject::~CegoBTreeObject()
59 {
60 }
61 
setSchema(const ListT<CegoField> & schema)62 void CegoBTreeObject::setSchema(const ListT<CegoField>& schema)
63 {
64     _schema = schema;
65 }
66 
setDataPageId(PageIdType pageId)67 void CegoBTreeObject::setDataPageId(PageIdType pageId)
68 {
69     _pageId = pageId;
70 }
71 
getDataPageId() const72 PageIdType CegoBTreeObject::getDataPageId() const
73 {
74     return _pageId;
75 }
76 
increaseRelevance()77 void CegoBTreeObject::increaseRelevance()
78 {
79     _relevance++;
80 }
81 
decreaseRelevance()82 void CegoBTreeObject::decreaseRelevance()
83 {
84     _relevance--;
85 }
86 
getRelevance() const87 int CegoBTreeObject::getRelevance() const
88 {
89     return _relevance;
90 }
91 
getEntrySize() const92 int CegoBTreeObject::getEntrySize() const
93 {
94     int entrySize = CegoContentObject::getBaseContentSize();
95 
96     entrySize = entrySize + sizeof(PageIdType); // pageId
97     entrySize = entrySize + sizeof(int); // relevance
98 
99     return entrySize;
100 }
101 
encode(char * buf)102 void CegoBTreeObject::encode(char *buf)
103 {
104     char* bufPtr = buf;
105 
106     int entrySize = getEntrySize();
107 
108     CegoContentObject::encodeBaseContent(bufPtr, entrySize);
109     bufPtr += CegoContentObject::getBaseContentSize();
110 
111     memcpy(bufPtr, &_pageId, sizeof(PageIdType));
112     bufPtr = bufPtr + sizeof(PageIdType);
113 
114     memcpy(bufPtr, &_relevance, sizeof(int));
115     bufPtr = bufPtr + sizeof(int);
116 }
117 
decode(char * buf)118 void CegoBTreeObject::decode(char *buf)
119 {
120     char* bufPtr = buf;
121 
122     int size;
123 
124     CegoContentObject::decodeBaseContent(bufPtr, size);
125     bufPtr += CegoContentObject::getBaseContentSize();
126 
127     memcpy(&_pageId, bufPtr, sizeof(PageIdType));
128     bufPtr = bufPtr + sizeof(PageIdType);
129 
130     memcpy(&_relevance, bufPtr, sizeof(int));
131     bufPtr = bufPtr + sizeof(int);
132 }
133 
isValid()134 bool CegoBTreeObject::isValid()
135 {
136     return _pageId != 0;
137 }
138 
operator =(const CegoBTreeObject & oe)139 CegoBTreeObject& CegoBTreeObject::operator = ( const CegoBTreeObject& oe)
140 {
141     CegoContentObject::operator=(oe);
142     _pageId = oe._pageId;
143     _relevance = oe._relevance;
144     return (*this);
145 }
146 
operator ==(const CegoBTreeObject & oe)147 bool CegoBTreeObject::operator == ( const CegoBTreeObject& oe)
148 {
149     return CegoContentObject::operator==(oe);
150 }
151 
getId() const152 Chain CegoBTreeObject::getId() const
153 {
154     return getTabName() + Chain("@") + getTableSet() + Chain("@") + getName();
155 }
156 
toChain() const157 Chain CegoBTreeObject::toChain() const
158 {
159     return getTabName() + Chain("@") + getTableSet() + Chain(" ") + getName();
160 }
161 
getElement() const162 Element* CegoBTreeObject::getElement() const
163 {
164     Element* pRoot = new Element(XML_OBJ_ELEMENT);
165 
166     pRoot->setAttribute(XML_TSID_ATTR, Chain(getTabSetId()));
167     switch ( getType() )
168     {
169     case CegoObject::BTREE:
170 	pRoot->setAttribute(XML_OBJTYPE_ATTR, XML_BTREEOBJ_VALUE);
171 	break;
172     case CegoObject::PBTREE:
173 	pRoot->setAttribute(XML_OBJTYPE_ATTR, XML_PBTREEOBJ_VALUE);
174 	break;
175     case CegoObject::UBTREE:
176 	pRoot->setAttribute(XML_OBJTYPE_ATTR, XML_UBTREEOBJ_VALUE);
177 	break;
178     case CegoObject::SYSTEM:
179     case CegoObject::TABLE:
180     case CegoObject::VIEW:
181     case CegoObject::RBSEG:
182     case CegoObject::FKEY:
183     case CegoObject::PROCEDURE:
184     case CegoObject::CHECK:
185     case CegoObject::JOIN:
186     case CegoObject::PAVLTREE:
187     case CegoObject::UAVLTREE:
188     case CegoObject::AVLTREE:
189     case CegoObject::TRIGGER:
190     case CegoObject::ALIAS:
191     case CegoObject::UNDEFINED:
192 	break;
193     }
194 
195     pRoot->setAttribute(XML_OBJNAME_ATTR, getName());
196 
197     CegoField *pF = _schema.First();
198     while ( pF )
199     {
200 	Element *pColElement = new Element(XML_SCHEMA_ELEMENT);
201 
202 	CegoXMLHelper xh;
203 	xh.setColInfo(pColElement, pF);
204 
205 	pRoot->addContent(pColElement);
206 	pF = _schema.Next();
207     }
208 
209     return pRoot;
210 }
211 
putElement(Element * pElement)212 void CegoBTreeObject::putElement(Element* pElement)
213 {
214     Element *pRoot = pElement;
215 
216     if ( pRoot )
217     {
218 
219 	Chain objName = pRoot->getAttributeValue(XML_OBJNAME_ATTR);
220 	int tabSetId = pRoot->getAttributeValue(XML_TSID_ATTR).asInteger();
221 
222 	setName(objName);
223 	setTabName(objName);
224 	setTabSetId(tabSetId);
225 
226 	Chain objType = pRoot->getAttributeValue(XML_OBJTYPE_ATTR);
227 	if ( objType == Chain(XML_BTREEOBJ_VALUE))
228 	    setType(CegoObject::BTREE);
229 	else if ( objType == Chain(XML_PBTREEOBJ_VALUE))
230 	    setType(CegoObject::PBTREE);
231 	else if ( objType == Chain(XML_UBTREEOBJ_VALUE))
232 	    setType(CegoObject::UBTREE);
233 
234 	ListT<Element*> colList = pRoot->getChildren(XML_SCHEMA_ELEMENT);
235 
236 	ListT<CegoField> fl;
237 	Element **pCol = colList.First();
238 	while ( pCol )
239 	{
240 	    Chain colName = (*pCol)->getAttributeValue(XML_COLNAME_ATTR);
241 	    Chain colType = (*pCol)->getAttributeValue(XML_COLTYPE_ATTR);
242 	    Chain colSize = (*pCol)->getAttributeValue(XML_COLSIZE_ATTR);
243 	    Chain colDim = (*pCol)->getAttributeValue(XML_COLDIM_ATTR);
244 
245 	    Chain colNullable = (*pCol)->getAttributeValue(XML_COLNULLABLE_ATTR);
246 	    Chain colDefValue = (*pCol)->getAttributeValue(XML_COLDEFVALUE_ATTR);
247 
248 	    bool isNullable;
249 	    if ( colNullable == Chain(XML_TRUE_VALUE) )
250 		isNullable = true;
251 	    else
252 		isNullable = false;
253 
254 	    CegoTypeConverter tc;
255 	    CegoDataType dataType = tc.getTypeId(colType);
256 
257 	    CegoFieldValue defValue;
258 	    if ( colDefValue != Chain("") )
259 	    {
260 		defValue = CegoFieldValue(dataType, colDefValue);
261 	    }
262 
263 	    CegoField f(CegoField(objName, objName, colName, dataType, colSize.asInteger(), colDim.asInteger(), defValue, isNullable));
264 	    fl.Insert(f);
265 
266 	    pCol = colList.Next();
267 	}
268 
269 	setSchema(fl);
270     }
271 }
272 
getFormatted() const273 Chain CegoBTreeObject::getFormatted() const
274 {
275     Chain s;
276 
277     int maxAttrLen = 12;
278     int maxDefLen = 10;
279 
280     CegoField* pF = _schema.First();
281     while (pF)
282     {
283 	if (maxAttrLen < pF->getAttrName().length())
284 	    maxAttrLen = pF->getAttrName().length();
285 	if (maxDefLen < pF->getValue().valAsChain().length())
286 	    maxDefLen = pF->getValue().valAsChain().length();
287 
288 	pF = _schema.Next();
289     }
290 
291     s += Chain("+") + fill("-", maxAttrLen) + fill(Chain("-"), maxDefLen + 30) + Chain("+\n");
292     s += Chain("| ObjectName : ") + getName() + fill(" ", maxAttrLen + maxDefLen + 17 - getName().length()) + Chain("|\n");
293 
294     s += Chain("| ObjectType : ");
295     switch ( getType() )
296     {
297     case CegoObject::BTREE:
298 	s += Chain("btree          ");
299 	break;
300     case CegoObject::UBTREE:
301 	s += Chain("unique btree   ");
302 	break;
303     case CegoObject::PBTREE:
304 	s += Chain("primary btree   ");
305 	break;
306     case CegoObject::SYSTEM:
307     case CegoObject::TABLE:
308     case CegoObject::VIEW:
309     case CegoObject::RBSEG:
310     case CegoObject::FKEY:
311     case CegoObject::PROCEDURE:
312     case CegoObject::CHECK:
313     case CegoObject::JOIN:
314     case CegoObject::PAVLTREE:
315     case CegoObject::UAVLTREE:
316     case CegoObject::AVLTREE:
317     case CegoObject::TRIGGER:
318     case CegoObject::ALIAS:
319     case CegoObject::UNDEFINED:
320 	break;
321     }
322 
323     s += fill(" ", maxAttrLen + maxDefLen + 1 ) + Chain("|\n");
324 
325     s += Chain("+-----------") + fill("-", maxAttrLen-10) + Chain("+---------------+") + fill("-", maxDefLen + 1) + Chain("+----------+\n");
326     s += Chain("| Attribute ") + fill(" ", maxAttrLen-10) + Chain("| Type          | Default ") + fill(" ", maxDefLen - 8) + Chain("| Nullable |\n");
327     s += Chain("+-----------") + fill("-", maxAttrLen-10) + Chain("+---------------+") + fill("-", maxDefLen + 1) + Chain("+----------+\n");
328 
329     pF = _schema.First();
330     while (pF)
331     {
332 
333 	int num = maxAttrLen - pF->getAttrName().length() ;
334 	s += Chain("| ") + pF->getAttrName() + fill(" ", num) + Chain(" |");
335 
336 
337 	switch (pF->getType())
338 	{
339 	case INT_TYPE:
340 	{
341 	    s += Chain("  int          |");
342 	    break;
343 	}
344 	case LONG_TYPE:
345 	{
346 	    s +=  Chain("  long         |");
347 	    break;
348 	}
349 	case BOOL_TYPE:
350 	{
351 	    s += Chain("  bool         |");
352 	    break;
353 	}
354 	case DATETIME_TYPE:
355 	{
356 	    s += Chain("  datetime     |");
357 	    break;
358 	}
359 	case VARCHAR_TYPE:
360 	{
361 	    Chain l(pF->getLength());
362 	    s += Chain("  string[") + l + Chain("]") + fill(" ", 6 - l.length()) + Chain("|");
363 	    break;
364 	}
365 	case BIGINT_TYPE:
366 	{
367 	    Chain l(pF->getLength());
368 	    s += Chain("  bigint[") + l + Chain("]") + fill(" ", 6 - l.length()) + Chain("|");
369 	    break;
370 	}
371 	case SMALLINT_TYPE:
372 	{
373 	    s += Chain("  smallint     |");
374 	    break;
375 	}
376 	case TINYINT_TYPE:
377 	{
378 	    s += Chain("  tinyint      |");
379 	    break;
380 	}
381 	case DECIMAL_TYPE:
382 	{
383 	    Chain l(pF->getLength());
384 	    s += Chain("  decimal[") + l + Chain("]") + fill(" ", 5 - l.length()) + Chain("|");
385 	    break;
386 	}
387 	case FIXED_TYPE:
388 	{
389 	    Chain l(pF->getLength());
390 	    s += Chain("  fixed[") + l + Chain("]") + fill(" ", 7 - l.length()) + Chain("|");
391 	    break;
392 	}
393 	case FLOAT_TYPE:
394 	{
395 	    s += Chain(" float         |");
396 	    break;
397 	}
398 	case DOUBLE_TYPE:
399 	{
400 	    s += Chain(" double        |");
401 	    break;
402 	}
403 	case BLOB_TYPE:
404 	{
405 	    s += Chain(" blob          |");
406 	    break;
407 	}
408 	case CLOB_TYPE:
409 	{
410 	    s += Chain(" clob          |");
411 	    break;
412 	}
413 	case NULL_TYPE:
414 	case PAGEID_TYPE:
415 	    break;
416 	}
417 
418 	Chain defVal = pF->getValue().valAsChain();
419 
420 	s += Chain(" ") + defVal + fill(" ", maxDefLen - defVal.length()) + Chain(" |");
421 
422 	if ( pF->isNullable() )
423 	    s += Chain(" y        |");
424 	else
425 	    s += Chain(" n        |");
426 
427 	pF = _schema.Next();
428 
429 	s += "\n";
430     }
431     s += Chain("+") + fill("-", maxAttrLen + 1) + Chain("+---------------+") + fill("-", maxDefLen + 1) + Chain("+----------+\n");
432 
433     return s;
434 }
435 
fill(const Chain & s,int num) const436 Chain CegoBTreeObject::fill(const Chain& s, int num) const
437 {
438     Chain fs = Chain("");
439     while (num > 0)
440     {
441 	fs = fs + s;
442 	num--;
443     }
444 
445     return fs;
446 }
447 
clone(bool isAttrRef)448 CegoContentObject* CegoBTreeObject::clone(bool isAttrRef)
449 {
450     CegoBTreeObject *pClone = new CegoBTreeObject(*this);
451     return (pClone);
452 }
453