/**************************************************************************************
 * head file of dbs_svr interfaces
 * AUTHOR: Cham Li
 * DATE: 2007-01-29
 * COPYRIGHT: video surveillance
 * DESCRIPTION: The file declares the interfaces to dbs_svr server.
 **************************************************************************************
 */
#ifndef DBS_API_H_
#define DBS_API_H_

#ifdef WIN32
#pragma warning(disable: 4786)
#pragma warning (disable:4290)
#pragma warning (disable:4996)


#pragma comment(lib, "WSOCK32.LIB")
#endif

#include <list>
#include <string>
#include <map>
#include <iostream>
#include <memory>

#include <stdio.h>
#include <string.h>

#define VS_DBS_ENCODE_BUFLEN 128*1024
#define VS_DBS_DECODE_BUFLEN	128*1024
#define VS_DBS_TRANS_BUFLEN 64*1024


#ifndef _DEF_S8_
#define _DEF_S8_
typedef char S8;
#endif

#ifndef _DEF_U8_
#define _DEF_U8_
typedef unsigned char U8;
#endif

#ifndef _DEF_S16_
#define _DEF_S16_
typedef short S16;
#endif

#ifndef _DEF_U16_
#define _DEF_U16_
typedef unsigned short U16;
#endif

#ifndef _DEF_S32_
#define _DEF_S32_
typedef int S32;
#endif

#ifndef _DEF_U32_
#define _DEF_U32_
typedef unsigned int U32;
#endif

using namespace std;
namespace dbsclient
{
/*define error code*/

const S32 ERR_MD_BASE = 100;

const S32 ERR_MD_NO_SUCH_REC = ERR_MD_BASE + 1;
const S32 ERR_MD_REC_EXIST = ERR_MD_BASE + 2;
const S32 ERR_MD_NO_SUCH_TABLE = ERR_MD_BASE + 3;
const S32 ERR_MD_NO_SUCH_ATTR = ERR_MD_BASE + 4;
const S32 ERR_MD_NO_REFERENCED_ROW = ERR_MD_BASE + 5; //the foreign keys not exist
const S32 ERR_MD_IS_REFERENCED_ROW = ERR_MD_BASE + 6; //foreign keys still in other tables


const S32 ERR_MD_TIME_OUT = ERR_MD_BASE + 10;
const S32 ERR_MD_DB_ERR = ERR_MD_BASE + 11;
const S32 ERR_MD_INVALID_PDU = ERR_MD_BASE + 12;
const S32 ERR_MD_NEXT_TIMEOUT = ERR_MD_BASE + 13;

const S32 ERR_SOCK_INVALID_PARAMS = ERR_MD_BASE + 21;
const S32 ERR_SOCK_SEND_FAILED = ERR_MD_BASE + 22;
const S32 ERR_SOCK_WAIT_TIMEOUT = ERR_MD_BASE + 23;
const S32 ERR_SOCK_SELECT_FAILED = ERR_MD_BASE + 24;
const S32 ERR_SOCK_RECV_FAILED = ERR_MD_BASE + 25;
const S32 ERR_SOCK_PEER_CLOSED = ERR_MD_BASE + 26;
const S32 ERR_SOCK_CONNECT_FAILED = ERR_MD_BASE + 27;
const S32 ERR_SOCK_UNCOMP_FAILED = ERR_MD_BASE + 28;//解压缩失败
const S32 ERR_SOCK_COMP_FAILED = ERR_MD_BASE + 29;//压缩失败
const S32 ERR_SOCK_MALLOC_FAILED = ERR_MD_BASE + 30;//分配内存失败



const S32 ERR_TAB_INVALID_ATTRINDEX = ERR_MD_BASE + 31;
const S32 ERR_TAB_INVALID_ATTRNAME = ERR_MD_BASE + 32;
const S32 ERR_REC_INVALID_ATTRNUM = ERR_MD_BASE + 33;

const S32 ERR_MD_PDU_TOO_LONG	= ERR_MD_BASE + 41;


/**************************************************************
 * db exception
 *
 *************************************************************/
class CDbsException
{
public:

