DBInterface.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. #include "StdAfx.h"
  2. #include "DBInterface.h"
  3. #include <string>
  4. #include "Global.h"
  5. #define MSG_SHOWPROMPTING WM_USER + 101
  6. extern HWND g_hwnd;
  7. CDBInterface::CDBInterface(void)
  8. {
  9. m_bOpen = FALSE;
  10. m_bSolve = FALSE;
  11. m_pdbInstance = NULL;
  12. m_hReConnectEvent = NULL;
  13. m_hReConnectThread = NULL;
  14. }
  15. CDBInterface::~CDBInterface(void)
  16. {
  17. CloseDatabase();
  18. }
  19. //************************************//
  20. // 数据库地址;
  21. // 数据库端口;
  22. // 数据库管理员账号;
  23. // 数据库管理员密码(使用加密);
  24. // 数据库名称;
  25. //
  26. // [函数]:GetIniInfo
  27. // [描述]:获取指定ini信息;
  28. // [参数]:
  29. // szPath:ini所在目录;
  30. // szIniName:ini名;
  31. // szConnectSQL:返回的sql连接字符串;
  32. // [返回]:void
  33. //
  34. //************************************//
  35. void CDBInterface::GetIniInfo(const char *szPath, const char *szIniName)
  36. {
  37. WCHAR szFile[MAX_PATH + 1];
  38. ::wmemset(szFile, 0, MAX_PATH + 1);
  39. if (szPath != NULL && szIniName != NULL)
  40. wsprintf(szFile, _T("%s\\%s"), szPath, szIniName);
  41. else
  42. wsprintf(szFile, _T("%s\\lyfzServiceInfo.ini"), g_ModulePath);
  43. TRACE("szFile =%s\n", szFile);
  44. GetPrivateProfileString(_T("ServerInfo"), _T("dbServer"), _T(""), g_szDBServer, MAX_PATH, szFile);
  45. g_dwDBServerPort = GetPrivateProfileInt(_T("ServerInfo"), _T("dbServerPort"), 0, szFile);
  46. GetPrivateProfileString(_T("ServerInfo"), _T("dbAccount"), _T(""), g_szDBAccount, MAX_PATH, szFile);
  47. GetPrivateProfileString(_T("ServerInfo"), _T("dbPassWord"), _T(""), g_szDBPassWord, MAX_PATH, szFile);
  48. GetPrivateProfileString(_T("ServerInfo"), _T("dbName"), _T(""), g_szDBName, MAX_PATH, szFile);
  49. if (g_dwDBServerPort != 0)
  50. wsprintf(m_szConnectString, _T("driver={SQL Server};Server=%s,%d;database=%s;uid=%s;pwd=%s"),
  51. g_szDBServer, g_dwDBServerPort, g_szDBName, g_szDBAccount, g_szDBPassWord);
  52. else
  53. wsprintf(m_szConnectString, _T("driver={SQL Server};Server=%s;database=%s;uid=%s;pwd=%s"),
  54. g_szDBServer, g_szDBName, g_szDBAccount, g_szDBPassWord);
  55. }
  56. BOOL CDBInterface::SolveDBError(CONST DWORD &dwError, LPCTSTR lpErrorString)
  57. {
  58. AutoThreadSection aSection(&s_critSection);
  59. if (m_bSolve) return TRUE;
  60. switch (dwError)
  61. {
  62. case ERROR_PIPE_NOT_CONNECTED:
  63. case WSAECONNRESET:
  64. case WSAECONNABORTED:
  65. {
  66. m_bSolve = TRUE;
  67. m_strConnectErrorDescriptor = lpErrorString;
  68. // 启用重连线程;
  69. CloseDatabase();
  70. StartThread();
  71. }
  72. break;
  73. default:
  74. // 其他错误,输出日志;
  75. //WriteClientLog(lpErrorString);
  76. break;
  77. }
  78. return FALSE;
  79. }
  80. int CDBInterface::StartThread()
  81. {
  82. if (m_hReConnectEvent == NULL)
  83. m_hReConnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // 无信号事件;
  84. if (m_hReConnectEvent == NULL)
  85. {
  86. m_bSolve = FALSE;
  87. return -1;
  88. }
  89. if (m_hReConnectThread == NULL)
  90. m_hReConnectThread = CreateThread(NULL, 0, ReConnectDatabaseThread, this, 0, NULL);
  91. if (m_hReConnectThread == NULL)
  92. {
  93. m_bSolve = FALSE;
  94. return -1;
  95. }
  96. else
  97. {
  98. CloseHandle(m_hReConnectThread);
  99. m_hReConnectThread = NULL;
  100. }
  101. return 0;
  102. }
  103. int CDBInterface::EndofThread()
  104. {
  105. if (m_hReConnectEvent)
  106. SetEvent(m_hReConnectEvent);
  107. if (m_hReConnectThread)
  108. {
  109. if (WaitForSingleObject(m_hReConnectThread, INFINITE) != WAIT_TIMEOUT)
  110. CloseHandle(m_hReConnectThread);
  111. m_hReConnectThread = NULL;
  112. }
  113. if (m_hReConnectEvent)
  114. CloseHandle(m_hReConnectEvent);
  115. m_hReConnectEvent = NULL;
  116. return 0L;
  117. }
  118. DWORD CDBInterface::ReConnectDatabaseThread(LPVOID lpPara)
  119. {
  120. CDBInterface *pInstance = (CDBInterface*)lpPara;
  121. do
  122. {
  123. if (pInstance->OpenDatabase())
  124. {
  125. pInstance->m_bSolve = FALSE;
  126. break;
  127. }
  128. } while (WaitForSingleObject(pInstance->m_hReConnectEvent, 5000L) == WAIT_TIMEOUT);
  129. if (pInstance->m_hReConnectEvent)
  130. CloseHandle(pInstance->m_hReConnectEvent);
  131. pInstance->m_hReConnectEvent = NULL;
  132. return 0L;
  133. }
  134. BOOL CDBInterface::OpenDatabase(const TCHAR *szSQLConnectString)
  135. {
  136. AutoThreadSection aSection(&s_critSection);
  137. if (m_pdbInstance == NULL)
  138. {
  139. m_pdbInstance = new CDatabase;
  140. if (szSQLConnectString == NULL)
  141. szSQLConnectString = m_szConnectString;
  142. try
  143. {
  144. m_pdbInstance->OpenEx(szSQLConnectString, CDatabase::noOdbcDialog);
  145. CString strShow;
  146. strShow.Format(_T("打开数据库成功"));
  147. ::SendMessage(g_hwnd, MSG_SHOWPROMPTING, (WPARAM)&strShow, 0);
  148. }
  149. catch (CDBException* e)
  150. {
  151. m_pdbInstance->Close();
  152. delete m_pdbInstance;
  153. m_pdbInstance = NULL;
  154. CString strShow;
  155. strShow.Format(_T("打开数据库失败:%s"), e->m_strError);
  156. ::SendMessage(g_hwnd, MSG_SHOWPROMPTING, (WPARAM)&strShow, 1);
  157. e->Delete();
  158. return FALSE;
  159. }
  160. m_bOpen = TRUE;
  161. }
  162. return m_bOpen;
  163. }
  164. void CDBInterface::CloseDatabase()
  165. {
  166. m_bOpen = FALSE;
  167. if (m_pdbInstance)
  168. {
  169. m_pdbInstance->Close();
  170. delete m_pdbInstance;
  171. }
  172. m_pdbInstance = NULL;
  173. }
  174. int CDBInterface::Execute(LPCTSTR pSql)
  175. {
  176. try
  177. {
  178. AutoThreadSection aSection(&s_critSection);
  179. if (!m_bOpen) return FALSE;
  180. //m_pdbInstance->BeginTrans();
  181. m_pdbInstance->ExecuteSQL(pSql);
  182. //m_pdbInstance->CommitTrans();
  183. }
  184. catch (CDBException* e)
  185. {
  186. //LOG4C((LOG_NOTICE,"执行SQL失败:%s",e->m_strError));
  187. //m_pdbInstance->Rollback();
  188. SolveDBError(GetLastError(), e->m_strError);
  189. e->Delete();
  190. return -1;
  191. }
  192. return 0;
  193. }
  194. //************************************//
  195. // [函数]:GetSelectCount
  196. // [描述]:通过选择语句“获取数据”
  197. // [参数]:
  198. // CString* pTableName, 表名
  199. // CString* pFilter where 字段条件
  200. // [返回]:返回查询的数量
  201. //
  202. //************************************//
  203. DWORD CDBInterface::GetSelectCount(CString* pTableName, CString* pFilter)
  204. {
  205. try
  206. {
  207. if (!m_bOpen)
  208. return -1;
  209. if(pTableName == NULL || (*pTableName) == _T(""))
  210. return -1;
  211. CString strSQL = _T("select count(*) as cot from ");
  212. if (!pFilter || (*pFilter) == _T(""))
  213. strSQL += (*pTableName);
  214. else
  215. strSQL += (*pTableName) + _T(" where ") + (*pFilter);
  216. char szSQL[MAX_PATH] = {0};
  217. WChar2Char(szSQL, strSQL);
  218. LOG4C((LOG_NOTICE, "执行语句[%s]", szSQL));
  219. CRecordset tagRecordset(m_pdbInstance);
  220. tagRecordset.Open(CRecordset::forwardOnly, strSQL);
  221. tagRecordset.GetFieldValue(_T("cot"), strSQL);
  222. tagRecordset.Close();
  223. char szValue[64] = {0};
  224. WChar2Char(szValue, strSQL);
  225. LOG4C((LOG_NOTICE, "记录数[%s]", szValue));
  226. return atol(szValue);
  227. }
  228. catch (CDBException* e)
  229. {
  230. char szTbaleName[128] = {0};
  231. char szError[512] = {0};
  232. WChar2Char(szTbaleName, (*pTableName));
  233. WChar2Char(szError, e->m_strError);
  234. LOG4C((LOG_NOTICE, "获取记录集数失败[%s]:%s", szTbaleName, szError));
  235. SolveDBError(GetLastError(), e->m_strError);
  236. e->Delete();
  237. return -1;
  238. }
  239. }
  240. //************************************//
  241. // [函数]:GetDataBySelect
  242. // [描述]:通过选择语句“获取数据”
  243. // [参数]:
  244. // CArray<CStringArray, CStringArray>& arr --------------数据容器
  245. // const std::vector<CString>& vFieldName -------------- 要读取的字段索引集
  246. // const UINT nTable ---------------------------------数据表名
  247. // CString* pfilter --------------------------------sql语句的条件限制Where clause
  248. // CString* pSort ----------------------------------排序Order By Clause
  249. // const int nType ---------------------------------=0(将所有字段的数据写入容器),>0(按索引字段读取数据写入容器)
  250. // [返回]:BOOL
  251. //
  252. //************************************//
  253. BOOL CDBInterface::GetDataBySelect(CArray<CStringArray, CStringArray>& arr, const UINT nTable, std::vector<CString>& vFieldName, CString* pfilter, CString* pSort)
  254. {
  255. if(vFieldName.empty())
  256. return FALSE;
  257. try{
  258. CString strTableName = _T("");
  259. GetTableNameByType(nTable, strTableName);
  260. if(strTableName == _T(""))
  261. return FALSE;
  262. AutoThreadSection aSection(&s_critSection);
  263. if (!IsOpen())
  264. return FALSE;
  265. DWORD nCount = GetSelectCount(&strTableName);
  266. if(nCount == 0)
  267. return FALSE;
  268. CRecordset set(m_pdbInstance);
  269. if (pfilter && _tcscmp((const WCHAR*)pfilter, _T("")) != 0)
  270. set.m_strFilter = (*pfilter);
  271. if (pSort && _tcscmp((const WCHAR*)pSort, _T("")) != 0)
  272. set.m_strSort = (*pSort);
  273. CString strOutField = _T("");
  274. int idx = 0;
  275. int nSize = vFieldName.size();
  276. std::vector<CString>::iterator it = vFieldName.begin();
  277. for(;it != vFieldName.end();)
  278. {
  279. CString strtmp = _T("");
  280. if(idx != (nSize - 1))
  281. strtmp = (*it) + _T(",");
  282. else
  283. strtmp = (*it);
  284. strOutField += strtmp;
  285. ++idx;
  286. ++it;
  287. }
  288. CString strSQL = _T("select ") + strOutField + _T(" from ") + strTableName;;
  289. set.Open(CRecordset::dynaset, strSQL);
  290. arr.SetSize(nCount, 1);
  291. int nIndex = 0;
  292. while (!set.IsEOF())
  293. {
  294. arr.ElementAt(nIndex).RemoveAll();
  295. int i = 0;
  296. std::vector<CString>::iterator it = vFieldName.begin();
  297. for(;it != vFieldName.end();)
  298. {
  299. arr.ElementAt(nIndex).Add(_T(""));
  300. CString strValue = _T("");
  301. set.GetFieldValue((*it), strValue);
  302. arr.ElementAt(nIndex).SetAt(i, strValue);
  303. i++;
  304. ++it;
  305. }
  306. set.MoveNext();
  307. nIndex++;
  308. if(arr.GetSize() <= nIndex)
  309. break;
  310. }
  311. arr.SetSize(nIndex, 1);
  312. set.Close();
  313. }
  314. catch (CDBException *e)
  315. {
  316. SolveDBError(GetLastError(), e->m_strError);
  317. e->Delete();
  318. return FALSE;
  319. }
  320. return TRUE;
  321. }
  322. //************************************//
  323. // [函数]:GetTableNameByString
  324. // [描述]:通过表名类型获取表名
  325. // [参数]:
  326. // const UINT nTable-------------------------------------表名的enum类型
  327. // CString& strTableName---------------------------------返回数据表名
  328. // [返回]:
  329. //
  330. //************************************//
  331. void CDBInterface::GetTableNameByType(const UINT nTable, CString& strTableName)
  332. {
  333. switch(nTable)
  334. {
  335. case NAME_renyuan1:
  336. strTableName = _T("renyuan");//
  337. break;
  338. case NAME_renyuan2:
  339. strTableName = _T("dbo.View_UserInfo");
  340. break;
  341. case NAME_accountview:
  342. strTableName = _T("dbo.accountview");//
  343. break;
  344. case NAME_LoginTimeSet:
  345. strTableName = _T("lonintimeset");
  346. break;
  347. case NAME_SetLoginBan:
  348. strTableName = _T("loninbanset");
  349. break;
  350. case NAME_lonindata:
  351. strTableName = _T("lonindata");
  352. break;
  353. case NAME_loginsign:
  354. strTableName = _T("loginsign");
  355. break;
  356. }
  357. }