#ifndef _CEGOOBJECTMANAGER_H_INCLUDED_
#define _CEGOOBJECTMANAGER_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoObjectManager.h
// -------------------
// Cego database object manager class definition
//     
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoObjectManager
// 
// Description: Basic database object handling
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfcbase/Chain.h>
#include <lfcbase/ListT.h>

// cego includes
#include "CegoDefs.h"
#include "CegoField.h"
#include "CegoObject.h"
#include "CegoDecodableObject.h"
#include "CegoBTreeObject.h"
#include "CegoTableObject.h"
#include "CegoKeyObject.h"
#include "CegoCheckObject.h"
#include "CegoTriggerObject.h"
#include "CegoAliasObject.h"
#include "CegoAliasObject.h"
#include "CegoViewObject.h"
#include "CegoProcObject.h"
#include "CegoDataPointer.h"
#include "CegoDatabaseManager.h"
#include "CegoObjectCursor.h"
#include "CegoLockHandler.h"

class CegoObjectCursor;

class CegoObjectManager {
    
public:
    
    CegoObjectManager(CegoDatabaseManager *pDBMng);
    ~CegoObjectManager();

    bool tableObjectExists(unsigned tabSetId, const Chain& objectName);
    bool objectExists(unsigned tabSetId, const Chain& objectName, CegoObject::ObjectType type);
    void getObjectList(unsigned tabSetId, CegoObject::ObjectType type, ListT<Chain>& objList);
    void setIgnoreInvalid(bool ignoreInvalid);
    void getObjectListByTable(unsigned tabSetId, const Chain& tabName, 
			      ListT<CegoTableObject>& idxList,
			      ListT<CegoBTreeObject>& btreeList,
			      ListT<CegoKeyObject>& keyList,
			      ListT<CegoCheckObject>& checkList,
			      ListT<CegoTriggerObject>& triggerList,
			      ListT<CegoAliasObject>& aliasList,
			      unsigned& numInvalid);
    void getObject(unsigned tabSetId, const Chain& objectName, CegoObject::ObjectType type, CegoDecodableObject& oe);
    void getObjectWithFix(unsigned tabSetId, const Chain& objectName, CegoObject::ObjectType type, CegoDecodableObject& oe, CegoBufferPage &bp);
    void createBTreeObject(CegoBTreeObject& btreeObject);
    void createTableObject(CegoTableObject& tableObject);
    void createKeyObject(CegoKeyObject& keyObject);
    void createCheckObject(CegoCheckObject& checkObject);
    void createViewObject(CegoViewObject& viewObject);
    void createProcObject(CegoProcObject& procObject);
    void createTriggerObject(CegoTriggerObject& triggerObject);
    void createAliasObject(CegoAliasObject& aliasObject);
    void truncateObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type);
    void removeObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type);
    unsigned traceObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type);
    void reorgObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type);
    void invalidateObject(unsigned tabSetId, const Chain& objectName, CegoObject::ObjectType type);
    void alterTableObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type, CegoTableObject& objEntry);
    void alterBTreeObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type, CegoBTreeObject& objEntry);
    void alterKeyObject(unsigned tabSetId, const Chain& keyName, CegoKeyObject& objEntry);
    void alterCheckObject(unsigned tabSetId, const Chain& checkName, CegoCheckObject& checkEntry);
    void alterTriggerObject(unsigned tabSetId, const Chain& triggerName, CegoTriggerObject& objEntry);
    CegoDataPointer insertData(CegoTableObject& oe, char* data, unsigned dataSize, bool doAppend = false, bool allowWrite = false);
    CegoDataPointer insertData(const CegoDataPointer& sysEntry, CegoTableObject& oe, char* data, unsigned dataSize, bool doAppend = false, bool allowWrite = false);
    void deleteData(CegoObject::ObjectType type, unsigned tabSetId, const CegoDataPointer& dp);
    CegoObjectCursor* getObjectCursor(unsigned tabSetId, const Chain& hashName, const Chain& objName, CegoObject::ObjectType type);
    void claimDataPtrUnlocked(unsigned tabSetId, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, unsigned& len, CegoBufferPage& bp);
    void releaseDataPtrUnlocked(CegoBufferPage& bp, bool isDirty = true);
    void releaseAndClaimDataPtrUnlocked(CegoBufferPage& bp, bool isDirty, unsigned tabSetId, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, unsigned& len, CegoBufferPage& nbp );
    unsigned getPageCount(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type);
    CegoDatabaseManager* getDBMng();
    CegoLockHandler* getLockHandler();
    void getNewFilePage(CegoBufferPage &bp, unsigned tabSetId, CegoObject::ObjectType type, bool allowWrite = false, bool doAppend = false);

protected:

    CegoDatabaseManager *_pDBMng;
    CegoLockHandler *_pLockHandle;    

    unsigned traceObjectPages(unsigned tabSetId, PageIdType pageId);
    
private:

    void createObject(const CegoDecodableObject& obj, PageIdType& pageId);
    void alterObject(unsigned tabSetId, const Chain& objName, CegoObject::ObjectType type, CegoDecodableObject& obj);
    void getHashPageId(const Chain& objName, const CegoObject::ObjectType objType, PageIdType& lowPageId, PageIdType& highPageId);
    void freeObjectPages(unsigned tabSetId, PageIdType pageId);
    unsigned countObjectPages(unsigned tabSetId, PageIdType pageId);
    void removeEmptyPages(unsigned tabSetId, PageIdType pageId, PageIdType& newPageId, PageIdType& newLastPageId);
    CegoDataPointer insertPageData(unsigned tabSetId, CegoObject::ObjectType type, PageIdType pageId, char* data, unsigned datasize, bool& isNewPage, bool allowWrite, bool doAppend);

    bool _ignoreInvalid;
    unsigned long _modId;
};
#endif
