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

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

#include <string.h>
#include <stdlib.h>

#define MAXROWBUF 1024

CegoXPorter::CegoXPorter(CegoDistManager* pGTM, CegoDbThreadPool* pDbPool)
{
    _pGTM = pGTM;
    _pDBMng = pGTM->getDBMng();
    _modId = _pDBMng->getModId("CegoXPorter");
    _pDbPool = pDbPool;
}

CegoXPorter::~CegoXPorter()
{  
}

void CegoXPorter::xmlExportTableSet(const Chain& tableSet, bool isStructure, const Chain& expFile)
{


    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting tableset ") +  tableSet);
    int tabSetId = _pDBMng->getTabSetId(tableSet);

    XMLSuite xml;

    Element* pRoot = new Element(XML_TABLESET_ELEMENT);    
    Document *pDoc = new Document(XML_EXPORT_DOC);

    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 )
    {
	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting counter ") +  *pCounterName + Chain("..."));
	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 )
    {
	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting table ") +  *pTab + Chain("..."));

	Element* pTabElement = new Element(XML_TABLE_ELEMENT);

	pTabElement->setAttribute(XML_NAME_ATTR, *pTab);		
	
	CegoTableObject toe;
	_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));
	    
	    CegoTypeConverter tc;
	    pColElement->setAttribute( XML_COLTYPE_ATTR, tc.getTypeString( pF->getType() ));
	    pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
	    
	    pSchemaElement->addContent(pColElement);
	    pF = schema.Next();
	}
	
	pTabElement->addContent(pSchemaElement);

	if ( isStructure == false )
	{
	    CegoExpOutStream *pOutStream = new CegoExpOutStream(tabSetId, *pTab, schema, _pGTM);
	    pTabElement->setOutStream(pOutStream);
	}
	pRoot->addContent(pTabElement);

	pTab = tabList.Next();
    }

    // index export

    ListT<Chain> idxList;
    _pGTM->getObjectList(tabSetId, CegoObject::INDEX, idxList);
    
    Chain *pIdx = idxList.First();
    while ( pIdx )
    {

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting index ") +  *pIdx + Chain("..."));

	CegoTableObject ioe;
	_pGTM->getObject(tabSetId, *pIdx, CegoObject::INDEX, 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::INDEX)	
	    pIdxElement->setAttribute(XML_INDEXTYPE_ATTR, XML_INDEX_VALUE);
	if ( ioe.getType() == CegoObject::PINDEX)
	    pIdxElement->setAttribute(XML_INDEXTYPE_ATTR, XML_PINDEX_VALUE);
	if ( ioe.getType() == CegoObject::UINDEX)
	    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());
	
	    CegoTypeConverter tc;
	    pColElement->setAttribute( XML_COLTYPE_ATTR, tc.getTypeString( pF->getType() ));
	    pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
	    
	    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 )
    {

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting btree ") +  *pBT + Chain("..."));

	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());
	
	    CegoTypeConverter tc;
	    pColElement->setAttribute( XML_COLTYPE_ATTR, tc.getTypeString( pF->getType() ));
	    pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));
	    
	    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 )
    {

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting foreign key ") +  *pFKey + Chain("..."));

	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 )
    {

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting check ") +  *pCheck + Chain("..."));

	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());

	Element* pCheckPredElement = coe.getPredDesc()->toElement();

	pCheckElement->addContent(pCheckPredElement);
	

	pRoot->addContent(pCheckElement);	
	pCheck = checkList.Next();
    }
    
    // view export

    ListT<Chain> viewList;
    _pGTM->getObjectList(tabSetId, CegoObject::VIEW, viewList);
    
    Chain *pView = viewList.First();
    while ( pView )
    {

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting view ") +  *pView + Chain("..."));

	// to ensure, the view is compiled, we load it in any case

	_pDBMng->useObject(tabSetId, *pView, CegoObject::VIEW, CegoDatabaseManager::SHARED, _pGTM->getThreadId());
	try
	{
	    _pGTM->getView(tabSetId, *pView);
	}
	catch ( Exception e )
	{
	    _pDBMng->unuseObject(tabSetId, *pView, CegoObject::VIEW, CegoDatabaseManager::SHARED);
	    throw e;
	}

	_pDBMng->unuseObject(tabSetId, *pView, CegoObject::VIEW, CegoDatabaseManager::SHARED);
	
	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());	    
	
	    CegoTypeConverter tc;
	    pColElement->setAttribute( XML_COLTYPE_ATTR, tc.getTypeString( pF->getType() ));

	    pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));

	    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 )
    {

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting procedure ") +  *pProc + Chain("..."));

	// to ensure, the view is compiled, we load it in any case
	_pDBMng->useObject(tabSetId, *pProc, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED, _pGTM->getThreadId());
	try
	{
	    _pGTM->getProcedure(tabSetId, *pProc);
	}
	catch ( Exception e )
	{
	    _pDBMng->unuseObject(tabSetId, *pProc, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED);
	    throw e;
	}       
	_pDBMng->unuseObject(tabSetId, *pProc, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED);

	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("..."));

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

    try
    {
	xml.getXMLChain( pOutFile );    
    }
    catch ( Exception e )
    {

	pOutFile->close();
	delete pOutFile;
	throw Exception(EXLOC, "Export failed", e );
    }

    pOutFile->close();
    delete pOutFile;

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

    delete pDoc;
}

