///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAdminThread.cc  
// ------------------                                                     
// Cego admin thread class implementation
//                                                         
// Design and Implementation by Bjoern Lemke
//               
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoAdminThread
// 
// Description: Handling all database admin requests
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// LFC INCLUDES
#include <lfcbase/Exception.h>
#include <lfcbase/Host.h>
#include <lfcbase/Datetime.h>
#include <lfcbase/AESCrypt.h>
#include <lfcbase/Sleeper.h>
#include <lfcbase/Net.h>
#include <lfcbase/ThreadLock.h>
#include <lfcbase/CommandExecuter.h>
#include <lfcbase/Directory.h>

// CEGO INCLUDES
#include "CegoXMLdef.h"
#include "CegoAdminThread.h"
#include "CegoAdminThreadPool.h"
#include "CegoXPorter.h"
#include "CegoRecoveryManager.h"
#include "CegoBufferPoolEntry.h"

// POSIX INCLUDES
#include <stdlib.h>
#include <string.h>

extern char __caseSensitiveFlag;
extern char __quoteEscapeFlag;
extern char __allowDuplicateNull;

extern char __currencySymbol;
extern char __decimalPoint;

extern Chain __dateTimeFormat;
extern ListT<Chain> __dateFormatList;
extern ThreadLock __dateFormatLock;

CegoAdminThread::CegoAdminThread() : Thread()
{
}

CegoAdminThread::CegoAdminThread(CegoAdminThreadPool *pPool, CegoDatabaseManager *pDBMng, CegoDbThreadPool *pDbPool) : Thread()
{
    _pDBMng = pDBMng;
    _pPool = pPool;
    _pTabMng = new CegoQueryManager(pDBMng);

    // not auth for admin, required for tableset recovery to access all objects
    _pTabMng->disableAuth();
    
    _pDbPool = pDbPool;

    _modId = _pDBMng->getModId("CegoAdminThread");
}

CegoAdminThread::~CegoAdminThread()  
{
}

const Chain& CegoAdminThread::lastAction() const
{
    return _lastAction;
}

void* CegoAdminThread::job(void* arg)
{	
    _idx = *(unsigned long long*)arg;

    _pTim = new NanoTimer();
    
    _pPool->setTid(_idx, getTid());
    _pTabMng->setThreadId(getTid());

    unsigned queueDelay = _pDBMng->getQueueDelay();
	
    while ( ! _pPool->isTerminated() )
    {	
	try
	{
	    _pTim->reset();
	    _pTim->start();

	    _pRequest = _pPool->nextRequest();
	    
	    if ( _pRequest ) 
	    {
#ifdef CGDEBUG
		_pDBMng->log(_modId, Logger::DEBUG, Chain("Thread ") + Chain(_idx) + Chain(": serving service request"));
#endif
		_pPool->setState(_idx, CegoAdminThreadPool::CONNECTED);
	
		_pDBMng->increaseActiveAdmThread();			

		CegoAdminHandler* pAH = 0;
		try
		{
		    pAH = new CegoAdminHandler(_pDBMng, _pRequest);
		    serveSession(pAH);
		    delete pAH;
		}
		catch ( Exception e)
		{	
		    if ( pAH )
			delete pAH;

		    Chain msg;
		    Chain module;
		    unsigned line;
		    
		    Chain exep;
		    while ( e.pop(module, line, msg) )
		    {
			exep += Chain("\n\t") + module + Chain("(") +  Chain(line) + Chain(") : ") + msg;
		    }

		    _pDBMng->log(_modId, Logger::LOGERR, Chain("Thread ") + Chain(_idx) + Chain(": Admin session aborted : ") + exep);

		}
		_pDBMng->decreaseActiveAdmThread();
#ifdef CGDEBUG
		_pDBMng->log(_modId, Logger::DEBUG, Chain("Thread ") + Chain(_idx) + Chain(": service request finished"));
#endif

		_pPool->setState(_idx, CegoAdminThreadPool::READY);

		delete _pRequest;	
	    }
	    else
	    {		
		// _pDBMng->log(_modId, Logger::NOTICE, Chain("Thread ") + Chain(_idx) + Chain(": Waiting for request" ));
		Sleeper s;
		s.microSleep(queueDelay);
	    }

	    Chain tableSet;

	    // check for asynchronous recovery requests
	    bool doRecovery = _pDBMng->nextRecovery(tableSet);
	    if ( doRecovery )
	    {
		_pPool->setState(_idx, CegoAdminThreadPool::BUSY);
		
		try 
		{
		    _pDBMng->increaseActiveAdmThread();

		    _pDBMng->log(_modId, Logger::NOTICE, Chain("Thread ") + Chain(_idx) + Chain(": Tableset recovery started for tableset " ) + tableSet);
		    CegoRecoveryManager recoveryMng(_pTabMng);
		    unsigned long long lsn = recoveryMng.startRecovery(tableSet);

		    _pDBMng->log(_modId, Logger::NOTICE, Chain("Thread ") + Chain(_idx) + Chain(": Tableset " ) + tableSet + Chain(" recovered to lsn ") + Chain(lsn));
		    
		    _pDBMng->decreaseActiveAdmThread();
		    _pPool->setState(_idx, CegoAdminThreadPool::READY);
		}
		catch ( Exception e)
		{
		    Chain msg;
		    e.pop(msg);
		    _pDBMng->log(_modId, Logger::LOGERR, Chain("Thread ") + Chain(_idx) + Chain(": ") + msg);
		}
		_pPool->setState(_idx, CegoAdminThreadPool::READY);
	    }
	    
	    _pTim->stop();
	    _pPool->addThreadIdle(_idx, _pTim->getSum());
	}
	catch ( Exception e)
	{
	    Chain msg;
	    e.pop(msg);
	    _pDBMng->log(_modId, Logger::LOGERR, Chain("Thread ") + Chain(_idx) + Chain(": ") + msg );
	}
    }

    delete _pTim;
    
    // _pDBMng->log(_modId, Logger::NOTICE, Chain("Thread ") + Chain(_idx) + Chain(": Terminated" ));
    return 0;
}

void CegoAdminThread::serveSession(CegoAdminHandler *pAH)
{   
#ifdef CGDEBUG
    _pDBMng->log(_modId, Logger::DEBUG, Chain("Thread ") + Chain(_idx) + Chain(": serving session"));
#endif
    
    if ( pAH->acceptSession() )
    {
	bool isTraceOn;
	if ( _pDBMng->checkAdminUser(pAH->getUser(), pAH->getPassword(), isTraceOn) == false )
	{
	    Chain msg = Chain("Invalid user or password");
	    pAH->sendError(msg);
	    return;
	}
	else
	{
	    Chain msg = Chain("Access granted");
	    pAH->sendResponse(msg);
	}

	_user = pAH->getUser();
	_password = pAH->getPassword();

	bool isTerminated = false;
	
	while ( isTerminated == false && _pPool->isTerminated() == false)
	{	    
	    CegoAdminHandler::RequestType reqType;
	    reqType = pAH->acceptRequest();

	    _pTim->stop();
	    _pPool->addThreadIdle(_idx, _pTim->getSum());
	    _pTim->reset();
	    _pTim->start();
   
	    if ( reqType != CegoAdminHandler::REQTIMEOUT )
	    {
		if ( isTraceOn )
		{
		    _pDBMng->incUserQuery(pAH->getUser());
		}
		_pPool->incNumRequest(_idx);
		
		_pPool->setState(_idx, CegoAdminThreadPool::BUSY);
		
		_pTim->stop();
		_pPool->addThreadIdle(_idx, _pTim->getSum());

		isTerminated = serveRequest(pAH, reqType);

		_pTim->reset();
		_pTim->start();
		
		_pPool->setState(_idx, CegoAdminThreadPool::CONNECTED);
	    }
	    else
	    {
#ifdef CGDEBUG
		_pDBMng->log(_modId, Logger::DEBUG, Chain("Thread ") + Chain(_idx) + Chain(": admin client request timeout occured, waitung ..."));
#endif
	    }
	}
    }
}

