///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoXPorter.cc
// -----------------
// Cego export and import 
//                                                         
// Design and Implementation by Bjoern Lemke               
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoXPorter
// 
// Description: Tableset export methods ( binary and xml )
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// cego includes
#include "CegoXPorter.h"
#include "CegoXMLdef.h"
#include "CegoExpOutStream.h"
#include "CegoImpInStream.h"
#include "CegoTypeConverter.h"
#include "CegoDataType.h"
#include "CegoAction.h"

// needed for malloc
#include <string.h>
#include <stdlib.h>

CegoXPorter::CegoXPorter(CegoQueryManager* pGTM, CegoAdminHandler* pAH)
{
    _pGTM = pGTM;
    _pDBMng = pGTM->getDBMng();
    _modId = _pDBMng->getModId("CegoXPorter");
    _pAH = pAH;
}

CegoXPorter::~CegoXPorter()
{  
}

void CegoXPorter::xmlImportTableSet(const Chain& tableSet, bool isStructure, const Chain& impFile)
{
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Importing tableset ") + tableSet + Chain("..."));
    _pGTM->setAppend(true);
    
    XMLSuite xml;
    
    File *pInFile = new File(impFile);
    CegoImpInStream* pInStream = 0;
    Document *pDoc = new Document(XML_IMPORT_DOC);
	
    try
    {	
	pInFile->open(File::READ);
	
	if ( isStructure == false )
	{
	    pInStream = new CegoImpInStream(tableSet, _pGTM, _pAH);
	}

	pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
	
	xml.setDocument(pDoc);    
	xml.setFile(pInFile);
	xml.setInStream(pInStream);
	
	xml.parse();
	
	if ( pInStream )
	{
	    delete pInStream;
	    pInStream = 0;
	}
	pInFile->close();
	delete pInFile;
	pInFile = 0;
	
	Element *pRoot = pDoc->getRootElement();
	
	// index import
	
	ListT<Element*> idxList = pRoot->getChildren(XML_INDEX_ELEMENT);
	Element **pIdxElement = idxList.First();
	while ( pIdxElement )
	{
	    Chain idxName = (*pIdxElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain tabName = (*pIdxElement)->getAttributeValue(XML_TABLENAME_ATTR);	
	    
	    CegoObject::ObjectType idxType;
	    
	    if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_INDEX_VALUE) )
		idxType = CegoObject::AVLTREE;
	    else if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_PINDEX_VALUE) )
		idxType = CegoObject::PAVLTREE;
	    else if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_UINDEX_VALUE) )
		idxType = CegoObject::UAVLTREE;
	    else if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_BTREE_VALUE) )
		idxType = CegoObject::BTREE;
	    else if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_PBTREE_VALUE) )
		idxType = CegoObject::PBTREE;
	    else if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_UBTREE_VALUE) )
		idxType = CegoObject::UBTREE;
	    else
		throw Exception(EXLOC, Chain("Unknown index type"));
	    
	    Chain info;
	    if ( idxType == CegoObject::AVLTREE 
		 || idxType == CegoObject::PAVLTREE 
	     || idxType == CegoObject::UAVLTREE ) 
		info = Chain("Importing index ") + idxName + Chain("...");
	    else
		info = Chain("Importing btree ") + idxName + Chain("...");
	    
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    ListT<Element*> schemaList = (*pIdxElement)->getChildren(XML_SCHEMA_ELEMENT);
	    
	    Element **pSchemaElement = schemaList.First();
	    
	    if ( pSchemaElement )
	    {
		ListT<Element*> colList = (*pSchemaElement)->getChildren(XML_COL_ELEMENT);
		ListT<CegoField> fl;
		Element **pCol = colList.First();
		while ( pCol ) 
		{	    
		    Chain colName = (*pCol)->getAttributeValue(XML_COLNAME_ATTR);
		    Chain colType = (*pCol)->getAttributeValue(XML_COLTYPE_ATTR);
		    Chain colNullable = (*pCol)->getAttributeValue(XML_COLNULLABLE_ATTR);
		    bool isNullable;
		    if ( colNullable == Chain(XML_TRUE_VALUE) ) 
			isNullable = true;
		    else
			isNullable = false;
		    
		    CegoDataType dt = CegoTypeConverter::getTypeId( colType );

		    unsigned colSize;
		    
		    if (dt == VARCHAR_TYPE
			|| dt == BIGINT_TYPE
			|| dt == DECIMAL_TYPE )
		    {
			colSize = (*pCol)->getAttributeValue(XML_COLSIZE_ATTR).asUnsigned();
		    }
		    else
		    {
			colSize = CegoTypeConverter::getTypeLen( dt );
		    }

		    unsigned colDim;
		    
		    if ( dt == DECIMAL_TYPE )
		    {
			// backward compatibility to cego version 2.45.x
			// there is still no COLDIM value specified
			// in this case, we use colSize as dim value and setup colSize to reserved len
			Chain dimCheck = (*pCol)->getAttributeValue(XML_COLDIM_ATTR);
			if ( dimCheck == Chain() )
			{
			    colDim = colSize;
			    colSize = RESERVED_BTREE_FLOATLEN;
			}
			else
			{
			    colDim = dimCheck.asUnsigned();
			}
		    }
		    else
		    {
			colDim = 0;
		    }
		    
		    Chain colDefValue = (*pCol)->getAttributeValue(XML_COLDEFVALUE_ATTR);
		    CegoFieldValue defValue;
		    
		    if ( colDefValue != Chain() )		    
			defValue = CegoFieldValue(dt, colDefValue);
		    
		    CegoField f(CegoField(tabName, tabName, colName, dt, colSize, colDim, defValue, isNullable));
		    fl.Insert(f);
		    
		    pCol = colList.Next();
		}		
		
		_pGTM->createQueryIndex(tableSet, idxName, tabName, fl, idxType);
	    }
	    
	    pIdxElement = idxList.Next();
	}
	
	// key import
	
	ListT<Element*> fkeyList = pRoot->getChildren(XML_FKEY_ELEMENT);
	Element **pFKeyElement = fkeyList.First();
	while ( pFKeyElement )
	{
	    Chain fkey = (*pFKeyElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain tableName = (*pFKeyElement)->getAttributeValue(XML_TABLENAME_ATTR);	
	    Chain refTable = (*pFKeyElement)->getAttributeValue(XML_REFTABLENAME_ATTR);	
	    
	    Chain info = Chain("Importing foreign key ") + fkey + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    ListT<Element*> keySchemaList = (*pFKeyElement)->getChildren(XML_KEYSCHEMA_ELEMENT);
	    
	    Element **pKeySchemaElement = keySchemaList.First();
	    
	    ListT<CegoField> keyList;
	    if ( pKeySchemaElement )
	    {
		ListT<Element*> colList = (*pKeySchemaElement)->getChildren(XML_COL_ELEMENT);
		ListT<CegoField> fl;
		Element **pCol = colList.First();
		while ( pCol ) 
		{
		    Chain colName = (*pCol)->getAttributeValue(XML_COLNAME_ATTR);		
		    keyList.Insert(CegoField(Chain(), colName));		
		    pCol = colList.Next();
		}
	    }
	    
	    ListT<Element*> refSchemaList = (*pFKeyElement)->getChildren(XML_REFSCHEMA_ELEMENT);
	    
	    Element **pRefSchemaElement = refSchemaList.First();
	    
	    ListT<CegoField> refList;
	    if ( pRefSchemaElement )
	    {
		ListT<Element*> colList = (*pKeySchemaElement)->getChildren(XML_COL_ELEMENT);
		ListT<CegoField> fl;
		Element **pCol = colList.First();
		while ( pCol ) 
		{
		    Chain colName = (*pCol)->getAttributeValue(XML_COLNAME_ATTR);		
		    refList.Insert(CegoField(Chain(), colName));		
		    pCol = colList.Next();
		}
	    }
	    
	    _pGTM->createQueryForeignKey(tableSet, fkey, tableName, keyList, refTable, refList);
	    
	    pFKeyElement = fkeyList.Next();
	}
	
	// check import
	
	ListT<Element*> checkList = pRoot->getChildren(XML_CHECK_ELEMENT);
	Element **pCheckElement = checkList.First();
	while ( pCheckElement )
	{
	    Chain checkName = (*pCheckElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain tableName = (*pCheckElement)->getAttributeValue(XML_TABLENAME_ATTR);	
	    	    
	    Chain info = Chain("Importing check ") + checkName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    	    
	    Chain condString = (*pCheckElement)->getAttributeValue(XML_COND_ATTR);
	    
	    Chain loadString = Chain("load condition ") + condString + Chain(";");
	    
	    CegoAction *pPA = new CegoAction(_pGTM);
	    
	    pPA->setTableSet(tableSet);
	    pPA->setCommandChain(loadString);
	    pPA->parse();
	    pPA->execute();
	    
	    CegoCondition* pCond = pPA->getCondition(true);

	    delete pPA;
	    
	    CegoPredicate *pPred;
	    if ( pCond->getCondType() == CegoCondition::PRED  )
	    {
		pPred = pCond->Left();
		pCond->setLeft(0);
		delete pCond;
	    }
	    else
	    {
		pPred = new CegoPredicate(pCond);
	    }
	    
	    _pGTM->createQueryCheck(tableSet, checkName, tableName, pPred);
	    	    
	    pCheckElement = checkList.Next();
	}
	
	// trigger import
	
	ListT<Element*> triggerList = pRoot->getChildren(XML_TRIGGER_ELEMENT);
	Element **pTriggerElement = triggerList.First();
	while ( pTriggerElement )
	{
	    Chain triggerName = (*pTriggerElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain tableName = (*pTriggerElement)->getAttributeValue(XML_TABLENAME_ATTR);
	    Chain triggerText = (*pTriggerElement)->getAttributeValue(XML_TRIGGERTEXT_ATTR);	

	    bool isBefore;
	    Chain isBeforeTag = (*pTriggerElement)->getAttributeValue(XML_ISBEFORE_ATTR);	
	    if ( isBeforeTag == Chain(XML_TRUE_VALUE) ) 
		isBefore = true;
	    else
		isBefore = false;

	    bool isOnInsert;
	    Chain isOnInsertTag = (*pTriggerElement)->getAttributeValue(XML_ISONINSERT_ATTR);	
	    if ( isOnInsertTag == Chain(XML_TRUE_VALUE) ) 
		isOnInsert = true;
	    else
		isOnInsert = false;

	    bool isOnUpdate;
	    Chain isOnUpdateTag = (*pTriggerElement)->getAttributeValue(XML_ISONUPDATE_ATTR);	
	    if ( isOnUpdateTag == Chain(XML_TRUE_VALUE) ) 
		isOnUpdate = true;
	    else
		isOnUpdate = false;

	    bool isOnDelete;
	    Chain isOnDeleteTag = (*pTriggerElement)->getAttributeValue(XML_ISONDELETE_ATTR);	
	    if ( isOnDeleteTag == Chain(XML_TRUE_VALUE) ) 
		isOnDelete = true;
	    else
		isOnDelete = false;
	    
	    Chain info = Chain("Importing trigger ") + triggerName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    	    	    
	    _pGTM->createQueryTrigger(tableSet, triggerName,
				     isBefore, isOnInsert, isOnUpdate, isOnDelete,
				     tableName, triggerText);

	    pTriggerElement = triggerList.Next();
	}

	// alias import

	ListT<Element*> aliasList = pRoot->getChildren(XML_ALIAS_ELEMENT);
	Element **pAliasElement = aliasList.First();
	while ( pAliasElement )
	{
	    Chain aliasName = (*pAliasElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain tableName = (*pAliasElement)->getAttributeValue(XML_TABLENAME_ATTR);
	    	    
	    Chain info = Chain("Importing alias ") + aliasName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);

	    ListT<CegoAttrAlias> aliasAttrList;

	    ListT<Element*> colList = (*pAliasElement)->getChildren(XML_COL_ELEMENT);
	    Element **pCol = colList.First();
	    while ( pCol ) 
	    {
		Chain colName = (*pCol)->getAttributeValue(XML_COLNAME_ATTR);
		Chain colAlias = (*pCol)->getAttributeValue(XML_COLALIAS_ATTR);
		aliasAttrList.Insert( CegoAttrAlias(colName, colAlias));
		pCol = colList.Next();
	    }

	    _pGTM->createQueryAlias(tableSet, aliasName,
				   tableName, aliasAttrList); 	    	   
	    
	    pAliasElement = aliasList.Next();
	}
	
	// view import
	
	ListT<Element*> viewList = pRoot->getChildren(XML_VIEW_ELEMENT);
	Element **pViewElement = viewList.First();
	while ( pViewElement )
	{
	    Chain viewName = (*pViewElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain viewStmt = (*pViewElement)->getAttributeValue(XML_VIEWSTMT_ATTR);	
	        
	    Chain info = Chain("Importing view ") + viewName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    ListT<Element*> viewSchemaList = (*pViewElement)->getChildren(XML_SCHEMA_ELEMENT);
	    
	    Element **pViewSchemaElement = viewSchemaList.First();

	    unsigned colId=1;
	    ListT<CegoField> fl;
	    if ( pViewSchemaElement )
	    {
		ListT<Element*> colList = (*pViewSchemaElement)->getChildren(XML_COL_ELEMENT);
		ListT<CegoField> fl;
		Element **pCol = colList.First();
		while ( pCol ) 
		{
		    Chain colName = (*pCol)->getAttributeValue(XML_COLNAME_ATTR);
		    Chain colType = (*pCol)->getAttributeValue(XML_COLTYPE_ATTR);
		    
		    CegoDataType dt = CegoTypeConverter::getTypeId( colType );

		    unsigned colSize;
		    
		    if (dt == VARCHAR_TYPE
			|| dt == BIGINT_TYPE
			|| dt == DECIMAL_TYPE )
		    {
			colSize = (*pCol)->getAttributeValue(XML_COLSIZE_ATTR).asUnsigned();
		    }
		    else
		    {
			colSize = CegoTypeConverter::getTypeLen( dt );
		    }

		    unsigned colDim;
		    if ( dt == DECIMAL_TYPE )
		    {
			
			// backward compatibility to cego version 2.45.x
			// there is still no COLDIM value specified
			// in this case, we use colSize as dim value and setup colSize to reserved len
			Chain dimCheck = (*pCol)->getAttributeValue(XML_COLDIM_ATTR);
			if ( dimCheck == Chain() )
			{
			    colDim = colSize;
			    colSize = RESERVED_BTREE_FLOATLEN;
			}
			else
			{
			    colDim = dimCheck.asUnsigned();
			}
		    }
		    else
		    {
			colDim = 0;
		    }
					    
		    CegoField f(CegoField(viewName, viewName, colName, dt, colSize, colDim));
		    f.setId(colId);
		    colId++;
		    
		    fl.Insert(f);
		    
		    pCol = colList.Next();
		}
		
		_pGTM->createQueryView(tableSet, viewName, fl, viewStmt);				
	    }
	    
	    pViewElement = viewList.Next();
	}

	// procedure import
	
	ListT<Element*> procList = pRoot->getChildren(XML_PROCEDURE_ELEMENT);
	Element **pProcElement = procList.First();
	while ( pProcElement )
	{
	    Chain procName = (*pProcElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain procText = (*pProcElement)->getAttributeValue(XML_PROCTEXT_ATTR);	
	    
	    Chain info = Chain("Importing procedure ") + procName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    _pGTM->createQueryProc(tableSet, procName, procText);
	    
	    pProcElement = procList.Next();
	}
	
	// counter import
	
	ListT<Element*> counterList = pRoot->getChildren(XML_COUNTER_ELEMENT);
	Element **pCounterElement = counterList.First();
	while ( pCounterElement )
	{
	    Chain counterName = (*pCounterElement)->getAttributeValue(XML_NAME_ATTR);
	    Chain counterValue = (*pCounterElement)->getAttributeValue(XML_VALUE_ATTR);
	    
	    Chain info = Chain("Importing counter ") + counterName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);	
	    _pDBMng->addCounter(tabSetId, counterName, counterValue.asUnsignedLongLong(), true);
	    
	    pCounterElement = counterList.Next();
	}
	
	delete pDoc;
	pDoc = 0;	
    }
    catch ( Exception e )
    {	
	if ( pInFile )
	{
	    pInFile->close();
	    delete pInFile;
	}
	if ( pInStream )
	    delete pInStream;

	if ( pDoc )
	    delete pDoc;
      
	throw Exception(EXLOC, Chain("Cannot import xml tableset"), e);
    }
}

unsigned long long CegoXPorter::xmlImportTable(const Chain& tableSet, const Chain& tableName, const Chain& impFile)
{
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Importing table ") + tableName + Chain("..."));

    _pGTM->setAppend(true);
   
    File *pInFile = 0;
    CegoImpInStream* pInStream = 0;
    Document *pDoc = 0;

    try
    {
	XMLSuite xml;

	pInFile = new File(impFile);
	pInFile->open(File::READ);
    
	pInStream = new CegoImpInStream(tableSet, tableName, _pGTM, _pAH);	
	pDoc = new Document(XML_IMPORT_DOC);
	pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
	
	xml.setDocument(pDoc);    
	xml.setFile(pInFile);
	xml.setInStream(pInStream);
	
	xml.parse();	
    }
    catch ( Exception e )
    {	
	if ( pInFile )
	{
	    pInFile->close();
	    delete pInFile;
	}
	if ( pInStream )
	    delete pInStream;
	if ( pDoc )
	    delete pDoc;

	throw Exception(EXLOC, Chain("Cannot import xml table"), e);
    }

    unsigned long long numRow = pInStream->numImported();
    
    pInFile->close();
    delete pInFile;
    delete pInStream;
    delete pDoc;

    return numRow;
}

void CegoXPorter::xmlExportTableSet(const Chain& tableSet, bool isStructure, const Chain& expFile)
{    
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting tableset ") +  tableSet);
    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    XMLSuite xml;

    Element* pRoot = new Element(XML_TABLESET_ELEMENT);    
    Document *pDoc = new Document(XML_EXPORT_DOC);
    ListT<CegoExpOutStream*> outStreamList;

    File *pOutFile = 0;
    
    try
    {		
	pOutFile = new File(expFile);	
	pOutFile->open(File::WRITE);

	pDoc->setDocType(XML_EXPORT_DOC);
	pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
	pRoot->setAttribute(XML_NAME_ATTR, tableSet);
	
	pDoc->setRootElement(pRoot);
	
	xml.setDocument(pDoc);
	
	// counter export
	
	ListT<Chain> counterNameList;
	_pDBMng->getCounterList(tabSetId, counterNameList);
	Chain *pCounterName = counterNameList.First();
	while ( pCounterName )
	{
	    Chain info = Chain("Exporting counter ") +  *pCounterName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    unsigned long long v = _pDBMng->getCounterValue(tabSetId, *pCounterName);
	    
	    Element *pCounterElement = new Element(XML_COUNTER_ELEMENT);
	    pCounterElement->setAttribute(XML_NAME_ATTR, *pCounterName);
	    pCounterElement->setAttribute(XML_VALUE_ATTR, Chain(v));
	    pRoot->addContent(pCounterElement);	
	    pCounterName = counterNameList.Next();
	}
	
	// table export
	ListT<Chain> tabList;
	_pGTM->getObjectList(tabSetId, CegoObject::TABLE, tabList);
	       	
	Chain *pTab = tabList.First();
	while ( pTab )
	{
	    Chain info = Chain("Exporting table ") +  *pTab + Chain(" ...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    Element* pTabElement = new Element(XML_TABLE_ELEMENT);
	    
	    pTabElement->setAttribute(XML_NAME_ATTR, *pTab);		
	    
	    CegoTableObject toe;
	    // we use the method from CegoDistManager to verify user access
	    _pGTM->getObject(tabSetId, *pTab, CegoObject::TABLE, toe);
	    
	    ListT<CegoField> schema = toe.getSchema();
	    
	    Element* pSchemaElement = new Element(XML_SCHEMA_ELEMENT);
	    
	    CegoField *pF = schema.First();
	    while ( pF ) 
	    {	    
		Chain tname;
		if (pF->getTableAlias().length() > 0)
		{
		    tname = pF->getTableAlias();
		}
		else
		{
		    tname = pF->getTableName();
		}
		
		Element *pColElement = new Element(XML_COL_ELEMENT);
		pColElement->setAttribute(XML_COLNAME_ATTR, pF->getAttrName());
		if ( pF->isNullable() )
		    pColElement->setAttribute(XML_COLNULLABLE_ATTR, XML_TRUE_VALUE);
		else
		    pColElement->setAttribute(XML_COLNULLABLE_ATTR, XML_FALSE_VALUE);
		
		if ( ! pF->getValue().isNull() )
		    pColElement->setAttribute(XML_COLDEFVALUE_ATTR, pF->getValue().valAsChain(false));
				
		pColElement->setAttribute( XML_COLTYPE_ATTR, CegoTypeConverter::getTypeString( pF->getType() ));
		pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
		pColElement->setAttribute(XML_COLDIM_ATTR, Chain(pF->getDim()));
		
		pSchemaElement->addContent(pColElement);
		pF = schema.Next();
	    }
	    
	    pTabElement->addContent(pSchemaElement);
	    
	    if ( isStructure == false )
	    {
		CegoExpOutStream *pOutStream = new CegoExpOutStream(tabSetId, *pTab, schema, _pGTM, _pAH);
		pTabElement->setOutStream(pOutStream);
		outStreamList.Insert(pOutStream);
	    }
	    pRoot->addContent(pTabElement);
	    
	    pTab = tabList.Next();
	}
	
	// index export
	
	ListT<Chain> idxList;
	_pGTM->getObjectList(tabSetId, CegoObject::AVLTREE, idxList);
	
	Chain *pIdx = idxList.First();
	while ( pIdx )
	{	    
	    Chain info = Chain("Exporting index ") +  *pIdx + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    CegoTableObject ioe;
	    _pGTM->getObject(tabSetId, *pIdx, CegoObject::AVLTREE, ioe);
	    
	    Element *pIdxElement = new Element(XML_INDEX_ELEMENT);
	    pIdxElement->setAttribute(XML_NAME_ATTR, *pIdx);
	    pIdxElement->setAttribute(XML_TABLENAME_ATTR, ioe.getTabName());
	    
	    if ( ioe.getType() == CegoObject::AVLTREE)	
		pIdxElement->setAttribute(XML_INDEXTYPE_ATTR, XML_INDEX_VALUE);
	    if ( ioe.getType() == CegoObject::PAVLTREE)
		pIdxElement->setAttribute(XML_INDEXTYPE_ATTR, XML_PINDEX_VALUE);
	    if ( ioe.getType() == CegoObject::UAVLTREE)
		pIdxElement->setAttribute(XML_INDEXTYPE_ATTR, XML_UINDEX_VALUE);
	    
	    Element* pSchemaElement = new Element(XML_SCHEMA_ELEMENT);
	    
	    CegoField *pF = ioe.getSchema().First();
	    while ( pF ) 
	    {		
		Element *pColElement = new Element(XML_COL_ELEMENT);
		pColElement->setAttribute(XML_COLNAME_ATTR, pF->getAttrName());
		
		pColElement->setAttribute( XML_COLTYPE_ATTR, CegoTypeConverter::getTypeString( pF->getType() ));
		pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
		pColElement->setAttribute(XML_COLDIM_ATTR, Chain(pF->getDim()));		
		
		pSchemaElement->addContent(pColElement);
		
		pF = ioe.getSchema().Next();
	    }
	    
	    pIdxElement->addContent( pSchemaElement );       
	    
	    pRoot->addContent(pIdxElement);
	    
	    pIdx = idxList.Next();
	}
	
	// btree export
	
	ListT<Chain> btreeList;
	_pGTM->getObjectList(tabSetId, CegoObject::BTREE, btreeList);
	
	Chain *pBT = btreeList.First();
	while ( pBT )
	{
	    Chain info = Chain("Exporting btree ") +  *pBT + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    CegoBTreeObject btoe;
	    _pGTM->getObject(tabSetId, *pBT, CegoObject::BTREE, btoe);
	    
	    Element *pBTElement = new Element(XML_INDEX_ELEMENT);
	    pBTElement->setAttribute(XML_NAME_ATTR, *pBT);
	    pBTElement->setAttribute(XML_TABLENAME_ATTR, btoe.getTabName());
	    
	    if ( btoe.getType() == CegoObject::BTREE)	
		pBTElement->setAttribute(XML_INDEXTYPE_ATTR, XML_BTREE_VALUE);
	    if ( btoe.getType() == CegoObject::PBTREE)
		pBTElement->setAttribute(XML_INDEXTYPE_ATTR, XML_PBTREE_VALUE);
	    if ( btoe.getType() == CegoObject::UBTREE)
		pBTElement->setAttribute(XML_INDEXTYPE_ATTR, XML_UBTREE_VALUE);
	    
	    Element* pSchemaElement = new Element(XML_SCHEMA_ELEMENT);
	    
	    CegoField *pF = btoe.getSchema().First();
	    while ( pF ) 
	    {	    
		Element *pColElement = new Element(XML_COL_ELEMENT);
		pColElement->setAttribute(XML_COLNAME_ATTR, pF->getAttrName());
		
		pColElement->setAttribute( XML_COLTYPE_ATTR, CegoTypeConverter::getTypeString( pF->getType() ));
		pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
		pColElement->setAttribute(XML_COLDIM_ATTR, Chain(pF->getDim()));
		
		pSchemaElement->addContent(pColElement);
		
		pF = btoe.getSchema().Next();
	    }
	    
	    pBTElement->addContent( pSchemaElement );       
	    
	    pRoot->addContent(pBTElement);
	    
	    pBT = btreeList.Next();
	}
	
	// key export
	
	ListT<Chain> fkeyList;
	_pGTM->getObjectList(tabSetId, CegoObject::FKEY, fkeyList);
	
	Chain *pFKey = fkeyList.First();
	while ( pFKey )
	{
	    Chain info = Chain("Exporting foreign key ") +  *pFKey + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info+ Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    CegoKeyObject koe;
	    _pGTM->getObject(tabSetId, *pFKey, CegoObject::FKEY, koe);
	    
	    Element *pFKeyElement = new Element(XML_FKEY_ELEMENT);
	    pFKeyElement->setAttribute(XML_NAME_ATTR, *pFKey);
	    pFKeyElement->setAttribute(XML_TABLENAME_ATTR, koe.getTabName());
	    pFKeyElement->setAttribute(XML_REFTABLENAME_ATTR, koe.getRefTable());
	    
	    Element* pKeySchemaElement = new Element(XML_KEYSCHEMA_ELEMENT);
	    
	    CegoField *pF = koe.getKeySchema().First();
	    while ( pF )
	    {
		Element *pColElement = new Element(XML_COL_ELEMENT);
		pColElement->setAttribute(XML_COLNAME_ATTR, pF->getAttrName());	    
		pKeySchemaElement->addContent(pColElement);
		pF = koe.getKeySchema().Next();
	    }
	    
	    Element* pRefSchemaElement = new Element(XML_REFSCHEMA_ELEMENT);
	    
	    pF = koe.getRefSchema().First();
	    while ( pF )
	    {
		Element *pColElement = new Element(XML_COL_ELEMENT);
		pColElement->setAttribute(XML_COLNAME_ATTR, pF->getAttrName());	    
		pRefSchemaElement->addContent(pColElement);
		pF = koe.getRefSchema().Next();
	    }
	    
	    pFKeyElement->addContent(pKeySchemaElement);
	    pFKeyElement->addContent(pRefSchemaElement);
	    
	    pRoot->addContent(pFKeyElement);	
	    pFKey = fkeyList.Next();
	}
	
	// check export
	
	ListT<Chain> checkList;
	_pGTM->getObjectList(tabSetId, CegoObject::CHECK, checkList);
	
	Chain *pCheck = checkList.First();
	while ( pCheck )
	{
	    Chain info = Chain("Exporting check ") +  *pCheck + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    CegoCheckObject coe;
	    _pGTM->getObject(tabSetId, *pCheck, CegoObject::CHECK, coe);
	    
	    Element *pCheckElement = new Element(XML_CHECK_ELEMENT);
	    pCheckElement->setAttribute(XML_NAME_ATTR, *pCheck);
	    pCheckElement->setAttribute(XML_TABLENAME_ATTR, coe.getTabName());

	    Chain predString = coe.getPredDesc()->toChain(tabSetId);
	    
	    pCheckElement->setAttribute(XML_COND_ATTR, predString);
	    
	    pRoot->addContent(pCheckElement);	
	    pCheck = checkList.Next();
	}

	// trigger export
	
	ListT<Chain> triggerList;
	_pGTM->getObjectList(tabSetId, CegoObject::TRIGGER, triggerList);
	
	Chain *pTrigger = triggerList.First();
	while ( pTrigger )
	{
	    Chain info = Chain("Exporting tigger ") +  *pTrigger + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    CegoTriggerObject tro;
	    _pGTM->getObject(tabSetId, *pTrigger, CegoObject::TRIGGER, tro);
	    
	    Element *pTriggerElement = new Element(XML_TRIGGER_ELEMENT);
	    pTriggerElement->setAttribute(XML_NAME_ATTR, *pTrigger);
	    pTriggerElement->setAttribute(XML_TABLENAME_ATTR, tro.getTabName());

	    if ( tro.isBefore() )
		pTriggerElement->setAttribute(XML_ISBEFORE_ATTR, XML_TRUE_VALUE);
	    else
		pTriggerElement->setAttribute(XML_ISBEFORE_ATTR, XML_FALSE_VALUE);

	    if ( tro.isOnInsert() )
		pTriggerElement->setAttribute(XML_ISONINSERT_ATTR, XML_TRUE_VALUE);
	    else
		pTriggerElement->setAttribute(XML_ISONINSERT_ATTR, XML_FALSE_VALUE);

	    if ( tro.isOnUpdate() )
		pTriggerElement->setAttribute(XML_ISONUPDATE_ATTR, XML_TRUE_VALUE);
	    else
		pTriggerElement->setAttribute(XML_ISONUPDATE_ATTR, XML_FALSE_VALUE);

	    if ( tro.isOnDelete() )
		pTriggerElement->setAttribute(XML_ISONDELETE_ATTR, XML_TRUE_VALUE);
	    else
		pTriggerElement->setAttribute(XML_ISONDELETE_ATTR, XML_FALSE_VALUE);
	    	    
	    pTriggerElement->setAttribute(XML_TRIGGERTEXT_ATTR, tro.getTriggerText());
	    	    	    
	    pRoot->addContent(pTriggerElement);	
	    pTrigger = triggerList.Next();
	}

	// alias export
	
	ListT<Chain> aliasList;
	_pGTM->getObjectList(tabSetId, CegoObject::ALIAS, aliasList);
	
	Chain *pAlias = aliasList.First();
	while ( pAlias )
	{
	    Chain info = Chain("Exporting alias ") +  *pAlias + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    CegoAliasObject ao;
	    _pGTM->getObject(tabSetId, *pAlias, CegoObject::ALIAS, ao);
	    
	    Element *pAliasElement = new Element(XML_ALIAS_ELEMENT);
	    pAliasElement->setAttribute(XML_NAME_ATTR, *pAlias);
	    pAliasElement->setAttribute(XML_TABLENAME_ATTR, ao.getTabName());
	  
	    CegoAttrAlias *pA = ao.getAliasList().First();
	    while ( pA )
	    {
		Element *pColElement = new Element(XML_COL_ELEMENT);
		pColElement->setAttribute(XML_COLNAME_ATTR, pA->getAttrName());
		pColElement->setAttribute(XML_COLALIAS_ATTR, pA->getAliasName());	    
				
		pAliasElement->addContent(pColElement);
		pA = ao.getAliasList().Next();
	    }
	    
	    pRoot->addContent(pAliasElement);	
	    pAlias = aliasList.Next();
	}

	// view export
	
	ListT<Chain> viewList;
	_pGTM->getObjectList(tabSetId, CegoObject::VIEW, viewList);
	
	Chain *pView = viewList.First();
	while ( pView )
	{
	    Chain info = Chain("Exporting view ") +  *pView + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info+ Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    // to ensure, the view is compiled, we load it in any case
	    
	    _pDBMng->useObject(tabSetId, *pView, CegoObject::VIEW, CegoDatabaseManager::SHARED, _pGTM);
	    try
	    {
		_pGTM->getView(tabSetId, *pView);
	    }
	    catch ( Exception e )
	    {
		_pDBMng->unuseObject(tabSetId, *pView, CegoObject::VIEW);
		throw Exception(EXLOC, Chain("Cannot export view ") + *pView, e);
	    }
	    
	    _pDBMng->unuseObject(tabSetId, *pView, CegoObject::VIEW);
	    
	    CegoViewObject vo;
	    _pGTM->getObject(tabSetId, *pView, CegoObject::VIEW,  vo);
	    
	    Element *pViewElement = new Element(XML_VIEW_ELEMENT);
	    pViewElement->setAttribute(XML_NAME_ATTR, *pView);
	    pViewElement->setAttribute(XML_VIEWSTMT_ATTR, vo.getViewStmt());
	    
	    Element* pViewSchemaElement = new Element(XML_SCHEMA_ELEMENT);
	    
	    CegoField *pF = vo.getSchema().First();
	    while ( pF )
	    {
		Element *pColElement = new Element(XML_COL_ELEMENT);
		pColElement->setAttribute(XML_COLNAME_ATTR, pF->getAttrName());	    
		
		pColElement->setAttribute( XML_COLTYPE_ATTR, CegoTypeConverter::getTypeString( pF->getType() ));
		
		pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
		pColElement->setAttribute(XML_COLDIM_ATTR, Chain(pF->getDim()));
			
		pViewSchemaElement->addContent(pColElement);
		pF = vo.getSchema().Next();
	    }
	    
	    pViewElement->addContent(pViewSchemaElement);
	    
	    pRoot->addContent(pViewElement);	
	    pView = viewList.Next();
	}
	
	// proc export
	
	ListT<Chain> procList;
	_pGTM->getObjectList(tabSetId, CegoObject::PROCEDURE, procList);
	
	Chain *pProc = procList.First();
	while ( pProc )
	{
	    Chain info = Chain("Exporting procedure ") +  *pProc + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    // to ensure, the view is compiled, we load it in any case
	    _pDBMng->useObject(tabSetId, *pProc, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED, _pGTM);
	    try
	    {
		_pGTM->getProcedure(tabSetId, *pProc);
	    }
	    catch ( Exception e )
	    {
		_pDBMng->unuseObject(tabSetId, *pProc, CegoObject::PROCEDURE);
		throw Exception(EXLOC, Chain("Cannot export procedure ") + *pProc, e);
	    }       
	    _pDBMng->unuseObject(tabSetId, *pProc, CegoObject::PROCEDURE);
	    
	    CegoProcObject po;
	    _pGTM->getObject(tabSetId, *pProc, CegoObject::PROCEDURE, po);
	    
	    Element *pProcElement = new Element(XML_PROCEDURE_ELEMENT);
	    pProcElement->setAttribute(XML_NAME_ATTR, *pProc);
	    pProcElement->setAttribute(XML_PROCTEXT_ATTR, po.getProcText());
	    
	    pRoot->addContent(pProcElement);	
	    pProc = procList.Next();
	}
	
	_pDBMng->log(_modId, Logger::NOTICE, Chain("Writing export to ") +  expFile + Chain("..."));

	xml.getXMLChain( pOutFile );    

	pOutFile->close();
	delete pOutFile;
	pOutFile = 0;
		
	CegoExpOutStream **pOutStream = outStreamList.First();
	while ( pOutStream )
	{
	    delete *pOutStream;
	    pOutStream = outStreamList.Next();
	}
	outStreamList.Empty();

	delete pDoc;
	pDoc = 0;

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Export finished succesful"));    

    }
    catch ( Exception e )
    {
	if ( pOutFile )
	{
	    pOutFile->close();
	    if ( pOutFile->exists() )
		pOutFile->remove();
	    delete pOutFile;
	}
	
	CegoExpOutStream **pOutStream = outStreamList.First();
	while ( pOutStream )
	{
	    delete *pOutStream;
	    pOutStream = outStreamList.Next();
	}	

	if ( pDoc )
	    delete pDoc;

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

unsigned long long CegoXPorter::xmlExportTable(const Chain& tableSet, const Chain& tableName, const Chain& expFile)
{
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting table ") + tableName + Chain("..."));

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);

    XMLSuite xml;

    Element* pRoot = new Element(XML_TABLESET_ELEMENT);    
    Document *pDoc = new Document(XML_EXPORT_DOC);
    CegoExpOutStream *pOutStream = 0;
    File *pOutFile = new File(expFile);
    
    try
    {
	pOutFile->open(File::WRITE);
	
	pDoc->setDocType(XML_EXPORT_DOC);
	pDoc->setAttribute(XML_VERSION_ATTR, XML_VERSION_VALUE);
	
	pRoot->setAttribute(XML_NAME_ATTR, tableSet);
	
	pDoc->setRootElement(pRoot);
	
	xml.setDocument(pDoc);
	
	Element* pTabElement = new Element(XML_TABLE_ELEMENT);
	
	pTabElement->setAttribute(XML_NAME_ATTR, tableName);		
	
	CegoTableObject toe;
	_pGTM->getObject(tabSetId, tableName, CegoObject::TABLE, toe);
	
	ListT<CegoField> schema = toe.getSchema();
	
	Element* pSchemaElement = new Element(XML_SCHEMA_ELEMENT);
	
	CegoField *pF = schema.First();
	while ( pF ) 
	{	
	    Chain tname;
	    if (pF->getTableAlias().length() > 0)
	    {
		tname = pF->getTableAlias();
	    }
	    else
	    {
		tname = pF->getTableName();
	    }
	    
	    Element *pColElement = new Element(XML_COL_ELEMENT);
	    pColElement->setAttribute(XML_COLNAME_ATTR, pF->getAttrName());
	    if ( pF->isNullable() )
		pColElement->setAttribute(XML_COLNULLABLE_ATTR, XML_TRUE_VALUE);
	    else
		pColElement->setAttribute(XML_COLNULLABLE_ATTR, XML_FALSE_VALUE);
	    
	    if ( ! pF->getValue().isNull() )
		pColElement->setAttribute(XML_COLDEFVALUE_ATTR, pF->getValue().valAsChain(false));
	    
	    pColElement->setAttribute( XML_COLTYPE_ATTR, CegoTypeConverter::getTypeString( pF->getType() ));
	    pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
	    pColElement->setAttribute(XML_COLDIM_ATTR, Chain(pF->getDim()));
	    
	    pSchemaElement->addContent(pColElement);
	    pF = schema.Next();
	}
	
	pTabElement->addContent(pSchemaElement);
	
	pOutStream = new CegoExpOutStream(tabSetId, tableName, schema, _pGTM, _pAH);
	pTabElement->setOutStream(pOutStream);
	
	pRoot->addContent(pTabElement);
	
	xml.getXMLChain( pOutFile );
	
	unsigned long long numExported = pOutStream->numExported();
	
	pOutFile->close();
	delete pOutFile;
	pOutFile = 0;
	
	delete pOutStream;
	pOutStream = 0;
		
	delete pDoc;
	pDoc = 0;
	
	return numExported;
    }
    catch ( Exception e )
    {
	if ( pOutFile )
	{
	    pOutFile->close();
	    if ( pOutFile->exists() )
		pOutFile->remove();
	    delete pOutFile;
	}

	if ( pOutStream )
	    delete pOutStream;

	if ( pDoc )
	    delete pDoc;

	throw Exception(EXLOC, Chain("Cannot export xml table"), e);
    }
}

void CegoXPorter::binImportTableSet(const Chain& tableSet, bool isStructure, const Chain& impFile, bool doPlain)
{
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Binary importing tableset ")  + tableSet);

    _pGTM->setAppend(true);

    File *pInFile = new File(impFile);

    try
    {
	pInFile->open(File::READ);
	
	Chain impTableSet;
	readHeader(pInFile, impTableSet);
	
	if ( impTableSet != tableSet )
	{
	    throw Exception(EXLOC, "Tableset mismatch");	
	}
	
	pInFile->readByte((char*)&_tag, sizeof(BinTag));
	
	while ( _tag != EOFTAG)
	{	    
	    if ( _tag == TABTAG )
	    {
		readTableObject(pInFile, tableSet, doPlain);	    
	    }
	    else if ( _tag == IDXTAG )
	    {
		readIndexObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == KEYTAG )
	    {
		readKeyObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == CHECKTAG )
	    {
		readCheckObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == TRIGGERTAG )
	    {
		readTriggerObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == ALIASTAG )
	    {		
		readAliasObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == VIEWTAG )
	    {
		readViewObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == PROCTAG )
	    {
		readProcObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == CNTTAG )
	    {
		readCounterObject(pInFile, tableSet);	    
	    }
	}
    }
    catch ( Exception e)
    {
	pInFile->close();
	delete pInFile;       
	throw Exception(EXLOC, Chain("Cannot import binary tableset"), e);
    }
    
    pInFile->close();
    delete pInFile;
}

unsigned long long CegoXPorter::binImportTable(const Chain& tableSet, const Chain& tableName, const Chain& impFile, bool doPlain)
{
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Importing tablename ") + tableName + Chain("..."));
    
    _pGTM->setAppend(true);

    unsigned long long numRow=0;
    
    File *pInFile = new File(impFile);

    try
    {
	pInFile->open(File::READ);
	
	Chain impTableSet;
	readHeader(pInFile, impTableSet);
	
	pInFile->readByte((char*)&_tag, sizeof(BinTag));
	
	if ( _tag == TABTAG )
	{
	    numRow = readTableObject(pInFile, tableSet, doPlain);	    
	}
    }
    catch ( Exception e )
    {
	pInFile->close();
	delete pInFile;
	throw Exception(EXLOC, Chain("Cannot import binary table"), e);
    }
    
    pInFile->close();
    delete pInFile;

    return numRow;
}

void CegoXPorter::binExportTableSet(const Chain& tableSet, bool isStructure, const Chain& expFile, bool doPlain)
{
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting tableset ") + tableSet + Chain(" ( binary ) ..."));

    File *pOutFile = new File(expFile);

    try
    {
	unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
	
	pOutFile->open(File::WRITE);

	writeHeader(pOutFile, tableSet);
         
	// table export
	ListT<Chain> tabList;
	_pGTM->getObjectList(tabSetId, CegoObject::TABLE, tabList);
	
	Chain *pTab = tabList.First();
	while ( pTab )
	{
	    Chain info = Chain("Exporting table ") + *pTab + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    	    
	    CegoTableObject toe;
	    // we use the method from CegoDistManager to verify user access
	    _pGTM->getObject(tabSetId, *pTab, CegoObject::TABLE, toe);
	    	    
	    writeTableObject(pOutFile, tabSetId, *pTab, toe.getSchema(), doPlain);
	    
	    pTab = tabList.Next();
	}
	
	// index export
	
	ListT<Chain> idxList;
	_pGTM->getObjectList(tabSetId, CegoObject::AVLTREE, idxList);
	
	Chain *pIdx = idxList.First();
	while ( pIdx )
	{
	    Chain info = Chain("Exporting index ") + *pIdx + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    	    
	    CegoTableObject ioe;
	    _pGTM->getObject(tabSetId, *pIdx, CegoObject::AVLTREE, ioe);
	    
	    writeIndexObject(pOutFile, tabSetId, *pIdx, ioe.getTabName(), ioe.getType(), ioe.getSchema());
	    
	    pIdx = idxList.Next();
	}

	// btree export
	
	ListT<Chain> btreeList;
	_pGTM->getObjectList(tabSetId, CegoObject::BTREE, btreeList);
	
	Chain *pBT = btreeList.First();
	while ( pBT )
	{
	    Chain info = Chain("Exporting btree ") + *pBT + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    	    
	    CegoBTreeObject btoe;
	    _pGTM->getObject(tabSetId, *pBT, CegoObject::BTREE, btoe);
	    
	    writeIndexObject(pOutFile, tabSetId, *pBT, btoe.getTabName(), btoe.getType(), btoe.getSchema());
	    
	    pBT = btreeList.Next();
	}
	
	// key export
	
	ListT<Chain> fkeyList;
	_pGTM->getObjectList(tabSetId, CegoObject::FKEY, fkeyList);
	
	Chain *pFKey = fkeyList.First();
	while ( pFKey )
	{
	    Chain info = Chain("Exporting foreign key ") + *pFKey + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    CegoKeyObject koe;
	    _pGTM->getObject(tabSetId, *pFKey, CegoObject::FKEY, koe);
	    
	    writeKeyObject(pOutFile, tabSetId, *pFKey, koe.getTabName(), koe.getRefTable(), koe.getKeySchema(), koe.getRefSchema());
	    
	    pFKey = fkeyList.Next();
	}
	
	// check export
	
	ListT<Chain> checkList;
	_pGTM->getObjectList(tabSetId, CegoObject::CHECK, checkList);
	
	Chain *pCheck = checkList.First();
	while ( pCheck )
	{   	   
	    Chain info = Chain("Exporting check ") + *pCheck + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
   
	    CegoCheckObject coe;
	    _pGTM->getObject(tabSetId, *pCheck, CegoObject::CHECK, coe);
	    
	    writeCheckObject(pOutFile, tabSetId, *pCheck, coe.getTabName(), coe.getPredDesc());
	    
	    pCheck = checkList.Next();
	}

	// trigger export
	
	ListT<Chain> triggerList;
	_pGTM->getObjectList(tabSetId, CegoObject::TRIGGER, triggerList);
	
	Chain *pTrigger = triggerList.First();
	while ( pTrigger )
	{   	   
	    Chain info = Chain("Exporting trigger ") + *pTrigger + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
   
	    CegoTriggerObject toe;
	    _pGTM->getObject(tabSetId, *pTrigger, CegoObject::TRIGGER, toe);
	    
	    writeTriggerObject(pOutFile, tabSetId, *pTrigger, toe.getTabName(),
			       toe.isBefore(), toe.isOnInsert(), toe.isOnUpdate(), toe.isOnDelete(), 
			       toe.getTriggerText());
	    
	    pTrigger = triggerList.Next();
	}

	// alias export
	
	ListT<Chain> aliasList;
	_pGTM->getObjectList(tabSetId, CegoObject::ALIAS, aliasList);
	
	Chain *pAlias = aliasList.First();
	while ( pAlias )
	{   	   
	    Chain info = Chain("Exporting alias ") + *pAlias + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
   
	    CegoAliasObject aoe;
	    _pGTM->getObject(tabSetId, *pAlias, CegoObject::ALIAS, aoe);
	    
	    writeAliasObject(pOutFile, tabSetId, *pAlias, aoe.getTabName(), aoe.getAliasList());
	    
	    pAlias = aliasList.Next();
	}

	// view export
	
	ListT<Chain> viewList;
	_pGTM->getObjectList(tabSetId, CegoObject::VIEW, viewList);
	
	Chain *pView = viewList.First();
	while ( pView )
	{
	    Chain info = Chain("Exporting view ") + *pView + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	    
	    // to ensure, the view is compiled, we load it in any case
	    _pGTM->getView(tabSetId, *pView);
	    
	    CegoViewObject vo;
	    _pGTM->getObject(tabSetId, *pView, CegoObject::VIEW,  vo);
	    
	    writeViewObject(pOutFile, tabSetId, *pView, vo.getSchema(), vo.getViewStmt());
	    
	    pView = viewList.Next();
	}
	
	// proc export
	
	ListT<Chain> procList;
	_pGTM->getObjectList(tabSetId, CegoObject::PROCEDURE, procList);
	
	Chain *pProc = procList.First();
	while ( pProc )
	{
	    Chain info = Chain("Exporting procedure ") + *pProc + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);

	    // to ensure, the view is compiled, we load it in any case
	    _pGTM->getProcedure(tabSetId, *pProc);

	    CegoProcObject po;
	    _pGTM->getObject(tabSetId, *pProc, CegoObject::PROCEDURE, po);
	    
	    writeProcObject(pOutFile, tabSetId, *pProc, po.getProcText());
	    
	    pProc = procList.Next();	    
	}
	
	// counter export
	
	ListT<Chain> counterNameList;
	_pDBMng->getCounterList(tabSetId, counterNameList);
	Chain *pCounterName = counterNameList.First();
	while ( pCounterName )
	{
	    Chain info = Chain("Exporting counter ") + *pCounterName + Chain("...");
	    if ( _pAH )
		_pAH->sendInfo(info + Chain("\n"));
	    _pDBMng->log(_modId, Logger::NOTICE, info);
	       
	    unsigned long long v = _pDBMng->getCounterValue(tabSetId, *pCounterName);	
	    writeCounterObject(pOutFile, tabSetId, *pCounterName, v);
	    pCounterName = counterNameList.Next();
	}
	
	_tag = EOFTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));	
    }
    catch ( Exception e)
    {
	if ( pOutFile )
	{
	    pOutFile->close();
	    if ( pOutFile->exists() )
		 pOutFile->remove();
	    delete pOutFile;
	}
	throw Exception(EXLOC, Chain("Cannot export binary tableset"), e);
    }
    
    pOutFile->close();
    delete pOutFile;
}

unsigned long long CegoXPorter::binExportTable(const Chain& tableSet, const Chain& tableName, const Chain& expFile, bool doPlain)
{
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting tableset ") + tableSet + Chain(" (binary) ..."));

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
   
    File *pOutFile = new File(expFile);
    
    unsigned long numRow = 0;
    
    try
    {	
	pOutFile->open(File::WRITE);
	
	writeHeader(pOutFile, tableSet);
	
	CegoTableObject toe;
	_pGTM->getObject(tabSetId, tableName, CegoObject::TABLE, toe);
	
	numRow = writeTableObject(pOutFile, tabSetId, tableName, toe.getSchema(), doPlain);
	
	_tag = EOFTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));	
    }
    catch( Exception e )
    {
	pOutFile->close();
	if ( pOutFile->exists() )
	    pOutFile->remove();
	delete pOutFile;

	throw Exception(EXLOC, Chain("Cannot export binary table"), e);
    }

    pOutFile->close();
    delete pOutFile;

    return numRow;	    
}