	/**
	 * constructor and destructor
	 */
	CDbsException( S32 iErrCode, const string& strDesc ) :
		m_iErrCode(iErrCode), m_strDesc(strDesc)
	{
		/* null */
	}
	CDbsException()
	{
		this->m_iErrCode = 0;
		this->m_strDesc = "";
	}

	CDbsException( const CDbsException& oDbEx )
	{
		this->m_iErrCode = oDbEx.m_iErrCode;
		this->m_strDesc = oDbEx.m_strDesc;
	}
	virtual ~CDbsException(){}
	S32 error() const {return m_iErrCode; }
	const string& what() const { return m_strDesc; }

private:

	/**
	 * error code
	 */
	S32 m_iErrCode;

	/**
	 * error description
	 */
	string m_strDesc;
};

/*************************************************************************
 * this class help convert attribute values
 * to some data type automatically
 *
 ************************************************************************/

enum ATTR_TYPE
{
	TYPE_OF_ATTR_S32 = 1,
	TYPE_OF_ATTR_U32 =	 2,
	TYPE_OF_ATTR_CSTR = 3,
	TYPE_OF_ATTR_BSTR = 4,
	TYPE_OF_ATTR_JTATTE = 5,		//only used in joint select
	TYPE_OF_ATTR_NULL = 6			//NULL value
};

class CAttrValue
{
public:

	/*constructor and destructor */
	CAttrValue()
	{
		m_nLen = sizeof(int);
		m_strBuf = (S8*)new int[1];
		memset( m_strBuf, 0, m_nLen );
		m_nDataType = TYPE_OF_ATTR_NULL;
	}
	CAttrValue(S32 iValue)
	{
		m_nLen = sizeof(S32);
		m_strBuf = (S8*)new S32[1];
		memcpy( m_strBuf, & iValue, m_nLen );
		m_nDataType = TYPE_OF_ATTR_S32;
	}

	CAttrValue(U32 nValue)
	{
		m_nLen = sizeof(U32);
		m_strBuf = (S8*)new U32[1];
		memcpy( m_strBuf, & nValue, m_nLen );
		m_nDataType = TYPE_OF_ATTR_U32;
	}

	CAttrValue( const string& strValue, bool bJtAttr = false )
	{
		if( 0 == strValue.length() )
		{
			m_strBuf = 0;
			m_nLen = 0;
		}
		else
		{
			m_nLen = strValue.length() ;
			m_strBuf = new S8[m_nLen+1];
			strcpy(m_strBuf, strValue.c_str());
		}

		if( ! bJtAttr )
			m_nDataType = TYPE_OF_ATTR_CSTR;
		else
			m_nDataType = TYPE_OF_ATTR_JTATTE;
	}

	CAttrValue( const S8* strValue )
	{
		m_nLen = strlen(strValue);
		if( m_nLen )
		{
			m_strBuf = new S8[m_nLen+1];
			strcpy(m_strBuf, strValue );
		}
		else
		{
			m_strBuf = 0;
		}
		m_nDataType = TYPE_OF_ATTR_CSTR;
	}

	CAttrValue( const S8* strValue, U32 nLen )
	{
		m_nLen = nLen;
		if( m_nLen )
		{
			m_strBuf = new S8[m_nLen];
			memcpy(m_strBuf, strValue, m_nLen);
		}
		else
		{
			m_strBuf = 0;
		}
		m_nDataType = TYPE_OF_ATTR_BSTR;
	}


	CAttrValue( const CAttrValue& oCopy )
	{
		m_strBuf = 0;
		m_nDataType = oCopy.m_nDataType;
		m_nLen = oCopy.m_nLen;

		if( 0 == oCopy.m_strBuf || 0 == oCopy.m_nLen)
			return;

		if( TYPE_OF_ATTR_CSTR == m_nDataType || TYPE_OF_ATTR_JTATTE == m_nDataType)
		{
			m_strBuf = new S8[m_nLen+1];
			m_strBuf[m_nLen] = 0;
		}
		else
		{
			m_strBuf = new S8[m_nLen];
		}

		memcpy( m_strBuf, oCopy.m_strBuf, oCopy.m_nLen );
	}