bool CegoAdminThread::serveRequest(CegoAdminHandler *pAH, CegoAdminHandler::RequestType reqType)
{
    bool isTerminated = false;

    try
    {	
	switch ( reqType ) 
	{		    
	case CegoAdminHandler::GET_TABLESETLIST:
	{
	    srvGetTableSetList(pAH);
	    break;
	}	
	case CegoAdminHandler::LOCKINFO:
	{
	    srvLockInfo(pAH);
	    break;
	}
	case CegoAdminHandler::LOCKSTAT:
	{
	    srvLockStat(pAH);
	    break;
	}
	case CegoAdminHandler::VERIFYLOCKS:
	{
	    srvVerifyLocks(pAH);
	    break;
	}
	case CegoAdminHandler::PARAMETERINFO:
	{
	    srvParameterInfo(pAH);
	    break;
	}
	case CegoAdminHandler::POOLINFO:
	{
	    srvPoolInfo(pAH);
	    break;
	}
	case CegoAdminHandler::POOLENTRYLIST:
	{
	    srvPoolEntryList(pAH);
	    break;
	}
	case CegoAdminHandler::THREADINFO:
	{
	    srvThreadInfo(pAH);
	    break;
	}
	case CegoAdminHandler::DBTHREADINFO:
	{
	    srvDbThreadInfo(pAH);
	    break;
	}
	case CegoAdminHandler::DBTHREADHIST:
	{
	    srvDbThreadHistory(pAH);
	    break;
	}
	case CegoAdminHandler::QUERYHISTLAST:
	{
	    srvQueryHistoryLast(pAH);
	    break;
	}
	case CegoAdminHandler::QUERYHISTCOST:
	{
	    srvQueryHistoryCost(pAH);
	    break;
	}
	case CegoAdminHandler::SET_NUMQUERYLAST:
	{
	    srvNumQueryLast(pAH);
	    break;
	}
	case CegoAdminHandler::SET_NUMQUERYCOST:
	{
	    srvNumQueryCost(pAH);
	    break;
	}
	case CegoAdminHandler::ADMTHREADINFO:
	{
	    srvAdmThreadInfo(pAH);
	    break;
	}
	case CegoAdminHandler::DBTHREADABORT:
	{
	    srvDbThreadAbort(pAH);
	    break;
	}
	case CegoAdminHandler::SHOWQUERYCACHE:
	{
	    srvShowQueryCache(pAH);
	    break;
	}
	case CegoAdminHandler::LISTQUERYCACHE:
	{
	    srvListQueryCache(pAH);
	    break;
	}
	case CegoAdminHandler::CLEANQUERYCACHE:
	{
	    srvCleanQueryCache(pAH);
	    break;
	}
	case CegoAdminHandler::SETQUERYCACHEPARAM:
	{
	    srvSetQueryCacheParam(pAH);
	    break;
	}
	case CegoAdminHandler::SHOWTABLECACHE:
	{
	    srvShowTableCache(pAH);
	    break;
	}
	case CegoAdminHandler::LISTTABLECACHE:
	{
	    srvListTableCache(pAH);
	    break;
	}
	case CegoAdminHandler::CLEANTABLECACHE:
	{
	    srvCleanTableCache(pAH);
	    break;
	}
	case CegoAdminHandler::SETTABLECACHEPARAM:
	{
	    srvSetTableCacheParam(pAH);
	    break;
	}
	case CegoAdminHandler::DEFINE_TABLESET:
	{
	    srvDefineTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::REMOVE_TABLESET:
	{
	    srvRemoveTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::RESET_TABLESET:
	{
	    srvResetTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::CREATE_TABLESET:
	{
	    srvCreateTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::DROP_TABLESET:
	{
	    srvDropTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::START_TABLESET:
	{
	    srvStartTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::STOP_TABLESET:
	{
	    srvStopTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::START_RECOVERY:
	{
	    srvStartRecovery(pAH);	      	
	    break;
	}
	case CegoAdminHandler::STOP_RECOVERY:
	{
	    srvStopRecovery(pAH);
	    break;
	}
	case CegoAdminHandler::GET_TSINFO:
	{		
	    srvGetTSInfo(pAH);
	    break;
	}
	case CegoAdminHandler::GET_DETAILED_TSINFO:
	{		
	    srvGetDetailedTSInfo(pAH);
	    break;
	}
	case CegoAdminHandler::GET_ARCHLOG_INFO:
	{		
	    srvGetArchLogInfo(pAH);
	    break;
	}
	case CegoAdminHandler::GET_TRANSACTION_INFO:
	{		
	    srvGetTransactionInfo(pAH);
	    break;
	}
	case CegoAdminHandler::GET_BUSTAT:
	{		
	    srvGetBUStatInfo(pAH);
	    break;
	}
	case CegoAdminHandler::SET_LSN:
	{
	    srvSetLSN(pAH);
	    break;
	}
	case CegoAdminHandler::EXPORT_TABLESET:
	{
	    srvExportTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::IMPORT_TABLESET:
	{
	    srvImportTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::EXPORT_TABLE:
	{
	    srvExportTable(pAH);
	    break;
	}
	case CegoAdminHandler::IMPORT_TABLE:
	{
	    srvImportTable(pAH);
	    break;
	}
	case CegoAdminHandler::ADD_DATAFILE:
	{
	    srvAddDatafile(pAH);
	    break;
	}
	case CegoAdminHandler::SHOW_USER:
	{
	    srvUserInfo(pAH);
	    break;
	}	    
	case CegoAdminHandler::ADD_USER:
	{
	    srvAddUser(pAH);
	    break;
	}
	case CegoAdminHandler::REMOVE_USER:
	{
	    srvRemoveUser(pAH);
	    break;
	}
	case CegoAdminHandler::CHANGE_PWD:
	{
	    srvChangePwd(pAH);
	    break;
	}
	case CegoAdminHandler::LIST_ROLE:
	{
	    srvListRole(pAH);
	    break;
	}
	case CegoAdminHandler::SHOW_ROLE:
	{
	    srvShowRole(pAH);
	    break;
	}
	case CegoAdminHandler::CREATE_ROLE:
	{
	    srvCreateRole(pAH);
	    break;
	}
	case CegoAdminHandler::DROP_ROLE:
	{
	    srvDropRole(pAH);
	    break;
	}
	case CegoAdminHandler::ASSIGN_ROLE:
	{
	    srvAssignRole(pAH);
	    break;
	}
	case CegoAdminHandler::REMOVE_ROLE:
	{
	    srvRemoveRole(pAH);
	    break;
	}
	case CegoAdminHandler::SET_PERM:
	{
	    srvSetPerm(pAH);
	    break;
	}
	case CegoAdminHandler::REMOVE_PERM:
	{
	    srvRemovePerm(pAH);
	    break;
	}
	case CegoAdminHandler::USER_TRACE:
	{
	    srvUserTrace(pAH);
	    break;
	}
	case CegoAdminHandler::SYNC_TABLESET:
	{
	    srvSyncTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::INIT_LOGS:
	{
	    srvInitLogs(pAH);
	    break;
	}
	case CegoAdminHandler::ADD_ARCHLOG:
	{
	    srvAddArchLog(pAH);
	    break;
	}
	case CegoAdminHandler::REMOVE_ARCHLOG:
	{
	    srvRemoveArchLog(pAH);
	    break;
	}
	case CegoAdminHandler::BEGIN_BACKUP:
	{
	    srvBeginBackup(pAH);
	    break;
	}
	case CegoAdminHandler::EXECUTE_BACKUP:
	{
	    srvExecuteBackup(pAH);
	    break;
	}
	case CegoAdminHandler::END_BACKUP:
	{
	    srvEndBackup(pAH);
	    break;
	}
	case CegoAdminHandler::LIST_BACKUP:
	{
	    srvListBackup(pAH);
	    break;
	}
	case CegoAdminHandler::RESTORE:
	{
	    srvRestore(pAH);
	    break;
	}
	case CegoAdminHandler::RECOVER:
	{
	    srvRecover(pAH);
	    break;
	}
	case CegoAdminHandler::VERIFY_TABLESET:
	{
	    srvVerifyTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::CORRECT_TABLESET:
	{
	    srvCorrectTableSet(pAH);
	    break;
	}
	case CegoAdminHandler::SET_LOGMNG:
	{
	    srvSetLogMng(pAH);
	    break;
	}
	case CegoAdminHandler::SET_BACKUPMNG:
	{
	    srvSetBackupMng(pAH);
	    break;
	}
	case CegoAdminHandler::SHOW_LOGMNG:
	{
	    srvShowLogMng(pAH);
	    break;
	}
	case CegoAdminHandler::SHOW_BACKUPMNG:
	{
	    srvShowBackupMng(pAH);
	    break;
	}
	case CegoAdminHandler::SET_CHECKPOINT:
	{
	    srvSetCheckpoint(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSINITFILE:
	{
	    srvSetTSInitFile(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSSYSSIZE:
	{
	    srvSetTSSysSize(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSTMPSIZE:
	{
	    srvSetTSTmpSize(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSAPPSIZE:
	{
	    srvSetTSAppSize(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSROOTPATH:
	{
	    srvSetTSRootPath(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSLOGNUM:
	{
	    srvSetTSLogNum(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSLOGSIZE:
	{
	    srvSetTSLogSize(pAH);
	    break;
	}
	case CegoAdminHandler::SET_TSSORTAREASIZE:
	{
	    srvSetTSSortAreaSize(pAH);
	    break;
	}
	case CegoAdminHandler::ENABLE_TABLECACHE:
	{
	    srvEnableTableCache(pAH);
	    break;
	}
	case CegoAdminHandler::DISABLE_TABLECACHE:
	{
	    srvDisableTableCache(pAH);
	    break;
	}
	case CegoAdminHandler::ENABLE_QUERYCACHE:
	{
	    srvEnableQueryCache(pAH);
	    break;
	}
	case CegoAdminHandler::DISABLE_QUERYCACHE:
	{
	    srvDisableQueryCache(pAH);
	    break;
	}
	case CegoAdminHandler::RESET_BUSTAT:
	{
	    srvResetBUStat(pAH);
	    break;
	}
	case CegoAdminHandler::ENABLE_ARCHLOG:
	{
	    srvEnableArchLog(pAH);
	    break;
	}
	case CegoAdminHandler::DISABLE_ARCHLOG:
	{
	    srvDisableArchLog(pAH);
	    break;
	}
	case CegoAdminHandler::ENABLE_APPENDMODE:
	{
	    srvEnableAppendMode(pAH);
	    break;
	}
	case CegoAdminHandler::DISABLE_APPENDMODE:
	{
	    srvDisableAppendMode(pAH);
	    break;
	}
	case CegoAdminHandler::SET_AUTOCORRECT:
	{
	    srvSetAutoCorrect(pAH);
	    break;
	}
	case CegoAdminHandler::SESSION_CLOSE:
	{
	    isTerminated=true;
	    
#ifdef CGDEBUG
	    _pDBMng->log(_modId, Logger::DEBUG, Chain(" Thread ") + Chain(_idx) + Chain(": terminating session"));
#endif
	    pAH->sendResponse(Chain("Session Closed"));	    
	    break;
	}
	case CegoAdminHandler::GET_OBJECT_INFO:
	case CegoAdminHandler::REQTIMEOUT:
	case CegoAdminHandler::UNKNOWN:
	{
	    pAH->sendError(Chain("Invalid request"));
	}    
	}
    }
    catch ( Exception e )
    {       
	Chain msg;
	Chain module;
	unsigned line;
			
	Chain exep;
	while ( e.pop(module, line, msg) )
	{
	    exep += Chain("\n\t") + module + Chain("(") +  Chain(line) + Chain(") : ") + msg;
	}
	
	_pDBMng->log(_modId, Logger::LOGERR, Chain("Admin Thread ") + Chain(_idx) + Chain(" : ") + exep);
	
	pAH->sendError(msg);
    }    
    return isTerminated;
}


void CegoAdminThread::srvLockInfo(CegoAdminHandler *pAH)
{
    try
    {
	Chain lockCat;
	pAH->getLockCat( lockCat );
	
	Element *pLockInfo = new Element(XML_LOCKINFO_ELEMENT);
	Element *pLockEntry;
	
	Chain lockName;
	unsigned lockCount;
	unsigned long long numRdLock;
	unsigned long long numWrLock;
	unsigned long long sumRdDelay;
	unsigned long long sumWrDelay;
	
	if ( lockCat == Chain(XML_LOCK_THREADPOOL_VALUE) )
	{
	    _pPool->getLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	    pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	    pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	    pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));    
	    pLockInfo->addContent(pLockEntry);
	    
	    pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	    _pDbPool->getLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	    pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	    pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	    pLockInfo->addContent(pLockEntry);    
	    	    
	    pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	    _pDBMng->getDBMLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	    pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	    pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	    pLockInfo->addContent(pLockEntry);    
	    
	    pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	    _pDBMng->getXMLLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	    pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	    pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	    pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	    pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	    pLockInfo->addContent(pLockEntry);
	}  
	else if ( lockCat == Chain(XML_LOCK_LOGMNG_VALUE) )
	{
	    ListT<Chain> tsList;
	    _pDBMng->getActiveTableSet( tsList, true, false);
	    
	    Chain *pTabSet = tsList.First();
	    while ( pTabSet )
	    {
		unsigned tabSetId = _pDBMng->getTabSetId(*pTabSet);
		
		pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
		_pDBMng->getLMLockStat(tabSetId, lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
		pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
		pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
		pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
		pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
		pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
		pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
		pLockInfo->addContent(pLockEntry);    
			
		pTabSet = tsList.Next();
	    }
	}
	else if ( lockCat == Chain(XML_LOCK_QUERYCACHE_VALUE) )
	{
	    ListT<Chain> tsList;
	    _pDBMng->getActiveTableSet(tsList, true, false);
	    
	    Chain *pTabSet = tsList.First();
	    while ( pTabSet )
	    {
		unsigned tabSetId = _pDBMng->getTabSetId(*pTabSet);
		
		if ( _pDBMng->getQCLockStat(tabSetId, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay) )
		{
		    pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
		    pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), *pTabSet);
		    pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
		    pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
		    pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
		    pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
		    pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
		    pLockInfo->addContent(pLockEntry);    
		}
		pTabSet = tsList.Next();
	    }
	}
	else if ( lockCat == Chain(XML_LOCK_TABLECACHE_VALUE) )
	{
	    ListT<Chain> tsList;
	    _pDBMng->getActiveTableSet(tsList, true, false);
	    
	    Chain *pTabSet = tsList.First();
	    while ( pTabSet )
	    {
		unsigned tabSetId = _pDBMng->getTabSetId(*pTabSet);

		if ( _pDBMng->getTCLockStat(tabSetId, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay) )
		{		
		    pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);		    
		    pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), *pTabSet);
		    pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
		    pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
		    pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
		    pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
		    pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
		    pLockInfo->addContent(pLockEntry);    
		}
		pTabSet = tsList.Next();
	    }
	}
	else 
	{
	    unsigned low = 0;
	    unsigned high = 0;
	    
	    if ( lockCat == Chain(XML_LOCK_REC_VALUE) )
	    {
		low = 0;
		high = _pDBMng->getNumRecordSema();
	    }
	    else if ( lockCat == Chain(XML_LOCK_RBREC_VALUE) )
	    {
		low = _pDBMng->getNumRecordSema();
		high = _pDBMng->getNumRecordSema() 
		    + _pDBMng->getNumRBRecordSema();
	    }
	    else if ( lockCat == Chain(XML_LOCK_SYSREC_VALUE) )
	    {
		low = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema();
		high = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema();
	    }
	    else if ( lockCat == Chain(XML_LOCK_SYSPAGE_VALUE) )
	    {
		low = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema();
		high = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema();
	    }
	    else if ( lockCat == Chain(XML_LOCK_DATAPAGE_VALUE) )
	    {
		low = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema();
		high = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema() 
		    + _pDBMng->getNumDataPageSema();
	    }
	    else if ( lockCat == Chain(XML_LOCK_IDXPAGE_VALUE) )
	    {
		low = _pDBMng->getNumRecordSema() 
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema()
		    + _pDBMng->getNumDataPageSema();
		high = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema()
		    + _pDBMng->getNumDataPageSema()
		    + _pDBMng->getNumIndexPageSema();
	    }
	    else if ( lockCat == Chain(XML_LOCK_RBPAGE_VALUE) )
	    {
		low = _pDBMng->getNumRecordSema() 
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema()
		    + _pDBMng->getNumDataPageSema()
		    + _pDBMng->getNumIndexPageSema();
		high = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema()
		    + _pDBMng->getNumDataPageSema()
		    + _pDBMng->getNumIndexPageSema()
		    + _pDBMng->getNumRBPageSema();		
	    }
	    else if ( lockCat == Chain(XML_LOCK_DATAFILE_VALUE) )
	    {		
		low = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema()
		    + _pDBMng->getNumDataPageSema()
		    + _pDBMng->getNumIndexPageSema()
		    + _pDBMng->getNumRBPageSema();
		high = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema()
		    + _pDBMng->getNumDataPageSema()
		    + _pDBMng->getNumIndexPageSema()
		    + _pDBMng->getNumRBPageSema() 
		    + _pDBMng->getNumDataFileSema();
	    }
	    else if ( lockCat == Chain(XML_LOCK_BUFFERPOOL_VALUE) )
	    {		
		low = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema() 
		    + _pDBMng->getNumDataPageSema()
		    + _pDBMng->getNumIndexPageSema()
		    + _pDBMng->getNumRBPageSema()
		    + _pDBMng->getNumDataFileSema();
		high = _pDBMng->getNumRecordSema()
		    + _pDBMng->getNumRBRecordSema()
		    + _pDBMng->getNumSysRecordSema()
		    + _pDBMng->getNumSysPageSema()
		    + _pDBMng->getNumDataPageSema() 
		    + _pDBMng->getNumIndexPageSema()
		    + _pDBMng->getNumRBPageSema() 
		    + _pDBMng->getNumDataFileSema() 
		    + _pDBMng->getNumBufferPoolSema();
	    }
	    else
	    {		
		throw Exception(EXLOC, "Unknown lock cat");
	    }
	    
	    unsigned semId;	    
	    for (  semId = low; semId < high; semId++ )
	    {
		pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
		_pTabMng->getLHLockStat(semId, lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
		pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
		pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
		pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
		pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
		pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
		pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
		pLockInfo->addContent(pLockEntry);    
	    }
	}
	
	_lastAction = Chain("LockInfo");
	pAH->sendResponse(Chain("LockInfo"), 
		      pLockInfo);
    }
    catch ( Exception e )
    {
	Chain msg;
	e.pop(msg);
	pAH->sendError(msg);	
    }
}

void CegoAdminThread::srvLockStat(CegoAdminHandler *pAH)
{
    try
    {	
	Element *pLockStat = new Element(XML_LOCKSTAT_ELEMENT);
	Element *pLockEntry;
	
	Chain lockGroup;
	Chain lockName;
	unsigned numLock;
	unsigned lockCount;
	unsigned long long numRdLock;
	unsigned long long numWrLock;
	unsigned long long sumRdDelay;
	unsigned long long sumWrDelay;
	
	_pPool->getLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	
	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(1));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));    
	pLockStat->addContent(pLockEntry);
	
	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	_pDbPool->getLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(1));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	_pDbPool->getAggThreadLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));	
	pLockStat->addContent(pLockEntry);    
	
	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	_pDBMng->getDBMLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(1));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    
	
	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	_pDBMng->getXMLLockStat(lockName, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockName);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(1));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	_pDBMng->getAggQCLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	_pDBMng->getAggTCLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);
	
	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	_pDBMng->getAggLMLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);
	
	lockGroup = Chain(RECLOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(RBRECLOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(SYSRECLOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(SYSPAGELOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(DATAPAGELOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(IDXPAGELOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(RBPAGELOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(DATAFILELOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    

	lockGroup = Chain(POOLLOCKGROUP);
	_pTabMng->getLHAggLockStat(lockGroup, numLock, lockCount, numRdLock, numWrLock, sumRdDelay, sumWrDelay);

	pLockEntry = new Element(XML_LOCKENTRY_ELEMENT);
	pLockEntry->setAttribute(Chain(XML_LOCKID_ATTR), lockGroup);
	pLockEntry->setAttribute(Chain(XML_NUMLOCK_ATTR), Chain(numLock));
	pLockEntry->setAttribute(Chain(XML_LOCKCOUNT_ATTR), Chain(lockCount));
	pLockEntry->setAttribute(Chain(XML_RDLOCKHIT_ATTR), Chain(numRdLock));
	pLockEntry->setAttribute(Chain(XML_RDLOCKDELAY_ATTR), Chain(sumRdDelay));
	pLockEntry->setAttribute(Chain(XML_WRLOCKHIT_ATTR), Chain(numWrLock));
	pLockEntry->setAttribute(Chain(XML_WRLOCKDELAY_ATTR), Chain(sumWrDelay));
	pLockStat->addContent(pLockEntry);    
	
	_lastAction = Chain("LockStat");
	pAH->sendResponse(Chain("LockStat"), 
			  pLockStat);
    }
    catch ( Exception e )
    {
	Chain msg;
	e.pop(msg);
	pAH->sendError(msg);	
    }
}


void CegoAdminThread::srvVerifyLocks(CegoAdminHandler *pAH)
{
    try
    {	
	_pPool->verifyLocks(pAH);
	_pDbPool->verifyLocks(pAH);	
	_pDBMng->verifyLocks(pAH);
	
	CegoLockHandler lockHandler(_pDBMng);    
	lockHandler.verifyLocks(pAH);

	pAH->sendResponse(Chain("Locks verified"));    
    }
    catch ( Exception e )
    {
	Chain msg;
	e.pop(msg);
	pAH->sendError(msg);	
    }
}



void CegoAdminThread::srvParameterInfo(CegoAdminHandler *pAH)
{
    _lastAction = Chain("ParameterInfo");
        
    // get several parameters here
    Chain dbName = _pDBMng->getDbName();
    unsigned pageSize = _pDBMng->getPageSize();
    unsigned queueDelay = _pDBMng->getQueueDelay();
    
    CegoDbHandler::ProtocolType protType = _pDBMng->getProtType();
    
    unsigned numRBRecordSema = _pDBMng->getNumRBRecordSema();
    unsigned numRecordSema = _pDBMng->getNumRecordSema();
    unsigned numSysRecordSema = _pDBMng->getNumSysRecordSema();
    unsigned numSysPageSema = _pDBMng->getNumSysPageSema();
    unsigned numDataPageSema = _pDBMng->getNumDataPageSema();
    unsigned numIndexPageSema = _pDBMng->getNumIndexPageSema();
    unsigned numRBPageSema = _pDBMng->getNumRBPageSema();
    unsigned numDataFileSema = _pDBMng->getNumDataFileSema();
    unsigned numBufferPoolSema = _pDBMng->getNumBufferPoolSema();
    unsigned maxFixTries = _pDBMng->getMaxFixTries();
    unsigned maxPageDelete = _pDBMng->getMaxPageDelete();

    unsigned pageLockTimeout = _pDBMng->getPageLockTimeout();
    unsigned recLockTimeout = _pDBMng->getRecLockTimeout();
    unsigned fileLockTimeout = _pDBMng->getFileLockTimeout();
    unsigned poolLockTimeout = _pDBMng->getPoolLockTimeout();
    unsigned numLockTries = _pDBMng->getNumLockTries();

    unsigned numQueryLast = _pDBMng->getNumQueryLast();
    unsigned numQueryCost = _pDBMng->getNumQueryCost();

    unsigned maxSendLen = _pDBMng->getMaxSendLen();
    
    Chain dateTimeFormat = __dateTimeFormat; // _pDBMng->getDateTimeFormat();
    Chain archRestoreProg = _pDBMng->getArchRestoreProg();    
    unsigned archRestoreTimeout = _pDBMng->getArchRestoreTimeout();    
    Chain backupProg = _pDBMng->getBackupProg();
    
    Element *pParameterList = new Element(XML_PARAMETERLIST_ELEMENT);

    Element *pParameterInfo;

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_DBNAME_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, dbName);
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_PROTOCOL_ATTR);
    if ( protType == CegoDbHandler::XML )	
	pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain("xml"));
    else if ( protType == CegoDbHandler::SERIAL )
	pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain("serial"));
    else if ( protType == CegoDbHandler::FASTSERIAL )
	pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain("fastserial"));
    
    pParameterList->addContent(pParameterInfo);
    
    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_PAGESIZE_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(pageSize));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_QUEUEDELAY_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(queueDelay));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMRECSEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numRecordSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMRBRECSEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numRBRecordSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMSYSRECSEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numSysRecordSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMSYSPAGESEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numSysPageSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMDATAPAGESEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numDataPageSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMIDXPAGESEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numIndexPageSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMRBPAGESEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numRBPageSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMDATAFILESEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numDataFileSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMBUFFERPOOLSEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numBufferPoolSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMBUFFERPOOLSEMA_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numDataFileSema));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_MAXFIXTRIES_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(maxFixTries));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_MAXPAGEDELETE_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(maxPageDelete));
    pParameterList->addContent(pParameterInfo);    

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_PAGELOCKTIMEOUT_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(pageLockTimeout));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_RECLOCKTIMEOUT_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(recLockTimeout));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_POOLLOCKTIMEOUT_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(poolLockTimeout));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_FILELOCKTIMEOUT_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(fileLockTimeout));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMLOCKTRIES_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numLockTries));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_MAXSENDLEN_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(maxSendLen));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_DATETIMEFORMAT_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(dateTimeFormat));
    pParameterList->addContent(pParameterInfo);

    Chain *pScanFormat = __dateFormatList.First();
    while ( pScanFormat )
    {
       pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
       pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_SCANDATETIMEFORMAT_ATTR);
       pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, *pScanFormat);
       pParameterList->addContent(pParameterInfo);
       pScanFormat = __dateFormatList.Next();
    }
    
    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_LOGMNGPROG_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(archRestoreProg));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_LOGMNGTIMEOUT_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(archRestoreTimeout));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_BACKUPMNGPROG_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(backupProg));
    pParameterList->addContent(pParameterInfo);

    Chain csMode = Chain(XML_ID_VALUE);
    if ( __caseSensitiveFlag == 1 )
        csMode = Chain(XML_STR_VALUE);
    else if ( __caseSensitiveFlag == 2 )
        csMode = Chain(XML_NONE_VALUE);
    
    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_CSMODE_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, csMode);
    pParameterList->addContent(pParameterInfo);

    Chain qescMode = Chain(XML_OFF_VALUE);
    if ( __quoteEscapeFlag )
    {
	qescMode = Chain(XML_ON_VALUE);
    }

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_QESCMODE_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, qescMode);
    pParameterList->addContent(pParameterInfo);

    Chain dupNull = Chain(XML_OFF_VALUE);
    if ( __allowDuplicateNull )
	dupNull = Chain(XML_ON_VALUE);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_DUPLICATENULL_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, dupNull);
    pParameterList->addContent(pParameterInfo);
    
    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_CURRENCYSYMBOL_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(__currencySymbol));
    pParameterList->addContent(pParameterInfo);
    
    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_DECIMALPOINT_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(__decimalPoint));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMQUERYLAST_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numQueryLast));
    pParameterList->addContent(pParameterInfo);

    pParameterInfo = new Element(XML_PARAMETERINFO_ELEMENT);
    pParameterInfo->setAttribute(XML_PARAMNAME_ATTR, XML_NUMQUERYCOST_ATTR);
    pParameterInfo->setAttribute(XML_PARAMVALUE_ATTR, Chain(numQueryCost));
    pParameterList->addContent(pParameterInfo);
	    
    pAH->sendResponse(Chain("ParameterInfo"), 
		      pParameterList);    
}

