#include "StdAfx.h" #include "WxAdoPool.h" #include "Global.h" ////////////////////////////////////////////////////////////////////////// CWxAdoPool::CWxAdoPool() { m_nRef = 0; m_nObjRef = 0; m_nMaxCount = 0; m_nMinCount = 0; m_bNeedExit = FALSE; m_bNeedStop = FALSE; m_bNeedConnection = FALSE; ::CoInitialize(NULL);//初始化COM环境 } CWxAdoPool::~CWxAdoPool() { m_strDBType.Empty(); m_strDBAccount.Empty(); m_strDBName.Empty(); m_strDBSource.Empty(); m_strPassWord.Empty(); DestroyAllDBConnections(); ::CoUninitialize(); } DWORD CWxAdoPool::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 */) { if ( !lpDBSource || lpDBSource[0] == _T('\0') || !lpDBName || lpDBName[0] == _T('\0') ) { return 0; } m_strDBType = lpDBType; m_strDBSource = lpDBSource; m_dwDBPort = dwDBPort; m_strDBAccount = lpDBAccount; m_strPassWord = lpPassWord; m_strDBName = lpDBName; m_nMinCount = nMinConn; m_nMaxCount = nMaxConn; return IntiAllConnections(); } void CWxAdoPool::ReleasePool() { DestroyAllDBConnections(); } INT CWxAdoPool::IntiAllConnections() { DestroyAllDBConnections(); #if USE_ODBC // 开始按照最小数量开始创建; int nCount = 0; CDatabase *pDatabase = NULL; for (int i = 0; i < m_nMinCount; i++) { pDatabase = InitAConnection(); if ( pDatabase ) { nCount++; m_listIdleConnections._push_back(pDatabase); InterlockedIncrement(&m_nObjRef); //增加引用计数; pDatabase = NULL; } } #else int nCount = 0; pAdoObj pDatabase = NULL; for ( int i = 0; i < m_nMinCount; i++) { pDatabase = InitAConnection(); if (pDatabase) { nCount++; m_listIdleConnections._push_back(pDatabase); InterlockedIncrement(&m_nObjRef); pDatabase = NULL; } } #endif return nCount; } void CWxAdoPool::DestroyAllDBConnections() { m_bNeedExit = TRUE; // 首先等待m_listBusyConnections.size() == 0; while(1) { if ( m_listBusyConnections.size() == 0 ) break; Sleep(1000); } pAdoObj pObj = NULL; AdoConnList::iterator itIdle = m_listIdleConnections.begin(); while (itIdle != m_listIdleConnections.end()) { pObj = *itIdle; if (NULL != pObj) { //if (pObj->pConnection) //{ // pObj->pConnection->Close(); // pObj->pConnection->Release(); //} //if (pObj->pCommand) //{ // pObj->pCommand->Release(); //} //if (pObj->pRecordSet) // pObj->pRecordSet.Release(); #ifdef _DEBUG OutputDebugString(_T("删除连接池对象\n")); #endif delete pObj; pObj = NULL; } itIdle = m_listIdleConnections.erase(itIdle); } m_bNeedExit = FALSE; } pAdoObj CWxAdoPool::GetAConnection( IN CONST DWORD &dwTimeOut /* = 1000 */ ) { if ( m_bNeedExit )// 停止获取; return NULL; // 1.首先到池中查找有无空闲对象; BOOL bGetIdl = FALSE; DWORD dwTime = GetTickCount(); pAdoObj pConnection = NULL; do { if ( m_listIdleConnections._size() > 0){ //AutoThreadSection aSection(&m_critSection); pConnection = m_listIdleConnections._pop_front_(); if (pConnection) { m_listBusyConnections._push_back(pConnection); bGetIdl = TRUE; } } else { if (m_nObjRef < m_nMaxCount) { //AutoThreadSection aSection(&m_critSection); pConnection = InitAConnection(); if (pConnection){ //bGetIdl = TRUE; m_listBusyConnections._push_back(pConnection); InterlockedIncrement(&m_nObjRef); //增加引用计数; WxAdoGlobal::WriteTextLog(_T("创建连接对象:共有 %d 个"), m_nObjRef); break; } } } if ( !bGetIdl ) { // 未找到,小憩一会,防止CPU爆满; Sleep(0); // 超时,则结束返回NULL; if ( (GetTickCount() - dwTime) >= dwTimeOut){ WxAdoGlobal::WriteTextLog(_T("获取连接对象超时")); break; } } } while ( !bGetIdl ); return pConnection; } void CWxAdoPool::RestoreAConnection(IN pAdoObj pObj) { if (pObj != NULL ){ m_listBusyConnections._remove(pObj); if (pObj->pConnection->GetState() != adStateClosed) m_listIdleConnections._push_back(pObj); else delete pObj; } } pAdoObj CWxAdoPool::InitAConnection() { if ( m_nObjRef == m_nMaxCount ) return NULL; pAdoObj pObj = new AdoObj; pObj->pConnection.CreateInstance(__uuidof(Connection)); TCHAR szConnString[MAX_PATH] = {0}; if (m_dwDBPort != 0) { if ( m_strDBType.CompareNoCase(_T("mssql")) == 0 ) { if ( m_strDBAccount.IsEmpty() ) _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITH_PORT, m_strDBSource, m_dwDBPort,m_strDBName); else _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITH_PORT,m_strDBSource, m_dwDBPort, m_strDBName, m_strDBAccount, m_strPassWord); } else if (m_strDBType.CompareNoCase(_T("mysql")) == 0) { _stprintf_s(szConnString, MAX_PATH, _T("DRIVER=MariaDB ODBC 3.0 Driver;SERVER=%s;PORT=%d;DATABASE=%s;UID=%s;PWD=%s;"), m_strDBSource, m_dwDBPort, m_strDBName, m_strDBAccount, m_strPassWord); } else if (m_strDBType.CompareNoCase(_T("psql")) == 0) { } else if (m_strDBType.CompareNoCase(_T("sqlite3")) == 0) { } } else { if ( m_strDBType.CompareNoCase(_T("mssql")) == 0 ) { if ( m_strDBAccount.IsEmpty() ) _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName); else _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName, m_strDBAccount, m_strPassWord); } else if (m_strDBType.CompareNoCase(_T("mysql")) == 0) { _stprintf_s(szConnString, MAX_PATH, _T("DRIVER=MariaDB ODBC 3.0 Driver;SERVER=%s;PORT=3306;DATABASE=%s;UID=%s;PWD=%s;"), m_strDBSource, m_strDBName, m_strDBAccount, m_strPassWord); } else if (m_strDBType.CompareNoCase(_T("psql")) == 0) { } else if (m_strDBType.CompareNoCase(_T("sqlite3")) == 0) { } } try { HRESULT hr = pObj->pConnection->Open(_bstr_t(szConnString), "", "", adModeUnknown); if (FAILED(hr)) { if (pObj) delete pObj; pObj = NULL; return NULL; } pObj->pCommand.CreateInstance(__uuidof(Command)); // 将库连接赋于它; pObj->pCommand->ActiveConnection = pObj->pConnection; } catch (_com_error &e) { _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); if (pObj) delete pObj; pObj = NULL; WxAdoGlobal::WriteTextLog(_T("SQL连接串:%08lx,%s,%s,%s"), e.Error(), e.ErrorMessage(), (TCHAR*)bstrSource, (TCHAR*)bstrDescription); } return pObj; } void CWxAdoPool::CloseAConnection(pAdoObj &pDataBase) { m_listIdleConnections._remove(pDataBase); InterlockedDecrement(&m_nObjRef); // 减少计数; if ( pDataBase ) delete pDataBase; pDataBase = NULL; } void CWxAdoPool::CloseBusyConnection(IN pAdoObj &pDataBase) { m_listBusyConnections._remove(pDataBase); InterlockedDecrement(&m_nObjRef); // 减少计数; if ( pDataBase ) pDataBase->pConnection->Close(); }