#include "MysqlClient.h" #include "common/Utils.h" //#include "Spdlogger.h" #include "Logger.h" #include using namespace std; static int64_t GetTimestamp() { return chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); } MysqlClient::MysqlClient(MysqlOption option) : option(option) { conn(); } MysqlClient::~MysqlClient() { this->close(); } static int64_t g_tickErr {0}; int MysqlClient::conn() { if (mysql_) { return 0; } if (GetTimestamp() - g_tickErr <= 5) { return 1; } mysql_ = mysql_init(nullptr); MYSQL* ret = mysql_real_connect(mysql_, option.host.c_str(), option.user.c_str(), option.password.c_str(), option.dbname.c_str(), option.port, NULL, 0); if (ret == NULL) { std::string err = mysql_error(mysql_); //Spdlogger::info("[mysql] connect failed: {}", mysql_error(mysql_)); mysql_ = nullptr; g_tickErr = GetTimestamp(); } else { g_tickErr = 0; mysql_query(mysql_, "set names 'utf8';"); } return 0; } bool MysqlClient::isConnected() { return (mysql_ != nullptr); } void MysqlClient::close() { if (mysql_) { mysql_close(mysql_); mysql_ = nullptr; } } static int MysqlQuery(MYSQL* mysql, const std::string& sql) { int err = 0; if (!mysql) { XLOGE() << "Mysql exec error, database is not connected."; return err; } if (sql.empty()) { XLOGE() << "Mysql exec error, sql is empty."; return err; } err = mysql_query(mysql, sql.c_str()); if (0 != err) { err = mysql_errno(mysql); XLOGE() << "Mysql exec error: " << err << "," << mysql_error(mysql) << ", sql=" << sql; return err; } return err; } int MysqlClient::exec(std::string sql) { int err = MysqlQuery(mysql_, sql); // 确保读取并释放结果集,否则会产生 [2014,Commands out of sync;] 错误 MYSQL_RES* res = mysql_store_result(mysql_); if (res) { mysql_free_result(res); } return err; } int MysqlClient::exec(std::string sql, vector& result) { result.clear(); int err = MysqlQuery(mysql_, sql); if (err != 0) { return err; } MYSQL_RES* res = mysql_store_result(mysql_); if (res) { vector fieldNames; while (true) { MYSQL_FIELD* field = mysql_fetch_field(res); if (!field) { break; } fieldNames.push_back(field->name); } while (true) { MYSQL_ROW row = mysql_fetch_row(res); if (!row) { break; } Fields rowData; for (size_t i = 0; i < fieldNames.size(); ++i) { string field_text = (row[i] == NULL) ? "" : row[i]; rowData.set(fieldNames[i], field_text); } result.push_back(rowData); } // 释放结果集 mysql_free_result(res); } return 0; }