void CegoAdminThread::srvPoolInfo(CegoAdminHandler *pAH)
{
    _lastAction = Chain("PoolInfo");
    
    unsigned pageSize;
    unsigned long long numTotal;
    unsigned long long numUsed;
    unsigned long long numFree;
    unsigned long long numDirty;
    unsigned long long numFixes;
    unsigned long long numPersistent;
    unsigned long long numNoSync;
    unsigned long long numDiskRead;
    unsigned long long numDiskWrite;
    double hitRate;
    double spreadRate;
    unsigned long long readDelay;
    unsigned long long writeDelay;
    unsigned long long curFixCount;
    unsigned long long maxFixCount;
    unsigned long long avgFixTry;
    
    unsigned long long statStart;
    unsigned long long uptime;
    
    _pDBMng->poolInfo(pageSize, numTotal, numUsed, numFree, numDirty, numFixes, numPersistent, numNoSync, numDiskRead, numDiskWrite, hitRate, spreadRate, readDelay, writeDelay, curFixCount, maxFixCount, avgFixTry, statStart, uptime);
    
    Element *pPoolInfo = new Element(XML_POOLINFO_ELEMENT);
    
    // format hitrate
    Chain hrFormated = Chain(hitRate, "%3.2f") + Chain("%");
    Chain srFormated = Chain(spreadRate, "%3.3f");

    pPoolInfo->setAttribute(XML_PAGESIZE_ATTR, Chain(pageSize));
    pPoolInfo->setAttribute(XML_NUMTOTAL_ATTR, Chain(numTotal));
    pPoolInfo->setAttribute(XML_NUMUSED_ATTR, Chain(numUsed));
    pPoolInfo->setAttribute(XML_NUMFREE_ATTR, Chain(numFree));
    pPoolInfo->setAttribute(XML_NUMDIRTY_ATTR, Chain(numDirty));
    pPoolInfo->setAttribute(XML_NUMFIXES_ATTR, Chain(numFixes));
    pPoolInfo->setAttribute(XML_NUMPERSISTENT_ATTR, Chain(numPersistent));
    pPoolInfo->setAttribute(XML_NUMNOSYNC_ATTR, Chain(numNoSync));
    pPoolInfo->setAttribute(XML_NUMDISKREAD_ATTR, Chain(numDiskRead));
    pPoolInfo->setAttribute(XML_NUMDISKWRITE_ATTR, Chain(numDiskWrite));
    pPoolInfo->setAttribute(XML_BPHITRATE_ATTR, hrFormated);
    pPoolInfo->setAttribute(XML_SPREADRATE_ATTR, srFormated);
    pPoolInfo->setAttribute(XML_READDELAY_ATTR, Chain(readDelay));
    pPoolInfo->setAttribute(XML_WRITEDELAY_ATTR, Chain(writeDelay));
    pPoolInfo->setAttribute(XML_CURFIXCOUNT_ATTR, Chain(curFixCount));
    pPoolInfo->setAttribute(XML_MAXFIXCOUNT_ATTR, Chain(maxFixCount));
    pPoolInfo->setAttribute(XML_AVGFIXTRY_ATTR, Chain(avgFixTry));

    Datetime ts(statStart);
    pPoolInfo->setAttribute(XML_STATSTART_ATTR, ts.asChain(BUPMNG_STATDTFORMAT));

    pPoolInfo->setAttribute(XML_UPTIME_ATTR, Chain(uptime));
        
    pAH->sendResponse(Chain("PoolInfo"), 
		      pPoolInfo);    
}

void CegoAdminThread::srvPoolEntryList(CegoAdminHandler *pAH)
{
    _lastAction = Chain("PoolEntryList");
     
    ListT<CegoBufferPoolEntry> entryList;
    _pDBMng->getPoolEntryList(entryList);
    
    CegoBufferPoolEntry *pEntry = entryList.First();

    while ( pEntry )
    {
	Element *pPoolEntryList = new Element(XML_POOLENTRYLIST_ELEMENT);

	unsigned numEntry=0;
	while ( pEntry && numEntry < 20)
	{
	    Element *pEntryElement = new Element(XML_POOLENTRY_ELEMENT);

	    pEntryElement->setAttribute(XML_SEGMENT_ATTR, Chain(pEntry->getSegment()));
	    pEntryElement->setAttribute(XML_POS_ATTR, Chain(pEntry->getPos()));
	    pEntryElement->setAttribute(XML_OCCSTATE_ATTR, Chain(pEntry->getOccState()));
	    
	    if ( pEntry->isDirty() )
		pEntryElement->setAttribute(XML_ISDIRTY_ATTR, Chain("y"));
	    else
		pEntryElement->setAttribute(XML_ISDIRTY_ATTR, Chain("n"));
	    
	    pEntryElement->setAttribute(XML_NUMFIXES_ATTR, Chain(pEntry->getNumFixes()));
	    
	    pEntryElement->setAttribute(XML_TSID_ATTR, Chain(pEntry->getTabSetId()));
	    // pEntryElement->setAttribute(XML_FILEID_ATTR, Chain(pEntry->getFileId()));
	    pEntryElement->setAttribute(XML_PAGEID_ATTR, Chain(pEntry->getPageId()));
	    pEntryElement->setAttribute(XML_FIXSTAT_ATTR, Chain(pEntry->getFixStat()));
	    pEntryElement->setAttribute(XML_NUMUSAGE_ATTR, Chain(pEntry->getNumUsage()));
	    
	    pPoolEntryList->addContent(pEntryElement);
	    pEntry = entryList.Next();
	    numEntry++;
	}
	if ( pAH->syncWithInfo(Chain("PoolEntryList"), pPoolEntryList) == false )
	    return;
    }
    pAH->sendResponse(Chain("PoolEntryList"));    
}

void CegoAdminThread::srvThreadInfo(CegoAdminHandler *pAH)
{
    _lastAction = Chain("ThreadInfo");
		    
    unsigned numDbThread;
    unsigned numAdmThread;
    unsigned numLogThread;
    unsigned actDbThread;
    unsigned actAdmThread;
       
    _pDBMng->getThreadInfo(numDbThread, numAdmThread, numLogThread, actDbThread, actAdmThread);
    
    Element *pDbInfo = new Element(XML_THREADINFO_ELEMENT);	
    
    pDbInfo->setAttribute(XML_NUMDBTHREAD_ATTR, Chain(numDbThread));
    pDbInfo->setAttribute(XML_NUMADMTHREAD_ATTR, Chain(numAdmThread));
    
    pDbInfo->setAttribute(XML_ACTIVEDBTHREAD_ATTR, Chain(actDbThread));
    pDbInfo->setAttribute(XML_ACTIVEADMTHREAD_ATTR, Chain(actAdmThread));

    
    pAH->sendResponse(Chain("ThreadInfo"), 
		      pDbInfo);    
}

void CegoAdminThread::srvDbThreadInfo(CegoAdminHandler *pAH)
{
    _lastAction = Chain("DBThreadInfo");
        
    unsigned poolLimit = _pDbPool->getPoolLimit();
    
    Element *pThreadInfo = new Element(XML_THREADINFO_ELEMENT);
    
    for ( unsigned i = 0 ; i < poolLimit ; i++ )
    {
	CegoDbThreadPool::ThreadState state;
	unsigned long long numRequest;
	unsigned long long numQueryRequest;
	unsigned long long threadLoad;
	unsigned long long allocatedSortArea;
	Chain lastAction;
	_pDbPool->getThreadInfo(i, numRequest, numQueryRequest, threadLoad, allocatedSortArea, state, lastAction);
	
	Element *pN = new Element(XML_THREAD_ELEMENT);
	pN->setAttribute(XML_THID_ATTR, Chain(i));	
	pN->setAttribute(XML_NUMREQUEST_ATTR, Chain(numRequest));
	pN->setAttribute(XML_NUMQUERYREQUEST_ATTR, Chain(numQueryRequest));
	pN->setAttribute(XML_THREADLOAD_ATTR, Chain(threadLoad));
	pN->setAttribute(XML_ALLOCATEDSORT_ATTR, Chain(allocatedSortArea));
	pN->setAttribute(XML_LASTACTION_ATTR, lastAction);
	
	if ( state == CegoDbThreadPool::READY )
	    pN->setAttribute(XML_STATUS_ATTR, XML_READY_VALUE);
	else if ( state == CegoDbThreadPool::CONNECTED )
	    pN->setAttribute(XML_STATUS_ATTR, XML_CONNECTED_VALUE);
	else if ( state == CegoDbThreadPool::BUSY )
	    pN->setAttribute(XML_STATUS_ATTR, XML_BUSY_VALUE);
	
	pThreadInfo->addContent(pN);
    }
    
    pAH->sendResponse(Chain("DBThreadinfo"), 
		      pThreadInfo);
}

void CegoAdminThread::srvDbThreadHistory(CegoAdminHandler *pAH)
{
    _lastAction = Chain("DBThreadHistory");

    unsigned threadId;
    pAH->getThreadId(threadId);

    ListT<CegoDbThread::QueryEntry> queryHistory;
    _pDbPool->getThreadHistory(threadId, queryHistory);

    Element *pQueryHist = new Element(XML_QUERYHIST_ELEMENT);

    CegoDbThread::QueryEntry *pQE = queryHistory.First();
    while ( pQE )
    {
	Element *pElem = new Element(XML_QUERY_ELEMENT);

	Datetime ts(pQE->getTimestamp());

	pElem->setAttribute(XML_THRIDX_ATTR, Chain(pQE->getIndex()));
	pElem->setAttribute(XML_TIMESTAMP_ATTR, ts.asChain());
	pElem->setAttribute(XML_QUERY_ATTR, pQE->getQuery());
	pElem->setAttribute(XML_COST_ATTR, Chain(pQE->getCost()));

	pQueryHist->addContent(pElem);
	
	pQE = queryHistory.Next();	
    }    
    pAH->sendResponse(Chain("DBThreadHist"), 
		      pQueryHist);
}

void CegoAdminThread::srvQueryHistoryLast(CegoAdminHandler *pAH)
{
    _lastAction = Chain("QueryHistoryLast");
    
    unsigned numLast;
    pAH->getNumLast(numLast);
    
    ListT<CegoDbThread::QueryEntry> queryList;
    
    _pDbPool->getQueryHistoryLast(numLast, queryList);
    
    Element *pQueryHist = new Element(XML_QUERYHIST_ELEMENT);
    
    CegoDbThread::QueryEntry *pQE = queryList.First();
    while ( pQE )
    {
	Element *pElem = new Element(XML_QUERY_ELEMENT);
	
	Datetime ts(pQE->getTimestamp());
	
	pElem->setAttribute(XML_THRIDX_ATTR, Chain(pQE->getIndex()));
	pElem->setAttribute(XML_TIMESTAMP_ATTR, ts.asChain());
	pElem->setAttribute(XML_QUERY_ATTR, pQE->getQuery());
	pElem->setAttribute(XML_COST_ATTR, Chain(pQE->getCost()));
	
	pQueryHist->addContent(pElem);
	
	pQE = queryList.Next();	
    }

    pAH->sendResponse(Chain("QueryHistLast"), 
		      pQueryHist);
}

void CegoAdminThread::srvQueryHistoryCost(CegoAdminHandler *pAH)
{
    _lastAction = Chain("QueryHistoryCost");

    unsigned numCost;
    pAH->getNumCost(numCost);

    ListT<CegoDbThread::QueryEntry> queryList;
    _pDbPool->getQueryHistoryCost(numCost, queryList);

    Element *pQueryHist = new Element(XML_QUERYHIST_ELEMENT);

    CegoDbThread::QueryEntry *pQE = queryList.First();
    while ( pQE )
    {
	Element *pElem = new Element(XML_QUERY_ELEMENT);

	Datetime ts(pQE->getTimestamp());

	pElem->setAttribute(XML_THRIDX_ATTR, Chain(pQE->getIndex()));
	pElem->setAttribute(XML_TIMESTAMP_ATTR, ts.asChain());
	pElem->setAttribute(XML_QUERY_ATTR, pQE->getQuery());
	pElem->setAttribute(XML_COST_ATTR, Chain(pQE->getCost()));
	
	pQueryHist->addContent(pElem);
	
	pQE = queryList.Next();	
    }    
    pAH->sendResponse(Chain("QueryHistCost"), 
		      pQueryHist);
}

void CegoAdminThread::srvNumQueryLast(CegoAdminHandler *pAH)
{
    _lastAction = Chain("NumQueryLast");
    
    unsigned numLast;
    pAH->getNumLast(numLast);

    _pDBMng->setNumQueryLast(numLast);
    pAH->sendResponse(Chain("Num query last set"));
}