void CegoXPorter::xmlImportTableSet(const Chain& tableSet, bool isStructure, const Chain& impFile, bool doLogging)
{

    _pDBMng->log(_modId, Logger::NOTICE, Chain("Importing tableset ") + tableSet + Chain("..."));

    _pGTM->setAppend(true);

    int tabSetId = _pDBMng->getTabSetId(tableSet);

    XMLSuite xml;
    
    File *pInFile = new File(impFile);
    pInFile->open(File::READ);
	
    CegoImpInStream* pInStream = 0;

    if ( isStructure == false )
    {
	pInStream = new CegoImpInStream(tableSet, _pGTM, doLogging);
    }

    Document *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();

    pInFile->close();
    delete pInStream;

    Element *pRoot = pDoc->getRootElement();

    // check tableset 

    if ( tableSet != pRoot->getAttributeValue(XML_NAME_ATTR) )
    {

	throw Exception(EXLOC, "Tableset mismatch");	
    }

    // 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);	

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Importing index ") + idxName + Chain("..."));

	CegoObject::ObjectType idxType;

	if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_INDEX_VALUE) )
	    idxType = CegoObject::INDEX;
	else if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_PINDEX_VALUE) )
	    idxType = CegoObject::PINDEX;
	else if ( (*pIdxElement)->getAttributeValue(XML_INDEXTYPE_ATTR) == Chain(XML_UINDEX_VALUE) )
	    idxType = CegoObject::UINDEX;
	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;
	
	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 colSize = (*pCol)->getAttributeValue(XML_COLSIZE_ATTR);
		Chain colNullable = (*pCol)->getAttributeValue(XML_COLNULLABLE_ATTR);
		bool isNullable;
		if ( colNullable == Chain(XML_TRUE_VALUE) ) 
		    isNullable = true;
		else
		    isNullable = false;

		CegoTypeConverter tc;
		CegoDataType type = tc.getTypeId( colType );

		Chain colDefValue = (*pCol)->getAttributeValue(XML_COLDEFVALUE_ATTR);
		CegoFieldValue defValue;

		if ( colDefValue != Chain("") )		    
		    defValue = CegoFieldValue(type, colDefValue);
		
		CegoField f(CegoField(tabName, tabName, colName, type, colSize.asInteger(), defValue, isNullable));		
		fl.Insert(f);

		pCol = colList.Next();
	    }
	    
	    _pGTM->createDistIndexTable(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);	

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Importing foreign key ") + fkey + Chain("..."));

	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->createDistForeignKey(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);	

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Importing check ") + checkName + Chain("..."));

	ListT<Element*> checkPredList = (*pCheckElement)->getChildren(XML_PRED_ELEMENT);

	Element **pCheckPredElement = checkPredList.First();

	CegoPredDesc *pPredDesc = new CegoPredDesc(*pCheckPredElement, _pGTM);

	_pGTM->createDistCheck(tableSet, checkName, tableName, pPredDesc);

	pCheckElement = checkList.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);	

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Importing view ") + viewName + Chain("..."));

	ListT<Element*> viewSchemaList = (*pViewElement)->getChildren(XML_SCHEMA_ELEMENT);

	Element **pViewSchemaElement = viewSchemaList.First();

	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);
		Chain colSize = (*pCol)->getAttributeValue(XML_COLSIZE_ATTR);

		CegoTypeConverter tc;
		CegoDataType type = tc.getTypeId( colType );
		
		CegoField f(CegoField(viewName, viewName, colName, type, colSize.asInteger()));		
		fl.Insert(f);

		pCol = colList.Next();
	    }

	    _pGTM->createDistView(tableSet, viewName, fl, viewStmt);

	    // if ( _pDbPool )		
	    // 	_pDbPool->loadObject(tabSetId, viewName, CegoObject::VIEW);

	}

	pViewElement = viewList.Next();
    }

    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);	

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Importing procedure ") + procName + Chain("..."));

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

	// if ( _pDbPool )
	//    _pDbPool->loadObject(tabSetId, procName, CegoObject::PROCEDURE);

	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);

	_pDBMng->log(_modId, Logger::NOTICE, Chain("Importing counter ") + counterName + Chain("..."));

	int tabSetId = _pDBMng->getTabSetId(tableSet);	
	_pDBMng->addCounter(tabSetId, counterName, counterValue.asLong(), true);
	
	pCounterElement = counterList.Next();
    }
    
    delete pDoc;
}

