///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoSystemObject.cc
// -------------------
// Cego system object implementation
//     
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoSystemObject
//
// Description: Description of all system tables like $table, $procedure, etc,
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// cego includes
#include "CegoSystemObject.h"

#include <string.h>
#include <stdlib.h>

CegoSystemObject::CegoSystemObject(CegoDatabaseManager* pDBMng) : CegoObjectManager(pDBMng)
{    
    _modId = _pDBMng->getModId("CegoSystemObject");  
}

CegoSystemObject::~CegoSystemObject()
{
}

void CegoSystemObject::createSystemSpace(unsigned tabSetId)
{
    ListT<CegoField> fl;

    fl.Insert(CegoField(Chain(), Chain(), Chain(SYSTAB_TS_ATTR), DATETIME_TYPE, sizeof(unsigned long long), 0, CegoFieldValue(), false, 1));
    fl.Insert(CegoField(Chain(), Chain(), Chain(SYSTAB_BUINFO_ATTR), VARCHAR_TYPE, 20, 0, CegoFieldValue(), false, 2));
    fl.Insert(CegoField(Chain(), Chain(), Chain(SYSTAB_BUMSG_ATTR), VARCHAR_TYPE, 50, 0, CegoFieldValue(), true, 3));

    CegoTableObject bustatTable(tabSetId, CegoObject::SYSTEM, Chain(SYSTAB_BUSTAT_ID), fl, Chain(SYSTAB_BUSTAT_ID));
    createTableObject(bustatTable);
}

bool CegoSystemObject::objectExists(unsigned tabSetId, const Chain& objectName, CegoObject::ObjectType type)
{
    if ( type == CegoObject::SYSTEM )
    {
	if ( objectName == (Chain(SYSTAB_TABLE_ID)))
	    return true;
	if ( objectName == (Chain(SYSTAB_VIEW_ID)))
	    return true;
	if ( objectName == (Chain(SYSTAB_PROC_ID)))
	    return true;
	if ( objectName == (Chain(SYSTAB_INDEX_ID)))
	    return true;
	if ( objectName == (Chain(SYSTAB_BTREE_ID)))
	    return true;
	if ( objectName == (Chain(SYSTAB_KEY_ID)))
	    return true;
	if ( objectName == (Chain(SYSTAB_BUSTAT_ID)))
	    return CegoObjectManager::objectExists(tabSetId, objectName, type);
	
	return false;
    }
    else
    {
	return CegoObjectManager::objectExists(tabSetId, objectName, type);
    }    
}