	void operator = ( const CAttrValue& oCopy )
	{
		if(m_strBuf)
			delete []m_strBuf;

		m_strBuf = 0;
		m_nDataType = oCopy.m_nDataType;
		m_nLen = oCopy.m_nLen;

		if( 0 == oCopy.m_strBuf || 0 == oCopy.m_nLen)
			return;

		if( TYPE_OF_ATTR_CSTR == m_nDataType || TYPE_OF_ATTR_JTATTE == m_nDataType )
		{
			m_strBuf = new S8[m_nLen+1];
			m_strBuf[m_nLen] = 0;
		}
		else
		{
			m_strBuf = new S8[m_nLen];
		}

		memcpy( m_strBuf, oCopy.m_strBuf, oCopy.m_nLen );

	}

	virtual ~CAttrValue()
	{
		if( m_strBuf )
			delete [] m_strBuf;
	}

	U32 length() const { return m_nLen; }

	operator S32() const
	{
		if(m_strBuf != NULL) return * (S32*)m_strBuf;
		else return 0;
	}

	operator U32() const
	{
		if(m_strBuf != NULL) return * (U32*)m_strBuf;
		else return 0;
	}

	operator S8*() const
	{
		return m_strBuf;
	}

	/**
	 * get attribute type
	 */
	ATTR_TYPE getAttrType() const { return m_nDataType; }
	std::string getAttrTypeString() const
	{
		if( TYPE_OF_ATTR_S32 == m_nDataType )
			return "TYPE_OF_ATTR_S32";
		else if( TYPE_OF_ATTR_U32 == m_nDataType )
			return "TYPE_OF_ATTR_U32";
		else if( TYPE_OF_ATTR_CSTR == m_nDataType )
			return "TYPE_OF_ATTR_CSTR";
		else if( TYPE_OF_ATTR_BSTR == m_nDataType )
			return "TYPE_OF_ATTR_BSTR";
		else if( TYPE_OF_ATTR_JTATTE == m_nDataType )
			return "TYPE_OF_ATTR_JTATTE";
		else if (TYPE_OF_ATTR_NULL == m_nDataType)
			return "TYPE_OF_ATTR_NULL";
		else
			return "";
	}


private:

	/*
	 * value buffer and length
	 */
	S8* m_strBuf;
	U32 m_nLen;
	ATTR_TYPE m_nDataType;

};

/*define record operation*/
enum REC_OP_TYPE
{
	REC_OP_REMOVE = -1,
	REC_OP_SELECT = 0,
	REC_OP_ADD = 1,
	REC_OP_UPDATE = 2,
	REC_OP_SET = 3
};

/***********************************************************************
 * class record
 *
 **********************************************************************/
enum Rel_AlgeBra
{
	REL_EQ = 0,		// =
	REL_GT = 1,		// >
	REL_GE = 2,		// >=
	REL_LT = 3,		// <
	REL_LE = 4,		// <=
	REL_LIKE = 5,   // like
	REL_IS = 6		//is
};

class CRecord
{
public:

struct SAttrInfo
{
	string strName;
	CAttrValue oValue;
	Rel_AlgeBra nRelOp;

	SAttrInfo(): nRelOp(REL_EQ) {}
	static string RelOpToString( Rel_AlgeBra nRelOp )
	{
		switch(nRelOp)
		{
			case REL_EQ :
				return "EQ";
			case REL_GT :
				return "GT";
			case REL_GE :
				return "GE";
			case REL_LT :
				return "LT";
			case REL_LE :
				return "LE";
			case REL_LIKE :
				return "LIKE";
			case REL_IS :
				return "IS";
			default:
				return "";
		}

		return "";
	}
};

public:

	/**
	 * constructor and destructor
	 */
	explicit CRecord(){}
	/**
	 * @strTabName: table name. use the form as "table1:table2" for joint selection
	 */
	explicit CRecord( const string& strTabName): m_strTabName(strTabName){}
	virtual ~CRecord(){}