/////////////////////
// private methods //
/////////////////////

void CegoXPorter::writeHeader(File *pOutFile, const Chain& tableSet)
{
    unsigned tslen = tableSet.length()-1;
    _tag = TSTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
    pOutFile->writeByte((char*)&tslen, sizeof(unsigned));
    pOutFile->writeByte((char*)tableSet, tslen);    
}

unsigned long long CegoXPorter::writeTableObject(File *pOutFile, unsigned tabSetId, const Chain& tableName, const ListT<CegoField>& schema, bool doPlain)
{
    CegoField *pF;
    if ( doPlain )
    {
	// checking for blobs 
	pF = schema.First();
	while ( pF ) 
	{
	    CegoDataType dt = pF->getType();
	    if ( dt == BLOB_TYPE || dt == CLOB_TYPE )
		throw Exception(EXLOC, "Binary export not supported for blob/clob columns");
	    pF = schema.Next();
	}
    }
    
    _tag = TABTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
        
    unsigned tlen = tableName.length()-1;
    pOutFile->writeByte((char*)&tlen, sizeof(unsigned));
    pOutFile->writeByte((char*)tableName, tlen);
    
    pF = schema.First();
    while ( pF ) 
    {
	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));

	unsigned id = pF->getId();
	unsigned alen = pF->getAttrName().length()-1;

	pOutFile->writeByte((char*)&id, sizeof(unsigned));
	pOutFile->writeByte((char*)&alen, sizeof(unsigned));
	pOutFile->writeByte((char*)pF->getAttrName(), alen);

	char isNullable;
	if ( pF->isNullable() )     
	    isNullable=1;
	else
	    isNullable=0;
	
	pOutFile->writeByte((char*)&isNullable, sizeof(char));		

	CegoDataType dt = pF->getType();
	pOutFile->writeByte((char*)&dt, sizeof(CegoDataType));		

	unsigned len = pF->getLength();
	pOutFile->writeByte((char*)&len, sizeof(unsigned));

	unsigned dim = pF->getDim();
	pOutFile->writeByte((char*)&dim, sizeof(unsigned));
	
	unsigned defValLen = pF->getValue().getEncodingLength();
	    
	if ( defValLen > XP_MAXCOLBUF )
	    throw Exception(EXLOC, "Col buffer exceeded");
	
	pF->getValue().encode(_colBuffer);
	    
	pOutFile->writeByte((char*)&defValLen, sizeof(unsigned));
	pOutFile->writeByte((char*)_colBuffer, defValLen);

	pF = schema.Next();
    }
    
    return writeTableData(pOutFile, tabSetId, tableName, schema, doPlain);
}

