#ifndef _CEGORECOVERYMANAGER_H_INCLUDED_
#define _CEGORECOVERYMANAGER_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoRecoveryManager.h
// ---------------------
// Cego recovery 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: CegoRecoveryManager
// 
// Description: 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

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

// xml includes
#include <lfc/XMLOutStream.h>

// cego includes
#include "CegoDataType.h"
#include "CegoTupleState.h"
#include "CegoField.h"
#include "CegoPredDesc.h"
#include "CegoQueryHelper.h"
#include "CegoLockHandler.h"
#include "CegoTransactionManager.h"
#include "CegoAlterDesc.h"
#include "CegoDefs.h"
#include "CegoProcedure.h"
#include "CegoView.h"
#include "CegoDistManager.h"

class CegoRecoveryManager {

public:

    enum RecoveryMode { LOCAL, REMOTE }; 
    enum RecoveryState { RECPITREACHED, RECINCOMPLETE, RECOK };

    CegoRecoveryManager(CegoDistManager *pTabMng, RecoveryMode mode);
    ~CegoRecoveryManager();

    long recoverTableSet(const Chain& tableSet, int pit);
    RecoveryState recoverCurrentTransactionLog(int tabSetId, int pit, long& lsn, int& ts);

private:

    class DeleteRecord {

    public:

	DeleteRecord() 
	{
	    _tid = 0; 
	    _pPred = 0;	    
	};
	DeleteRecord(int tid) 
	{ 
	    _tid = tid; 
	    _pPred = 0;
	};
	DeleteRecord(
	    int tid,
	    const Chain& table,
	    CegoPredDesc* pPred) 
	{ 
	    _tid = tid;
	    _table = table;
	    _pPred = pPred;
	};

	~DeleteRecord() 
	{
	};

	void clean()
	{
	    if ( _pPred )
		delete _pPred;
	}

	
	int getTid() { return _tid; };
	const Chain& getTable() { return _table; };
	CegoPredDesc* getPred() { return _pPred; };

	DeleteRecord& operator = ( const DeleteRecord& dr) { 
	    _tid = dr._tid;
	    _table = dr._table;
	    _pPred = dr._pPred;
	    return *this;
	};
	
	bool operator == ( const DeleteRecord& dr) {
	    return ( dr._tid == _tid );
	};
	
    private:
	int _tid;
	Chain _table;
	CegoPredDesc* _pPred;
    };

    class UpdateRecord {

    public:

	UpdateRecord() 
	{ 
	    _tid=0;
	    _pPred=0;
	};
	UpdateRecord(int tid) 
	{ 
	    _tid = tid;
	    _pPred=0;
	};
	UpdateRecord(
	    int tid,
	    const Chain& table,
	    CegoPredDesc* pPred,
	    const ListT<CegoField>& updList,
	    const ListT<CegoExpr*>& exprList ) 
	{ 
	    _tid = tid;
	    _table = table;
	    _pPred = pPred;
	    _updList = updList;
	    _exprList = exprList;
	};

	~UpdateRecord() 
	{
	};
	
	int getTid() { return _tid; };
	const Chain& getTable() { return _table; };
	CegoPredDesc* getPred() { return _pPred; };
	ListT<CegoField>& getUpdateList() { return _updList; };
	ListT<CegoExpr*>& getExprList() { return _exprList; };

	void clean()
	{
	    if ( _pPred )
		delete _pPred;
	    CegoExpr **pExpr = _exprList.First();
	    while ( pExpr )
	    {	       
		delete *pExpr;
		pExpr = _exprList.Next();
	    } 	    
	}

	UpdateRecord& operator = ( const UpdateRecord& ur) { 
	    _tid = ur._tid;
	    _table = ur._table;
	    _pPred = ur._pPred;
	    _updList = ur._updList;
	    _exprList = ur._exprList;
	    return *this;
	};
	
	bool operator == ( const UpdateRecord& ur) {
	    return ( ur._tid == _tid );
	};
	
    private:
	int _tid;
	Chain _table;
	CegoPredDesc* _pPred;
	ListT<CegoField> _updList;
	ListT<CegoExpr*> _exprList;
    };


    ListT<DeleteRecord> _delRecList;
    ListT<UpdateRecord> _updRecList;

    long dataFileRecovery(const Chain& tableSet, int tabSetId, long lsn);
    long transactionRecovery(const Chain& tableSet, int tabSetId, long cplsn, int pit);

    int recoverCurrentDataFileLog(int tabSetId, bool& endOfBackup);


    bool archiveComplete(const Chain& tableSet);

    Logger* _pLogger;
    CegoDistManager* _pGTM;
    CegoDatabaseManager* _pDBMng;
    
    Chain _shellCmd;

    RecoveryMode _recoveryMode;
    unsigned long _modId;
};

#endif