void CegoXPorter::xmlExportTable(const Chain& tableSet, const Chain& tableName, const Chain& expFile)
{

    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting table ") + tableName + Chain("..."));

    int tabSetId = _pDBMng->getTabSetId(tableSet);

    XMLSuite xml;

    Element* pRoot = new Element(XML_TABLESET_ELEMENT);    
    Document *pDoc = new Document(XML_EXPORT_DOC);

    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));
	
	CegoTypeConverter tc;
	pColElement->setAttribute( XML_COLTYPE_ATTR, tc.getTypeString( pF->getType() ));
	pColElement->setAttribute(XML_COLSIZE_ATTR, Chain(pF->getLength()));

	pSchemaElement->addContent(pColElement);
	pF = schema.Next();
    }
    
    pTabElement->addContent(pSchemaElement);
    
    CegoExpOutStream *pOutStream = new CegoExpOutStream(tabSetId, tableName, schema, _pGTM);
    pTabElement->setOutStream(pOutStream);
    
    pRoot->addContent(pTabElement);
    
    File *pOutFile = new File(expFile);
    pOutFile->open(File::WRITE);

    try
    {
	xml.getXMLChain( pOutFile );
    }
    catch ( Exception e )
    {

	pOutFile->close();
	delete pOutFile;
	throw Exception(EXLOC, "Export failed", e );
    }

    pOutFile->close();
    delete pOutFile;
}

void CegoXPorter::xmlImportTable(const Chain& tableSet, const Chain& tableName, const Chain& impFile, bool doLogging)
{

    _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, doLogging);
	
	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, "Import failed", e );
    }
    
    pInFile->close();
    delete pInFile;
    delete pInStream;
    delete pDoc;
    
}

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 = 0;

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

	writeHeader(pOutFile, tableSet);
         
	// table export
	ListT<Chain> tabList;
	_pGTM->getObjectList(tabSetId, CegoObject::TABLE, tabList);
	
	Chain *pTab = tabList.First();
	while ( pTab )
	{
	    
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting table ") + *pTab + Chain("..."));
	    
	    CegoTableObject toe;
	    _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::INDEX, idxList);
	
	Chain *pIdx = idxList.First();
	while ( pIdx )
	{
	    
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting index ") + *pIdx + Chain("..."));
	    
	    CegoTableObject ioe;
	    _pGTM->getObject(tabSetId, *pIdx, CegoObject::INDEX, 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 )
	{
	    
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting btree ") + *pBT + Chain("..."));
	    
	    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 )
	{
	    
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting foreign key ") + *pFKey + Chain("..."));
	    
	    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 )
	{
	    
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting check ") + *pCheck + Chain("..."));
	    
	    CegoCheckObject coe;
	    _pGTM->getObject(tabSetId, *pCheck, CegoObject::CHECK, coe);
	    
	    writeCheckObject(pOutFile, tabSetId, *pCheck, coe.getTabName(), coe.getPredDesc());
	    
	    pCheck = checkList.Next();
	}
	
	
	// view export
	
	ListT<Chain> viewList;
	_pGTM->getObjectList(tabSetId, CegoObject::VIEW, viewList);
	
	Chain *pView = viewList.First();
	while ( pView )
	{
	    
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting view ") + *pView + Chain("..."));

	    // 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 )
	{
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting procedure ") + *pProc + Chain("..."));

	    // 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 )
	{
	    
	    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting counter ") + *pCounterName + Chain("..."));
	    
	    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();
	    delete pOutFile;
	}
	throw Exception(EXLOC, "Export failed", e);
    }
    
    pOutFile->close();
    delete pOutFile;
    
}

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

void CegoXPorter::writeTableObject(File *pOutFile, int 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 )
		throw Exception(EXLOC, "Binary export not supported for blob tables");
	    pF = schema.Next();
	}
    }
    
    _tag = TABTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
        
    int tlen = tableName.length()-1;
    pOutFile->writeByte((char*)&tlen, sizeof(int));
    pOutFile->writeByte((char*)tableName, tlen);
    
    pF = schema.First();
    while ( pF ) 
    {

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

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

	pOutFile->writeByte((char*)&id, sizeof(int));
	pOutFile->writeByte((char*)&alen, sizeof(int));
	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));		

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

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

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

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

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

    int tlen = tableName.length()-1;
    pOutFile->writeByte((char*)&tlen, sizeof(int));
    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));

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

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

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