void CegoXPorter::writeIndexObject(File *pOutFile, unsigned tabSetId, const Chain& idxName, const Chain& tableName, CegoObject::ObjectType type, const ListT<CegoField>& schema)
{    
    _tag = IDXTAG;

    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
        
    unsigned ilen = idxName.length()-1;
    pOutFile->writeByte((char*)&ilen, sizeof(unsigned));
    pOutFile->writeByte((char*)idxName, ilen);

    unsigned tlen = tableName.length()-1;
    pOutFile->writeByte((char*)&tlen, sizeof(unsigned));
    pOutFile->writeByte((char*)tableName, tlen);

    pOutFile->writeByte((char*)&type, sizeof(CegoObject::ObjectType));

    CegoField *pF = schema.First();
    while ( pF ) 
    {
	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));

	unsigned alen = pF->getAttrName().length()-1;
	pOutFile->writeByte((char*)&alen, sizeof(unsigned));
	pOutFile->writeByte((char*)pF->getAttrName(), alen);

	CegoDataType dt = pF->getType();
	pOutFile->writeByte((char*)&dt, sizeof(CegoDataType));		

	unsigned len = pF->getLength();
	pOutFile->writeByte((char*)&len, sizeof(unsigned));		
	
	pF = schema.Next();
    }
}

