WxAdoPool.cpp 6.7 KB

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