WxAdoPool.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #include "StdAfx.h"
  2. #include "WxAdoPool.h"
  3. #include "Global.h"
  4. //////////////////////////////////////////////////////////////////////////
  5. CWxAdoPool::CWxAdoPool()
  6. {
  7. m_nRef = 0;
  8. m_nObjRef = 0;
  9. m_nMaxCount = 0;
  10. m_nMinCount = 0;
  11. m_bNeedExit = FALSE;
  12. m_bNeedStop = FALSE;
  13. m_bNeedConnection = FALSE;
  14. ::CoInitialize(NULL);//初始化COM环境
  15. }
  16. CWxAdoPool::~CWxAdoPool()
  17. {
  18. m_strDBType.Empty();
  19. m_strDBAccount.Empty();
  20. m_strDBName.Empty();
  21. m_strDBSource.Empty();
  22. m_strPassWord.Empty();
  23. DestroyAllDBConnections();
  24. ::CoUninitialize();
  25. }
  26. 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 */)
  27. {
  28. if ( !lpDBSource || lpDBSource[0] == _T('\0') || !lpDBName || lpDBName[0] == _T('\0') )
  29. {
  30. return 0;
  31. }
  32. m_strDBType = lpDBType;
  33. m_strDBSource = lpDBSource;
  34. m_dwDBPort = dwDBPort;
  35. m_strDBAccount = lpDBAccount;
  36. m_strPassWord = lpPassWord;
  37. m_strDBName = lpDBName;
  38. m_nMinCount = nMinConn;
  39. m_nMaxCount = nMaxConn;
  40. return IntiAllConnections();
  41. }
  42. void CWxAdoPool::ReleasePool()
  43. {
  44. DestroyAllDBConnections();
  45. }
  46. INT CWxAdoPool::IntiAllConnections()
  47. {
  48. DestroyAllDBConnections();
  49. #if USE_ODBC
  50. // 开始按照最小数量开始创建;
  51. int nCount = 0;
  52. CDatabase *pDatabase = NULL;
  53. for (int i = 0; i < m_nMinCount; i++)
  54. {
  55. pDatabase = InitAConnection();
  56. if ( pDatabase )
  57. {
  58. nCount++;
  59. m_listIdleConnections._push_back(pDatabase);
  60. InterlockedIncrement(&m_nObjRef); //增加引用计数;
  61. pDatabase = NULL;
  62. }
  63. }
  64. #else
  65. int nCount = 0;
  66. pAdoObj pDatabase = NULL;
  67. for ( int i = 0; i < m_nMinCount; i++)
  68. {
  69. pDatabase = InitAConnection();
  70. if (pDatabase)
  71. {
  72. nCount++;
  73. m_listIdleConnections._push_back(pDatabase);
  74. InterlockedIncrement(&m_nObjRef);
  75. pDatabase = NULL;
  76. }
  77. }
  78. #endif
  79. return nCount;
  80. }
  81. void CWxAdoPool::DestroyAllDBConnections()
  82. {
  83. m_bNeedExit = TRUE;
  84. // 首先等待m_listBusyConnections.size() == 0;
  85. while(1)
  86. {
  87. if ( m_listBusyConnections.size() == 0 )
  88. break;
  89. Sleep(1000);
  90. }
  91. pAdoObj pObj = NULL;
  92. AdoConnList::iterator itIdle = m_listIdleConnections.begin();
  93. while (itIdle != m_listIdleConnections.end())
  94. {
  95. pObj = *itIdle;
  96. if (NULL != pObj)
  97. {
  98. //if (pObj->pConnection)
  99. //{
  100. // pObj->pConnection->Close();
  101. // pObj->pConnection->Release();
  102. //}
  103. //if (pObj->pCommand)
  104. //{
  105. // pObj->pCommand->Release();
  106. //}
  107. //if (pObj->pRecordSet)
  108. // pObj->pRecordSet.Release();
  109. #ifdef _DEBUG
  110. OutputDebugString(_T("删除连接池对象\n"));
  111. #endif
  112. delete pObj;
  113. pObj = NULL;
  114. }
  115. itIdle = m_listIdleConnections.erase(itIdle);
  116. }
  117. m_bNeedExit = FALSE;
  118. }
  119. pAdoObj CWxAdoPool::GetAConnection( IN CONST DWORD &dwTimeOut /* = 1000 */ )
  120. {
  121. if ( m_bNeedExit )// 停止获取;
  122. return NULL;
  123. // 1.首先到池中查找有无空闲对象;
  124. BOOL bGetIdl = FALSE;
  125. DWORD dwTime = GetTickCount();
  126. pAdoObj pConnection = NULL;
  127. do
  128. {
  129. if ( m_listIdleConnections._size() > 0){
  130. //AutoThreadSection aSection(&m_critSection);
  131. pConnection = m_listIdleConnections._pop_front_();
  132. if (pConnection)
  133. {
  134. m_listBusyConnections._push_back(pConnection);
  135. bGetIdl = TRUE;
  136. }
  137. }
  138. else
  139. {
  140. if (m_nObjRef < m_nMaxCount)
  141. {
  142. //AutoThreadSection aSection(&m_critSection);
  143. pConnection = InitAConnection();
  144. if (pConnection){
  145. //bGetIdl = TRUE;
  146. m_listBusyConnections._push_back(pConnection);
  147. InterlockedIncrement(&m_nObjRef); //增加引用计数;
  148. WxAdoGlobal::WriteTextLog(_T("创建连接对象:共有 %d 个"), m_nObjRef);
  149. break;
  150. }
  151. }
  152. }
  153. if ( !bGetIdl ) {
  154. // 未找到,小憩一会,防止CPU爆满;
  155. Sleep(0);
  156. // 超时,则结束返回NULL;
  157. if ( (GetTickCount() - dwTime) >= dwTimeOut){
  158. WxAdoGlobal::WriteTextLog(_T("获取连接对象超时"));
  159. break;
  160. }
  161. }
  162. } while ( !bGetIdl );
  163. return pConnection;
  164. }
  165. void CWxAdoPool::RestoreAConnection(IN pAdoObj pObj)
  166. {
  167. if (pObj != NULL ){
  168. m_listBusyConnections._remove(pObj);
  169. if (pObj->pConnection->GetState() != adStateClosed)
  170. m_listIdleConnections._push_back(pObj);
  171. else
  172. delete pObj;
  173. }
  174. }
  175. pAdoObj CWxAdoPool::InitAConnection()
  176. {
  177. if ( m_nObjRef == m_nMaxCount )
  178. return NULL;
  179. pAdoObj pObj = new AdoObj;
  180. pObj->pConnection.CreateInstance(__uuidof(Connection));
  181. TCHAR szConnString[MAX_PATH] = {0};
  182. if (m_dwDBPort != 0)
  183. {
  184. if ( m_strDBType.CompareNoCase(_T("mssql")) == 0 )
  185. {
  186. if ( m_strDBAccount.IsEmpty() )
  187. _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITH_PORT, m_strDBSource, m_dwDBPort,m_strDBName);
  188. else
  189. _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITH_PORT,m_strDBSource, m_dwDBPort, m_strDBName, m_strDBAccount, m_strPassWord);
  190. }
  191. else if (m_strDBType.CompareNoCase(_T("mysql")) == 0)
  192. {
  193. _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);
  194. }
  195. else if (m_strDBType.CompareNoCase(_T("psql")) == 0)
  196. {
  197. }
  198. else if (m_strDBType.CompareNoCase(_T("sqlite3")) == 0)
  199. {
  200. }
  201. }
  202. else
  203. {
  204. if ( m_strDBType.CompareNoCase(_T("mssql")) == 0 )
  205. {
  206. if ( m_strDBAccount.IsEmpty() )
  207. _stprintf_s(szConnString, MAX_PATH, DB_SW_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName);
  208. else
  209. _stprintf_s(szConnString, MAX_PATH, DB_SS_CONN_WITHOUT_PORT, m_strDBSource, m_strDBName, m_strDBAccount, m_strPassWord);
  210. }
  211. else if (m_strDBType.CompareNoCase(_T("mysql")) == 0)
  212. {
  213. _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);
  214. }
  215. else if (m_strDBType.CompareNoCase(_T("psql")) == 0)
  216. {
  217. }
  218. else if (m_strDBType.CompareNoCase(_T("sqlite3")) == 0)
  219. {
  220. }
  221. }
  222. try
  223. {
  224. HRESULT hr = pObj->pConnection->Open(_bstr_t(szConnString), "", "", adModeUnknown);
  225. if (FAILED(hr))
  226. {
  227. if (pObj)
  228. delete pObj;
  229. pObj = NULL;
  230. return NULL;
  231. }
  232. pObj->pCommand.CreateInstance(__uuidof(Command));
  233. // 将库连接赋于它;
  234. pObj->pCommand->ActiveConnection = pObj->pConnection;
  235. }
  236. catch (_com_error &e)
  237. {
  238. _bstr_t bstrSource(e.Source());
  239. _bstr_t bstrDescription(e.Description());
  240. if (pObj)
  241. delete pObj;
  242. pObj = NULL;
  243. WxAdoGlobal::WriteTextLog(_T("SQL连接串:%08lx,%s,%s,%s"), e.Error(), e.ErrorMessage(), (TCHAR*)bstrSource, (TCHAR*)bstrDescription);
  244. }
  245. return pObj;
  246. }
  247. void CWxAdoPool::CloseAConnection(pAdoObj &pDataBase)
  248. {
  249. m_listIdleConnections._remove(pDataBase);
  250. InterlockedDecrement(&m_nObjRef); // 减少计数;
  251. if ( pDataBase )
  252. delete pDataBase;
  253. pDataBase = NULL;
  254. }
  255. void CWxAdoPool::CloseBusyConnection(IN pAdoObj &pDataBase)
  256. {
  257. m_listBusyConnections._remove(pDataBase);
  258. InterlockedDecrement(&m_nObjRef); // 减少计数;
  259. if ( pDataBase )
  260. pDataBase->pConnection->Close();
  261. }