123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- // DBConnPool.cpp: implementation of the DBConnPool class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "DBConnPool.h"
- DBConnect * pDBConn = NULL;
- void InitDBIterface(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)
- {
- DBConnPool::Instanse()->SetDBInfo(strDstAddress,strUsername,strPassword,strDBName,minConn,maxConn);
- int cout = DBConnPool::Instanse()->InitializeAllDBConnections();
- }
- DBConnect * GetAConnect()
- {
- DBConnGuard oConnGuard(pDBConn);
- return pDBConn;
- }
- //////////////////////////////////////DBConnect/////////////////////////
- DBConnect::DBConnect(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName,BOOL &state)
- {
- m_bDBOpen = false;
- if (0 == Open(strDstAddress,strUsername,strPassword,strDBName))
- {
- state =true;
- }
- else
- {
- state = false;
- }
- }
- DBConnect::~DBConnect()
- {
- Close();
- }
- int DBConnect::Open(LPCTSTR strDstAddress, LPCTSTR strUsername, LPCTSTR strPassword, LPCTSTR strDBName)
- {
- _strDstAddress = strDstAddress;
- _strDBName = strDBName;
- _strUsername = strUsername;
- _strPassword = strPassword;
- HRESULT comhr = ::CoInitialize(NULL);
- if (FAILED(comhr))
- {
- return -1;
- }
- HRESULT hr = _connection_ptr.CreateInstance(__uuidof(Connection));
- if (FAILED(hr))
- {
- return -1;
- }
- char szSQL[SQL_BUFFER_LEN] = {0};
- memset(szSQL, 0, SQL_BUFFER_LEN);
- sprintf(szSQL, "Driver=SQL Server;Server=%s;DATABASE=%s", strDstAddress, strDBName);
- try
- {
- // 连接到服务器上数据库
- _connection_ptr->Open(szSQL, strUsername, strPassword,adModeUnknown) ;
- if (FAILED(hr))
- return -1;
- }
- catch (_com_error &err)
- {
- TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
- return -1;
- }
- m_bDBOpen = TRUE;
- return 0;
- }
- int DBConnect::Close()
- {
- if (m_bDBOpen)
- {
- HRESULT hr =_connection_ptr->Close();
- if (FAILED(hr))
- {
- return -1;
- }
- ::CoUninitialize();
- m_bDBOpen = FALSE;
- }
- return 0;
- }
- int DBConnect::UserLogin(LPCSTR name,LPCSTR password)
- {
- if (!m_bDBOpen)
- {
- return -1;
- }
- // 创建Command对象
- _CommandPtr cmd;
- HRESULT hr = cmd.CreateInstance(__uuidof(Command));
- if (FAILED(hr))
- {
- return -1;
- }
- char szSQL[SQL_BUFFER_LEN] = {0};
- sprintf(szSQL, "select count(*) as count from t_user where name =/'%s/' and password =/'%s/'",
- name,password);
- cmd->ActiveConnection = _connection_ptr;
- cmd->CommandText = _bstr_t(szSQL);
- cmd->CommandType = adCmdText;
- try
- {
- _RecordsetPtr rs = cmd->Execute(NULL, NULL, adCmdUnknown);
- if (FAILED(hr))
- {
- return -1;
- }
- _variant_t count;
- while (!rs->ADOEOF)
- {
- count = rs->GetCollect("count");
- rs->MoveNext() ;
- }
- if(count.intVal == 0)
- return -1;
- }
- catch (_com_error &err)
- {
- TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
- return -1;
- }
- return 0;
- }
- int DBConnect::GetSubmitInfo(vector<SOAP_SUBMIT_SMS> &vecsoapSms)
- {
- if (!m_bDBOpen)
- {
- return -1;
- }
- // 创建Command对象
- _CommandPtr cmd;
- HRESULT hr = cmd.CreateInstance(__uuidof(Command));
- if (FAILED(hr))
- {
- return -1;
- }
- string strSql = "exec SP_SMS_GETSUBMIT";
- cmd->ActiveConnection = _connection_ptr;
- cmd->CommandText = _bstr_t(strSql.c_str());
- cmd->CommandType = adCmdText;
- try
- {
- _RecordsetPtr rs = cmd->Execute(NULL, NULL, adCmdUnknown);
- if (FAILED(hr))
- {
- return -1;
- }
- while (!rs->ADOEOF)
- {
- _variant_t id;
- _variant_t recverid;
- _variant_t recvertel;
- _variant_t messagecontent;
- _variant_t recverphonetype;
- _variant_t inout;
- _variant_t sendtime;
- _variant_t cardtime;
- _variant_t schoolid;
- _variant_t classid;
- _variant_t rfidno;
- id = rs->GetCollect("id");
- recverid = rs->GetCollect("recverid");
- recvertel = rs->GetCollect("recvertel");
- messagecontent = rs->GetCollect("messagecontent");
- recverphonetype = rs->GetCollect("recverphonetype");
- inout = rs->GetCollect("inout");
- sendtime = rs->GetCollect("sendtime");
- cardtime = rs->GetCollect("cardtime");
- schoolid = rs->GetCollect("schoolid");
- classid = rs->GetCollect("classid");
- rfidno = rs->GetCollect("rfidno");
- SOAP_SUBMIT_SMS submitsms;
- submitsms.id = (int)(long)id;
- VarientToString(recverid, submitsms.recverid);
- VarientToString(recvertel, submitsms.recvertel);
- VarientToString(messagecontent, submitsms.messagecontent);
- VarientToString(recverphonetype, submitsms.recverphonetype);
- submitsms.inout = (int)(long)inout;
- VarientToString(sendtime, submitsms.sendtime);
- VarientToString(cardtime, submitsms.cardtime);
- VarientToString(rfidno, submitsms.rfidno);
- submitsms.schoolid = (int)(long)schoolid;
- submitsms.classid = (int)(long)classid;
- vecsoapSms.push_back(submitsms);
- rs->MoveNext() ;
- }
- }
- catch (_com_error &err)
- {
- TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
- return -1;
- }
- return 0;
- }
- int DBConnect::InsertHistory(int id)
- {
- if (!m_bDBOpen)
- {
- return -1;
- }
- // 创建Command对象
- _CommandPtr cmd;
- HRESULT hr = cmd.CreateInstance(__uuidof(Command));
- if (FAILED(hr))
- {
- return -1;
- }
- char szSQL[SQL_BUFFER_LEN] = {0};
- sprintf(szSQL, "exec SP_SMS_SUBMITRESULT %d", id);
- try
- {
- cmd->ActiveConnection = _connection_ptr;
- cmd->CommandText = _bstr_t(szSQL);
- cmd->CommandType = adCmdText;
- cmd->Execute(NULL, NULL, adCmdUnknown);
- }
- catch (_com_error &err)
- {
- TRACE(_T("数据库操作失败! 错误信息:%s, 文件:%s, 行:%d./n"), err.ErrorMessage(), __FILE__, __LINE__);
- return -1;
- }
- return 0;
- }
- void DBConnect::VarientToString(_variant_t var, string& str)
- {
- if (VT_NULL == var.vt)
- {
- str = "";
- }
- else
- {
- str = (char*)_bstr_t(var);
- }
- }
- //////////////////////////////////////End//////////////////////////////
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- DBConnPool* DBConnPool::m_pInstanse = NULL;
- DBConnPool::DBConnPool()
- {
- m_bNeedStop = FALSE;
- m_bNeedConnection = FALSE;
- m_hMaintanceThread = INVALID_HANDLE_VALUE;
- // 线程控制
- m_hHaveData = CreateEvent (NULL, TRUE, FALSE, _T("DataConnPool"));
- InitializeCriticalSection(&m_csIdleConnList);
- InitializeCriticalSection(&m_csBusyConnList);
- }
- void DBConnPool::SetDBInfo(LPCSTR strDstAddress, LPCSTR strUsername, LPCSTR strPassword, LPCSTR strDBName,int minConn,int maxConn)
- {
- _strDBName = strDBName;
- _strDstAddress = strDstAddress;
- _strPassword = strPassword;
- _strUsername = strUsername;
- m_nMaxCount = maxConn;
- m_nMinCount = minConn;
- }
- DBConnPool::~DBConnPool()
- {
- m_hMaintanceThread = INVALID_HANDLE_VALUE;
- m_bNeedStop = TRUE;
- CloseHandle(m_hHaveData);
- CloseHandle(m_hMaintanceThread);
- DeleteCriticalSection(&m_csIdleConnList);
- DeleteCriticalSection(&m_csBusyConnList);
- }
- DBConnPool *DBConnPool::Instanse()
- {
- if (NULL == m_pInstanse)
- {
- m_pInstanse = new DBConnPool();
- }
- return m_pInstanse;
- }
- int DBConnPool::InitializeAllDBConnections()
- {
- // 先清除现有的数据
- DestroyAllDBConnections();
- // 开始按照最小数量开始创建
- DBConnect * pDBConnect = NULL;
- int nCount = 0;
- for (int i = 0; i < m_nMinCount; i++)
- {
- nCount = InitializeAConnection();
- }
- // 创建一个工作线程,用来进行一些后台维护工作
- if (INVALID_HANDLE_VALUE == m_hMaintanceThread)
- {
- m_hMaintanceThread = CreateThread(NULL, NULL, thread_run, (LPVOID)this, 0, NULL);
- }
- return nCount;
- }
- void DBConnPool::DestroyAllDBConnections()
- {
- // 销毁数据库连接可以使用大锁
- EnterCriticalSection(&m_csIdleConnList);
- DBConnectList::iterator itIdle = m_listIdleConnection.begin();
- DBConnectList::iterator itIdleEnd = m_listIdleConnection.end();
- while (itIdle != itIdleEnd)
- {
- if (NULL != (*itIdle))
- {
- (*itIdle)->Close();
- delete (*itIdle);
- }
- // erase本身就会把跌代器指向下一个
- itIdle = m_listIdleConnection.erase(itIdle);
- }
- LeaveCriticalSection(&m_csIdleConnList);
- // 还有使用中的连接
- EnterCriticalSection(&m_csBusyConnList);
- DBConnectList::iterator itBusy = m_listBusyConnection.begin();
- DBConnectList::iterator itBusyEnd = m_listBusyConnection.end();
- while (itBusy != itBusyEnd)
- {
- if (NULL != (*itBusy))
- {
- (*itBusy)->Close();
- delete (*itBusy);
- }
- // erase本身就会把跌代器指向下一个
- itBusy = m_listBusyConnection.erase(itBusy);
- }
- LeaveCriticalSection(&m_csBusyConnList);
- }
- int DBConnPool::InitializeAConnection()
- {
- BOOL bSuccess = FALSE;
- DBConnect * pDBEngine = new DBConnect(_strDstAddress, _strUsername, _strPassword, _strDBName, bSuccess);
- if (bSuccess)
- {
- m_bNeedConnection = FALSE;
- return RestoreAConnection(pDBEngine);
- }
- else
- {
- delete pDBEngine;
- return m_listIdleConnection.size();
- }
- }
- void DBConnPool::CloseAConnection(DBConnect* pDBEngine)
- {
- pDBEngine->Close();
- // 从空闲队列将其删除
- EnterCriticalSection(&m_csIdleConnList);
- m_listIdleConnection.remove(pDBEngine);
- LeaveCriticalSection(&m_csIdleConnList);
- }
- DBConnect * DBConnPool::GetAConnection()
- {
- DBConnect * pDBEngine = NULL;
- // 做一个循环,反复尝试五次取连接,每次间隔1秒钟
- int nTimes = 0;
- while ((m_listIdleConnection.size() <= 0) && (nTimes < 5))
- {
- Sleep(1000);
- nTimes++;
- }
- if (5 == nTimes)
- {
- // 这样狼狈的进来肯定是没有可用连接了,记录日志退出
- // g_pSvrLog->AddRunLog(LL_ERROR, _T("Waiting for a connection for a long time, but failed."));
- return pDBEngine;
- }
- // 从空闲队列中取出,并且加入到使用队列中
- EnterCriticalSection(&m_csIdleConnList);
- if (m_listIdleConnection.size() > 0)
- {
- pDBEngine = m_listIdleConnection.front();
- m_listIdleConnection.pop_front();
- // 加入使用的连接队列
- EnterCriticalSection(&m_csBusyConnList);
- m_listBusyConnection.push_back(pDBEngine);
- LeaveCriticalSection(&m_csBusyConnList);
- }
- LeaveCriticalSection(&m_csIdleConnList);
- if (m_listIdleConnection.size() <= 1)
- {
- // 剩余空闲连接的数目小于等于1个时候需要检查开始创建
- if ((m_listIdleConnection.size() + m_listBusyConnection.size()) < m_nMaxCount)
- {
- // 还小于最大限制,可以创建
- SetEvent(m_hHaveData);
- m_bNeedConnection = TRUE;
- }
- else
- {
- // 超出限制了,做个记录吧
- //g_pSvrLog->AddRunLog(LL_ERROR, _T("Database connection reached max count."));
- }
- }
- return pDBEngine;
- }
- int DBConnPool::RestoreAConnection(DBConnect* pDBEngine)
- {
- if (NULL != pDBEngine)
- {
- // 从使用中的队列取出
- EnterCriticalSection(&m_csBusyConnList);
- m_listBusyConnection.remove(pDBEngine);
- LeaveCriticalSection(&m_csBusyConnList);
- // 加入到空闲队列中
- EnterCriticalSection(&m_csIdleConnList);
- m_listIdleConnection.push_back(pDBEngine);
- LeaveCriticalSection(&m_csIdleConnList);
- }
- EnterCriticalSection(&m_csIdleConnList);
- int nCount = m_listIdleConnection.size();
- LeaveCriticalSection(&m_csIdleConnList);
- return nCount;
- }
- void DBConnPool::StopThread()
- {
- m_bNeedStop = TRUE;
- // 因为线程是无限制等待信号的,所以这里先把标志位置为停止,然后发信号让线程检测
- SetEvent(m_hHaveData);
- // 等待退出
- WaitForSingleObject(m_hMaintanceThread, INFINITE);
- CloseHandle(m_hMaintanceThread);
- }
- BOOL DBConnPool::IsNeedStop()
- {
- return m_bNeedStop;
- }
- BOOL DBConnPool::IsNeedConnection()
- {
- return m_bNeedConnection;
- }
- /************************************************************************/
- /* 维护线程 */
- /************************************************************************/
- DWORD WINAPI DBConnPool::thread_run( LPVOID pdata)
- {
- DBConnPool * pConPool = (DBConnPool *) pdata;
- while (!pConPool->IsNeedStop())
- {
- // 设置事件为无信号, 并且无限制等待
- ResetEvent(pConPool->m_hHaveData);
- WaitForSingleObject(pConPool->m_hHaveData, INFINITE);
- if (pConPool->IsNeedConnection())
- {
- // g_pSvrLog->AddRunLog(LL_DEBUG, _T("Create a new DB connection."));
- pConPool->InitializeAConnection();
- }
- }
- return 0;
- }
|