|
@@ -1,468 +0,0 @@
|
|
|
-// 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;
|
|
|
-}
|