	/**
	 * get attribute value
	 * @strAttrName: attribute name. use the form "TabName.FieldName" for joint select
	 * @return value or throw exception
	 */
	const CAttrValue& getAttrValue( const string& strAttrName ) const
	throw (CDbsException);

	/**
	 * set attribute name
	 * @strAttrName: attribute name. use the form "TabName.FieldName" for joint select
	 * @value: attribute value
	 * @return 0 or throw exception
	 */
	int setAttrValue( const string& strAttrName, const CAttrValue& value, Rel_AlgeBra nRelOp=REL_EQ )
	throw (CDbsException);

	/**
	 * set joint attr
	 * @strAttrName1: attribute name of table1, just like "DevBaseInfo.DevId"
	 * @strAttrName2: attribute name of table2, just like "DevNwSetting.DevId"
	 */
	int setJointAttr( const string& strAttrName1, const string& strAttrName2 )
	throw (CDbsException);

	/**
	 * set/get table name.
	 * strTabName: table name. use the form as "table1:table2" for joint selection
	 * return table name
	 */
	S32 setTabName( const string& strTabName )
	{
		m_strTabName = strTabName;
		return 0;
	}

	const string& getTabName() const
	{
		return m_strTabName;
	}

	/**
	 * set operation value
	 * return operation value
	 */
	S32 setOpValue(REC_OP_TYPE op)
	{
		m_op = op;
		return 0;
	}

	/**
	 * get operation value
	 * return operation value
	 */
	REC_OP_TYPE getOpValue() const
	{
		return m_op;
	}

	/**
	 * get attribute name and value pair by count
	 * @nNum: attribute number. start with zero.
	 * return attribute or throw exception
	 */
	const SAttrInfo& getAttrByNum( U32 nNum ) const
	throw (CDbsException);

	/**
	 * get attribute count
	 */
	U32 getAttrCount() const { return m_oAttrs.size(); }

	/**
	 * clear record
	 */
	S32 clear();


private:

	/**
	 * table name
	 */
	string m_strTabName;

	/**
	 * attributes' name and value
	 */
	list< SAttrInfo > m_oAttrs;


	/**
	 * value 0 means select; 1 means add; 2 means update; -1 means remove.
	 */
	REC_OP_TYPE m_op;

};


class CDbsInterface;

/**
 * class query result.
 */
class CResult
{
public:

	/**
	 * constructor and destructor
	 */
	explicit CResult() : m_pMdIfInst(0), m_iSessId(0),m_iSeqId(0),m_iNextNum(0),m_bFinish(false){/*null*/}
	virtual ~CResult();

	/**
	 * get output records.
	 */
	const list<CRecord>& getRecs() const { return m_oRecs; }

	/**
	 * get the next result
	 * if there is not next result, return END_OF_RESULT.
	 * otherwise return 0.
	 */
#	define END_OF_RESULT	 1
	S32 nextResult()
	throw (CDbsException);

	/**
	 * check whether there will be more successive result
	 */
	bool moreResult() const { return ! m_bFinish; }


private:

	/**
	 * set instance of CDbsInterface
	 */
	S32 setMdIfInst( CDbsInterface* pMdIfInst )
	{
		m_pMdIfInst = pMdIfInst;
		return 0;
	}

	/**
	 * set session id
	 */
	S32 setSessId( S32 iSessId ){ m_iSessId=iSessId; return 0;}
	S32 getSessId() const { return m_iSessId; }

	/**
	 * set sequence id
	 */
	S32 setSeqId( S32 iSeqId ){ m_iSeqId = iSeqId; return 0;}
	S32 getSeqId() const { return m_iSeqId; }

	/**
	 * set finish flag
	 */
	S32 setFinishFlag( bool bFinish ){ m_bFinish = bFinish; return 0;}


	/**
	 * get output record variable
	 */
	list<CRecord>& Recs() { return m_oRecs; }

	/**
	 * clear the results
	 */
	S32 clear() { m_oRecs.clear(); return 0; }


private:

	/**
	 * instance if CDbsInterface
	 */
	CDbsInterface* m_pMdIfInst;

	/**
	 * session id
	 */
	S32 m_iSessId;

	/**
	 * sequence id
	 */
	S32 m_iSeqId;