void CegoXPorter::writeKeyObject(File *pOutFile, int 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));
    
    int klen = keyName.length()-1;
    pOutFile->writeByte((char*)&klen, sizeof(int));
    pOutFile->writeByte((char*)keyName, klen);

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

    int rtlen = refTable.length()-1;
    pOutFile->writeByte((char*)&rtlen, sizeof(int));
    pOutFile->writeByte((char*)refTable, rtlen);
    

    CegoField *pF = keySchema.First();
    while ( pF ) 
    {
	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	
	int alen = pF->getAttrName().length()-1;
	pOutFile->writeByte((char*)&alen, sizeof(int));
	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));
	
	int alen = pF->getAttrName().length()-1;
	pOutFile->writeByte((char*)&alen, sizeof(int));
	pOutFile->writeByte((char*)pF->getAttrName(), alen);
	
	pF = refSchema.Next();	
    }
}

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

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

    int pdlen = pPredDesc->getEncodingLength();

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

void CegoXPorter::writeViewObject(File *pOutFile, int tabSetId, const Chain& viewName, const ListT<CegoField>& viewSchema, const Chain& viewStmt)
{

    _tag = VIEWTAG;
    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
        
    int vlen = viewName.length()-1;
    pOutFile->writeByte((char*)&vlen, sizeof(int));
    pOutFile->writeByte((char*)viewName, vlen);

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

    CegoField *pF = viewSchema.First();
    while ( pF )
    {

	_tag = FLDTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	
	int alen = pF->getAttrName().length()-1;
	pOutFile->writeByte((char*)&alen, sizeof(int));
	pOutFile->writeByte((char*)pF->getAttrName(), alen);


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

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

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

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

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

}

void CegoXPorter::writeTableData(File *pOutFile, int tabSetId, const Chain& tableName, const ListT<CegoField>& schema, bool doPlain)
{
    CegoObjectCursor *pOC;
    ListT<CegoField> rowSchema = schema;
        
    pOC = _pGTM->getObjectCursor(tabSetId, tableName, tableName, CegoObject::TABLE);
    
    CegoDataPointer dp;

    if  ( doPlain )
    {
	char *buf;
	int len;
	
	buf = (char*)pOC->getFirst(len, dp);
	
	while ( buf )
	{
	    _tag = ROWTAG;
	    pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	    pOutFile->writeByte((char*)&len, sizeof(int));
	    pOutFile->writeByte(buf, len);
	    
	    buf = (char*)pOC->getNext(len, dp);
	}
    }
    else
    {
	CegoDataPointer dp;
	if ( _pGTM->getFirstTuple( pOC, rowSchema, dp ) )
	{
	    writeRow(pOutFile, tabSetId, rowSchema);
	    while ( _pGTM->getNextTuple(pOC, rowSchema, dp ) )
	    {
		writeRow(pOutFile, tabSetId, rowSchema);
	    }
	}
	else
	{
	    // noRows
	}
    }
}

void CegoXPorter::writeRow(File *pOutFile, int 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 )
	    {
		int colLen = pF->getValue().getEncodingLength();
		
		if ( colLen > XP_MAXCOLBUF )
		    throw Exception(EXLOC, "Col buffer exceeded");
		
		pF->getValue().encode(_colBuffer);
		
		pOutFile->writeByte((char*)&colLen, sizeof(int));
		pOutFile->writeByte((char*)_colBuffer, colLen);
	    }
	    else
	    {
		int fileId;
		int pageId;
		memcpy(&fileId, pF->getValue().getValue(), sizeof(int));
		memcpy(&pageId, (void*)((long)pF->getValue().getValue() + sizeof(int)), sizeof(int));
		
		long blobSize;
		unsigned char* blobBuf = _pGTM->getBlobData(tabSetId, fileId, pageId, blobSize);

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

		delete blobBuf;
		
	    }
	}		
	else
	{
	    int colLen = 0;
	    pOutFile->writeByte((char*)&colLen, sizeof(int));
	}
	pF = rowSchema.Next();
    }
}

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

    _pGTM->setAppend(true);

    File *pInFile = 0;

    try
    {
	pInFile = new File(impFile);
	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, doLogging, 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 == VIEWTAG )
	    {
		readViewObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == PROCTAG )
	    {
		readProcObject(pInFile, tableSet);	    
	    }
	    else if ( _tag == CNTTAG )
	    {
		readCounterObject(pInFile, tableSet);	    
	    }
	}
    }
    catch ( Exception e)
    {
	if ( pInFile )
	{
	    pInFile->close();
	    delete pInFile;      
	}
	throw Exception(EXLOC, "Import failed", e);
	
    }
    
    pInFile->close();
    delete pInFile;
}

