#ifndef __ODBC_POOL__
#define __ODBC_POOL__

#pragma once

#include "SafeList.h"
//#include <afxdb.h>

typedef SafeList<AdoObj*> AdoConnList;

class CWxAdoPool
{
	ThreadSection m_critSection;
	// 空闲数据库连接池;
	AdoConnList m_listIdleConnections;
	// 在使用的数据库连接池;
	AdoConnList m_listBusyConnections;

	// 可用的指标：最大、最小;
	INT m_nMaxCount;
	INT m_nMinCount;

	// 引入的指针变量;
	DWORD m_dwDBPort;
	CString m_strDBType;
	CString m_strDBSource;
	CString m_strDBAccount;
	CString m_strPassWord;
	CString m_strDBName;

	BOOL m_bNeedExit;	// 退出数据池;
	BOOL m_bNeedStop;
	BOOL m_bNeedConnection;
public:
	CWxAdoPool(void) ;
	~CWxAdoPool(void);

	// 获取实例指针;
	static CWxAdoPool* GetInstance()
	{
		static CWxAdoPool* pInstance = NULL;
		if ( pInstance == NULL )
			pInstance = new CWxAdoPool;

		return pInstance;
	}

	// 初始化所有连接;
	DWORD InitializePool( 
		IN LPCTSTR lpDBType,
		IN LPCTSTR lpDBSource, 
		IN CONST DWORD &dwDBPort, 
		IN LPCTSTR lpDBAccount, 
		IN LPCTSTR lpPassWord, 
		IN LPCTSTR lpDBName, 
		IN CONST INT &nMinConn = 1, 
		IN CONST INT &nMaxConn = 5
		);

	// 关闭所有连接;
	void ReleasePool();

	// 设置数据库信息;
	void SetDBConnectionInfo(IN LPCTSTR lpDBSource, IN CONST DWORD &dwDBPort, IN LPCTSTR lpDBAccount, IN LPCTSTR lpPassWord, IN LPCTSTR lpDBName);
	// 初始化所有连接;
	INT IntiAllConnections();
	// 断开所有连接;
	void DestroyAllDBConnections();

	// 获取一个空闲连接;
	pAdoObj GetAConnection( IN CONST DWORD &dwTimeOut = 1000 );
	// 交还连接给空闲队列;
	void RestoreAConnection(IN pAdoObj pDBEngine);
	// 关闭一个连接;
	void CloseAConnection(pAdoObj &pDBEngine);
	// 关闭使用的连接;
	void CloseBusyConnection(IN pAdoObj &pDataBase);
private:
	volatile LONG m_nRef;
	volatile LONG m_nObjRef;
	// 创建一个连接;
	pAdoObj InitAConnection();
	// 将守卫类友元化;
	friend class CAdoConnGuard;
};

// ODBC守卫垫片类;
class CAdoConnGuard
{
	pAdoObj m_pAdoConn;
public:
	CAdoConnGuard(pAdoObj &pDBConn, CONST DWORD &dwTimeOut = 30000 ):m_pAdoConn(NULL)
	{
		pDBConn = CWxAdoPool::GetInstance()->GetAConnection( dwTimeOut );
		m_pAdoConn = pDBConn;
	}

	virtual ~CAdoConnGuard()
	{
		CWxAdoPool::GetInstance()->RestoreAConnection(m_pAdoConn);
	}
};



#endif // __SAFE_LIST__
