#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-2019 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 objectExists(int tabSetId, const Chain& objectName, CegoObject::ObjectType type);
    void getObjectList(int tabSetId, CegoObject::ObjectType type, ListT<Chain>& objList);

    void setIgnoreInvalid(bool ignoreInvalid);
    void getObjectListByTable(int tabSetId, const Chain& tabName, 
			      ListT<CegoTableObject>& idxList,
			      ListT<CegoBTreeObject>& btreeList,
			      ListT<CegoKeyObject>& keyList,
			      ListT<CegoCheckObject>& checkList,
			      ListT<CegoTriggerObject>& triggerList,
			      ListT<CegoAliasObject>& aliasList,
			      int& numInvalid);

    void getObject(int tabSetId, const Chain& objectName, CegoObject::ObjectType type, CegoDecodableObject& oe);
    void getObjectWithFix(int 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(int tabSetId, const Chain& objName, CegoObject::ObjectType type);
    void removeObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type);

    int traceObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type);

    void reorgObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type);

    void invalidateObject(int tabSetId, const Chain& objectName, CegoObject::ObjectType type);

    void alterTableObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type, CegoTableObject& objEntry);
    void alterBTreeObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type, CegoBTreeObject& objEntry);

    void alterProcObject(int tabSetId, const Chain& procName, CegoProcObject& procEntry);
    void alterViewObject(int tabSetId, const Chain& viewName, CegoViewObject& viewEntry);
    void alterKeyObject(int tabSetId, const Chain& keyName, CegoKeyObject& objEntry);
    void alterCheckObject(int tabSetId, const Chain& checkName, CegoCheckObject& checkEntry);
    void alterTriggerObject(int tabSetId, const Chain& triggerName, CegoTriggerObject& objEntry);
    
    CegoDataPointer insertData(CegoTableObject& oe, char* data, int dataSize, bool doAppend = false, bool allowWrite = false);

    CegoDataPointer insertData(const CegoDataPointer& sysEntry, CegoTableObject& oe, char* data, int dataSize, bool doAppend = false, bool allowWrite = false);
    void deleteData(CegoObject::ObjectType type, int tabSetId, const CegoDataPointer& dp);
    
    CegoObjectCursor* getObjectCursor(int tabSetId, const Chain& hashName, const Chain& objName, CegoObject::ObjectType type);
    
    void claimDataPtrUnlocked(int tabSetId, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len, CegoBufferPage& bp);
    void releaseDataPtrUnlocked(CegoBufferPage& bp, bool isDirty = true);

    void releaseAndClaimDataPtrUnlocked(CegoBufferPage& bp, bool isDirty, int tabSetId, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len, CegoBufferPage& nbp );
    
    int getPageCount(int tabSetId, const Chain& objName, CegoObject::ObjectType type);

    CegoDatabaseManager* getDBMng();
    CegoLockHandler* getLockHandler();

    void getNewFilePage(CegoBufferPage &bp, int tabSetId, CegoObject::ObjectType type, bool allowWrite = false, bool doAppend = false);

protected:

    CegoDatabaseManager *_pDBMng;
    CegoLockHandler *_pLockHandle;    

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

    void createObject(CegoObject& objEntry, PageIdType& pageId);

    void getHashPageId(const Chain& objName, const CegoObject::ObjectType objType, PageIdType& lowPageId, PageIdType& highPageId);

    void freeObjectPages(int tabSetId, PageIdType pageId);

    int countObjectPages(int tabSetId, PageIdType pageId);
    void removeEmptyPages(int tabSetId, PageIdType pageId, PageIdType& newPageId, PageIdType& newLastPageId);
    
    CegoDataPointer insertPageData(int tabSetId, CegoObject::ObjectType type, PageIdType pageId, char* data, int datasize, bool& isNewPage, bool allowWrite, bool doAppend);

    bool _ignoreInvalid;
    unsigned long _modId;
};

#endif