void CegoXPorter::binExportTable(const Chain& tableSet, const Chain& tableName, const Chain& expFile, bool doPlain)
{

    _pDBMng->log(_modId, Logger::NOTICE, Chain("Exporting tableset ") + tableSet + Chain(" (binary) ..."));

    int tabSetId = _pDBMng->getTabSetId(tableSet);

    File *pOutFile = 0;

    try
    {

	pOutFile = new File(expFile);
	pOutFile->open(File::WRITE);
	
	writeHeader(pOutFile, tableSet);
	
	CegoTableObject toe;
	_pGTM->getObject(tabSetId, tableName, CegoObject::TABLE, toe);
	
	writeTableObject(pOutFile, tabSetId, tableName, toe.getSchema(), doPlain);
	
	_tag = EOFTAG;
	pOutFile->writeByte((char*)&_tag, sizeof(BinTag));
	
    }
    catch( Exception e )
    {
	if ( pOutFile )
	{
	    pOutFile->close();
	    delete pOutFile;
	}
	throw Exception(EXLOC, "Export failed", e);
    }

    pOutFile->close();
    delete pOutFile;
	    
}

void CegoXPorter::binImportTable(const Chain& tableSet, const Chain& tableName, const Chain& impFile, bool doLogging, bool doPlain)
{

    _pDBMng->log(_modId, Logger::NOTICE, Chain("Importing tablename ") + tableName + Chain("..."));

    _pGTM->setAppend(true);

    File *pInFile = 0;

    try
    {
	pInFile = new File(impFile);
	pInFile->open(File::READ);
	
	Chain impTableSet;
	readHeader(pInFile, impTableSet);
	
	pInFile->readByte((char*)&_tag, sizeof(BinTag));
	
	if ( _tag == TABTAG )
	{
	    readTableObject(pInFile, tableSet, doLogging, doPlain);	    
	}
    }
    catch ( Exception e )
    {
	if ( pInFile )
	{
	    pInFile->close();
	    delete pInFile;
	}
	throw Exception(EXLOC, "Import failed", e);
    }
    
    pInFile->close();
    delete pInFile;
    
}

void CegoXPorter::readHeader(File *pInFile, Chain& tableSet)
{

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
    
    if ( _tag != TSTAG )
    {
	throw Exception(EXLOC, "Wrong format in import file");
    }
    
    int tslen;
    pInFile->readByte((char*)&tslen, sizeof(int));
    
    if ( tslen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "inBuf exceeded");
    }
    
    pInFile->readByte((char*)_inBuf, tslen);
    tableSet = Chain(_inBuf, tslen);

}