void CegoXPorter::writeKeyObject(File *pOutFile, unsigned tabSetId, const Chain& keyName, const Chain& tableName, const Chain& refTable, 
				 const ListT<CegoField>& keySchema, const ListT<CegoField>& refSchema)
{
    _tag = KEYTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
    
    unsigned klen = keyName.length()-1;
    pOutFile->writeByte((char*)&klen, sizeof(unsigned));
    pOutFile->writeByte((char*)keyName, klen);

    unsigned tlen = tableName.length()-1;
    pOutFile->writeByte((char*)&tlen, sizeof(unsigned));
    pOutFile->writeByte((char*)tableName, tlen);

    unsigned rtlen = refTable.length()-1;
    pOutFile->writeByte((char*)&rtlen, sizeof(unsigned));
    pOutFile->writeByte((char*)refTable, rtlen);
    
    CegoField *pF = keySchema.First();
    while ( pF ) 
    {
	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	
	unsigned alen = pF->getAttrName().length()-1;
	pOutFile->writeByte((char*)&alen, sizeof(unsigned));
	pOutFile->writeByte((char*)pF->getAttrName(), alen);
	
	pF = keySchema.Next();
    }

    _tag = SEPTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
    
    pF = refSchema.First();
    while ( pF )
    {
	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	
	unsigned alen = pF->getAttrName().length()-1;
	pOutFile->writeByte((char*)&alen, sizeof(unsigned));
	pOutFile->writeByte((char*)pF->getAttrName(), alen);
	
	pF = refSchema.Next();	
    }
}