	/**
	 * next number
	 */
	S32 m_iNextNum;

	/**
	 * finish flag
	 */
	bool m_bFinish;

	/**
	 * out records
	 */
	list<CRecord> m_oRecs;


friend class dbsclient::CDbsInterface;

};

/**
 * class meta data interface
 */
class CDbsIfImpl;

class CDbsInterface
{
public:

	/**
	 * constructor and destructor
	 */
	CDbsInterface();
	virtual ~CDbsInterface();

	/**
	 * connect to server and will break up the old connection
	 * @nSvrIp: server ip address in net-work byte order
	 * @nSvrPort: server port
	 * @bTransConn: if this is true, it means that the connection only last in one interaction
	 * return 0 or -1
	 */
	S32 connectServer( U32 nSvrIp, U32 nSvrPort, bool bTransConn=false )
	throw (CDbsException);


	S32 connectServer( string strWWWName, U32 nSvrPort, bool bTransConn=false )
	throw (CDbsException);

	/**
	 * close connection
	 */
	S32 closeConnection();


	/**
	 * regist to server
	 * @nNeType: ne type
	 * @nNeId: ne id
	 * return 0 or throw exception
	 */
	S32 regist( U32 nNeType, U32 nNeId,U32 nTimeOut=6000000)
	throw (CDbsException);

	/**
	 * deregister
	 */
	S32 deregist()
	throw (CDbsException);

	/**
	 * transaction interfaces
 	 */
	S32 beginTrans(U32 nTransId);
	S32 commitTrans()
	throw (CDbsException);
	S32 abortTrans();

	/**
	 * batch interfaces
	 */
	S32 beginBatch();
	S32 commitBatch( CResult& oResult)
	throw (CDbsException);
	S32 abortBatch();

	/**
	 * get record from table
	 * @oCondRec: get-condition
	 * @oResult: output result
	 * @nReqCount: request record count
	 * @nWhereStart: from where start
	 * return records number or throw exception
	 */
	S32 getRec( const list<string>* pAttrNames,
				 const CRecord& oCondRec,
				 CResult& oResult,
				 U32 nReqCount=0xffffffff,
				 U32 nWhereStart=0 )
	throw (CDbsException);


	/**
	 * add record into table
	 * @oRec: record to be insert into table
	 * return result or throw exception
	 */
	S32 addRec( const CRecord& oRec )
	throw (CDbsException);


	/**
	 * add a record into table if it is not exist, else modify it.
	 * @oRec: record to be insert into table
	 * return result or throw exception
	 */
	S32 setRec( const CRecord& oRec )
	throw (CDbsException);


	/**
	 * update record in the table
	 * @oRec: record to be updated. it only include the updated attributes.
	 * @oCondRec: update-condition.
	 * return result or throw exception
	 */
	S32 updateRec( const CRecord& oRec, const CRecord& oCondRec)
	throw (CDbsException);

	/**
	 * remove record from table
	 * @oCondRec: remove-condition
	 * return result or throw exception
	 */
	S32 remvRec( const CRecord& oCondRec)
	throw (CDbsException);

	/**
	 *get media server devices' dbs_svr
	 *@nSurSvrId: surveillance server id
	 *@strTabName:table name from which get data.
	 *@oResult: output result
	 *return 0 or throw exception
	 */
	S32 getSurSvrData( U32 nSurSvrId,
					 	const string& strTabName,
					 	CResult& oResult)
	throw (CDbsException);

	S32 getDomainData( string szDomainId,
					 	const string& strTabName,
					 	CResult& oResult)
	throw (CDbsException);

	S32 execSql( string szExecSql)
	throw (CDbsException);

	virtual S32 CreateDevGpsInfoTbl( string szDevId)
	throw (CDbsException);
	virtual S32 DropDevGpsInfoTbl( string szDevId)
	throw (CDbsException);
	virtual S32 CreateCliAlmActTbl()
	throw (CDbsException);
	S32 DropCliAlmActTbl()
	throw (CDbsException);

	/**
	 * set data asyncly
	 * @oRec: record
	 * return session id
	 */
	S32 asyncSetData( const CRecord& oRec )
	throw (CDbsException);