void CegoAdminThread::srvNumQueryCost(CegoAdminHandler *pAH)
{
    _lastAction = Chain("NumQueryCost");
    
    unsigned numCost;
    pAH->getNumCost(numCost);
				    
    _pDBMng->setNumQueryCost(numCost);
    
    pAH->sendResponse(Chain("Num query cost set"));
}

void CegoAdminThread::srvAdmThreadInfo(CegoAdminHandler *pAH)
{
    _lastAction = Chain("AdminThreadInfo");    
    
    unsigned poolLimit = _pPool->getPoolLimit();
    
    Element *pThreadInfo = new Element(XML_THREADINFO_ELEMENT);
    
    for ( unsigned i = 0 ; i < poolLimit ; i++ )
    {
	CegoAdminThreadPool::ThreadState state;
	unsigned long long numRequest;
	unsigned long long threadLoad;
	Chain lastAction;
	_pPool->getThreadInfo(i, numRequest, threadLoad, state, lastAction);
	
	Element *pN = new Element(XML_THREAD_ELEMENT);
	pN->setAttribute(XML_THID_ATTR, Chain(i));
	pN->setAttribute(XML_NUMREQUEST_ATTR, Chain(numRequest));
	pN->setAttribute(XML_THREADLOAD_ATTR, Chain(threadLoad));
	
	if ( state == CegoAdminThreadPool::READY )
	    pN->setAttribute(XML_STATUS_ATTR, XML_READY_VALUE);
	else if ( state == CegoAdminThreadPool::CONNECTED )
	    pN->setAttribute(XML_STATUS_ATTR, XML_CONNECTED_VALUE);
	else if ( state == CegoAdminThreadPool::BUSY )
	    pN->setAttribute(XML_STATUS_ATTR, XML_BUSY_VALUE);
	
	pN->setAttribute(XML_LASTACTION_ATTR, lastAction);
	pThreadInfo->addContent(pN);
    }

    pAH->sendResponse(Chain("AdminThreadinfo"), 
		      pThreadInfo);
}

void CegoAdminThread::srvDbThreadAbort(CegoAdminHandler *pAH)
{
    unsigned threadId;
    pAH->getThreadId(threadId);

    _lastAction = Chain("ThreadAbort");
    _pDbPool->abortThread(threadId);
    pAH->sendResponse(Chain("Thread aborted"));		
}	

void CegoAdminThread::srvShowQueryCache(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);   

    Element *pCacheInfo = 0;

    CegoQueryCache* pCache = _pDBMng->getQueryCache(tableSet);

    if ( pCache )
    {
	pCacheInfo = pCache->getCacheInfo();
	pAH->sendResponse(Chain("QueryCache Info"), pCacheInfo); 
    }
    else
    {
	pAH->sendResponse(Chain("QueryCache not available")); 
    }

    _lastAction = Chain("ShowQueryCache");    
}

void CegoAdminThread::srvListQueryCache(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);   

    Element *pCacheList = 0;

    CegoQueryCache* pCache = _pDBMng->getQueryCache(tableSet);

    if ( pCache )
    {
	pCacheList = pCache->getCacheList();
	pAH->sendResponse(Chain("QueryCache List"), pCacheList); 
    }
    else
    {
	pAH->sendResponse(Chain("QueryCache not available")); 
    }

    _lastAction = Chain("ListQueryCache");    
}

void CegoAdminThread::srvCleanQueryCache(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);   

    CegoQueryCache* pCache = _pDBMng->getQueryCache(tableSet);

    if ( pCache )
    {
	pCache->clean();
    }

    pAH->sendResponse(Chain("Query Cache cleaned"));		

    _lastAction = Chain("CleanQueryCache");    
}

void CegoAdminThread::srvSetQueryCacheParam(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    unsigned maxEntry;
    pAH->getQueryCacheMaxEntry(maxEntry);

    unsigned maxSize;
    pAH->getQueryCacheMaxSize(maxSize);

    unsigned threshold;
    pAH->getQueryCacheThreshold(threshold);

    unsigned hashRange;
    pAH->getQueryCacheHashRange(hashRange);

    if ( maxEntry > 0 )
	_pDBMng->setMaxQueryCacheEntry(tableSet, maxEntry);
    if ( maxSize > 0 )
	_pDBMng->setMaxQueryCacheSize(tableSet, maxSize);
    if ( hashRange > 0 )
	_pDBMng->setQueryCacheHashRange(tableSet, hashRange);
    if ( threshold != -1 )
	_pDBMng->setQueryCacheThreshold(tableSet, threshold);
    
    pAH->sendResponse(Chain("QueryCache params set"));		

    _lastAction = Chain("SetQueryCacheParam");       
}

void CegoAdminThread::srvShowTableCache(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);   

    Element *pCacheInfo = 0;

    CegoTableCache* pCache = _pDBMng->getTableCache(tableSet);

    if ( pCache )
    {
	pCacheInfo = pCache->getCacheInfo();
	pAH->sendResponse(Chain("TableCache Info"), pCacheInfo); 
    }
    else
    {
	pAH->sendResponse(Chain("TableCache not available")); 
    }

    _lastAction = Chain("ShowTableCache");    
}

void CegoAdminThread::srvListTableCache(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    Element *pCacheList = 0;

    CegoTableCache* pCache = _pDBMng->getTableCache(tableSet);

    if ( pCache )
    {
	pCacheList = pCache->getCacheList();
	pAH->sendResponse(Chain("TableCache List"), pCacheList); 
    }
    else
    {
	pAH->sendResponse(Chain("TableCache not enabled")); 
    }
    
    _lastAction = Chain("ListTableCache");    
}

void CegoAdminThread::srvCleanTableCache(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    CegoTableCache* pCache = _pDBMng->getTableCache(tableSet);

    if ( pCache )
    {
	pCache->clean();
    }

    pAH->sendResponse(Chain("TableCache cleaned"));		
    _lastAction = Chain("CleanTableCache"); 
}

void CegoAdminThread::srvSetTableCacheParam(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    Chain cacheFilter;
    pAH->getTableCacheFilter(cacheFilter);
    
    unsigned maxEntry;
    pAH->getTableCacheMaxEntry(maxEntry);

    unsigned maxSize;
    pAH->getTableCacheMaxSize(maxSize);

    unsigned hashRange;
    pAH->getTableCacheHashRange(hashRange);

    if ( cacheFilter != Chain() )
	_pDBMng->setTableCacheFilter(tableSet, cacheFilter);
    if ( maxEntry > 0  )
	_pDBMng->setTableCacheMaxEntry(tableSet, maxEntry);
    if ( maxSize > 0 ) 
	_pDBMng->setTableCacheMaxSize(tableSet, maxSize);
    if ( hashRange > 0 )
	_pDBMng->setTableCacheHashRange(tableSet, hashRange);
    
    pAH->sendResponse(Chain("TableCache params set"));		

    _lastAction = Chain("SetTableCacheParam");
}

void CegoAdminThread::srvRemoveTableSet(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);   
    _pDBMng->rmTableSetDef(tableSet);
    _lastAction = Chain("Remove TableSet ") + tableSet;    
    pAH->sendResponse(Chain("Table set removed"));
}

void CegoAdminThread::srvResetTableSet(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);   
    _pTabMng->resetTableSet(tableSet);
    _lastAction = Chain("Reset TableSet ") + tableSet;    
    pAH->sendResponse(Chain("Table set reset"));
}

void CegoAdminThread::srvCreateTableSet(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);   
    _lastAction = Chain("Create TableSet ") + tableSet;
    _pTabMng->createTableSet(tableSet);
    pAH->sendResponse(Chain("Table set created"));
}

void CegoAdminThread::srvDropTableSet(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    _lastAction = Chain("Drop TableSet ") + tableSet;    
    _pTabMng->dropTableSet(tableSet);
    pAH->sendResponse(Chain("Table set dropped"));
}

void CegoAdminThread::srvStartTableSet(CegoAdminHandler *pAH)
{
    Chain tableSet;   
    pAH->getTableSet(tableSet);
    bool cleanIt = pAH->getCleanup();
    bool forceload = pAH->getForceload();
    bool cpDump = pAH->getCPDump();
    bool noInit = pAH->getNoInit();

    _lastAction = Chain("Start TableSet ") + tableSet;    

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
    _pDBMng->lockPool(tabSetId, true);
    try
    {
	_pTabMng->startQueryTableSet(tableSet, cleanIt, true, cpDump);    
	if ( forceload )
	{
	    _pDbPool->loadObjects(tabSetId);
	}

	Chain initWarn;
	
	if ( noInit == false )
	{
	    try
	    {
		Chain batchFileName = _pDBMng->getTSInitFile(tableSet);
		
		if ( batchFileName != Chain() )
		{
		    File batchFile(batchFileName);
		    
		    if ( batchFile.exists() ) 
		    {
			_pDBMng->log(_modId, Logger::NOTICE, Chain("Processing init file ") + batchFileName);
			
			CegoAction* pAction = new CegoAction(_pTabMng);
			
			pAction->setLogToFile(true);
			
			try
			{
			    pAction->setTableSet(tableSet);
			    
			    Chain errorMsg;
			    if ( pAction->processBatchFile(batchFileName, false, false, errorMsg) == false )
				throw Exception(EXLOC, errorMsg);	    
			}
			catch ( Exception e )
			{
			    delete pAction;
			    Chain msg;
			    e.pop(msg);
			    throw Exception(EXLOC, Chain("Init error : ") + msg);
			}
			
			delete pAction;
		    }
		    else
		    {
			throw Exception(EXLOC, Chain("Init file <") + batchFileName + Chain("> does not exist"));
		    }	  
		}
	    }
	    catch ( Exception e )
	    {
		Chain msg;
		e.pop(initWarn);		
	    }
	}

	if ( initWarn == Chain() )	    
	    pAH->sendResponse(Chain("Tableset started"));
	else
	    pAH->sendResponse(Chain("Tableset started ( ") + initWarn + Chain(" )"));
    }
    catch ( Exception e )
    {
	_pDBMng->unlockPool(tabSetId);
	throw Exception(EXLOC, Chain("Cannot start tableset"), e);
    }
    _pDBMng->unlockPool(tabSetId);
}

void CegoAdminThread::srvStopTableSet(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);   
    _lastAction = Chain("Stop TableSet ") + tableSet;    

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
    _pDBMng->lockPool(tabSetId, true);
    try
    {
	_pDbPool->unloadObjects(tabSetId);	
	_pTabMng->stopTableSet(tableSet, true);
	pAH->sendResponse(Chain("Tableset stopped"));
    }
    catch ( Exception e )
    {
	_pDBMng->unlockPool(tabSetId);
	throw Exception(EXLOC, Chain("Cannot stop tableset"), e);
    }
    _pDBMng->unlockPool(tabSetId);	
}

void CegoAdminThread::srvVerifyTableSet(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);   
    _lastAction = Chain("Verify TableSet ") + tableSet;

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
    _pDBMng->lockPool(tabSetId, false);

    unsigned errCount = 0;
    
    try
    {
	_pTabMng->setActiveUser(tableSet, _user, _password);
	
	ListT<Chain> tableList; 
	_pTabMng->getObjectList(tabSetId, CegoObject::TABLE, tableList);
		
	Chain *pTable = tableList.First();
	while ( pTable )
	{

	    Chain info("Verification of table " + *pTable);
	    pAH->sendInfo(info + Chain("\n"));

	    if (  _pTabMng->verifyTable(tableSet, *pTable, pAH) )
	    {
		pAH->sendInfo(Chain("... ok\n"));
	    }
	    else
	    {
		errCount++;
		pAH->sendInfo(Chain("... failed\n"));
	    }
	    	    
	    pTable = tableList.Next();		
	}
	
	ListT<Chain> viewList; 
	_pTabMng->getObjectList(tabSetId, CegoObject::VIEW, viewList);
	
	Chain *pView = viewList.First();
	while ( pView )
	{

	    Chain info("Verification of view " + *pView);
	    pAH->sendInfo(info + Chain("\n"));

	    if ( _pTabMng->verifyView(tableSet, *pView, pAH) )
	    {
		pAH->sendInfo(Chain("... ok\n"));
	    }
	    else
	    {
		errCount++;
		pAH->sendInfo(Chain("... failed\n"));
	    }
	    
	    pView = viewList.Next();		
	}
	
	ListT<Chain> procList; 
	_pTabMng->getObjectList(tabSetId, CegoObject::PROCEDURE, procList);
	
	Chain *pProc = procList.First();
	while ( pProc )
	{
	    Chain info("Verification of procedure " + *pProc);
	    pAH->sendInfo(info + Chain("\n"));

	    if ( _pTabMng->verifyProcedure(tableSet, *pProc, pAH) )
	    {
		pAH->sendInfo(Chain("... ok\n"));
	    }
	    else
	    {
		errCount++;
		pAH->sendInfo(Chain("... failed\n"));
	    }
	    
	    pProc = procList.Next();		
	}
	pAH->sendResponse(Chain("Tableset verified with ") + Chain(errCount) + Chain(" errors"));
    }
    catch ( Exception e )
    {
	_pDBMng->unlockPool(tabSetId);
	throw Exception(EXLOC, Chain("Cannot verify tableset"), e);
    }
    _pDBMng->unlockPool(tabSetId);   
}
    
void CegoAdminThread::srvCorrectTableSet(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);   
    _lastAction = Chain("Correct TableSet ") + tableSet;

    unsigned sumCorrected=0;
    
    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    // during correction, we stop any log activies
    _pDBMng->stopLog(tabSetId);

    _pDBMng->lockPool(tabSetId, false);
    
    try
    {
	_pTabMng->setActiveUser(tableSet, _user, _password);
	
	ListT<Chain> tableList; 
	_pTabMng->getObjectList(tabSetId, CegoObject::TABLE, tableList);
		
	Chain *pTable = tableList.First();
	while ( pTable )
	{

	    unsigned numCorrected = _pTabMng->correctTable(tableSet, *pTable);
		
	    if ( numCorrected > 0 ) 
	    {
		sumCorrected += numCorrected;
		pAH->sendInfo(*pTable + Chain(" ... ") + Chain(numCorrected) + Chain(" indexes corrected\n"));
	    }
	    else
	    {
		pAH->sendInfo(*pTable + Chain(" ... ok\n"));
	    }
	    
	    pTable = tableList.Next();		
	}
	pAH->sendResponse(Chain("Tableset corrected with ") + Chain(sumCorrected) + Chain(" corrections"));
    }
    catch ( Exception e )
    {
	_pDBMng->unlockPool(tabSetId);
	_pDBMng->startLog(tabSetId);
	throw Exception(EXLOC, Chain("Cannot correct tableset"), e);
    }
    _pDBMng->unlockPool(tabSetId);
    _pDBMng->startLog(tabSetId);
}

void CegoAdminThread::srvSetLogMng(CegoAdminHandler *pAH)
{   
    Chain progName;
    unsigned timeout;
    pAH->getLogManager(progName);
    pAH->getLogManagerTimeout(timeout);
    
    _lastAction = Chain("set log manager");    

    _pDBMng->setArchRestoreProg(progName);
    _pDBMng->setArchRestoreTimeout(timeout);

    pAH->sendResponse(Chain("Log manager set"));
}

void CegoAdminThread::srvShowLogMng(CegoAdminHandler *pAH)
{   
    _lastAction = Chain("show log manager");    

    Chain progName = _pDBMng->getArchRestoreProg();
    unsigned timeout = _pDBMng->getArchRestoreTimeout();
    
    Element *pLMI = new Element(XML_LOGMNGINFO_ELEMENT);
    pLMI->setAttribute(XML_LOGMNGPROG_ATTR, progName);
    pLMI->setAttribute(XML_LOGMNGTIMEOUT_ATTR, Chain(timeout));
    
    pAH->sendResponse(Chain("Log manager Info"), pLMI);
}

void CegoAdminThread::srvSetBackupMng(CegoAdminHandler *pAH)
{   
    Chain progName;
    pAH->getBackupManager(progName);
    
    _lastAction = Chain("set backup manager");    

    _pDBMng->setBackupProg(progName);

    pAH->sendResponse(Chain("Backup manager set"));
}