void CegoXPorter::writeCheckObject(File *pOutFile, unsigned tabSetId, const Chain& checkName, const Chain& tableName, 
				   CegoPredicate *pPredDesc)
{
    _tag = CHECKTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
    
    unsigned cklen = checkName.length()-1;
    pOutFile->writeByte((char*)&cklen, sizeof(unsigned));
    pOutFile->writeByte((char*)checkName, cklen);

    unsigned tlen = tableName.length()-1;
    pOutFile->writeByte((char*)&tlen, sizeof(unsigned));
    pOutFile->writeByte((char*)tableName, tlen);

    unsigned pdlen = pPredDesc->getEncodingLength();

    pOutFile->writeByte((char*)&pdlen, sizeof(unsigned));
    
    if ( pdlen < XP_MAXPDBUF )
    {
	pPredDesc->encode(_pdBuffer, 0);
	pOutFile->writeByte(_pdBuffer, pdlen);
    }
    else
    {
	throw Exception(EXLOC, "Predicate buffer exceeded");
    }
}

void CegoXPorter::writeTriggerObject(File *pOutFile, unsigned tabSetId, const Chain& triggerName, const Chain& tableName,
				   bool isBefore, bool isOnInsert, bool isOnUpdate, bool isOnDelete, 
				   const Chain& triggerText)
{
    _tag = TRIGGERTAG;

    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));

    unsigned len;
    
    len = triggerName.length()-1;
    pOutFile->writeByte((char*)&len, sizeof(unsigned));
    pOutFile->writeByte((char*)triggerName, len);

    len = tableName.length()-1;
    pOutFile->writeByte((char*)&len, sizeof(unsigned));
    pOutFile->writeByte((char*)tableName, len);

    len = 1;
    char flag;

    if ( isBefore )
	flag = 1;
    else
	flag = 0;
    pOutFile->writeByte((char*)&flag, sizeof(char));

    if ( isOnInsert )
	flag = 1;
    else
	flag = 0;
    pOutFile->writeByte((char*)&flag, sizeof(char));

    if ( isOnUpdate )
	flag = 1;
    else
	flag = 0;
    pOutFile->writeByte((char*)&flag, sizeof(char));

    if ( isOnDelete )
	flag = 1;
    else
	flag = 0;
    pOutFile->writeByte((char*)&flag, sizeof(char));
    
    len = triggerText.length()-1;
    pOutFile->writeByte((char*)&len, sizeof(unsigned));
    pOutFile->writeByte((char*)triggerText, len);
}