	/*
	 * wait request from dbs_svr server
	 */
	S32 waitMsg();


	/**
	 * hook handler of db message
	 * return 0.
	 */
	S32 hookMdMsgHdlr(  S32 (*handleMdMsg)(const list<CRecord>& oRecs, U32 nTransId) );


	/**
	 * get next result
	 */
	S32 getNextResult( S32 iSessId,S32 iSeqId, S32 iNextNum,
						bool& bFinish, list<CRecord>& oRecs  )
	throw (CDbsException);


#ifndef WIN32 
//仅仅用于server网元写告警/事件
	void WriteAlarm2DBS(U32 nNeId, U32 nSvrType, U32 nSvrIp, U32 nTime,
	   U32 nModuType, U32 nCause, U32 nSpec, U32 nAlarmType,
	   U32 nAlarmSev, U32 nAlmCond, const S8 *pstrText);
	
	void WriteEvent2DBS(U32 nNeId, U32 nSvrType, U32 nSvrIp, U32 nTime,
		U32 nModuType,  U32 nEvtType,  U32 nEvtInfo,  const S8 *pstrText );
#endif

	bool isOpen(){return m_bConnOpen;};

friend class dbsclient::CResult;

protected:

	/**
	 * open connection
	 */
	S32 openConnection()
	throw (CDbsException);

	/**
	 * check whether it is transaction connection
	 */
	bool isTransConn() const { return m_bTransConn; }


private:

	/**
	 * the connection is for transaction or whole session
	 */
	bool m_bTransConn;

	/**
	 * whether the connection is open
	 */
	bool m_bConnOpen;

	/**
	 * is batch or transaction operation
	 */
	bool m_bBatchOp;



	/**
	 * instance of CDbsIfImpl
	 */
	CDbsIfImpl* m_pDbsIfImpl;



	/* prevent initializtion and assignment */
	CDbsInterface( const CDbsInterface& );
	void operator =(const CDbsInterface&);

};

/************************************************************************************
 * class md interface implementation
 *
 *************************************************************************************/

/**
 * abstract dbs_svr interface implementation
 */
class CDbsIfImpl
{
public:

	/**
	 * constructor and destructor
	 */
	CDbsIfImpl(): m_nNeId(0), m_nNeType(0), m_MdMsgHdlr(0) {}
	virtual ~CDbsIfImpl(){}


	/**
	 * connect to server
	 * @nSvrIp: server ip address in net-work byte order
	 * @nSvrPort: server port
	 * return 0 or -1
	 */
	virtual S32 setSvrAddr( U32 nSvrIp, U32 nSvrPort)
	throw (CDbsException) = 0;

	/**
	 * open connection
	 */
	virtual S32 openConnection()
	throw (CDbsException) = 0;

	/**
	 * close connection
	 */
	virtual S32 closeConnection() = 0;

	/**
	 * regist to server
	 * @nNeType: ne type
	 * @nNeId: ne id
	 * return 0 or throw exception
	 */
	virtual S32 regist( U32 nNeType, U32 nNeId, U32 nTimeOut)
	throw (CDbsException) = 0;

	/**
	 * deregister
	 */
	virtual S32 deregist()
	throw (CDbsException) = 0;


	/**
	 * transaction interfaces
 	*/
	virtual S32 beginTrans(U32 nTransId) = 0;
	virtual S32 commitTrans()
	throw (CDbsException) =  0;
	virtual S32 abortTrans() = 0;

	/**
	 * batch interfaces
	 */
	virtual S32 beginBatch() = 0;
	virtual S32 commitBatch( S32& iSessId,
							S32& iSeqId,
							bool& bFinish,
							list<CRecord>& oRecs )
	throw (CDbsException)  = 0;
	virtual S32 abortBatch() = 0;

	/**
	 * get record from table
	 * @oRecs: output records
	 * @oCondRec: get-condition
	 * return result or throw exception
	 */
	virtual S32 getRec( const list<string>* pAttrNames,
						const CRecord& oCondRec,
						U32 nReqCount,
						U32 nWhereStart,
				 		S32& iSessId,
				 		S32& iSeqId,
				 		bool& bFinish,
				 		list<CRecord>& oRecs )
	throw (CDbsException) = 0;