void CegoAdminThread::srvShowBackupMng(CegoAdminHandler *pAH)
{   
    _lastAction = Chain("show backup manager");    

    Chain progName = _pDBMng->getBackupProg();
    
    Element *pLMI = new Element(XML_BACKUPMNGINFO_ELEMENT);
    pLMI->setAttribute(XML_BACKUPMNGPROG_ATTR, progName);
    
    pAH->sendResponse(Chain("Backup manager Info"), pLMI);
}

void CegoAdminThread::srvSetCheckpoint(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    unsigned tmout;
    pAH->getTimeoutValue(tmout);
    
    _lastAction = Chain("Set checkpoint for ") + tableSet;    

    _pDBMng->setCheckpointInterval(tableSet, tmout);
    
    pAH->sendResponse(Chain("Checkpoint interval set"));    
}

void CegoAdminThread::srvSetTSInitFile(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    Chain initFile;
    pAH->getTSInitFile(initFile);
    
    _lastAction = Chain("Set initfile for ") + tableSet;    

    _pDBMng->setTSInitFile(tableSet, initFile);
    
    pAH->sendResponse(Chain("Initfile set"));
}

void CegoAdminThread::srvSetTSSysSize(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    unsigned sysSize;
    pAH->getSysSize(sysSize);
    
    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_DEFINED_VALUE) )
    {
	throw Exception(EXLOC, "Tableset must be in state DEFINED for reconfiguration");
    }

    _lastAction = Chain("Set system size for ") + tableSet;
    
    _pDBMng->setTSSysSize(tableSet, sysSize);
    
    pAH->sendResponse(Chain("System size set"));    
}

void CegoAdminThread::srvSetTSTmpSize(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    unsigned tmpSize;
    pAH->getTmpSize(tmpSize);

    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_DEFINED_VALUE) )
    {
	throw Exception(EXLOC, "Tableset must be in state DEFINED for reconfiguration");
    }
    
    _lastAction = Chain("Set temp size for ") + tableSet;    

    _pDBMng->setTSTmpSize(tableSet, tmpSize);
    
    pAH->sendResponse(Chain("Temp size set"));
}

void CegoAdminThread::srvSetTSAppSize(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    unsigned appSize;
    pAH->getAppSize(appSize);

    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_DEFINED_VALUE) )
    {
	throw Exception(EXLOC, "Tableset must be in state DEFINED for reconfiguration");
    }
    
    _lastAction = Chain("Set app size for ") + tableSet;    

    _pDBMng->setTSAppSize(tableSet, appSize);
    
    pAH->sendResponse(Chain("App size set"));
}

void CegoAdminThread::srvSetTSRootPath(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    Chain tsRoot;
    pAH->getTSRootPath(tsRoot);

    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_DEFINED_VALUE) )
    {
	throw Exception(EXLOC, "Tableset must be in state DEFINED for reconfiguration");
    }
        
    _lastAction = Chain("Set tsroot for ") + tableSet;

    _pDBMng->resetTSRoot(tableSet, tsRoot);

    pAH->sendResponse(Chain("TSRoot set"));    
}

void CegoAdminThread::srvSetTSLogNum(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    unsigned logNum;
    pAH->getTSLogNum(logNum);

    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_DEFINED_VALUE) )
    {
	throw Exception(EXLOC, "Tableset must be in state DEFINED for reconfiguration");
    }
    
    _lastAction = Chain("Set logNum for ") + tableSet;    

    _pDBMng->setTSLogNum(tableSet, logNum);
    
    pAH->sendResponse(Chain("Log number set"));
}

void CegoAdminThread::srvSetTSLogSize(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    unsigned logSize;
    pAH->getTSLogSize(logSize);

    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_DEFINED_VALUE) )
    {
	throw Exception(EXLOC, "Tableset must be in state DEFINED for reconfiguration");
    }
    
    _lastAction = Chain("Set logSize for ") + tableSet;    

    _pDBMng->setTSLogSize(tableSet, logSize);
    
    pAH->sendResponse(Chain("Log size set"));
}

void CegoAdminThread::srvSetTSSortAreaSize(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    unsigned long long sortAreaSize;
    pAH->getTSSortAreaSize(sortAreaSize);
    
    _lastAction = Chain("Set sort area size for ") + tableSet;    

    _pDBMng->setTSSortAreaSize(tableSet, sortAreaSize);
    
    pAH->sendResponse(Chain("Sort area size set"));
}

void CegoAdminThread::srvStartRecovery(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    if ( _pDBMng->isArchiveMode(tableSet) == false )
    {
	throw Exception(EXLOC, "Archive mode not enabled for " + tableSet);
    }

    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_OFFLINE_VALUE) )
    {
	throw Exception(EXLOC, Chain("Tableset must be in status ") + Chain(XML_OFFLINE_VALUE) + Chain(" to start recovery"));
    }
    
    _lastAction = Chain("Start Recovery for ") + tableSet;    
    _pDBMng->startRecovery(tableSet);
   
    pAH->sendResponse(Chain("Starting recovery ..."));
}

void CegoAdminThread::srvStopRecovery(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    _lastAction = Chain("Stop Recovery for ") + tableSet;    
	
    if ( _pDBMng->getRecoveryMode(tabSetId) == CegoDatabaseManager::ON )
    {
	_pDBMng->setRecoveryMode(tabSetId, CegoDatabaseManager::REQOFF);
	
	while ( _pDBMng->getRecoveryMode(tabSetId) != CegoDatabaseManager::OFF )
	{
	    Sleeper s;
	    s.secSleep(LOGMNG_RECOVERY_DELAY);
	}
    }

    pAH->sendResponse(Chain("Stopped recovery"));
}      	


void CegoAdminThread::srvGetTSInfo(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    Element* pTSInfo = _pDBMng->getTableSetInfo(tableSet); 
    
    _lastAction = Chain("GetTSInfo");
    pAH->sendResponse(Chain("TS Info"), 
		      pTSInfo);
}

void CegoAdminThread::srvGetDetailedTSInfo(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    Element* pTSInfo = getDetailedTSInfo(tableSet); 
    
    _lastAction = Chain("GetDetailedTSInfo");
    pAH->sendResponse(Chain("Detailed TS Info"), 
		      pTSInfo);
}

void CegoAdminThread::srvGetArchLogInfo(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    Element* pArchInfo = getArchLogInfo(tableSet); 
    
    _lastAction = Chain("GetArchLogInfo");
    pAH->sendResponse(Chain("Arch Log Info"), 
		      pArchInfo);
}

void CegoAdminThread::srvGetTransactionInfo(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    Element* pTAInfo = getTransactionInfo(tableSet); 
    
    _lastAction = Chain("GetTransactionInfo");
    pAH->sendResponse(Chain("Transaction Info"), 
		      pTAInfo);
}

void CegoAdminThread::srvGetBUStatInfo(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    Element* pBUSInfo = getBUStatInfo(tableSet); 
    
    _lastAction = Chain("GetBUStatInfo");
    pAH->sendResponse(Chain("BUStat Info"), 
		      pBUSInfo);
}

void CegoAdminThread::srvSetLSN(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    pAH->getTableSet(tableSet);
    
    unsigned long long lsn;
    pAH->getLSN(lsn);
    
    _pDBMng->setTableSetRunState(tableSet, XML_OFFLINE_VALUE);
    _pDBMng->setCommittedLSN(tableSet, lsn);
    
    pAH->sendResponse(Chain("Tableset LSN set"));
}

void CegoAdminThread::srvExportTableSet(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain expFile;
    bool isStructure;
    Chain expMode;

    pAH->getTableSet(tableSet);
    pAH->getFileName(expFile);
    pAH->getIsStructure(isStructure);
    pAH->getMode(expMode);


    // to avoid lock timeouts during tableset export, we avoid pool locking
    // seems to be not needful
    
    try
    {    
	Chain status = _pDBMng->getTableSetRunState(tableSet);
	if ( status != Chain(XML_ONLINE_VALUE) )
	{
	    throw Exception(EXLOC, "Tableset must be online for export");
	}
	
	_lastAction = Chain("Export tableset ") + tableSet;    
        
	_pTabMng->setActiveUser(tableSet, _user, _password);
	CegoXPorter exp(_pTabMng, pAH);
	
	if ( expMode == Chain(XML_XML_VALUE) )
	{
	    exp.xmlExportTableSet(tableSet, isStructure, expFile);
	}
	else if ( expMode == Chain(XML_BIN_VALUE) )
	{
	    exp.binExportTableSet(tableSet, isStructure, expFile, false);
	}
	else if ( expMode == Chain(XML_PLAIN_VALUE) )
	{
	    exp.binExportTableSet(tableSet, isStructure, expFile, true);
	}
	pAH->sendResponse(Chain("Tableset " + tableSet + " exported"));

    }
    catch ( Exception e )
    {
	throw Exception(EXLOC, Chain("Cannot export tableset"), e);
    }
}

void CegoAdminThread::srvImportTableSet(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain impFile;
    bool isStructure;
    Chain impMode;

    pAH->getTableSet(tableSet);
    pAH->getFileName(impFile);
    pAH->getIsStructure(isStructure);
    pAH->getMode(impMode);

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    // during import we stop any log activies
    _pDBMng->stopLog(tabSetId);

    // and we lock bufffer pool for corresponding tableset
    _pDBMng->lockPool(tabSetId, false);

    try
    {    
	Chain status = _pDBMng->getTableSetRunState(tableSet);
	if ( status != Chain(XML_ONLINE_VALUE) )
	{
	    throw Exception(EXLOC, "Tableset must be online for import");
	}
	
	_lastAction = Chain("Import tableset ") + tableSet;    
	
	_pTabMng->setActiveUser(tableSet, _user, _password);    
	CegoXPorter imp(_pTabMng, pAH);
	
	if ( impMode == Chain(XML_XML_VALUE) )
	{
	    imp.xmlImportTableSet(tableSet, isStructure, impFile);
	}
	else if ( impMode == Chain(XML_BIN_VALUE) )
	{
	    imp.binImportTableSet(tableSet, isStructure, impFile, false);
	}
	else if ( impMode == Chain(XML_PLAIN_VALUE) )
	{
	    imp.binImportTableSet(tableSet, isStructure, impFile, true);
	}
	
	pAH->sendResponse(Chain("Tableset " + tableSet + " imported"));
    }    
    catch ( Exception e )
    {
	_pDBMng->unlockPool(tabSetId);
	_pDBMng->startLog(tabSetId);
	throw Exception(EXLOC, Chain("Cannot import tableset"), e);
    }


    _pDBMng->unlockPool(tabSetId);
    _pDBMng->startLog(tabSetId);  	

    // to commit import actions, we write checkpoint here
    _pDBMng->writeCheckPoint(tableSet, true, false, _pTabMng->getLockHandle());

    // switch to new backup branch
    if ( _pDBMng->isArchiveMode(tableSet) )
	_pDBMng->nextTableSetBackupBranch(tableSet);

}

void CegoAdminThread::srvExportTable(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain tableName;
    Chain expFile;
    Chain expMode;

    pAH->getTableSet(tableSet);
    pAH->getTableName(tableName);
    pAH->getFileName(expFile);
    pAH->getMode(expMode);
    
    // same as for whole tableset, no locking here

    try
    {    
	Chain status = _pDBMng->getTableSetRunState(tableSet);
	if ( status != Chain(XML_ONLINE_VALUE) )
	{
	    throw Exception(EXLOC, "Tableset must be online for export");
	}
	
	_pTabMng->setActiveUser(tableSet, _user, _password);
	
	unsigned long long numExported = 0;
	
	CegoXPorter exp(_pTabMng, pAH);
	if ( expMode == Chain(XML_XML_VALUE) )
	{
	    numExported = exp.xmlExportTable(tableSet, tableName, expFile);
	}
	else if ( expMode == Chain(XML_BIN_VALUE) )
	{
	    numExported = exp.binExportTable(tableSet, tableName, expFile, false);
	}
	else if ( expMode == Chain(XML_PLAIN_VALUE) )
	{
	    numExported = exp.binExportTable(tableSet, tableName, expFile, true);
	}
	
	pAH->sendResponse(Chain("Table " + tableName + " exported with " + Chain(numExported) + " rows"));
    }
    catch ( Exception e )
    {
	throw Exception(EXLOC, Chain("Cannot export table"), e);
    }
}
    
void CegoAdminThread::srvImportTable(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain tableName;
    Chain impFile;
    Chain impMode;

    pAH->getTableSet(tableSet);
    pAH->getTableName(tableName);
    pAH->getFileName(impFile);
    pAH->getMode(impMode);

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
   
    // during import we stop any log activies
    _pDBMng->stopLog(tabSetId);

    _pDBMng->lockPool(tabSetId, false);

    try
    {    
	Chain status = _pDBMng->getTableSetRunState(tableSet);
	if ( status != Chain(XML_ONLINE_VALUE) )
	{
	    throw Exception(EXLOC, "Tableset must be online for import");
	}

	_pTabMng->setActiveUser(tableSet, _user, _password);
	
	CegoXPorter imp(_pTabMng, pAH);
	
	unsigned long long numImported = 0;
	
	if ( impMode == Chain(XML_XML_VALUE) )
	{
	    numImported = imp.xmlImportTable(tableSet, tableName, impFile);
	}
	else if ( impMode == Chain(XML_BIN_VALUE) )
	{
	    numImported = imp.binImportTable(tableSet, tableName, impFile, false);
	}
	else if ( impMode == Chain(XML_PLAIN_VALUE) )
	{
	    numImported = imp.binImportTable(tableSet, tableName, impFile, true);
	}
	
	if ( numImported > 0 )
	    pAH->sendResponse(Chain("Table " + tableName + " imported with " + Chain(numImported) + " rows"));
	else
	    pAH->sendResponse(Chain("No rows available for table " + tableName));
    }
    catch ( Exception e )
    {
	_pDBMng->unlockPool(tabSetId);
	throw Exception(EXLOC, Chain("Cannot import tableset"), e);
    }

    _pDBMng->unlockPool(tabSetId);
    _pDBMng->startLog(tabSetId);  	

    // to commit import actions, we write checkpoint here
    _pDBMng->writeCheckPoint(tableSet, true, false, _pTabMng->getLockHandle());

    // switch to new backup branch
    if ( _pDBMng->isArchiveMode(tableSet) )
	_pDBMng->nextTableSetBackupBranch(tableSet);

}

void CegoAdminThread::srvUserInfo(CegoAdminHandler *pAH)
{
    Element* pUserInfo = _pDBMng->getUserList(); 
    
    _lastAction = Chain("showUser");
    pAH->sendResponse(Chain("User Info"), pUserInfo); 
}

void CegoAdminThread::srvAddUser(CegoAdminHandler *pAH)
{
    Chain user;
    Chain password;
    pAH->getUser(user);
    pAH->getPassword(password);

    _pDBMng->addUser(user, password);
    
    pAH->sendResponse(Chain("User " + user + " added"));
}	

void CegoAdminThread::srvRemoveUser(CegoAdminHandler *pAH)
{
    Chain user;
    pAH->getUser(user);    
    _pDBMng->removeUser(user);
    pAH->sendResponse(Chain("User " + user + " removed"));
}
	
void CegoAdminThread::srvChangePwd(CegoAdminHandler *pAH)
{
    Chain user;
    Chain password;

    pAH->getUser(user);
    pAH->getPassword(password);
    _pDBMng->changePassword(user, password);
    pAH->sendResponse(Chain("Password changed for user " + user));		    
}

void CegoAdminThread::srvListRole(CegoAdminHandler *pAH)
{
    Element* pRoleList = _pDBMng->getRoleList();     
    _lastAction = Chain("listRole");
    pAH->sendResponse(Chain("Role List"), pRoleList);
}

void CegoAdminThread::srvShowRole(CegoAdminHandler *pAH)
{
    Chain role;

    pAH->getRole(role);
    Element* pPermInfo = _pDBMng->getPermInfo(role);
    pAH->sendResponse(Chain("Role info"), pPermInfo);
}

void CegoAdminThread::srvCreateRole(CegoAdminHandler *pAH)
{    
    Chain role;

    pAH->getRole(role);
    _pDBMng->createRole(role);
    pAH->sendResponse(Chain("Role " ) + role + Chain(" created"));
}