void CegoXPorter::writeAliasObject(File *pOutFile, unsigned tabSetId, const Chain& aliasName, const Chain& tableName,
				   const ListT<CegoAttrAlias>& aliasList)
{
    _tag = ALIASTAG;

    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));

    unsigned len;
    
    len = aliasName.length()-1;
    pOutFile->writeByte((char*)&len, sizeof(unsigned));
    pOutFile->writeByte((char*)aliasName, len);

    len = tableName.length()-1;
    pOutFile->writeByte((char*)&len, sizeof(unsigned));
    pOutFile->writeByte((char*)tableName, len);

    CegoAttrAlias *pA = aliasList.First();
    while ( pA )
    {
	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	
	unsigned len;
	
	len = pA->getAttrName().length()-1;
	pOutFile->writeByte((char*)&len, sizeof(unsigned));
	pOutFile->writeByte((char*)pA->getAttrName(), len);
	
	len = pA->getAliasName().length()-1;
	pOutFile->writeByte((char*)&len, sizeof(unsigned));
	pOutFile->writeByte((char*)pA->getAliasName(), len);
	
	pA = aliasList.Next();
    }    
}

void CegoXPorter::writeViewObject(File *pOutFile, unsigned tabSetId, const Chain& viewName, const ListT<CegoField>& viewSchema, const Chain& viewStmt)
{
    _tag = VIEWTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
        
    unsigned vlen = viewName.length()-1;
    pOutFile->writeByte((char*)&vlen, sizeof(unsigned));
    pOutFile->writeByte((char*)viewName, vlen);

    unsigned slen = viewStmt.length()-1;
    pOutFile->writeByte((char*)&slen, sizeof(unsigned));
    pOutFile->writeByte((char*)viewStmt, slen);

    CegoField *pF = viewSchema.First();
    while ( pF )
    {
	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	
	unsigned alen = pF->getAttrName().length()-1;
	pOutFile->writeByte((char*)&alen, sizeof(unsigned));
	pOutFile->writeByte((char*)pF->getAttrName(), alen);

	CegoDataType dt = pF->getType();
	pOutFile->writeByte((char*)&dt, sizeof(CegoDataType));		

	unsigned len = pF->getLength();
	pOutFile->writeByte((char*)&len, sizeof(unsigned));		

	unsigned dim = pF->getDim();
	pOutFile->writeByte((char*)&dim, sizeof(unsigned));		

	pF = viewSchema.Next();
    }        
}

void CegoXPorter::writeProcObject(File *pOutFile, unsigned tabSetId, const Chain& procName, const Chain& procText)
{
    _tag = PROCTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
    
    unsigned plen = procName.length()-1;
    pOutFile->writeByte((char*)&plen, sizeof(unsigned));
    pOutFile->writeByte((char*)procName, plen);

    unsigned txtlen = procText.length()-1;
    pOutFile->writeByte((char*)&txtlen, sizeof(unsigned));
    pOutFile->writeByte((char*)procText, txtlen);
}

void CegoXPorter::writeCounterObject(File *pOutFile, unsigned tabSetId, const Chain& counterName, unsigned long long counterValue)
{
    _tag = CNTTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
    
    unsigned clen = counterName.length()-1;
    pOutFile->writeByte((char*)&clen, sizeof(unsigned));
    pOutFile->writeByte((char*)counterName, clen);
    pOutFile->writeByte((char*)&counterValue, sizeof(unsigned long long));
}

unsigned long long CegoXPorter::writeTableData(File *pOutFile, unsigned tabSetId, const Chain& tableName, const ListT<CegoField>& schema, bool doPlain)
{    
    if ( _pAH )
    {
	Chain info = Chain("Exporting table data for ") +  tableName + Chain(" ...");
	_pAH->sendInfo(info + Chain("\n"));
    }
       
    CegoObjectCursor *pOC = 0;
    ListT<CegoField> rowSchema = schema;

    unsigned long long rowCount = 0;
    
    try
    {	
	pOC = _pGTM->getObjectCursor(tabSetId, tableName, tableName, CegoObject::TABLE);
	
	CegoDataPointer dp;
		
	if  ( doPlain )
	{
	    char *buf;
	    unsigned len;
	    
	    buf = (char*)pOC->getFirst(len, dp);
	    
	    while ( buf )
	    {
		_tag = ROWTAG;
		pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
		pOutFile->writeByte((char*)&len, sizeof(unsigned));
		pOutFile->writeByte(buf, len);
		
		rowCount++;
		if ( _pAH && ( rowCount % XP_ROWINTERVAL == 0 ) )
		    _pAH->sendInfo(Chain(rowCount) + Chain(" rows\r"));
		
		buf = (char*)pOC->getNext(len, dp);
	    }
	}
	else
	{
	    CegoDataPointer dp;
	    bool moreRow = _pGTM->getFirstTuple( pOC, rowSchema, dp );
	    
	    while ( moreRow )
	    {
		writeRow(pOutFile, tabSetId, rowSchema);
		
		rowCount++;
		if ( _pAH && ( rowCount % XP_ROWINTERVAL == 0 ) )
		    _pAH->sendInfo(Chain(rowCount) + Chain(" rows\r"));
		
		moreRow = _pGTM->getNextTuple(pOC, rowSchema, dp );
	    }
	}
	
	if ( _pAH )
	    _pAH->sendInfo(Chain(rowCount) + Chain(" rows exported\n"));
    }
    catch ( Exception e)
    {
	if ( pOC )
	{
	    delete pOC;
	}
	throw Exception(EXLOC, Chain("Cannot write table data"), e);
    }

    delete pOC;

    return rowCount;
}