	/**
	 * add record into table
	 * @oRec: record to be insert into table
	 * return result or throw exception
	 */
	virtual S32 addRec( const CRecord& oRec )
	throw (CDbsException) = 0;


	/**
	 * add a record into table if it is not exist, else modify it.
	 * @oRec: record to be insert into table
	 * return result or throw exception
	 */
	virtual S32 setRec( const CRecord& oRec )
	throw (CDbsException) = 0;

	/**
	 * update record in the table
	 * @oRec: record to be updated. it only include the updated attributes.
	 * @oCondRec: update-condition.
	 * return result or throw exception
	 */
	virtual S32 updateRec( const CRecord& oRec, const CRecord& oCondRec)
	throw (CDbsException) = 0;

	/**
	 * remove record from table
	 * @oCondRec: remove-condition
	 * return result or throw exception
	 */
	virtual S32 remvRec( const CRecord& oCondRec)
	throw (CDbsException) = 0;

	/**
	 *get media server devices' dbs_svr
	 *@nSurSvrId: surveillance server id
	 *@strTabName:table name from which get data.
	 *@oResult: output result
	 *return 0 or throw exception
	 */
	virtual S32 getSurSvrData( U32 nSurSvrId,
								const string& strTabName,
								S32& iSessId,
								S32& iSeqId,
								bool& bFinish,
								list<CRecord>& oRecs )
	throw (CDbsException) = 0;

	virtual S32 getDomainData( string szDomainId,
								const string& strTabName,
								S32& iSessId,
								S32& iSeqId,
								bool& bFinish,
								list<CRecord>& oRecs )
	throw (CDbsException) = 0;

	virtual S32 execSql( string szExecSql)
	throw (CDbsException) = 0;
	/**
	 * remove record from table @strTabName
	 * @strTabName: table name
	 * @oRec: record
	 * return session id
	 */
	virtual S32 asyncSetData( const CRecord& oRec)
	throw (CDbsException) = 0;


	/**
	 * get next result
	 */
	virtual S32 getNextResult( S32 iSessId,S32 iSeqId, S32 iNextNum,
						bool& bFinish, list<CRecord>& oRecs  )
	throw (CDbsException) = 0;

	/**
	 * wait message
	 */
	virtual S32 waitMsg() = 0;


	/**
	 * hook handler of db message
	 * @oRecs: record list
	 * @nTransId: 0 means not a transaction
	 * return 0.
	 */
	S32 hookMdMsgHdlr(	S32 (*handleMdMsg)(const list<CRecord>& oRecs, U32 nTransId) )
	{
		m_MdMsgHdlr = handleMdMsg;
		return 0;
	}
	
protected:

	/**
	 * ne id
	 */
	U32 m_nNeId;

	/**
	 * ne type
	 */
	U32 m_nNeType;

	/**
	 * dbs_svr server message handler
	 */
	S32 (*m_MdMsgHdlr)(const list<CRecord>& oRecs, U32 nTransId );

};


};// end of namespace

#define VS_DBS_MAGIC 0x69707673 //"ipvs"
typedef struct
{
	U32 magic;		//VS_DBS_MAGIC(0x69707673; //"ipvs")
	U32 nVersion;
	U32 nDataLength;	//后续数据包的长度
}VsDbsPacketHeader;

#define DBS_HDR_SIZE					        sizeof(VsDbsPacketHeader)
#define DBS_EXT_DATA_P(pMsg)					((S8*)(pMsg) + DBS_HDR_SIZE)
#define DBS_EXT_DATA_LEN(pMsg)					(((VsDbsPacketHeader*)(pMsg))->nDataLength)
#define DBS_MSG_LEN(pMsg)						(DBS_EXT_DATA_LEN(pMsg)+DBS_HDR_SIZE)
#define IS_DBS_MSG(pMsg)						(((VsDbsPacketHeader*)(pMsg))->magic==VS_DBS_MAGIC) 


#endif