void CegoAdminThread::srvDropRole(CegoAdminHandler *pAH)
{    
    Chain role;    

    pAH->getRole(role);
    _pDBMng->dropRole(role);
    pAH->sendResponse(Chain("Role ") + role + Chain(" dropped"));
}

void CegoAdminThread::srvAssignRole(CegoAdminHandler *pAH)
{
    Chain user;
    Chain role;    

    pAH->getUser(user);
    pAH->getRole(role);
    _pDBMng->assignUserRole(user, role);
    pAH->sendResponse(Chain("Role set for user " + user));		    
}

void CegoAdminThread::srvRemoveRole(CegoAdminHandler *pAH)
{
    Chain user;
    Chain role;

    pAH->getUser(user);
    pAH->getRole(role);   
    _pDBMng->removeUserRole(user, role);
    pAH->sendResponse(Chain("Role ") + role + Chain(" removed from user ") + user);
}

void CegoAdminThread::srvSetPerm(CegoAdminHandler *pAH)
{
    Chain role;
    Chain tableSet;
    Chain filter;
    Chain perm;
    Chain permid;    

    pAH->getRole(role);
    pAH->getTableSet(tableSet);
    pAH->getFilter(filter);
    pAH->getPerm(perm);
    pAH->getPermId(permid);
    _pDBMng->setPerm(role, permid, tableSet, filter, perm);
    pAH->sendResponse(Chain("Permission ") + permid + Chain(" set"));
}

void CegoAdminThread::srvRemovePerm(CegoAdminHandler *pAH)
{
    Chain role;
    Chain permid;

    pAH->getRole(role);
    pAH->getPermId(permid);
    _pDBMng->removePerm(role, permid);
    pAH->sendResponse(Chain("Permission ") + permid + Chain(" removed"));
}

void CegoAdminThread::srvUserTrace(CegoAdminHandler *pAH)
{
    Chain user;
    bool isOn;

    pAH->getUser(user);
    pAH->getTrace(isOn);
    _pDBMng->setUserTrace(user, isOn);
    pAH->sendResponse(Chain("User trace set for ") + user);		    
}

void CegoAdminThread::srvSyncTableSet(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain bumsg;
    Chain escCmd;
    unsigned timeout;

    pAH->getTableSet(tableSet);
    pAH->getEscapeCmd(escCmd);
    pAH->getTimeoutValue(timeout);
    pAH->getBUMsg(bumsg);    
    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
    _pDBMng->lockPool(tabSetId, false);
    try
    {    
	_pTabMng->syncTableSet(tableSet, bumsg, escCmd, timeout);
	
	Chain msg;
	if ( escCmd == Chain() )
	{
	    msg = Chain("Tableset ") + tableSet + Chain(" in sync");
	}
	else
	{
	    msg = Chain("Tableset ") + tableSet + Chain(" in sync with escape command");
	}
	pAH->sendResponse(msg);
    }
    catch ( Exception e )
    {
	_pDBMng->unlockPool(tabSetId);
	throw Exception(EXLOC, Chain("Cannot synchronize tableset"), e);
    }
    _pDBMng->unlockPool(tabSetId);
}

void CegoAdminThread::srvInitLogs(CegoAdminHandler *pAH)
{
    Chain tableSet;

    pAH->getTableSet(tableSet);    
    _pDBMng->initLogFiles(tableSet, true);
    pAH->sendResponse(Chain("Logs for tableset " + tableSet + " initialized"));
}

void CegoAdminThread::srvAddArchLog(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain archId;
    Chain archPath;

    pAH->getTableSet(tableSet);
    pAH->getArchId(archId);
    pAH->getArchPath(archPath);
    _pDBMng->addArchLog(tableSet, archId, archPath);
    pAH->sendResponse(Chain("Archlog " + archPath + " added to " + tableSet));    
}

void CegoAdminThread::srvRemoveArchLog(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain archId;

    pAH->getTableSet(tableSet);
    pAH->getArchId(archId);
    _pDBMng->removeArchLog(tableSet, archId);
    pAH->sendResponse(Chain("Archlog id " + archId + " removed from " + tableSet));
}

void CegoAdminThread::srvBeginBackup(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain msg;

    pAH->getTableSet(tableSet);
    pAH->getBUMsg(msg);
    _pTabMng->beginBackup(tableSet, msg);
    pAH->sendResponse(Chain("Backup started"));
}

void CegoAdminThread::srvExecuteBackup(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain msg;
    Chain result;
    
    pAH->getTableSet(tableSet);
    pAH->getBUMsg(msg);
    result = executeBackup(pAH, tableSet, msg);  
    pAH->sendResponse(Chain("Backup execution status : ") + result);
}

void CegoAdminThread::srvEndBackup(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain msg;
    bool keepTicket;

    pAH->getTableSet(tableSet);
    pAH->getBUMsg(msg);
    pAH->getKeepTicket(keepTicket);
    _pTabMng->endBackup(tableSet, msg, keepTicket);    
    pAH->sendResponse(Chain("Backup ended"));
}

void CegoAdminThread::srvListBackup(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain pit;
    Element *pBackupInfo;
    
    pAH->getTableSet(tableSet);
    pAH->getPit(pit);
    pBackupInfo = getBackupInfo(tableSet, pit);
    _lastAction = Chain("listBackup");
    pAH->sendResponse(Chain("Backup list"), pBackupInfo);
}

void CegoAdminThread::srvRestore(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain backupId;
    
    pAH->getTableSet(tableSet);
    pAH->getBackupId(backupId);
    Chain result = executeRestore(pAH, tableSet, backupId);
    pAH->sendResponse(Chain("Restore execution status : ") + result);
}

void CegoAdminThread::srvRecover(CegoAdminHandler *pAH)
{
    Chain tableSet;
    Chain pit;
    long long pitTS = 0;
    unsigned long long targetLSN = 0;
    
    pAH->getTableSet(tableSet);
    pAH->getPit(pit);
    pAH->getLSN(targetLSN);
    
    if ( pit != Chain() )
    {
	__dateFormatLock.readLock(DBM_LOCKTIMEOUT);
	try
	{
	    Datetime pitTime;
	    pitTime = Datetime(pit, __dateFormatList);
	    pitTS = pitTime.asLong();
	}
	catch ( Exception e )
	{
	    __dateFormatLock.unlock();
	    throw Exception(EXLOC, Chain("Cannot get pit information"), e);   
	}
	__dateFormatLock.unlock();
    }

    CegoRecoveryManager recoveryMng(_pTabMng);
    unsigned long long lsn = recoveryMng.recoverTableSet(tableSet, pitTS, targetLSN, pAH);
    pAH->sendResponse(Chain("Tableset recovered to lsn ") + Chain(lsn));
}

void CegoAdminThread::srvEnableTableCache(CegoAdminHandler *pAH)
{
    Chain tableSet;

    pAH->getTableSet(tableSet);
    _pDBMng->setTableCacheMode(tableSet, true);
    _pDBMng->allocateTableCache(tableSet);
    pAH->sendResponse(Chain("Table cache enabled"));
}

void CegoAdminThread::srvDisableTableCache(CegoAdminHandler *pAH)
{
    Chain tableSet;

    pAH->getTableSet(tableSet);
    _pDBMng->releaseTableCache(tableSet);
    _pDBMng->setTableCacheMode(tableSet, false);    
    pAH->sendResponse(Chain("Table cache disabled"));
}

void CegoAdminThread::srvEnableQueryCache(CegoAdminHandler *pAH)
{
    Chain tableSet;

    pAH->getTableSet(tableSet);
    _pDBMng->setQueryCacheMode(tableSet, true);
    _pDBMng->allocateQueryCache(tableSet);
    pAH->sendResponse(Chain("Query cache enabled"));
}

void CegoAdminThread::srvDisableQueryCache(CegoAdminHandler *pAH)
{
    Chain tableSet;

    pAH->getTableSet(tableSet);
    _pDBMng->releaseQueryCache(tableSet);    
    _pDBMng->setQueryCacheMode(tableSet, false);
    pAH->sendResponse(Chain("Query cache disabled"));
}

void CegoAdminThread::srvDefineTableSet(CegoAdminHandler *pAH)
{   
    Chain tableSet;
    Chain tsRoot;
    unsigned sysSize;
    unsigned tmpSize;
    unsigned appSize;
    unsigned logFileSize;
    unsigned logFileNum;
    unsigned long long sortAreaSize;
    unsigned branchId;
    
    pAH->getTableSet(tableSet);
    pAH->getTableSetRoot(tsRoot);
    pAH->getSysSize(sysSize);
    pAH->getTmpSize(tmpSize);
    pAH->getAppSize(appSize);
    pAH->getLogFileSize(logFileSize);
    pAH->getLogFileNum(logFileNum);
    pAH->getSortAreaSize(sortAreaSize);
    pAH->getBranchId(branchId);
    
    unsigned sysFid = _pDBMng->nextTSID();
    unsigned tmpFid = _pDBMng->nextFID();

    Chain resultMsg;

    
    _pDBMng->addTableSetDef(tableSet, tsRoot, sysFid, tmpFid, sysSize, tmpSize, appSize, logFileSize, logFileNum, sortAreaSize, branchId); 
    
    pAH->sendResponse(Chain("Tableset ") + tableSet + Chain(" defined"));
}


void CegoAdminThread::srvAddDatafile(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    Chain fileName;
    pAH->getFileName(fileName);
    
    unsigned fileSize;
    pAH->getFileSize(fileSize);

    Chain fileType;
    pAH->getFileType(fileType);


    unsigned fileId = _pDBMng->nextFID();
    
    Chain runState = _pDBMng->getTableSetRunState(tableSet);
    
    if ( runState != Chain(XML_DEFINED_VALUE) )
    {	
	_pTabMng->addDataFile(tableSet, fileType, fileId, fileName, fileSize);
	
	if ( runState == Chain(XML_ONLINE_VALUE) )
	{
	    _pDBMng->writeCheckPoint(tableSet, true, false, _pTabMng->getLockHandle());
	}
    }
    
    try
    {
	_pDBMng->addDataFile(tableSet, fileType, fileId, fileName, fileSize); 	    
    }
    catch ( Exception e )
    {
	Chain msg = e.getBaseMsg();
	throw Exception(EXLOC, msg);		
    }
	
    pAH->sendResponse(Chain("Datafile added"));
}

void CegoAdminThread::srvGetTableSetList(CegoAdminHandler *pAH)
{    
    Element* pTabSetInfo = _pDBMng->getTableSetList(); 

    bool getUsage;
    pAH->getUsage(getUsage);
    if ( getUsage )
    {	
	ListT<Element*> tabSetList = pTabSetInfo->getChildren(XML_TABLESET_ELEMENT);
	Element **pTabSet = tabSetList.First();
	while ( pTabSet )
	{
	    Chain tableSet = (*pTabSet)->getAttributeValue(XML_NAME_ATTR);
	    addTableSetUsage(*pTabSet);
	    
	    pTabSet = tabSetList.Next();
	}
    }
    pAH->sendResponse(Chain("Tableset list"), pTabSetInfo);		      
}


void CegoAdminThread::srvResetBUStat(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    Chain resultMsg;

    _pTabMng->resetBUStat(tableSet);
    
    pAH->sendResponse(Chain("BUStat reset done"));   
}



void CegoAdminThread::srvEnableArchLog(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    
    ListT<Chain> archIdList;
    ListT<Chain> archPathList;
    _pDBMng->getArchLogInfo(tableSet, archIdList, archPathList);
    
    if ( archIdList.Size() == 0 )
    {	    
	Chain msg = Chain("No valid archive locations available");
	throw Exception(EXLOC, msg);	    
    }
    _pDBMng->enableArchLog(tableSet);
    
    // switch to new backup branch
    _pDBMng->nextTableSetBackupBranch(tableSet);

    pAH->sendResponse(Chain("Arch mode enabled"));
}

void CegoAdminThread::srvDisableArchLog(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);

    Chain status = _pDBMng->getTableSetRunState(tableSet);

    if ( status == Chain(XML_BACKUP_VALUE) )
    {
	Chain msg = Chain("Tableset is already in backup mode");
	throw Exception(EXLOC, msg);
    }

    _pDBMng->disableArchLog(tableSet);

    pAH->sendResponse(Chain("Arch mode disabled"));
}

void CegoAdminThread::srvEnableAppendMode(CegoAdminHandler *pAH)
{
    Chain tableSet;

    pAH->getTableSet(tableSet);

    _pDBMng->setAppendMode(tableSet, true);
    
    pAH->sendResponse(Chain("Append mode enabled"));
}

void CegoAdminThread::srvDisableAppendMode(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);
    _pDBMng->setAppendMode(tableSet, false);
    pAH->sendResponse(Chain("Append mode disabled"));    
}

void CegoAdminThread::srvSetAutoCorrect(CegoAdminHandler *pAH)
{
    Chain tableSet;
    pAH->getTableSet(tableSet);
    Chain mode;
    pAH->getMode(mode);
    _pDBMng->setAutoCorrect(tableSet, mode);
    
    pAH->sendResponse(Chain("Auto correct mode set"));
}

CegoAdminHandler* CegoAdminThread::getSession(const Chain& role, const Chain& hostname, const Chain& user, const Chain& pwd)
{    
    Net n (  NETMNG_MSG_BUFLEN, NETMNG_SIZEBUFLEN, NETMNG_MAXSENDLEN );
    
    NetHandler *pN;

    unsigned adminPort;
    _pDBMng->getAdminPort(adminPort);
     
    try 
    {
	pN = n.connect(hostname, adminPort);	
    }
    catch ( Exception e )
    {
	throw Exception(EXLOC, Chain("Cannot get session to ") + hostname, e);	
    }

    CegoAdminHandler* pAH = new CegoAdminHandler( _pDBMng, pN);
    
    CegoAdminHandler::ResultType res = pAH->requestSession(user, pwd, false);
    if ( res != CegoAdminHandler::ADM_OK )
    {
	Chain msg;
	pAH->getMsg(msg);
	closeSession(pAH);

	throw Exception(EXLOC, msg);	
    }
    
    return pAH;
}

void CegoAdminThread::closeSession(CegoAdminHandler* pAH)
{
    pAH->closeSession();
    NetHandler* pN = pAH->getNetHandle();
    delete pAH;
    delete pN;
}

