#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-2010 Bjoern Lemke
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// INTERFACE MODULE
//
// Class: CegoObjectManager
// 
// Description: 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

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

// cego includes
#include "CegoField.h"
#include "CegoObject.h"
#include "CegoDecodableObject.h"
#include "CegoBTreeObject.h"
#include "CegoTableObject.h"
#include "CegoKeyObject.h"
#include "CegoCheckObject.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 getObjectListByTable(int tabSetId, const Chain& tabName, 
			      ListT<CegoTableObject>& idxList,
			      ListT<CegoBTreeObject>& btreeList,
			      ListT<CegoKeyObject>& keyList,
			      ListT<CegoCheckObject>& checkList, bool ignoreInvalid = true);

    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 truncateObject(int tabSetId, const Chain& objName, CegoObject::ObjectType type);
    void removeObject(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 alterKeyObject(int tabSetId, const Chain& keyName, CegoObject::ObjectType type, CegoKeyObject& objEntry);
    void alterCheckObject(int tabSetId, const Chain& checkName, CegoObject::ObjectType type, CegoCheckObject& objEntry);

    void alterProcObject(int tabSetId, const Chain& procName, CegoProcObject& procEntry);
    void alterViewObject(int tabSetId, const Chain& viewName, CegoViewObject& viewEntry);
    void alterCheckObject(int tabSetId, const Chain& checkName, CegoCheckObject& checkEntry);

    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);
    
    unsigned long claimDataPtr(int tabSetId, CegoLockHandler::LockMode lockMode, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len);
    void releaseDataPtr(unsigned long lockId, bool isDirty = true);

    unsigned long releaseAndClaimDataPtr(unsigned long lockId, bool isDirty, int tabSetId, CegoLockHandler::LockMode lockMode, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len);

    CegoBufferPage claimDataPtrUnlocked(int tabSetId, CegoBufferPool::FixMode fixMode, const CegoDataPointer& dp, char*& ptr, int& len);
    void releaseDataPtrUnlocked(CegoBufferPage& bp, bool isDirty = true);

    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;    
    
private:

    void createObject(CegoObject& objEntry, int& fileId, int& pageId);
    
    void freeObjectPages(int tabSetId, int fileId, int pageId);
    int countObjectPages(int tabSetId, int fileId, int pageId);
    void removeEmptyPages(int tabSetId, int fileId, int pageId, int& newFileId, int& newPageId, int& newLastFileId, int& newLastPageId);
    
    CegoDataPointer insertPageData(int tabSetId, CegoObject::ObjectType type, int fileId, int pageId, char* data, int datasize, bool& isNewPage, bool allowWrite, bool doAppend);

    unsigned long _modId;
};

#endif