void CegoXPorter::readTableObject(File *pInFile, const Chain& tableSet, bool doLogging, bool doPlain)
{

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

    ListT<CegoField> schema;

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

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

	int alen;
	pInFile->readByte((char*)&alen, sizeof(int));
	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));		

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

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

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

    ListT<CegoField> idxList;
    _pGTM->createDistDataTable(tableSet, tableName, CegoObject::TABLE, schema, idxList, true);

    if ( doPlain )
    {
	
	int tabSetId = _pDBMng->getTabSetId(tableSet);
	
	CegoBufferPage bp;
	_pGTM->getObjectWithFix(tabSetId, tableName, CegoObject::TABLE, _oe, bp);
	_sysEntry = CegoDataPointer(bp.getFileId(), bp.getPageId(), bp.getEntryPos());
	_pDBMng->bufferUnfix(bp, false, _pGTM->getLockHandle());	
	
	char rowBuf[MAXROWBUF];
	while ( _tag == ROWTAG )
	{
	    // readRow(pInFile, tabSetId, tableName, schema, doLogging);
	    
	    int rowLen;
	    pInFile->readByte((char*)&rowLen, sizeof(int));
	    pInFile->readByte(rowBuf, rowLen);
	    
	    CegoDataPointer dp;
	    dp = _pGTM->insertData(_sysEntry, _oe, rowBuf, rowLen, true);
	    
	    pInFile->readByte((char*)&_tag, sizeof(BinTag));
	}
    }
    else
    {
	_isFirst = true;
	int tabSetId = _pDBMng->getTabSetId(tableSet);
	while ( _tag == ROWTAG )
	{
	    readRow(pInFile, tabSetId, tableName, schema, doLogging);
	    pInFile->readByte((char*)&_tag, sizeof(BinTag));
	}
    }
}

void CegoXPorter::readIndexObject(File *pInFile, const Chain& tableSet)
{

    int ilen;

    
    pInFile->readByte((char*)&ilen, sizeof(int));
    
    if ( ilen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "inBuf exceeded");
    }
    
    pInFile->readByte((char*)_inBuf, ilen);
    Chain idxName = Chain(_inBuf, ilen);
    
    int tlen;    
    pInFile->readByte((char*)&tlen, sizeof(int));
    
    if ( tlen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "inBuf 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)
    {

	int alen;
	pInFile->readByte((char*)&alen, sizeof(int));
	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));		

	int len;
	pInFile->readByte((char*)&len, sizeof(int));		
	
	schema.Insert(CegoField(idxName, idxName, attrName, dt, len));
    
	pInFile->readByte((char*)&_tag, sizeof(BinTag));
	
    }
    _pDBMng->log(_modId, Logger::NOTICE, Chain("Creating index ") + idxName + Chain("..."));
    _pGTM->createDistIndexTable(tableSet, idxName, tableName, schema, type);
}

