WxAdoPool.cpp 6.6 KB

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