Element* CegoAdminThread::getDetailedTSInfo(const Chain& tableSet)
{
    Chain tsRoot;
    Chain runState;
    Chain archMode;
    Chain autoCorrect;
    Chain appendMode;
    Chain tableCache;
    Chain queryCache;
    Chain cpDump;
    
    Chain tableCacheFilter;
    unsigned tableCacheMaxEntry;
    unsigned tableCacheMaxSize;
    unsigned tableCacheHashRange;
    
    unsigned queryCacheMaxEntry;
    unsigned queryCacheMaxSize;
    unsigned queryCacheThreshold;
    unsigned queryCacheHashRange;

    Chain tsTicket;
    Chain tsInitFile;
    unsigned checkpoint;

    runState = _pDBMng->getTableSetRunState(tableSet);
    tsRoot = _pDBMng->getTSRoot(tableSet);
    tsTicket = _pDBMng->getTSTicket(tableSet);
    tsInitFile = _pDBMng->getTSInitFile(tableSet);
    checkpoint = _pDBMng->getCheckpointInterval(tableSet);
    
    if ( _pDBMng->isArchiveMode(tableSet) )
	archMode = Chain(XML_ON_VALUE);
    else
	archMode = Chain(XML_OFF_VALUE);

    autoCorrect = _pDBMng->getAutoCorrect(tableSet);

    if ( _pDBMng->getAppendMode(tableSet) )
	appendMode = Chain(XML_ON_VALUE);
    else
	appendMode = Chain(XML_OFF_VALUE);
    
    if ( _pDBMng->getTableCacheMode(tableSet) )
        tableCache = Chain(XML_ON_VALUE);
    else
	tableCache = Chain(XML_OFF_VALUE);

    tableCacheFilter = _pDBMng->getTableCacheFilter(tableSet);
    tableCacheMaxSize = _pDBMng->getTableCacheMaxSize(tableSet);

    tableCacheMaxEntry = _pDBMng->getTableCacheMaxEntry(tableSet);
    tableCacheHashRange = _pDBMng->getTableCacheHashRange(tableSet);

    if ( _pDBMng->getQueryCacheMode(tableSet) )
        queryCache = Chain(XML_ON_VALUE);
    else
	queryCache = Chain(XML_OFF_VALUE);

    queryCacheMaxEntry = _pDBMng->getMaxQueryCacheEntry(tableSet);
    queryCacheMaxSize = _pDBMng->getMaxQueryCacheSize(tableSet);
    queryCacheThreshold = _pDBMng->getQueryCacheThreshold(tableSet);
    queryCacheHashRange = _pDBMng->getQueryCacheHashRange(tableSet);
    
    Element *pTSInfo = new Element(XML_TABLESET_ELEMENT);
    
    pTSInfo->setAttribute(XML_NAME_ATTR, tableSet);
    pTSInfo->setAttribute(XML_RUNSTATE_ATTR, runState);
    pTSInfo->setAttribute(XML_TSROOT_ATTR, tsRoot);
    pTSInfo->setAttribute(XML_TSTICKET_ATTR, tsTicket);
    pTSInfo->setAttribute(XML_TSINITFILE_ATTR, tsInitFile);
    pTSInfo->setAttribute(XML_CHECKPOINT_ATTR, Chain(checkpoint));
    
    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
    unsigned long long clsn = _pDBMng->getCommittedLSN(tableSet);
    unsigned long long wlsn = _pDBMng->getCurrentLSN(tabSetId);
    
    unsigned long long tid = _pDBMng->getTID(tableSet);
    unsigned long long sortAreaSize = _pDBMng->getTSSortAreaSize(tabSetId);
    Chain branchId = _pDBMng->getTableSetBackupBranch(tableSet);

    if ( _pDBMng->checkPointDumpEnabled(tabSetId) )
        cpDump = Chain(XML_ON_VALUE);
    else
	cpDump = Chain(XML_OFF_VALUE);

    Chain sysFileName = _pDBMng->getSysFileName(tableSet);
    Chain tempFileName = _pDBMng->getTmpFileName(tableSet);
    
    pTSInfo->setAttribute(XML_SYSFILE_ATTR, sysFileName);
    pTSInfo->setAttribute(XML_TEMPFILE_ATTR, tempFileName);
    
    pTSInfo->setAttribute(XML_SORTAREASIZE_ATTR, Chain(sortAreaSize));
    pTSInfo->setAttribute(XML_BRANCHID_ATTR, branchId);    
    pTSInfo->setAttribute(XML_TSID_ATTR, Chain(tabSetId));
    pTSInfo->setAttribute(XML_TID_ATTR, Chain(tid));
    pTSInfo->setAttribute(XML_LSN_ATTR, Chain(clsn));
    pTSInfo->setAttribute(XML_WRITTENLSN_ATTR, Chain(wlsn));
    pTSInfo->setAttribute(XML_ARCHMODE_ATTR, archMode);
    pTSInfo->setAttribute(XML_AUTOCORRECT_ATTR, autoCorrect);
    pTSInfo->setAttribute(XML_APPENDMODE_ATTR, appendMode);
    
    pTSInfo->setAttribute(XML_CPDUMP_ATTR, cpDump);
    
    pTSInfo->setAttribute(XML_TABLECACHE_ATTR, tableCache);
    pTSInfo->setAttribute(XML_QUERYCACHE_ATTR, queryCache);

    pTSInfo->setAttribute(XML_QUERYCACHEMAXENTRY_ATTR, Chain(queryCacheMaxEntry));
    pTSInfo->setAttribute(XML_QUERYCACHEMAXSIZE_ATTR, Chain(queryCacheMaxSize));
    pTSInfo->setAttribute(XML_QUERYCACHETHRESHOLD_ATTR, Chain(queryCacheThreshold));
    pTSInfo->setAttribute(XML_QUERYCACHEHASHRANGE_ATTR, Chain(queryCacheHashRange));
    
    pTSInfo->setAttribute(XML_TABLECACHEFILTER_ATTR, Chain(tableCacheFilter));
    pTSInfo->setAttribute(XML_TABLECACHEMAXSIZE_ATTR, Chain(tableCacheMaxSize));
    pTSInfo->setAttribute(XML_TABLECACHEMAXENTRY_ATTR, Chain(tableCacheMaxEntry));
    pTSInfo->setAttribute(XML_TABLECACHEHASHRANGE_ATTR, Chain(tableCacheHashRange));

    unsigned totalSysPages=0;
    unsigned usedSysPages=0;
    unsigned totalTempPages=0;
    unsigned usedTempPages=0;
    
    Chain status =_pDBMng->getTableSetRunState(tableSet);
    
    if ( status == Chain(XML_ONLINE_VALUE) )
    {
	unsigned sysfid = tabSetId;
	unsigned tmpfid = _pDBMng->getTmpFid(tableSet);
	
	totalSysPages = _pDBMng->getNumPages(sysfid);
	usedSysPages = _pDBMng->getNumUsedPages(sysfid, _pTabMng->getLockHandle());
	totalTempPages = _pDBMng->getNumPages(tmpfid);
	usedTempPages = _pDBMng->getNumUsedPages(tmpfid, _pTabMng->getLockHandle());	    
    }
    else
    {
	totalSysPages = _pDBMng->getSysSize(tableSet);
	totalTempPages = _pDBMng->getTmpSize(tableSet);
    }
    
    pTSInfo->setAttribute(XML_SYSTOTAL_ATTR, Chain(totalSysPages));
    pTSInfo->setAttribute(XML_SYSUSED_ATTR, Chain(usedSysPages));
    
    pTSInfo->setAttribute(XML_TEMPTOTAL_ATTR, Chain(totalTempPages));
    pTSInfo->setAttribute(XML_TEMPUSED_ATTR, Chain(usedTempPages));
    
    ListT<Chain> dfList;
    ListT<unsigned> fidList;
    ListT<unsigned> dfSizeList;
    
    _pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, dfSizeList);
    
    Chain *pFileName = dfList.First();
    unsigned *pFid = fidList.First();
    unsigned *pDFSize = dfSizeList.First();
    
    while ( pFileName && pFid )
    {
	Element *pF = new Element(XML_DATAFILE_ELEMENT);
	pF->setAttribute(XML_NAME_ATTR, *pFileName);
	pF->setAttribute(XML_TYPE_ATTR, Chain(XML_APPFILE_VALUE));
		
	unsigned totalPages = 0;
	unsigned usedPages = 0;
	
	if ( status == Chain(XML_ONLINE_VALUE) )
	{
	    totalPages = _pDBMng->getNumPages(*pFid);
	    usedPages = _pDBMng->getNumUsedPages(*pFid, _pTabMng->getLockHandle());
	}
	else
	{
	    totalPages = *pDFSize;
	}
	
	pF->setAttribute(XML_NUMTOTAL_ATTR, Chain(totalPages));
	pF->setAttribute(XML_NUMUSED_ATTR, Chain(usedPages));
	
	pTSInfo->addContent(pF);
	
	pFileName = dfList.Next();
	pFid = fidList.Next();
	pDFSize = dfSizeList.Next();
    }
    
    dfList.Empty();
    fidList.Empty();
    dfSizeList.Empty();

    _pDBMng->getDataFileInfo(tableSet, Chain(XML_SYSFILE_VALUE), dfList, fidList, dfSizeList);
    pFileName = dfList.First();
    pFid = fidList.First();
    pDFSize = dfSizeList.First();
    
    while ( pFileName && pFid )
    {	
	Element *pF = new Element(XML_DATAFILE_ELEMENT);
	pF->setAttribute(XML_NAME_ATTR, *pFileName);
	pF->setAttribute(XML_TYPE_ATTR, Chain(XML_SYSFILE_VALUE));
	
	unsigned totalPages = 0;
	unsigned usedPages = 0;
	
	if ( status == Chain(XML_ONLINE_VALUE) )
	{
	    totalPages = _pDBMng->getNumPages(*pFid);
	    usedPages = _pDBMng->getNumUsedPages(*pFid, _pTabMng->getLockHandle());
	}
	else
	{
	    totalPages = *pDFSize;
	}
	
	pF->setAttribute(XML_NUMTOTAL_ATTR, Chain(totalPages));
	pF->setAttribute(XML_NUMUSED_ATTR, Chain(usedPages));
	
	pTSInfo->addContent(pF);
	
	pFileName = dfList.Next();
	pFid = fidList.Next();
	pDFSize = dfSizeList.Next();
    }
    
    dfList.Empty();
    fidList.Empty();
    dfSizeList.Empty();

    _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, dfSizeList);
    pFileName = dfList.First();
    pFid = fidList.First();
    pDFSize = dfSizeList.First();
    
    while ( pFileName && pFid )
    {	
	Element *pF = new Element(XML_DATAFILE_ELEMENT);
	pF->setAttribute(XML_NAME_ATTR, *pFileName);
	pF->setAttribute(XML_TYPE_ATTR, Chain(XML_TEMPFILE_VALUE));
	
	unsigned totalPages = 0;
	unsigned usedPages = 0;
	
	if ( status == Chain(XML_ONLINE_VALUE) )
	{
	    totalPages = _pDBMng->getNumPages(*pFid);
	    usedPages = _pDBMng->getNumUsedPages(*pFid, _pTabMng->getLockHandle());
	}
	else
	{
	    totalPages = *pDFSize;
	}
	
	pF->setAttribute(XML_NUMTOTAL_ATTR, Chain(totalPages));
	pF->setAttribute(XML_NUMUSED_ATTR, Chain(usedPages));
	
	pTSInfo->addContent(pF);
	
	pFileName = dfList.Next();
	pFid = fidList.Next();	
	pDFSize = dfSizeList.Next();
    }
    
    ListT<Chain> lfList;
    ListT<unsigned> sizeList;
    ListT<Chain> statusList;
    
    _pDBMng->getLogFileInfo(tableSet, lfList, sizeList, statusList);	
    
    Chain *pLogName = lfList.First();
    unsigned *pSize= sizeList.First();
    Chain *pStatus = statusList.First();
    
    while ( pLogName && pSize && pStatus )
    {
	Element *pLE = new Element(XML_LOGFILE_ELEMENT);
	pLE->setAttribute(XML_NAME_ATTR, *pLogName);
	pLE->setAttribute(XML_SIZE_ATTR, Chain(*pSize));
	
	pLE->setAttribute(XML_STATUS_ATTR, *pStatus);

	if ( *pStatus == Chain(XML_ACTIVE_VALUE) )
	{
	    pLE->setAttribute(XML_OFFSET_ATTR, Chain(_pDBMng->getLogOffset(tabSetId)));
	}
	else
	{
	    pLE->setAttribute(XML_OFFSET_ATTR, Chain(0));
	}
	
	pTSInfo->addContent(pLE);
	
	pLogName = lfList.Next();
	pSize = sizeList.Next();
	pStatus = statusList.Next();
    }
          
    return pTSInfo; 
}


Element* CegoAdminThread::getArchLogInfo(const Chain& tableSet)
{
    Element *pArchInfo = new Element(XML_ARCHINFO_ELEMENT);

    ListT<Chain> archIdList;
    ListT<Chain> archPathList;

    _pDBMng->getArchLogInfo(tableSet, archIdList, archPathList);
    
    Chain branch = _pDBMng->getTableSetBackupBranch(tableSet);
    
    Chain *pArchId = archIdList.First();
    Chain *pArchPath = archPathList.First();
    
    while ( pArchId && pArchPath)
    {	
	Element *pNAL = new Element(XML_ARCHIVELOG_ELEMENT);
	pNAL->setAttribute(XML_ARCHID_ATTR, *pArchId);
	pNAL->setAttribute(XML_ARCHPATH_ATTR, *pArchPath);

	// retrive num files for archive for archive destination
	
	Directory archDir(*pArchPath);
	ListT<Chain> fileList = archDir.list();

	unsigned numFile=0;
	for ( Chain *pF = fileList.First(); pF != 0; pF = fileList.Next() )
	{
	    Tokenizer tok(*pF, Chain(LOGMNG_ARCHLOGSEP));
	    Chain ts,br;
	    if ( tok.nextToken(ts) )
		if ( ts == tableSet )
		    if ( tok.nextToken(br) )
			if ( br == branch )
			    numFile++;
	}
	
	pNAL->setAttribute(XML_NUMFILE_ATTR, Chain(numFile));

	// retrive num files for archive for log manager

	Chain numArchived = executeLogInfo(tableSet, *pArchPath);
	pNAL->setAttribute(XML_NUMARCHIVED_ATTR, numArchived);	
	
	pArchInfo->addContent(pNAL);

	pArchId = archIdList.Next();	
	pArchPath = archPathList.Next();
    }

    return pArchInfo;
}

void CegoAdminThread::addTableSetUsage(Element *pTSE)
{
    Chain tableSet = pTSE->getAttributeValue(XML_NAME_ATTR);
    
    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
    
    unsigned totalSysPages=0;
    unsigned usedSysPages=0;
    unsigned totalTempPages=0;
    unsigned usedTempPages=0;
    unsigned totalAppPages=0;
    unsigned usedAppPages=0;
   
    Chain status =_pDBMng->getTableSetRunState(tableSet);
    
    if ( status == Chain(XML_ONLINE_VALUE) )
    {
	unsigned sysfid = tabSetId;
	unsigned tmpfid = _pDBMng->getTmpFid(tableSet);
	
	totalSysPages = _pDBMng->getNumPages(sysfid);
	usedSysPages = _pDBMng->getNumUsedPages(sysfid, _pTabMng->getLockHandle());
	totalTempPages = _pDBMng->getNumPages(tmpfid);
	usedTempPages = _pDBMng->getNumUsedPages(tmpfid, _pTabMng->getLockHandle());	    
    }
    
    ListT<Chain> dfList;
    ListT<unsigned> fidList;
    ListT<unsigned> dfSizeList;
    
    _pDBMng->getDataFileInfo(tableSet, Chain(XML_APPFILE_VALUE), dfList, fidList, dfSizeList);
    
    Chain *pFileName = dfList.First();
    unsigned *pFid = fidList.First();
    
    while ( pFileName && pFid )
    {	
	unsigned totalPages = 0;
	unsigned usedPages = 0;
	
	if ( status == Chain(XML_ONLINE_VALUE) )
	{
	    totalPages = _pDBMng->getNumPages(*pFid);
	    usedPages = _pDBMng->getNumUsedPages(*pFid, _pTabMng->getLockHandle());
	}

	totalAppPages+=totalPages;
	usedAppPages+=usedPages;

	pFileName = dfList.Next();
	pFid = fidList.Next();
    }

    dfList.Empty();
    fidList.Empty();
    dfSizeList.Empty();

    _pDBMng->getDataFileInfo(tableSet, Chain(XML_SYSFILE_VALUE), dfList, fidList, dfSizeList);
    pFileName = dfList.First();
    pFid = fidList.First();
    
    while ( pFileName && pFid )
    {		
	unsigned totalPages = 0;
	unsigned usedPages = 0;
	
	if ( status == Chain(XML_ONLINE_VALUE) )
	{
	    totalPages = _pDBMng->getNumPages(*pFid);
	    usedPages = _pDBMng->getNumUsedPages(*pFid, _pTabMng->getLockHandle());
	}

	totalSysPages+=totalPages;
	usedSysPages+=usedPages;
		
	pFileName = dfList.Next();
	pFid = fidList.Next();
    }

    dfList.Empty();
    fidList.Empty();
    dfSizeList.Empty();

    _pDBMng->getDataFileInfo(tableSet, Chain(XML_TEMPFILE_VALUE), dfList, fidList, dfSizeList);
    pFileName = dfList.First();
    pFid = fidList.First();
    
    while ( pFileName && pFid )
    {		
	unsigned totalPages = 0;
	unsigned usedPages = 0;
	
	if ( status == Chain(XML_ONLINE_VALUE) )
	{
	    totalPages = _pDBMng->getNumPages(*pFid);
	    usedPages = _pDBMng->getNumUsedPages(*pFid, _pTabMng->getLockHandle());
	}

	totalTempPages+=totalPages;
	usedTempPages+=usedPages;
	       
	pFileName = dfList.Next();
	pFid = fidList.Next();
    }

    unsigned percentSysUsage = 0;
    if ( totalSysPages > 0 )
	percentSysUsage = usedSysPages  / ( totalSysPages  / 100 );

    unsigned percentTempUsage = 0;
    if ( totalTempPages > 0 )
	percentTempUsage = usedTempPages  / ( totalTempPages  / 100 );

    unsigned percentAppUsage = 0;
    if ( totalAppPages > 0 )
	percentAppUsage = usedAppPages  / ( totalAppPages  / 100 );

    pTSE->setAttribute(XML_SYSUSAGE_ATTR, Chain(percentSysUsage) + Chain("%"));  
    pTSE->setAttribute(XML_TEMPUSAGE_ATTR, Chain(percentTempUsage) + Chain("%"));  
    pTSE->setAttribute(XML_APPUSAGE_ATTR, Chain(percentAppUsage) + Chain("%"));
}