void CegoSystemObject::getObject(unsigned tabSetId, const Chain& objectName, CegoObject::ObjectType type, CegoDecodableObject& oe)
{
    if ( type == CegoObject::SYSTEM )
    {
	ListT<CegoField> schema;
	
	if ( objectName == (Chain(SYSTAB_TABLE_ID)))
	{	  	
	    CegoFieldValue defVal;
	    schema.Insert(CegoField(Chain(SYSTAB_TABLE_ID), Chain(SYSTAB_TABLE_ID), Chain(SYSTAB_NAME_ATTR),VARCHAR_TYPE, MAX_OBJNAME_LEN, 0, defVal, false, 1)); 
	    schema.Insert(CegoField(Chain(SYSTAB_TABLE_ID), Chain(SYSTAB_TABLE_ID), Chain(SYSTAB_SIZE_ATTR),INT_TYPE, sizeof(int), 0, defVal, false, 2)); 
	}
	else if ( objectName == (Chain(SYSTAB_PROC_ID)))
	{
	    CegoFieldValue defVal;
	    schema.Insert(CegoField(Chain(SYSTAB_PROC_ID), Chain(SYSTAB_PROC_ID), Chain(SYSTAB_NAME_ATTR),VARCHAR_TYPE, MAX_OBJNAME_LEN, 0, defVal, false, 1));
	    schema.Insert(CegoField(Chain(SYSTAB_PROC_ID), Chain(SYSTAB_PROC_ID), Chain(SYSTAB_STATUS_ATTR), VARCHAR_TYPE, 15, 0, defVal, false, 2));
	}
	else if ( objectName == (Chain(SYSTAB_VIEW_ID)))
	{
	    CegoFieldValue defVal;
	    schema.Insert(CegoField(Chain(SYSTAB_VIEW_ID), Chain(SYSTAB_VIEW_ID), Chain(SYSTAB_NAME_ATTR),VARCHAR_TYPE, MAX_OBJNAME_LEN, 0, defVal, false, 1));
	    schema.Insert(CegoField(Chain(SYSTAB_VIEW_ID), Chain(SYSTAB_VIEW_ID), Chain(SYSTAB_STATUS_ATTR), VARCHAR_TYPE, 15, 0, defVal, false, 2));
	}
	else if ( objectName == (Chain(SYSTAB_INDEX_ID)))
	{
	    CegoFieldValue defVal;
	    schema.Insert(CegoField(Chain(SYSTAB_INDEX_ID), Chain(SYSTAB_INDEX_ID), Chain(SYSTAB_NAME_ATTR),VARCHAR_TYPE, MAX_OBJNAME_LEN, 0, defVal, false, 1));
	    schema.Insert(CegoField(Chain(SYSTAB_INDEX_ID), Chain(SYSTAB_INDEX_ID), Chain(SYSTAB_SIZE_ATTR),INT_TYPE, sizeof(int), 0, defVal, false, 2));
	    schema.Insert(CegoField(Chain(SYSTAB_INDEX_ID), Chain(SYSTAB_INDEX_ID), Chain(SYSTAB_STATUS_ATTR), VARCHAR_TYPE, 15, 0, defVal, false, 3));
	}
	else if ( objectName == (Chain(SYSTAB_BTREE_ID)))
	{
	    CegoFieldValue defVal;
	    schema.Insert(CegoField(Chain(SYSTAB_BTREE_ID), Chain(SYSTAB_BTREE_ID), Chain(SYSTAB_NAME_ATTR),VARCHAR_TYPE, MAX_OBJNAME_LEN, 0, defVal, false, 1));
	    schema.Insert(CegoField(Chain(SYSTAB_BTREE_ID), Chain(SYSTAB_BTREE_ID), Chain(SYSTAB_SIZE_ATTR),INT_TYPE, sizeof(int), 0, defVal, false, 2));
	    schema.Insert(CegoField(Chain(SYSTAB_BTREE_ID), Chain(SYSTAB_BTREE_ID), Chain(SYSTAB_STATUS_ATTR), VARCHAR_TYPE, 15, 0, defVal, false, 3));
	}
	else if ( objectName == (Chain(SYSTAB_KEY_ID)))
	{
	    schema.Insert(CegoField(Chain(SYSTAB_KEY_ID), Chain(SYSTAB_KEY_ID), Chain(SYSTAB_NAME_ATTR),VARCHAR_TYPE, MAX_OBJNAME_LEN)); 
	}
	else
	{
	    CegoObjectManager::getObject(tabSetId, objectName, type, oe);
	    return;
	}
	
	CegoTableObject *pTO = new CegoTableObject(tabSetId, type, objectName, schema, objectName);
	
	char* buf = (char*)malloc( pTO->getEntrySize());
	pTO->encode(buf);
	oe.decode(buf);
	free(buf);
    }
    else
    {
	CegoObjectManager::getObject(tabSetId, objectName, type, oe);
    }    
}

void CegoSystemObject::getObjectWithFix(unsigned tabSetId, const Chain& objectName, CegoObject::ObjectType type, CegoDecodableObject& oe, CegoBufferPage& bp)
{
    CegoObjectManager::getObjectWithFix(tabSetId, objectName, type, oe, bp);
}

void CegoSystemObject::getObjectList(unsigned tabSetId, CegoObject::ObjectType type, ListT<Chain>& objList)
{
    if ( type == CegoObject::SYSTEM )
    {
	objList.Insert(Chain(SYSTAB_TABLE_ID));
	objList.Insert(Chain(SYSTAB_PROC_ID));
	objList.Insert(Chain(SYSTAB_VIEW_ID));
	objList.Insert(Chain(SYSTAB_INDEX_ID));
	objList.Insert(Chain(SYSTAB_BTREE_ID));
	objList.Insert(Chain(SYSTAB_KEY_ID));
	CegoObjectManager::getObjectList(tabSetId, type, objList);
    }
    else
    {
	CegoObjectManager::getObjectList(tabSetId, type, objList);
    }
}