void CegoXPorter::readKeyObject(File *pInFile, const Chain& tableSet)
{

    int klen;    
    pInFile->readByte((char*)&klen, sizeof(int));
    if ( klen > XP_MAXINBUF )
    {
	throw Exception(EXLOC, "inBuf exceeded");
    }
    pInFile->readByte((char*)_inBuf, klen);
    Chain keyName = Chain(_inBuf, klen);

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

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

    pInFile->readByte((char*)&_tag, sizeof(BinTag));
    ListT<CegoField> keySchema;	
    while ( _tag == FLDTAG)
    {

	int alen;
	pInFile->readByte((char*)&alen, sizeof(int));
	if ( alen > XP_MAXINBUF )
	{
	    throw Exception(EXLOC, "inBuf 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, "separater tag is missing");
    
    pInFile->readByte((char*)&_tag, sizeof(BinTag));
    ListT<CegoField> refSchema;	
    while ( _tag == FLDTAG)
    {

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

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

    _pDBMng->log(_modId, Logger::NOTICE, Chain("Creating foreign key ") + keyName + Chain("..."));
    _pGTM->createDistForeignKey(tableSet, keyName, tableName, keySchema, refTable, refSchema);    
}

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

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

    int pdlen;    
    pInFile->readByte((char*)&pdlen, sizeof(int));
    if ( pdlen > XP_MAXPDBUF )
    {
	throw Exception(EXLOC, "pdBuf exceeded");
    }
    pInFile->readByte((char*)_pdBuffer, pdlen);
    
    CegoPredDesc *pPredDesc = new CegoPredDesc(_pdBuffer, _pGTM);

    _pDBMng->log(_modId, Logger::NOTICE, Chain("Creating check ") + checkName + Chain("..."));
    _pGTM->createDistCheck(tableSet, checkName, tableName, pPredDesc);    
}

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

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

    int slen;    
    pInFile->readByte((char*)&slen, sizeof(int));
    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;
    while ( _tag == FLDTAG)
    {

	int alen;
	pInFile->readByte((char*)&alen, sizeof(int));
	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));		
	
	int len;
	pInFile->readByte((char*)&len, sizeof(int));		
	
	viewSchema.Insert(CegoField(viewName, viewName, attrName, dt, len));
    
	pInFile->readByte((char*)&_tag, sizeof(BinTag));
	
    }


    _pDBMng->log(_modId, Logger::NOTICE, Chain("Creating view ") + viewName + Chain("..."));
    _pGTM->createDistView(tableSet, viewName, viewSchema, viewStmt);   


    // if ( _pDbPool )
    // {
    //	int tabSetId = _pDBMng->getTabSetId(tableSet);
    //	_pDbPool->loadObject(tabSetId, viewName, CegoObject::VIEW);
    // }
	
}

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

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


    _pDBMng->log(_modId, Logger::NOTICE, Chain("Creating procedure ") + procName + Chain("..."));            

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

    // if ( _pDbPool )
    // {
    //	int tabSetId = _pDBMng->getTabSetId(tableSet);
    //	_pDbPool->loadObject(tabSetId, procName, CegoObject::PROCEDURE);
    // }

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

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

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

    _pDBMng->log(_modId, Logger::NOTICE, Chain("Creating counter ") + counterName + Chain("...")); 

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

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

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

    CegoField *pF = rowSchema.First();
    while ( pF ) 
    {
	    
	if ( pF->getType() != BLOB_TYPE )
	{
	    int colLen;
	    pInFile->readByte((char*)&colLen, sizeof(int));
	    
	    CegoFieldValue fv;
	    if ( colLen > 0 )
	    {
		if ( colLen > XP_MAXCOLBUF )
		    throw Exception(EXLOC, "Col buffer exceeded");
		
		pInFile->readByte((char*)_colBuffer, colLen);
		fv.decode(_colBuffer);
	    }
	    
	    CegoField f(pF->getTableName(), pF->getAttrName() );
	    f.setValue(fv);
	    fvl.Insert(f);
	}
	else
	{

	    long blobSize;
	    pInFile->readByte((char*)&blobSize, sizeof(long));
	    	    	    
	    unsigned char *blobBuf = (unsigned char*)malloc(blobSize);
	    if ( blobBuf == NULL )
	    {
		throw Exception(EXLOC, "malloc system error");     
	    }

	    pInFile->readByte((char*)blobBuf, blobSize);
	    	    
	    int fileId;
	    int pageId;

	    _pGTM->putBlobData(tabSetId, blobBuf, blobSize, fileId, pageId);
		    
	    free (blobBuf );

	    CegoField f(pF->getTableName(), pF->getAttrName() );

	    Chain blobRef = Chain("[") + Chain(fileId) + Chain(",") + Chain(pageId) + Chain("]");
	    CegoFieldValue fv(pF->getType(), blobRef);
	    f.setValue(fv);
	    fvl.Insert(f);

	}
	pF = rowSchema.Next();
	
    }
    
    if ( _isFirst )
    {
	_idxList.Empty();
	_keyList.Empty();
	_checkList.Empty();

	CegoBufferPage bp;
	_pGTM->getObjectWithFix(tabSetId, tableName, CegoObject::TABLE, _oe, bp);
	_sysEntry = CegoDataPointer(bp.getFileId(), bp.getPageId(), bp.getEntryPos());
	_pDBMng->bufferUnfix(bp, false, _pGTM->getLockHandle());

	_pGTM->getObjectListByTable(_oe.getTabSetId(), _oe.getName(), _idxList, _btreeList, _keyList, _checkList);
	_isFirst = false;
    }

    CegoField* pCF = rowSchema.First();
    CegoField* pCV =  fvl.First();
    
    int pos=1;
    while ( pCF && pCV)
    {	    
	CegoFieldValue fv = pCV->getValue();
	CegoQueryHelper qh;
	
	qh.prepareFieldValue(pCF, fv, pos);
	
	pCV->setValue(fv); 
	
	pCF = rowSchema.Next();
	pCV = fvl.Next();
	
	pos++;
    }
    if ( pCF || pCV )
    {
	throw Exception(EXLOC, "Mismatched argument count for value list");
    }

    CegoDataPointer dp;
    Chain virginIndex;

    _pGTM->insertDataTable(_oe, fvl, _idxList, _btreeList, _keyList, _checkList,
			   _sysEntry, virginIndex, dp, doLogging);        
}