Element* CegoAdminThread::getTransactionInfo(const Chain& tableSet)
{
    Element *pTA = new Element(XML_TAINFO_ELEMENT);

    CegoTransactionManager *pTM = _pTabMng->getTransactionManager();

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    ListT<Chain> rboList;    

    _pTabMng->getObjectList(tabSetId, CegoObject::RBSEG, rboList);
    
    Chain *pRBO = rboList.First();
    while ( pRBO )
    {
	Element *pTE = new Element(XML_TAENTRY_ELEMENT);
	
	unsigned numOp;
	pTM->getTransactionInfo(tabSetId, *pRBO, numOp);
	pTE->setAttribute(XML_RBO_ATTR, *pRBO);
	pTE->setAttribute(XML_NUMOP_ATTR, Chain(numOp));
	
	pTA->addContent(pTE);
	pRBO = rboList.Next();
    }   
    return pTA;
}

Element* CegoAdminThread::getBUStatInfo(const Chain& tableSet)
{
    Chain status = _pDBMng->getTableSetRunState(tableSet);
    if ( status != Chain(XML_ONLINE_VALUE) )
    {
	throw Exception(EXLOC, "Tableset must be online to list backup statistics");
    }

    Element *pBUS = new Element(XML_BUSINFO_ELEMENT);

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    CegoTableObject boe;    
    _pTabMng->getObject(tabSetId, Chain(SYSTAB_BUSTAT_ID), CegoObject::SYSTEM, boe);
    ListT<CegoField> fvl = boe.getSchema();

    CegoObjectCursor* pC = _pTabMng->getObjectCursor(tabSetId, SYSTAB_BUSTAT_ID, SYSTAB_BUSTAT_ID, CegoObject::SYSTEM);
    
    CegoDataPointer dp;    
    unsigned len;
    char *pc;
    
    pc = (char*)pC->getFirst(len, dp);		
    
    while ( pc && len > 0 )
    {
	unsigned long long tid;
	unsigned long long tastep;	    
	CegoTupleState ts;
       
	unsigned toff = CegoQueryHelper::decodeTupleHeader(tid, tastep, ts, pc);

	char* tp = pc + toff;
        unsigned tlen = len - toff;
	
	CegoQueryHelper::decodeFVL(fvl, tp, tlen);			    

	Element *pBUE = new Element(XML_BUENTRY_ELEMENT);
		
	CegoField *pF = fvl.First();
	while ( pF )	    
	{
	    if ( pF->getAttrName() == Chain(SYSTAB_TS_ATTR) )		
		pBUE->setAttribute(XML_TIMESTAMP_ATTR, pF->getValue().valAsChain());
	    else if ( pF->getAttrName() == Chain(SYSTAB_BUINFO_ATTR) )
		pBUE->setAttribute(XML_BUINFO_ATTR, pF->getValue().valAsChain());
	    else if ( pF->getAttrName() == Chain(SYSTAB_BUMSG_ATTR) )
	    {
		if ( pF->getValue().isNull() )
		    pBUE->setAttribute(XML_BUMSG_ATTR, Chain("none"));
		else			 
		    pBUE->setAttribute(XML_BUMSG_ATTR, pF->getValue().valAsChain());   
	    }
	    pF = fvl.Next();
	}
	
	pBUS->addContent(pBUE);

	pc = (char*)pC->getNext(len, dp);
    }

    pC->abort();
    delete pC;
   
    return pBUS;
}

Element* CegoAdminThread::getBackupInfo(const Chain& tableSet, const Chain& pit)
{
    Element *pBI = new Element(XML_BACKUPLIST_ELEMENT);

    ListT<Chain> backupList = executeListBackup(tableSet, pit);
        
    Chain *pBackup = backupList.First();

    while ( pBackup )
    {
	Element *pBE = new Element(XML_BACKUP_ELEMENT);

	Tokenizer t(*pBackup, Chain(","));

	Chain backupID;
	Chain backupTS;
	Chain logTS;
	
	if ( t.nextToken(backupID) == false )
	{
	    throw Exception(EXLOC, Chain("Invalid id token from backup manager : ") + Chain(*pBackup));
	}

	if ( t.nextToken(backupTS) == false )
	{
	    throw Exception(EXLOC, Chain("Invalid ts token from backup manager : ") + Chain(*pBackup));
	}

	if ( t.nextToken(logTS) == false )
	{
	    // we accept empty logTS token, since there might be still no archive logs available
	    // throw Exception(EXLOC, Chain("Invalid backup list from backup manager"));
	}
	
	pBE->setAttribute(XML_BACKUPID_ATTR, backupID);
	pBE->setAttribute(XML_BACKUPTS_ATTR, backupTS);
	pBE->setAttribute(XML_LOGTS_ATTR, logTS);
	pBI->addContent(pBE);

	pBackup = backupList.Next();
    }

    return pBI;
}

Element* CegoAdminThread::getObjectInfo(const Chain& tableSet)
{
    Element *pOI = new Element(XML_OBJLIST_ELEMENT);

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    ListT<Chain> tableList;
    _pTabMng->getObjectList(tabSetId, CegoObject::TABLE, tableList);

    Chain *pTableName = tableList.First();

    while ( pTableName )
    {
	Element *pOE = new Element(XML_OBJ_ELEMENT);
	
	pOE->setAttribute(XML_OBJTYPE_ATTR, XML_TABOBJ_VALUE);
	pOE->setAttribute(XML_OBJNAME_ATTR, *pTableName);	
	pOI->addContent(pOE);

	pTableName = tableList.Next();
    }

    ListT<Chain> idxList;
    _pTabMng->getObjectList(tabSetId, CegoObject::AVLTREE, idxList);

    Chain *pIndexName = idxList.First();

    while ( pIndexName )
    {
	Element *pOE = new Element(XML_OBJ_ELEMENT);
	
	pOE->setAttribute(XML_OBJTYPE_ATTR, XML_IDXOBJ_VALUE);
	pOE->setAttribute(XML_OBJNAME_ATTR, *pIndexName);	
	pOI->addContent(pOE);

	pIndexName = idxList.Next();
    }

    ListT<Chain> keyList;
    _pTabMng->getObjectList(tabSetId, CegoObject::FKEY, keyList);

    Chain *pKeyName = keyList.First();

    while ( pKeyName )
    {
	Element *pOE = new Element(XML_OBJ_ELEMENT);
	
	pOE->setAttribute(XML_OBJTYPE_ATTR, XML_FKEYOBJ_VALUE);
	pOE->setAttribute(XML_OBJNAME_ATTR, *pKeyName);	
	pOI->addContent(pOE);

	pKeyName = keyList.Next();
    }

    ListT<Chain> checkList;
    _pTabMng->getObjectList(tabSetId, CegoObject::CHECK, checkList);

    Chain *pCheckName = checkList.First();

    while ( pCheckName )
    {
	Element *pOE = new Element(XML_OBJ_ELEMENT);
	
	pOE->setAttribute(XML_OBJTYPE_ATTR, XML_CHECKOBJ_VALUE);
	pOE->setAttribute(XML_OBJNAME_ATTR, *pCheckName);	
	pOI->addContent(pOE);

	pCheckName = checkList.Next();
    }

    ListT<Chain> viewList;
    _pTabMng->getObjectList(tabSetId, CegoObject::VIEW, viewList);

    Chain *pViewName = viewList.First();

    while ( pViewName )
    {
	Element *pOE = new Element(XML_OBJ_ELEMENT);
	
	pOE->setAttribute(XML_OBJTYPE_ATTR, XML_VIEWOBJ_VALUE);
	pOE->setAttribute(XML_OBJNAME_ATTR, *pViewName);	
	pOI->addContent(pOE);

	pViewName = viewList.Next();
    }

    ListT<Chain> procList;
    _pTabMng->getObjectList(tabSetId, CegoObject::PROCEDURE, procList);

    Chain *pProcName = procList.First();

    while ( pProcName )
    {
	Element *pOE = new Element(XML_OBJ_ELEMENT);
	
	pOE->setAttribute(XML_OBJTYPE_ATTR, XML_PROCOBJ_VALUE);
	pOE->setAttribute(XML_OBJNAME_ATTR, *pProcName);	
	pOI->addContent(pOE);

	pProcName = procList.Next();
    }
    
    return pOI;
}


Chain CegoAdminThread::executeBackup(CegoAdminHandler* pAH, const Chain& tableSet, const Chain& msg)
{

    if ( _pDBMng->getTableSetRunState(tableSet) == Chain(XML_OFFLINE_VALUE) )
    {
	_pTabMng->extractTicket(tableSet);
    }
    else if ( _pDBMng->getTableSetRunState(tableSet) != Chain(XML_BACKUP_VALUE) )
    {
	throw Exception(EXLOC, Chain("Tableset must be in status OFFLINE or BACKUP"));
    }

    ListT<Chain> fileList;

    Chain tsTicket = _pDBMng->getTSTicket(tableSet);
    fileList.Insert(tsTicket);
    
    Chain sysFileName = _pDBMng->getSysFileName(tableSet);
    fileList.Insert(sysFileName);

    Chain tempFileName = _pDBMng->getTmpFileName(tableSet);
    fileList.Insert(tempFileName);
    
    ListT<Chain> dataFileList;
    _pDBMng->getDataFileInfo(tableSet, dataFileList);
    
    Chain *pDataFileName = dataFileList.First();
    while ( pDataFileName )
    {
	fileList.Insert(*pDataFileName);
	pDataFileName = dataFileList.Next();
    }

    Chain backupProg = _pDBMng->getBackupProg();
    
    if ( backupProg == Chain() )
    {
	throw Exception(EXLOC, Chain("No backup manager defined"));	
    }

    if ( File::exists(backupProg) == false )
    {
	throw Exception(EXLOC, Chain("Backup manager program <") + backupProg + Chain("> does not exist"));
    }

    Chain branch = _pDBMng->getTableSetBackupBranch(tableSet);
    
    Chain backupCommand = backupProg + Chain(" -t ") + tableSet
	+ Chain(" -b \"") + branch + Chain("\"")
	+ Chain(" -a \"");
    
    Chain *pFileName = fileList.First();
    while ( pFileName )
    {
	backupCommand += *pFileName;
	pFileName = fileList.Next();
	if ( pFileName )
	    backupCommand += Chain(" ");
    }
    backupCommand += Chain("\"");
    
    BackupStream buStream(pAH);

    buStream.open(backupCommand);

    if ( _pDBMng->getTableSetRunState(tableSet) == Chain(XML_OFFLINE_VALUE) )
    {
	Chain tsTicketName = _pDBMng->getTSTicket(tableSet);
	File tsTicket(tsTicketName);
	tsTicket.remove();
    }
    
    return Chain("OK");
}

ListT<Chain> CegoAdminThread::executeListBackup(const Chain& tableSet, const Chain& pit)
{
    Chain backupProg = _pDBMng->getBackupProg();

    if ( backupProg == Chain() )
    {
	throw Exception(EXLOC, Chain("No backup manager defined"));	
    }
    
    if ( File::exists(backupProg) == false )
    {
	throw Exception(EXLOC, Chain("Backup manager program <") + backupProg + Chain("> does not exist"));	
    }

    Chain branch = _pDBMng->getTableSetBackupBranch(tableSet);
    Chain backupCommand = backupProg + Chain(" -t ") + tableSet;
    if ( pit != Chain() )
	backupCommand += Chain(" -p \"") + pit + Chain("\"");
    backupCommand += Chain(" -b \"") + branch + Chain("\"")
	+ Chain(" -l ");
    
    Chain backupInfo = CommandExecuter::executeStream(backupCommand);
    Tokenizer t(backupInfo, Chain("\n"));
    Chain backupId;
    ListT<Chain> backupList;
    while ( t.nextToken(backupId) )
    {
	backupList.Insert(backupId);
    }
    return backupList;
}

Chain CegoAdminThread::executeRestore(CegoAdminHandler* pAH, const Chain& tableSet, const Chain& backupId)
{    
    Chain backupProg = _pDBMng->getBackupProg();

    if ( backupProg == Chain() )
    {
	throw Exception(EXLOC, Chain("No backup manager defined"));	
    }
	
    if ( File::exists(backupProg) == false )
    {
	throw Exception(EXLOC, Chain("Backup manager program <") + backupProg + Chain("> does not exist"));	
    }

    Chain branch = _pDBMng->getTableSetBackupBranch(tableSet);
    
    Chain restoreCommand = backupProg + Chain(" -t ") + tableSet
	+ Chain(" -b \"") + branch + Chain("\"")
	+ Chain(" -r ") + backupId;

    BackupStream buStream(pAH);

    buStream.open(restoreCommand);


    Chain tsTicketName = _pDBMng->getTSTicket(tableSet);
    
    File tsTicket(tsTicketName);
    if ( tsTicket.exists() ) 
    {
	tsTicket.open(File::READ);
	
	XMLSuite xml;
	
	Document *pDoc = new Document;
	pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
	
	xml.setDocument(pDoc);    
	xml.setFile(&tsTicket);
	
	xml.parse();
	
	Element *pRoot = pDoc->getRootElement();
	pDoc->setRootElement(0);
	delete pDoc;
		
	_pDBMng->setTableSetInfo(tableSet, pRoot);
	
	tsTicket.close();
    
#ifdef CGDEBUG	
	_pDBMng->log(_modId, Logger::DEBUG, Chain("Removing backup ticket ") + tsTicket.getFileName() + Chain(" ..."));
#endif
	    
	tsTicket.remove();

	// in case of an online backup, we have to indicate an incomplete status, where file recovery is needed
	Chain status = _pDBMng->getTableSetRunState(tableSet);
	if ( status == Chain(XML_ONLINE_VALUE) )
	{	    	    
	    _pDBMng->setTableSetRunState(tableSet, XML_INCOMPLETE_VALUE);
	}	    
    }
    else
    {
	throw Exception(EXLOC, Chain("Ticket ") + tsTicketName + Chain(" not found"));
    }

    return Chain("OK");
}

Chain CegoAdminThread::executeLogInfo(const Chain& tableSet, const Chain& archPath)
{    

    Chain logmngProg = _pDBMng->getArchRestoreProg();
    Chain branch = _pDBMng->getTableSetBackupBranch(tableSet);
    
    if ( logmngProg == Chain() )
    {
	throw Exception(EXLOC, Chain("No log manager defined"));	
    }
	
    if ( File::exists(logmngProg) == false )
    {
	throw Exception(EXLOC, Chain("Log manager program <") + logmngProg + Chain("> does not exist"));	
    }

    LogInfoStream infoStream;
    
    try
    {
	Chain infoCommand = logmngProg + Chain(" -m list -t ") + tableSet
	    + Chain(" -p \"") + archPath + Chain("\"")
	    + Chain(" -b \"") + branch + Chain("\"")
	    + Chain(" -o numarchived") ;
		
	infoStream.open(infoCommand);	
    }
    catch ( Exception e)
    {
	Chain msg;
	e.pop(msg);
	
	Chain m = Chain("Log Manager Error ") + msg;
	throw Exception(EXLOC, m);
    }

    return infoStream.getResult().cutTrailing(" \n");
}