void CegoXPorter::writeRow(File *pOutFile, unsigned tabSetId, const ListT<CegoField>& rowSchema)
{    
    _tag = ROWTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));

    CegoField *pF = rowSchema.First();
    while ( pF ) 
    {
	if ( ! pF->getValue().isNull() )
	{
	    if ( pF->getType() == BLOB_TYPE )
	    {
		PageIdType pageId;
		memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
		
		unsigned long long blobSize;
		unsigned char* blobBuf = _pGTM->getBlobData(tabSetId, pageId, blobSize);

		pOutFile->writeByte((char*)&blobSize, sizeof(unsigned long long));
		pOutFile->writeByte((char*)blobBuf, blobSize);

		delete blobBuf;
	    }
	    else if ( pF->getType() == CLOB_TYPE )
	    {
		PageIdType pageId;
		memcpy(&pageId, pF->getValue().getValue(), sizeof(PageIdType));
		
		unsigned long long clobSize;
		char* clobBuf = _pGTM->getClobData(tabSetId, pageId, clobSize);

		pOutFile->writeByte((char*)&clobSize, sizeof(unsigned long long));
		pOutFile->writeByte((char*)clobBuf, clobSize);

		delete clobBuf;
	    }
	    else
	    {		
		unsigned colLen = pF->getValue().getEncodingLength();
		
		if ( colLen > XP_MAXCOLBUF )
		    throw Exception(EXLOC, "Col buffer exceeded");
		
		pF->getValue().encode(_colBuffer);
		
		pOutFile->writeByte((char*)&colLen, sizeof(unsigned));
		pOutFile->writeByte((char*)_colBuffer, colLen);
	    }
	}		
	else
	{
	    if ( pF->getType() == BLOB_TYPE || pF->getType() == CLOB_TYPE )
	    {
		unsigned long long colLen = 0;
		pOutFile->writeByte((char*)&colLen, sizeof(unsigned long long));
	    }
	    else
	    {
		unsigned colLen = 0;
		pOutFile->writeByte((char*)&colLen, sizeof(unsigned));
	    }
	}
	pF = rowSchema.Next();
    }
}

void CegoXPorter::readHeader(File *pInFile, Chain& tableSet)
{
    pInFile->readByte((char*)&_tag, sizeof(BinTag));
    
    if ( _tag != TSTAG )
    {
	throw Exception(EXLOC, "Wrong format in import file");
    }
    
    unsigned tslen;
    pInFile->readByte((char*)&tslen, sizeof(unsigned));
    
    if ( tslen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "InBuf exceeded");
    }
    
    pInFile->readByte((char*)_inBuf, tslen);
    tableSet = Chain(_inBuf, tslen);
}

unsigned long long CegoXPorter::readTableObject(File *pInFile, const Chain& tableSet, bool doPlain)
{
    unsigned tlen;
    
    pInFile->readByte((char*)&tlen, sizeof(unsigned));
    
    if ( tlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    
    pInFile->readByte((char*)_inBuf, tlen);
    Chain tableName = Chain(_inBuf, tlen);

    Chain info = Chain("Importing table ") + tableName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);
    
    ListT<CegoField> schema;

    pInFile->readByte((char*)&_tag, sizeof(BinTag));

    while ( _tag == FLDTAG)
    {
	unsigned id;
	pInFile->readByte((char*)&id, sizeof(unsigned));

	unsigned alen;
	pInFile->readByte((char*)&alen, sizeof(unsigned));
	if ( alen > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "InBuf exceeded");
	}

	pInFile->readByte((char*)_inBuf, alen);
	Chain attrName = Chain(_inBuf, alen);

	char n;
	pInFile->readByte((char*)&n, sizeof(char));

	bool isNullable;
	if ( n == 1 )
	    isNullable = true;
	else
	    isNullable = false;

	CegoDataType dt;
	pInFile->readByte((char*)&dt, sizeof(CegoDataType));		

	unsigned len;
	pInFile->readByte((char*)&len, sizeof(unsigned));		

	unsigned dim;
	pInFile->readByte((char*)&dim, sizeof(unsigned));		

	unsigned defValLen;
	pInFile->readByte((char*)&defValLen, sizeof(unsigned));
	
	CegoFieldValue defValue;
	if ( defValLen > 0 )
	{
	    if ( defValLen > XP_MAXCOLBUF )
		throw Exception(EXLOC, "Column buffer exceeded");
	    
	    pInFile->readByte((char*)_colBuffer, defValLen);
	    defValue.decode(_colBuffer);
	}

	schema.Insert(CegoField(tableName, tableName, attrName, dt, len, dim, defValue, isNullable, id));
    
	pInFile->readByte((char*)&_tag, sizeof(BinTag));
    }

    if ( _pAH )
    {
	Chain info = Chain("Importing table data for ") +  tableName + Chain(" ...");
	_pAH->sendInfo(info + Chain("\n"));
    }

    ListT<CegoField> idxList;
    _pGTM->createQueryTable(tableSet, tableName, schema, idxList, true);
    
    unsigned long long rowCount = 0;

    if ( doPlain )
    {
	unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
	
	CegoBufferPage bp;
	_pGTM->getObjectWithFix(tabSetId, tableName, CegoObject::TABLE, _oe, bp);
	_sysEntry = CegoDataPointer(bp.getPageId(), bp.getEntryPos());
	
	char rowBuf[XP_MAXROWBUF];
	while ( _tag == ROWTAG )
	{	    
	    unsigned rowLen;
	    pInFile->readByte((char*)&rowLen, sizeof(unsigned));

	    if ( rowLen > XP_MAXROWBUF )
		throw Exception(EXLOC, "Import row buffer exceeded");
	    
	    pInFile->readByte(rowBuf, rowLen);
	    
	    CegoDataPointer dp;
	    dp = _pGTM->insertData(_sysEntry, _oe, rowBuf, rowLen, true);

	    rowCount++;

	    if ( _pAH && ( rowCount % XP_ROWINTERVAL == 0 ) )
		_pAH->sendInfo(Chain(rowCount) + Chain(" rows\r"));
	    
	    pInFile->readByte((char*)&_tag, sizeof(BinTag));
	}
	_pDBMng->bufferUnfix(bp, true, _pGTM->getLockHandle());
    }
    else
    {
	ListT<CegoTableObject> idxList;
	ListT<CegoBTreeObject> btreeList;
	ListT<CegoKeyObject> keyList;
	ListT<CegoCheckObject> checkList;
	ListT<CegoTriggerObject> triggerList;
	ListT<CegoAliasObject> aliasList;

	unsigned tabSetId = _pDBMng->getTabSetId(tableSet);
	
	CegoBufferPage bp;
	_pGTM->getObjectWithFix(tabSetId, tableName, CegoObject::TABLE, _oe, bp);
	_sysEntry = CegoDataPointer(bp.getPageId(), bp.getEntryPos());
	
	unsigned numInvalid;
	_pGTM->getObjectListByTable(_oe.getTabSetId(), _oe.getName(), idxList, btreeList, keyList, checkList, triggerList, aliasList,
				    numInvalid);
	
	while ( _tag == ROWTAG )
	{
	    readRow(pInFile, tabSetId, tableName, schema);

	    rowCount++;

	    if ( _pAH && ( rowCount % XP_ROWINTERVAL == 0 ) )
		_pAH->sendInfo(Chain(rowCount) + Chain(" rows\r"));

	    pInFile->readByte((char*)&_tag, sizeof(BinTag));
	}

	_pDBMng->bufferUnfix(bp, true, _pGTM->getLockHandle());
    }

    if ( _pAH )
	_pAH->sendInfo(Chain(rowCount) + Chain(" rows imported\n"));

    return rowCount;
}

void CegoXPorter::readIndexObject(File *pInFile, const Chain& tableSet)
{
    unsigned ilen;
   
    pInFile->readByte((char*)&ilen, sizeof(unsigned));
    
    if ( ilen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "InBuf exceeded");
    }
    
    pInFile->readByte((char*)_inBuf, ilen);
    Chain idxName = Chain(_inBuf, ilen);
    
    unsigned tlen;    
    pInFile->readByte((char*)&tlen, sizeof(unsigned));
    
    if ( tlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    
    pInFile->readByte((char*)_inBuf, tlen);
    Chain tableName = Chain(_inBuf, tlen);
    
    CegoObject::ObjectType type;
    pInFile->readByte((char*)&type, sizeof(CegoObject::ObjectType));
    
    ListT<CegoField> schema;

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
	
    while ( _tag == FLDTAG)
    {
	unsigned alen;
	pInFile->readByte((char*)&alen, sizeof(unsigned));
	if ( alen > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "Import buffer exceeded");
	}

	pInFile->readByte((char*)_inBuf, alen);
	Chain attrName = Chain(_inBuf, alen);

	CegoDataType dt;
	pInFile->readByte((char*)&dt, sizeof(CegoDataType));		

	unsigned len;
	pInFile->readByte((char*)&len, sizeof(unsigned));		
	
	schema.Insert(CegoField(tableName, tableName, attrName, dt, len));

	pInFile->readByte((char*)&_tag, sizeof(BinTag));	
    }

    Chain info = Chain("Importing index ") + idxName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);
    
    _pGTM->createQueryIndex(tableSet, idxName, tableName, schema, type);
}

void CegoXPorter::readKeyObject(File *pInFile, const Chain& tableSet)
{
    unsigned klen;    
    pInFile->readByte((char*)&klen, sizeof(unsigned));
    if ( klen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, klen);
    Chain keyName = Chain(_inBuf, klen);

    unsigned tlen;    
    pInFile->readByte((char*)&tlen, sizeof(unsigned));
    if ( tlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, tlen);
    Chain tableName = Chain(_inBuf, tlen);

    unsigned rtlen;    
    pInFile->readByte((char*)&rtlen, sizeof(unsigned));
    if ( rtlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, rtlen);
    Chain refTable = Chain(_inBuf, rtlen);

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
    ListT<CegoField> keySchema;	
    while ( _tag == FLDTAG)
    {
	unsigned alen;
	pInFile->readByte((char*)&alen, sizeof(unsigned));
	if ( alen > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "Import buffer exceeded");
	}

	pInFile->readByte((char*)_inBuf, alen);
	Chain attrName = Chain(_inBuf, alen);

	keySchema.Insert(CegoField(Chain(), attrName));
    
	pInFile->readByte((char*)&_tag, sizeof(BinTag));	
    }

    if ( _tag != SEPTAG )
	throw Exception(EXLOC, "Import separater tag is missing");
    
    pInFile->readByte((char*)&_tag, sizeof(BinTag));
    ListT<CegoField> refSchema;	
    while ( _tag == FLDTAG)
    {
	unsigned alen;
	pInFile->readByte((char*)&alen, sizeof(unsigned));
	if ( alen > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "Import buffer exceeded");
	}

	pInFile->readByte((char*)_inBuf, alen);
	Chain attrName = Chain(_inBuf, alen);
	
	refSchema.Insert(CegoField(Chain(), attrName));
    
	pInFile->readByte((char*)&_tag, sizeof(BinTag));
    }

    Chain info = Chain("Importing foreign key ") + keyName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);

    _pGTM->createQueryForeignKey(tableSet, keyName, tableName, keySchema, refTable, refSchema);    
}

