tc_mysql.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #if TARS_MYSQL
  17. #include "util/tc_mysql.h"
  18. #include "util/tc_common.h"
  19. #include "util/tc_des.h"
  20. #include "util/tc_base64.h"
  21. #include "errmsg.h"
  22. #include <sstream>
  23. #include <string.h>
  24. namespace tars
  25. {
  26. TC_Mysql::TC_Mysql()
  27. :_bConnected(false)
  28. {
  29. _pstMql = mysql_init(NULL);
  30. }
  31. TC_Mysql::TC_Mysql(const string& sHost, const string& sUser, const string& sPasswd, const string& sDatabase, const string &sCharSet, int port, int iFlag)
  32. :_bConnected(false)
  33. {
  34. init(sHost, sUser, sPasswd, sDatabase, sCharSet, port, iFlag);
  35. _pstMql = mysql_init(NULL);
  36. }
  37. TC_Mysql::TC_Mysql(const TC_DBConf& tcDBConf)
  38. :_bConnected(false)
  39. {
  40. _dbConf = tcDBConf;
  41. _pstMql = mysql_init(NULL);
  42. }
  43. TC_Mysql::~TC_Mysql()
  44. {
  45. if (_pstMql != NULL)
  46. {
  47. mysql_close(_pstMql);
  48. _pstMql = NULL;
  49. }
  50. }
  51. void TC_Mysql::init(const string& sHost, const string& sUser, const string& sPasswd, const string& sDatabase, const string &sCharSet, int port, int iFlag)
  52. {
  53. _dbConf._host = sHost;
  54. _dbConf._user = sUser;
  55. _dbConf._password = sPasswd;
  56. _dbConf._database = sDatabase;
  57. _dbConf._charset = sCharSet;
  58. _dbConf._port = port;
  59. _dbConf._flag = iFlag;
  60. }
  61. void TC_Mysql::init(const TC_DBConf& tcDBConf)
  62. {
  63. _dbConf = tcDBConf;
  64. }
  65. TC_DBConf TC_Mysql::getDBConf()
  66. {
  67. return _dbConf;
  68. }
  69. void TC_Mysql::connect()
  70. {
  71. disconnect();
  72. if( _pstMql == NULL)
  73. {
  74. _pstMql = mysql_init(NULL);
  75. }
  76. //建立连接后, 自动调用设置字符集语句
  77. if(!_dbConf._charset.empty()) {
  78. if (mysql_options(_pstMql, MYSQL_SET_CHARSET_NAME, _dbConf._charset.c_str())) {
  79. throw TC_Mysql_Exception(string("TC_Mysql::connect: mysql_options MYSQL_SET_CHARSET_NAME ") + _dbConf._charset + ":" + string(mysql_error(_pstMql)));
  80. }
  81. }
  82. //设置连接超时
  83. if(_dbConf._connectTimeout > 0) {
  84. if (mysql_options(_pstMql, MYSQL_OPT_CONNECT_TIMEOUT, &_dbConf._connectTimeout)) {
  85. throw TC_Mysql_Exception(string("TC_Mysql::connect: mysql_options MYSQL_OPT_CONNECT_TIMEOUT ") + TC_Common::tostr(_dbConf._connectTimeout) + ":" + string(mysql_error(_pstMql)));
  86. }
  87. }
  88. if(_dbConf._writeReadTimeout > 0) {
  89. //设置读超时
  90. if (mysql_options(_pstMql, MYSQL_OPT_READ_TIMEOUT, &_dbConf._writeReadTimeout)) {
  91. throw TC_Mysql_Exception(string("TC_Mysql::connect: mysql_options MYSQL_OPT_READ_TIMEOUT ") + TC_Common::tostr(_dbConf._writeReadTimeout) + ":" + string(mysql_error(_pstMql)));
  92. }
  93. //设置写超时
  94. if (mysql_options(_pstMql, MYSQL_OPT_WRITE_TIMEOUT, &_dbConf._writeReadTimeout)) {
  95. throw TC_Mysql_Exception(string("TC_Mysql::connect: mysql_options MYSQL_OPT_WRITE_TIMEOUT ") + TC_Common::tostr(_dbConf._writeReadTimeout) + ":" + string(mysql_error(_pstMql)));
  96. }
  97. }
  98. if (mysql_real_connect(_pstMql, _dbConf._host.c_str(), _dbConf._user.c_str(), _dbConf._password.c_str(), _dbConf._database.c_str(), _dbConf._port, NULL, _dbConf._flag) == NULL)
  99. {
  100. throw TC_Mysql_Exception("[TC_Mysql::connect]: mysql_real_connect: " + string(mysql_error(_pstMql)));
  101. }
  102. _bConnected = true;
  103. }
  104. void TC_Mysql::disconnect()
  105. {
  106. if (_pstMql != NULL)
  107. {
  108. mysql_close(_pstMql);
  109. _pstMql = mysql_init(NULL);
  110. }
  111. _bConnected = false;
  112. }
  113. string TC_Mysql::escapeString(const string& sFrom)
  114. {
  115. string sTo;
  116. string::size_type iLen = sFrom.length() * 2 + 1;
  117. char *pTo = (char *)malloc(iLen);
  118. memset(pTo, 0x00, iLen);
  119. mysql_escape_string(pTo, sFrom.c_str(), sFrom.length());
  120. sTo = pTo;
  121. free(pTo);
  122. return sTo;
  123. }
  124. string TC_Mysql::buildInsertSQLNoSafe(const string &sTableName, const RECORD_DATA &mpColumns)
  125. {
  126. return buildSQLNoSafe(sTableName, "insert", mpColumns);
  127. }
  128. string TC_Mysql::buildInsertSQLNoSafe(const string &sTableName, const map<string, pair<FT, vector<string>>> &mpColumns)
  129. {
  130. return buildBatchSQLNoSafe(sTableName, "insert", mpColumns);
  131. }
  132. string TC_Mysql::buildReplaceSQLNoSafe(const string &sTableName, const RECORD_DATA &mpColumns)
  133. {
  134. return buildSQLNoSafe(sTableName, "replace", mpColumns);
  135. }
  136. string TC_Mysql::buildReplaceSQLNoSafe(const string &sTableName, const map<string, pair<FT, vector<string>>> &mpColumns)
  137. {
  138. return buildBatchSQLNoSafe(sTableName, "replace", mpColumns);
  139. }
  140. string TC_Mysql::buildSQLNoSafe(const string &sTableName, const string &command, const map<string, pair<FT, string> > &mpColumns)
  141. {
  142. ostringstream sColumnNames;
  143. ostringstream sColumnValues;
  144. map<string, pair<FT, string> >::const_iterator itEnd = mpColumns.end();
  145. for(map<string, pair<FT, string> >::const_iterator it = mpColumns.begin(); it != itEnd; ++it)
  146. {
  147. if (it == mpColumns.begin())
  148. {
  149. sColumnNames << "`" << it->first << "`";
  150. if(it->second.first == DB_INT)
  151. {
  152. sColumnValues << it->second.second;
  153. }
  154. else
  155. {
  156. sColumnValues << "'" << escapeString(it->second.second) << "'";
  157. }
  158. }
  159. else
  160. {
  161. sColumnNames << ",`" << it->first << "`";
  162. if(it->second.first == DB_INT)
  163. {
  164. sColumnValues << "," + it->second.second;
  165. }
  166. else
  167. {
  168. sColumnValues << ",'" + escapeString(it->second.second) << "'";
  169. }
  170. }
  171. }
  172. ostringstream os;
  173. os << command << " into " << sTableName << " (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")";
  174. return os.str();
  175. }
  176. string TC_Mysql::buildBatchSQLNoSafe(const string &sTableName, const string &command, const map<string, pair<FT, vector<string> >> &mpColumns)
  177. {
  178. if(mpColumns.empty())
  179. return "";
  180. ostringstream sColumnNames;
  181. ostringstream sColumnValues;
  182. size_t count = mpColumns.begin()->second.second.size();
  183. auto itEnd = mpColumns.end();
  184. for(auto it = mpColumns.begin(); it != itEnd; ++it)
  185. {
  186. if(it == mpColumns.begin())
  187. {
  188. sColumnNames << "`" << it->first << "`";
  189. }
  190. else
  191. {
  192. sColumnNames << ",`" << it->first << "`";
  193. }
  194. if(count != it->second.second.size())
  195. {
  196. throw TC_Mysql_Exception("[TC_Mysql::buildBatchSQLNoSafe]: column count not same!");
  197. }
  198. }
  199. for(size_t i = 0; i < count; i++)
  200. {
  201. sColumnValues << "(";
  202. auto itEnd = mpColumns.end();
  203. for(auto it = mpColumns.begin(); it != itEnd; ++it)
  204. {
  205. if(it != mpColumns.begin())
  206. sColumnValues << ",";
  207. if(it->second.first == DB_INT)
  208. {
  209. sColumnValues << it->second.second[i];
  210. }
  211. else
  212. {
  213. sColumnValues << "'" << escapeString(it->second.second[i]) << "'";
  214. }
  215. }
  216. sColumnValues << ")";
  217. if(i != count - 1)
  218. sColumnValues << ",";
  219. }
  220. ostringstream os;
  221. os << command << " into " << sTableName << " (" << sColumnNames.str() << ") values " << sColumnValues.str();
  222. return os.str();
  223. }
  224. string TC_Mysql::buildUpdateSQLNoSafe(const string &sTableName,const RECORD_DATA &mpColumns, const string &sWhereFilter)
  225. {
  226. ostringstream sColumnNameValueSet;
  227. map<string, pair<FT, string> >::const_iterator itEnd = mpColumns.end();
  228. for(map<string, pair<FT, string> >::const_iterator it = mpColumns.begin(); it != itEnd; ++it)
  229. {
  230. if (it == mpColumns.begin())
  231. {
  232. sColumnNameValueSet << "`" << it->first << "`";
  233. }
  234. else
  235. {
  236. sColumnNameValueSet << ",`" << it->first << "`";
  237. }
  238. if(it->second.first == DB_INT)
  239. {
  240. sColumnNameValueSet << "= " << it->second.second;
  241. }
  242. else
  243. {
  244. sColumnNameValueSet << "= '" << escapeString(it->second.second) << "'";
  245. }
  246. }
  247. ostringstream os;
  248. os << "update " << sTableName << " set " << sColumnNameValueSet.str() << " " << sWhereFilter;
  249. return os.str();
  250. }
  251. string TC_Mysql::realEscapeString(const string& sFrom)
  252. {
  253. if(!_bConnected)
  254. {
  255. connect();
  256. }
  257. string sTo;
  258. string::size_type iLen = sFrom.length() * 2 + 1;
  259. char *pTo = (char *)malloc(iLen);
  260. memset(pTo, 0x00, iLen);
  261. mysql_real_escape_string(_pstMql, pTo, sFrom.c_str(), sFrom.length());
  262. sTo = pTo;
  263. free(pTo);
  264. return sTo;
  265. }
  266. MYSQL *TC_Mysql::getMysql(void)
  267. {
  268. return _pstMql;
  269. }
  270. string TC_Mysql::buildInsertSQL(const string &sTableName, const RECORD_DATA &mpColumns)
  271. {
  272. return buildSQL(sTableName, "insert", mpColumns);
  273. }
  274. string TC_Mysql::buildInsertSQL(const string &sTableName, const map<string, pair<FT, vector<string> >> &mpColumns)
  275. {
  276. return buildBatchSQL(sTableName, "insert", mpColumns);
  277. }
  278. string TC_Mysql::buildReplaceSQL(const string &sTableName, const RECORD_DATA &mpColumns)
  279. {
  280. return buildSQL(sTableName, "replace", mpColumns);
  281. }
  282. string TC_Mysql::buildReplaceSQL(const string &sTableName, const map<string, pair<FT, vector<string>>> &mpColumns)
  283. {
  284. return buildBatchSQL(sTableName, "replace", mpColumns);
  285. }
  286. string TC_Mysql::buildSQL(const string &sTableName, const string &command, const map<string, pair<FT, string> > &mpColumns)
  287. {
  288. ostringstream sColumnNames;
  289. ostringstream sColumnValues;
  290. map<string, pair<FT, string> >::const_iterator itEnd = mpColumns.end();
  291. for(map<string, pair<FT, string> >::const_iterator it = mpColumns.begin(); it != itEnd; ++it)
  292. {
  293. if (it == mpColumns.begin())
  294. {
  295. sColumnNames << "`" << it->first << "`";
  296. if(it->second.first == DB_INT)
  297. {
  298. sColumnValues << it->second.second;
  299. }
  300. else
  301. {
  302. sColumnValues << "'" << realEscapeString(it->second.second) << "'";
  303. }
  304. }
  305. else
  306. {
  307. sColumnNames << ",`" << it->first << "`";
  308. if(it->second.first == DB_INT)
  309. {
  310. sColumnValues << "," + it->second.second;
  311. }
  312. else
  313. {
  314. sColumnValues << ",'" << realEscapeString(it->second.second) << "'";
  315. }
  316. }
  317. }
  318. ostringstream os;
  319. os << command << " into " << sTableName << " (" << sColumnNames.str() << ") values (" << sColumnValues.str() << ")";
  320. return os.str();
  321. }
  322. string TC_Mysql::buildBatchSQL(const string &sTableName, const string &command, const map<string, pair<FT, vector<string> >> &mpColumns)
  323. {
  324. if(mpColumns.empty())
  325. return "";
  326. ostringstream sColumnNames;
  327. ostringstream sColumnValues;
  328. size_t count = mpColumns.begin()->second.second.size();
  329. auto itEnd = mpColumns.end();
  330. for(auto it = mpColumns.begin(); it != itEnd; ++it)
  331. {
  332. if(it == mpColumns.begin())
  333. {
  334. sColumnNames << "`" << it->first << "`";
  335. }
  336. else
  337. {
  338. sColumnNames << ",`" << it->first << "`";
  339. }
  340. if(count != it->second.second.size())
  341. {
  342. throw TC_Mysql_Exception("[TC_Mysql::buildBatchSQL]: column count not same!" + TC_Common::tostr(count) + " !=" + TC_Common::tostr(it->second.second.size()));
  343. }
  344. }
  345. for(size_t i = 0; i < count; i++)
  346. {
  347. sColumnValues << "(";
  348. auto itEnd = mpColumns.end();
  349. for(auto it = mpColumns.begin(); it != itEnd; ++it)
  350. {
  351. if(it != mpColumns.begin())
  352. sColumnValues << ",";
  353. if(it->second.first == DB_INT)
  354. {
  355. sColumnValues << it->second.second[i];
  356. }
  357. else
  358. {
  359. sColumnValues << "'" << realEscapeString(it->second.second[i]) << "'";
  360. }
  361. }
  362. sColumnValues << ")";
  363. if(i != count - 1)
  364. sColumnValues << ",";
  365. }
  366. ostringstream os;
  367. os << command << " into " << sTableName << " (" << sColumnNames.str() << ") values " << sColumnValues.str();
  368. return os.str();
  369. }
  370. string TC_Mysql::buildUpdateSQL(const string &sTableName,const RECORD_DATA &mpColumns, const string &sWhereFilter)
  371. {
  372. ostringstream sColumnNameValueSet;
  373. map<string, pair<FT, string> >::const_iterator itEnd = mpColumns.end();
  374. for(map<string, pair<FT, string> >::const_iterator it = mpColumns.begin(); it != itEnd; ++it)
  375. {
  376. if (it == mpColumns.begin())
  377. {
  378. sColumnNameValueSet << "`" << it->first << "`";
  379. }
  380. else
  381. {
  382. sColumnNameValueSet << ",`" << it->first << "`";
  383. }
  384. if(it->second.first == DB_INT)
  385. {
  386. sColumnNameValueSet << "= " << it->second.second;
  387. }
  388. else
  389. {
  390. sColumnNameValueSet << "= '" << realEscapeString(it->second.second) << "'";
  391. }
  392. }
  393. ostringstream os;
  394. os << "update " << sTableName << " set " << sColumnNameValueSet.str() << " " << sWhereFilter;
  395. return os.str();
  396. }
  397. string TC_Mysql::getVariables(const string &sName)
  398. {
  399. string sql = "SHOW VARIABLES LIKE '" + sName + "'";
  400. MysqlData data = queryRecord(sql);
  401. if(data.size() == 0)
  402. {
  403. return "";
  404. }
  405. if(sName == data[0]["Variable_name"])
  406. {
  407. return data[0]["Value"];
  408. }
  409. return "";
  410. }
  411. void TC_Mysql::execute(const string& sSql)
  412. {
  413. /**
  414. 没有连上, 连接数据库
  415. */
  416. if(!_bConnected)
  417. {
  418. connect();
  419. }
  420. _sLastSql = sSql;
  421. int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
  422. if(iRet != 0)
  423. {
  424. /**
  425. 自动重新连接
  426. */
  427. int iErrno = mysql_errno(_pstMql);
  428. if (iErrno == 2013 || iErrno == 2006)
  429. {
  430. connect();
  431. iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
  432. }
  433. }
  434. if (iRet != 0)
  435. {
  436. throw TC_Mysql_Exception("[TC_Mysql::execute]: mysql_query: [ " + sSql+" ] :" + string(mysql_error(_pstMql)));
  437. }
  438. }
  439. TC_Mysql::MysqlData TC_Mysql::queryRecord(const string& sSql)
  440. {
  441. MysqlData data;
  442. /**
  443. 没有连上, 连接数据库
  444. */
  445. if(!_bConnected)
  446. {
  447. connect();
  448. }
  449. _sLastSql = sSql;
  450. int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
  451. if(iRet != 0)
  452. {
  453. /**
  454. 自动重新连接
  455. */
  456. int iErrno = mysql_errno(_pstMql);
  457. if (iErrno == 2013 || iErrno == 2006)
  458. {
  459. connect();
  460. iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
  461. }
  462. }
  463. if (iRet != 0)
  464. {
  465. throw TC_Mysql_Exception("[TC_Mysql::execute]: mysql_query: [ " + sSql+" ] :" + string(mysql_error(_pstMql)));
  466. }
  467. MYSQL_RES *pstRes = mysql_store_result(_pstMql);
  468. if(pstRes == NULL)
  469. {
  470. throw TC_Mysql_Exception("[TC_Mysql::queryRecord]: mysql_store_result: " + sSql + " : " + string(mysql_error(_pstMql)));
  471. }
  472. vector<string> vtFields;
  473. MYSQL_FIELD *field;
  474. while((field = mysql_fetch_field(pstRes)))
  475. {
  476. vtFields.push_back(field->name);
  477. }
  478. map<string, string> mpRow;
  479. MYSQL_ROW stRow;
  480. while((stRow = mysql_fetch_row(pstRes)) != (MYSQL_ROW)NULL)
  481. {
  482. mpRow.clear();
  483. unsigned long * lengths = mysql_fetch_lengths(pstRes);
  484. for(size_t i = 0; i < vtFields.size(); i++)
  485. {
  486. if(stRow[i])
  487. {
  488. mpRow[vtFields[i]] = string(stRow[i], lengths[i]);
  489. }
  490. else
  491. {
  492. mpRow[vtFields[i]] = "";
  493. }
  494. }
  495. data.data().push_back(mpRow);
  496. }
  497. mysql_free_result(pstRes);
  498. return data;
  499. }
  500. size_t TC_Mysql::travelRecord(const string& sSql, const std::function<void(const map<string, string> &)> & func)
  501. {
  502. size_t count = 0;
  503. /**
  504. 没有连上, 连接数据库
  505. */
  506. if (!_bConnected)
  507. {
  508. connect();
  509. }
  510. _sLastSql = sSql;
  511. int iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
  512. if (iRet != 0)
  513. {
  514. /**
  515. 自动重新连接
  516. */
  517. int iErrno = mysql_errno(_pstMql);
  518. if (iErrno == 2013 || iErrno == 2006)
  519. {
  520. connect();
  521. iRet = mysql_real_query(_pstMql, sSql.c_str(), sSql.length());
  522. }
  523. }
  524. if (iRet != 0)
  525. {
  526. throw TC_Mysql_Exception("[TC_Mysql::execute]: mysql_query: [ " + sSql + " ] :" + string(mysql_error(_pstMql)));
  527. }
  528. MYSQL_RES *pstRes = mysql_store_result(_pstMql);
  529. if (pstRes == NULL)
  530. {
  531. throw TC_Mysql_Exception("[TC_Mysql::queryRecord]: mysql_store_result: " + sSql + " : " + string(mysql_error(_pstMql)));
  532. }
  533. vector<string> vtFields;
  534. MYSQL_FIELD *field;
  535. while ((field = mysql_fetch_field(pstRes)))
  536. {
  537. vtFields.push_back(field->name);
  538. }
  539. MYSQL_ROW stRow;
  540. while ((stRow = mysql_fetch_row(pstRes)) != (MYSQL_ROW)NULL)
  541. {
  542. map<string, string> mpRow;
  543. unsigned long * lengths = mysql_fetch_lengths(pstRes);
  544. for (size_t i = 0; i < vtFields.size(); i++)
  545. {
  546. if (stRow[i])
  547. {
  548. mpRow[vtFields[i]] = string(stRow[i], lengths[i]);
  549. }
  550. else
  551. {
  552. mpRow[vtFields[i]] = "";
  553. }
  554. }
  555. func(mpRow);
  556. count++;
  557. }
  558. mysql_free_result(pstRes);
  559. return count;
  560. }
  561. size_t TC_Mysql::updateRecord(const string &sTableName, const RECORD_DATA &mpColumns, const string &sCondition)
  562. {
  563. string sSql = buildUpdateSQL(sTableName, mpColumns, sCondition);
  564. execute(sSql);
  565. return mysql_affected_rows(_pstMql);
  566. }
  567. size_t TC_Mysql::insertRecord(const string &sTableName, const RECORD_DATA &mpColumns)
  568. {
  569. string sSql = buildInsertSQL(sTableName, mpColumns);
  570. execute(sSql);
  571. return mysql_affected_rows(_pstMql);
  572. }
  573. size_t TC_Mysql::insertRecord(const string &sTableName, const map<string, pair<FT, vector<string> >> &mpColumns)
  574. {
  575. string sSql = buildInsertSQL(sTableName, mpColumns);
  576. execute(sSql);
  577. return mysql_affected_rows(_pstMql);
  578. }
  579. size_t TC_Mysql::replaceRecord(const string &sTableName, const RECORD_DATA &mpColumns)
  580. {
  581. string sSql = buildReplaceSQL(sTableName, mpColumns);
  582. execute(sSql);
  583. return mysql_affected_rows(_pstMql);
  584. }
  585. size_t TC_Mysql::replaceRecord(const string &sTableName, const map<string, pair<FT, vector<string>>> &mpColumns)
  586. {
  587. string sSql = buildReplaceSQL(sTableName, mpColumns);
  588. execute(sSql);
  589. return mysql_affected_rows(_pstMql);
  590. }
  591. size_t TC_Mysql::deleteRecord(const string &sTableName, const string &sCondition)
  592. {
  593. ostringstream sSql;
  594. sSql << "delete from " << sTableName << " " << sCondition;
  595. execute(sSql.str());
  596. return mysql_affected_rows(_pstMql);
  597. }
  598. size_t TC_Mysql::getRecordCount(const string& sTableName, const string &sCondition)
  599. {
  600. ostringstream sSql;
  601. sSql << "select count(*) as num from " << sTableName << " " << sCondition;
  602. MysqlData data = queryRecord(sSql.str());
  603. long n = atol(data[0]["num"].c_str());
  604. return n;
  605. }
  606. size_t TC_Mysql::getSqlCount(const string &sCondition)
  607. {
  608. ostringstream sSql;
  609. sSql << "select count(*) as num " << sCondition;
  610. MysqlData data = queryRecord(sSql.str());
  611. long n = atol(data[0]["num"].c_str());
  612. return n;
  613. }
  614. int TC_Mysql::getMaxValue(const string& sTableName, const string& sFieldName,const string &sCondition)
  615. {
  616. ostringstream sSql;
  617. sSql << "select " << sFieldName << " as f from " << sTableName << " " << sCondition << " order by f desc limit 1";
  618. MysqlData data = queryRecord(sSql.str());
  619. int n = 0;
  620. if(data.size() == 0)
  621. {
  622. n = 0;
  623. }
  624. else
  625. {
  626. n = atol(data[0]["f"].c_str());
  627. }
  628. return n;
  629. }
  630. bool TC_Mysql::existRecord(const string& sql)
  631. {
  632. return queryRecord(sql).size() > 0;
  633. }
  634. long TC_Mysql::lastInsertID()
  635. {
  636. return mysql_insert_id(_pstMql);
  637. }
  638. size_t TC_Mysql::getAffectedRows()
  639. {
  640. return mysql_affected_rows(_pstMql);
  641. }
  642. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  643. TC_Mysql::MysqlRecord::MysqlRecord(const map<string, string> &record)
  644. : _record(record)
  645. {
  646. }
  647. const string& TC_Mysql::MysqlRecord::operator[](const string &s)
  648. {
  649. map<string, string>::const_iterator it = _record.find(s);
  650. if(it == _record.end())
  651. {
  652. throw TC_Mysql_Exception("field '" + s + "' not exists.");
  653. }
  654. return it->second;
  655. }
  656. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  657. vector<map<string, string> >& TC_Mysql::MysqlData::data()
  658. {
  659. return _data;
  660. }
  661. size_t TC_Mysql::MysqlData::size()
  662. {
  663. return _data.size();
  664. }
  665. TC_Mysql::MysqlRecord TC_Mysql::MysqlData::operator[](size_t i)
  666. {
  667. return MysqlRecord(_data[i]);
  668. }
  669. }
  670. #endif