void CegoXPorter::readCheckObject(File *pInFile, const Chain& tableSet)
{
    unsigned cklen;    
    pInFile->readByte((char*)&cklen, sizeof(unsigned));
    if ( cklen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, cklen);
    Chain checkName = Chain(_inBuf, cklen);

    unsigned tlen;    
    pInFile->readByte((char*)&tlen, sizeof(unsigned));
    if ( tlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, tlen);
    Chain tableName = Chain(_inBuf, tlen);

    unsigned pdlen;    
    pInFile->readByte((char*)&pdlen, sizeof(unsigned));
    if ( pdlen > XP_MAXPDBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_pdBuffer, pdlen);

    CegoPredicate *pPredDesc = new CegoPredicate(_pdBuffer);

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
	
    Chain info = Chain("Importing check ") + checkName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);

    _pGTM->createQueryCheck(tableSet, checkName, tableName, pPredDesc);    
}

void CegoXPorter::readTriggerObject(File *pInFile, const Chain& tableSet)
{
    unsigned len;

    pInFile->readByte((char*)&len, sizeof(unsigned));
    if ( len > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }

    pInFile->readByte((char*)_inBuf, len);
    Chain triggerName = Chain(_inBuf, len);

    pInFile->readByte((char*)&len, sizeof(unsigned));
    if ( len > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }

    pInFile->readByte((char*)_inBuf, len);
    Chain tableName = Chain(_inBuf, len);
    
    char flag;

    bool isBefore;
    pInFile->readByte((char*)&flag, sizeof(char));
    if ( flag )
	isBefore = true;
    else
	isBefore = false;

    bool isOnInsert;
    pInFile->readByte((char*)&flag, sizeof(char));
    if ( flag )
	isOnInsert = true;
    else
	isOnInsert = false;

    bool isOnUpdate;
    pInFile->readByte((char*)&flag, sizeof(char));
    if ( flag )
	isOnUpdate = true;
    else
	isOnUpdate = false;

    bool isOnDelete;
    pInFile->readByte((char*)&flag, sizeof(char));
    if ( flag )
	isOnDelete = true;
    else
	isOnDelete = false;


    pInFile->readByte((char*)&len, sizeof(unsigned));
    if ( len > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }

    pInFile->readByte((char*)_inBuf, len);
    Chain triggerText = Chain(_inBuf, len);

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
    
    Chain info = Chain("Importing trigger ") + triggerName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);

    _pGTM->createQueryTrigger(tableSet, triggerName,
			     isBefore, isOnInsert, isOnUpdate, isOnDelete,
			     tableName, triggerText);    
}

void CegoXPorter::readAliasObject(File *pInFile, const Chain& tableSet)
{
    unsigned len;    
    pInFile->readByte((char*)&len, sizeof(unsigned));
    if ( len > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }

    pInFile->readByte((char*)_inBuf, len);
    Chain aliasName = Chain(_inBuf, len);

    pInFile->readByte((char*)&len, sizeof(unsigned));
    if ( len > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "InBuf exceeded");
    }
    pInFile->readByte((char*)_inBuf, len);
    Chain tableName = Chain(_inBuf, len);
    
    pInFile->readByte((char*)&_tag, sizeof(BinTag));

    ListT<CegoAttrAlias> aliasList;
    while ( _tag == FLDTAG)
    {
	pInFile->readByte((char*)&len, sizeof(unsigned));
	if ( len > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "InBuf exceeded");
	}

	pInFile->readByte((char*)_inBuf, len);
	Chain attrName = Chain(_inBuf, len);

	pInFile->readByte((char*)&len, sizeof(unsigned));
	if ( len > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "InBuf exceeded");
	}

	pInFile->readByte((char*)_inBuf, len);
	Chain aliasName = Chain(_inBuf, len);
	
	aliasList.Insert( CegoAttrAlias(attrName, aliasName));
	
	pInFile->readByte((char*)&_tag, sizeof(BinTag));	
    }

    Chain info = Chain("Importing alias ") + aliasName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);

    _pGTM->createQueryAlias(tableSet, aliasName,
			   tableName, aliasList);
}

void CegoXPorter::readViewObject(File *pInFile, const Chain& tableSet)
{
    unsigned vlen;    
    pInFile->readByte((char*)&vlen, sizeof(unsigned));
    if ( vlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }

    pInFile->readByte((char*)_inBuf, vlen);
    Chain viewName = Chain(_inBuf, vlen);

    unsigned slen;    
    pInFile->readByte((char*)&slen, sizeof(unsigned));
    if ( slen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "InBuf exceeded");
    }
    pInFile->readByte((char*)_inBuf, slen);
    Chain viewStmt = Chain(_inBuf, slen);
    
    pInFile->readByte((char*)&_tag, sizeof(BinTag));

    ListT<CegoField> viewSchema;
    unsigned colId=1;
    while ( _tag == FLDTAG)
    {
	unsigned alen;
	pInFile->readByte((char*)&alen, sizeof(unsigned));
	if ( alen > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "InBuf exceeded");
	}

	pInFile->readByte((char*)_inBuf, alen);
	Chain attrName = Chain(_inBuf, alen);

	CegoDataType dt;
	pInFile->readByte((char*)&dt, sizeof(CegoDataType));		
	
	unsigned len;
	pInFile->readByte((char*)&len, sizeof(unsigned));

	unsigned dim;
	pInFile->readByte((char*)&dim, sizeof(unsigned));


	CegoField f(CegoField(viewName, viewName, attrName, dt, len, dim));
	f.setId(colId);
	colId++;
		    
	viewSchema.Insert(f);
    
	pInFile->readByte((char*)&_tag, sizeof(BinTag));	
    }

    Chain info = Chain("Importing view ") + viewName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);

    _pGTM->createQueryView(tableSet, viewName, viewSchema, viewStmt);   
}

void CegoXPorter::readProcObject(File *pInFile, const Chain& tableSet)
{
    unsigned plen;    
    pInFile->readByte((char*)&plen, sizeof(unsigned));
    if ( plen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, plen);
    Chain procName = Chain(_inBuf, plen);

    unsigned txtlen;    
    pInFile->readByte((char*)&txtlen, sizeof(unsigned));
    if ( txtlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, txtlen);
    Chain procText = Chain(_inBuf, txtlen);

    Chain info = Chain("Importing procedure ") + procName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);

    _pGTM->createQueryProc(tableSet, procName, procText);

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
}

void CegoXPorter::readCounterObject(File *pInFile, const Chain& tableSet)
{
    unsigned clen;
    pInFile->readByte((char*)&clen, sizeof(unsigned));
    if ( clen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "Import buffer exceeded");
    }
    pInFile->readByte((char*)_inBuf, clen);
    Chain counterName = Chain(_inBuf, clen);

    unsigned long long counterValue;    
    pInFile->readByte((char*)&counterValue, sizeof(unsigned long long));

    Chain info = Chain("Importing counter ") + counterName + Chain("...");
    if ( _pAH )
	_pAH->sendInfo(info + Chain("\n"));
    _pDBMng->log(_modId, Logger::NOTICE, info);

    unsigned tabSetId = _pDBMng->getTabSetId(tableSet);	
    _pDBMng->addCounter(tabSetId, counterName, counterValue, true);

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
}

void CegoXPorter::readRow(File *pInFile, unsigned tabSetId, const Chain& tableName, const ListT<CegoField>& rowSchema)
{
    ListT<CegoField> fvl;

    CegoField *pF = rowSchema.First();
    while ( pF ) 
    {	    
	CegoField f(pF->getTableName(), pF->getAttrName() );
	
	if ( pF->getType() == BLOB_TYPE )
	{
	    unsigned long long blobSize;
	    pInFile->readByte((char*)&blobSize, sizeof(unsigned long long));
    
	    if ( blobSize > 0 )
	    {
		unsigned char *blobBuf = (unsigned char*)malloc(blobSize);
		if ( blobBuf == NULL )
		{
		    throw Exception(EXLOC, "Malloc system error");     
		}
		
		pInFile->readByte((char*)blobBuf, blobSize);
		
		PageIdType pageId;
		
		_pGTM->putBlobData(tabSetId, blobBuf, blobSize, pageId);
		
		free (blobBuf );
				
		Chain blobRef = Chain("[") + Chain(pageId) + Chain("]");
		CegoFieldValue fv(pF->getType(), blobRef);
		f.setValue(fv);
	    }
	    else
	    {
		// set blob null value
		CegoFieldValue fv;
		f.setValue(fv);
	    }
	}
	else if ( pF->getType() == CLOB_TYPE )
	{
	    unsigned long long clobSize;
	    pInFile->readByte((char*)&clobSize, sizeof(unsigned long long));

	    if ( clobSize > 0 )
	    {		
		char *clobBuf = (char*)malloc(clobSize);
		if ( clobBuf == NULL )
		{
		    throw Exception(EXLOC, "malloc system error");     
		}
		
		pInFile->readByte((char*)clobBuf, clobSize);
		
		PageIdType pageId;
		
		_pGTM->putClobData(tabSetId, clobBuf, clobSize, pageId);
		
		free (clobBuf );
		
		Chain clobRef = Chain("[") + Chain(pageId) + Chain("]");
		CegoFieldValue fv(pF->getType(), clobRef);
		f.setValue(fv);
	    }
	    else
	    {
		// set clob null value
		CegoFieldValue fv;
		f.setValue(fv);		
	    }
	}
	else
	{
	    unsigned colLen;
	    pInFile->readByte((char*)&colLen, sizeof(unsigned));
	    
	    CegoFieldValue fv;
	    if ( colLen > 0 )
	    {
		if ( colLen > XP_MAXCOLBUF )
		    throw Exception(EXLOC, "Col buffer exceeded");
		
		pInFile->readByte((char*)_colBuffer, colLen);
		fv.decode(_colBuffer);
	    }
	    else
	    {
		// null value
	    }
	    
	    f.setValue(fv);
	}

	fvl.Insert(f);
	pF = rowSchema.Next();	
    }
    
    CegoField* pCF = rowSchema.First();
    CegoField* pCV =  fvl.First();
    
    while ( pCF && pCV)
    {	    
	CegoFieldValue fv = pCV->getValue();
	
	CegoQueryHelper::prepareFieldValue(pCF, fv, _pGTM, _oe.getTabSetId());
	
	pCV->setValue(fv); 
	
	pCF = rowSchema.Next();
	pCV = fvl.Next();
    }
    if ( pCF || pCV )
    {
	throw Exception(EXLOC, "Mismatched argument count for value list");
    }

    CegoDataPointer dp;
    Chain virginIndex;

    ListT<CegoTableObject> idxList;
    ListT<CegoBTreeObject> btreeList;
    ListT<CegoKeyObject> keyList;
    ListT<CegoCheckObject> checkList;

    // we use append mode and no logging for insert
    _pGTM->insertDataTable(_oe, fvl, idxList, btreeList, keyList, checkList, _sysEntry, virginIndex, dp, false, true, false, false);
}
