6个文件已修改
14个文件已添加
1 文件已重命名
| | |
| | | #include "stdafx.h" |
| | | #include "ConnectionPool.h" |
| | | ConnectionPool::ConnectionPool() |
| | | { |
| | | if (!parseXmlFile()) |
| | | |
| | | #include <fstream> |
| | | #include <iostream> |
| | | #include <thread> |
| | | |
| | | ConnectionPool* ConnectionPool::getInstance() { |
| | | static ConnectionPool connPool; |
| | | return &connPool; |
| | | } |
| | | |
| | | ConnectionPool::ConnectionPool() { |
| | | // å è½½é
ç½®æä»¶ |
| | | if (!parseJsonFile()) { |
| | | std::cout << "parseJsonFile is failed!" << std::endl; |
| | | return; |
| | | for (m_num = 0; m_num < m_minSize;) { |
| | | bool flag = addConnection(); |
| | | if (!flag) { |
| | | return; |
| | | } |
| | | } |
| | | // 妿å线ç¨çä»»å¡å½æ°æ¯ç±»çééæå½æ°ï¼æä»¬éè¦æå®ä»»å¡å½æ°çå°ååä»»å¡å½æ°çææè
|
| | | thread producer(&ConnectionPool::productConnection, this); // åå»ºè¿æ¥ |
| | | thread recycler(&ConnectionPool::recycleConnection, this); // æ£æµå¹¶éæ¯è¿æ¥ |
| | | // 线ç¨å离ï¼é²æ¢é»å¡ä¸»çº¿ç¨ |
| | | for ( int i = 0 ; i < m_min_conn ; i++ ) { |
| | | addConnection( ); |
| | | } |
| | | // å建ä¸ä¸ªçº¿ç¨ï¼å¯¹è¿æ¥æ°è¿è¡çæ§ ï¼è¿æ¥æ°ä¸è¶³å°±åç»§ç»å建 |
| | | std::thread producer(&ConnectionPool::produce, this); |
| | | // å¯¹è¿æ¥æ°è¿è¡çæ§ ï¼å¦ææå¤ªå¤ç©ºé²å¾çº¿ç¨ ï¼é£ä¹å°±å¯¹å
¶è¿è¡éæ¯ |
| | | std::thread recycler( &ConnectionPool::recycle, this); |
| | | |
| | | // 线ç¨å离 |
| | | producer.detach(); |
| | | recycler.detach(); |
| | | } |
| | | ConnectionPool::~ConnectionPool() |
| | | { |
| | | while (!m_connections.empty()) { |
| | | MysqlConn* conn = m_connections.front(); |
| | | m_connections.pop(); |
| | | delete conn; |
| | | } |
| | | } |
| | | bool ConnectionPool::parseXmlFile() |
| | | { |
| | | TiXmlDocument xml("mysql.xml"); |
| | | // å è½½æä»¶ |
| | | bool res = xml.LoadFile(); |
| | | if (!res) { |
| | | return false; // æç¤º |
| | | } |
| | | // æ ¹ |
| | | TiXmlElement* rootElement = xml.RootElement(); |
| | | TiXmlElement* childElement = rootElement->FirstChildElement("mysql"); |
| | | // 读åä¿¡æ¯ |
| | | m_ip = childElement->FirstChildElement("ip")->GetText(); |
| | | m_port = static_cast<unsigned short>(stoi(string(childElement->FirstChildElement("port")->GetText()))); |
| | | m_user = childElement->FirstChildElement("username")->GetText(); |
| | | m_passwd = childElement->FirstChildElement("password")->GetText(); |
| | | m_dbName = childElement->FirstChildElement("dbName")->GetText(); |
| | | m_minSize = static_cast<int>(stoi(string(childElement->FirstChildElement("minSize")->GetText()))); |
| | | m_maxSize = static_cast<int>(stoi(string(childElement->FirstChildElement("maxSize")->GetText()))); |
| | | m_maxIdleTime = static_cast<int>(stoi(string(childElement->FirstChildElement("maxIdleTime")->GetText()))); |
| | | m_timeout = static_cast<int>(stoi(string(childElement->FirstChildElement("timeout")->GetText()))); |
| | | return true; |
| | | } |
| | | bool ConnectionPool::addConnection() |
| | | { |
| | | MysqlConn* conn = new MysqlConn; |
| | | bool res = conn->connect(m_user, m_passwd, m_dbName, m_ip, m_port); |
| | | if (res) { |
| | | // å·æ°ç©ºé²æ¶é´ |
| | | conn->refreashAliveTime(); |
| | | m_connections.push(conn); |
| | | ++m_num; |
| | | |
| | | bool ConnectionPool::parseJsonFile() { |
| | | |
| | | /*std::ifstream ifs("dbconf.json"); |
| | | Reader rd; |
| | | Value root; |
| | | rd.parse(ifs, root); |
| | | if ( root.isObject( ) ) { |
| | | m_ip = root["ip"].asString(); |
| | | m_port = root["port"].asInt(); |
| | | m_userName = root["userName"].asString(); |
| | | m_passwd = root["password"].asString(); |
| | | m_db = root["dbName"].asString(); |
| | | m_min_conn = root["minSize"].asInt(); |
| | | m_max_conn = root["maxSize"].asInt(); |
| | | max_del_time = root["maxDleTime"].asInt(); |
| | | m_timeout = root["timeout"].asInt(); |
| | | return true; |
| | | }*/ |
| | | return false; |
| | | } |
| | | |
| | | void ConnectionPool::description() { |
| | | std::cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". " |
| | | << m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". " |
| | | << max_del_time << std::endl; |
| | | } |
| | | |
| | | ConnectionPool::~ConnectionPool() { |
| | | while (!m_connkQueue.empty()) { |
| | | MysqlConn* conn = m_connkQueue.front(); |
| | | m_connkQueue.pop(); |
| | | delete conn; |
| | | } |
| | | else { |
| | | |
| | | } |
| | | |
| | | void ConnectionPool::addConnection() { |
| | | MysqlConn* conn = new MysqlConn(); |
| | | if ( !conn->connect( m_ip, m_userName, m_passwd, m_db, m_port ) ) { |
| | | std::cout << "ConnectionPool connect to mysql is failed!" << std::endl; |
| | | delete conn; |
| | | return false; // æç¤º |
| | | return; |
| | | } |
| | | conn->refreshActiveTime( ); |
| | | m_connkQueue.push(conn); |
| | | m_cond.notify_one(); // å¤éä¸ä¸ªçº¿ç¨ |
| | | } |
| | | void ConnectionPool::productConnection() |
| | | { |
| | | |
| | | void ConnectionPool::produce(){ |
| | | while (true) { |
| | | unique_lock<mutex> lc(m_mutex); |
| | | m_cond.wait(lc, [this]() {return m_connections.empty(); }); |
| | | if (m_num < m_maxSize) { |
| | | bool flag = addConnection(); |
| | | if (!flag) { |
| | | return; |
| | | } |
| | | std::unique_lock<std::mutex> lock(m_mutex); |
| | | while (m_connkQueue.size() >= m_min_conn) { // è¿æ¥éåçæ°éå¤§äºæå°çè¿æ¥æ° |
| | | m_cond.wait(lock); |
| | | } |
| | | // å¤é |
| | | m_cond1.notify_all(); |
| | | addConnection(); |
| | | } |
| | | } |
| | | void ConnectionPool::recycleConnection() |
| | | { |
| | | while (true) { |
| | | // ä¼ç 䏿®µæ¶é´ 0.5s |
| | | this_thread::sleep_for(milliseconds(500)); |
| | | lock_guard<mutex> lc(m_mutex); |
| | | while (!m_connections.empty() && m_num > m_minSize) { |
| | | MysqlConn* conn = m_connections.front(); |
| | | if (conn->getAliveTime() >= m_maxIdleTime) { |
| | | m_connections.pop(); |
| | | |
| | | // å é¤ç©ºé²è¿æ¥ |
| | | void ConnectionPool::recycle() { |
| | | while ( true ) { |
| | | std::this_thread::sleep_for( std::chrono::milliseconds(500)); // ä¼ç 500 ms |
| | | std::unique_lock<std::mutex>lock(m_mutex); |
| | | while ( m_connkQueue.size() > m_min_conn ) { |
| | | MysqlConn* conn = m_connkQueue.front( ); |
| | | if (conn->getActiveTime() >= max_del_time) { |
| | | m_connkQueue.pop(); |
| | | delete conn; |
| | | --m_num; |
| | | } |
| | | else { |
| | | break; |
| | |
| | | } |
| | | } |
| | | } |
| | | ConnectionPool* ConnectionPool::getConnectPool() |
| | | { |
| | | // ä¸ä½¿ç¨äºæ¥éç线ç¨å®å
¨çææ±æ¨¡å¼ |
| | | static ConnectionPool pool; // åªå¨ç¬¬ä¸æ¬¡è°ç¨å½æ°æ¶åå§å |
| | | return &pool; |
| | | } |
| | | shared_ptr<MysqlConn> ConnectionPool::getConnection() |
| | | { |
| | | unique_lock<mutex> lc(m_mutex); |
| | | while (m_connections.empty()) { |
| | | if (cv_status::timeout == m_cond1.wait_for(lc, chrono::milliseconds(m_timeout))) { |
| | | if (m_connections.empty()) { |
| | | // cout << "out of time" << endl; |
| | | return nullptr; // ç»æ // æç¤º |
| | | // continue; // å©ç¨whileé
åcontinue ç»§ç»é»å¡ |
| | | } |
| | | |
| | | std::shared_ptr<MysqlConn> ConnectionPool::getMysqlConn() { |
| | | |
| | | std::unique_lock<std::mutex>lock(m_mutex); |
| | | while ( m_connkQueue.empty()) { |
| | | // 妿çå¾
䏿®µæ¶é´å,éåè¿æ¯ä¸ºç©º,è¿åä¸ä¸ª null |
| | | if ( std::cv_status::timeout == m_cond.wait_for(lock, std::chrono::milliseconds(m_timeout)) ) { |
| | | if( m_connkQueue.empty( ) ) return nullptr; |
| | | } |
| | | } |
| | | // è¦æå®å é¤å¨destructorï¼æ¥ä¿è¯è¿æ¥çå½è¿ |
| | | shared_ptr<MysqlConn> conn(m_connections.front(), [this](MysqlConn* conn) { |
| | | // å éä¿è¯éå线ç¨å®å
¨ |
| | | // m_mutex.lock(); // 1 |
| | | unique_lock<mutex> lc(m_mutex); // 2 |
| | | // lock_guard<mutex> lc(m_mutex); // 3 |
| | | conn->refreashAliveTime(); |
| | | m_connections.push(conn); |
| | | // m_mutex.unlock(); // 1 |
| | | std::shared_ptr<MysqlConn> connPtr(std::move(m_connkQueue.front()), [this](MysqlConn* conn) { |
| | | std::unique_lock <std::mutex>lock(m_mutex) ; |
| | | conn->refreshActiveTime(); |
| | | m_connkQueue.push(conn); |
| | | }); |
| | | m_connections.pop(); |
| | | m_cond.notify_all(); |
| | | return conn; |
| | | } |
| | | m_connkQueue.pop(); |
| | | m_cond.notify_one(); // å¤éé»å¡çç产è
线ç¨,å¼å§ç产 |
| | | return connPtr; |
| | | } |
| | |
| | | #pragma once |
| | | #include "MysqlConn.h" |
| | | #include "./tinyxml/tinyxml.h" |
| | | |
| | | #include <queue> |
| | | #include <mutex> |
| | | #include <thread> |
| | | #include <atomic> |
| | | #include <condition_variable> |
| | | //#include <json/json.h> |
| | | |
| | | #include "MysqlConn.h" |
| | | |
| | | #pragma comment(lib, "./tinyxml/x64/Debug/tinyxml.lib") |
| | | //using namespace Json; |
| | | |
| | | // åºç¨-å便¨¡å¼ï¼ææ±æ¨¡å¼[éè¦èèå¤çº¿ç¨å®å
¨é®é¢] |
| | | class ConnectionPool |
| | | { |
| | | private: |
| | | ConnectionPool(); |
| | | // ç§»å¨æ·è´æç»è¿æ¯æä¸ä»
æä¸ä¸ªå¯¹è±¡ï¼æä»¥ä¾æ§æ¯å±äºå便¨¡å¼ã |
| | | // delete 黿¢æ·è´æé åæ·è´èµå¼çç±»å¯¹è±¡çæ |
| | | ConnectionPool(ConnectionPool&) = delete; |
| | | ConnectionPool& operator=(ConnectionPool&) = delete; |
| | | ~ConnectionPool(); |
| | | // è§£æxmlé
ç½®æä»¶ è¯»åæ°æ®åºåè¿æ¥æ± çç¸å
³ä¿¡æ¯ |
| | | bool parseXmlFile(); |
| | | // æ·»å è¿æ¥ |
| | | bool addConnection(); |
| | | // 线ç¨å½æ° |
| | | void productConnection(); |
| | | void recycleConnection(); |
| | | |
| | | // åæ¾æ°æ®åºè¿æ¥æ± 建ç«çè¿æ¥ |
| | | queue<MysqlConn*> m_connections; |
| | | // ä¸äºåºæ¬ä¿¡æ¯ |
| | | string m_ip; // IP |
| | | unsigned short m_port; // ç«¯å£ |
| | | string m_user; // ç¨æ·å |
| | | string m_passwd; // å¯ç |
| | | string m_dbName; // æ°æ®åºåç§° |
| | | int m_minSize; // åå§è¿æ¥é(æå°è¿æ¥é) |
| | | int m_maxSize; // æå¤§è¿æ¥é |
| | | int m_timeout; // è¶
æ¶æ¶é¿ |
| | | int m_maxIdleTime; // æå¤§ç©ºé²æ¶é¿ |
| | | // 线ç¨å®å
¨ç¸å
³ |
| | | mutex m_mutex; |
| | | condition_variable m_cond; // ä»
ç¨ä¸ä¸ªæ¡ä»¶å鿥å¤é线ç¨ï¼ä½å¹¶ä¸å½±å线ç¨è¿è¡ |
| | | condition_variable m_cond1; |
| | | // è¿æ¥æ°é |
| | | atomic_int m_num; // è¿æ¥çæ»æ°é |
| | | public: |
| | | // è·ååä¾å¯¹è±¡çæ¥å£ |
| | | static ConnectionPool* getConnectPool(); |
| | | // ç¨æ·è·åè¿æ¥çæ¥å£, 妿è·å失败ï¼ä¼è¿ånullptr |
| | | shared_ptr<MysqlConn> getConnection(); |
| | | static ConnectionPool* getInstance( ); |
| | | |
| | | std::shared_ptr<MysqlConn> getMysqlConn(); // 仿°æ®åºè¿æ¥æ± è·åè¿æ¥ |
| | | |
| | | ConnectionPool(const ConnectionPool& other) = delete; |
| | | ConnectionPool& operator = (const ConnectionPool & other ) = delete; |
| | | |
| | | ~ConnectionPool(); |
| | | |
| | | void description(); |
| | | |
| | | protected: |
| | | ConnectionPool( ); // æé 彿° |
| | | private: |
| | | bool parseJsonFile(); // è§£æé
ç½® |
| | | |
| | | void produce(); |
| | | void recycle(); |
| | | void addConnection(); // å¢å è¿æ¥æ° |
| | | |
| | | std::string m_ip; |
| | | std::string m_userName; |
| | | std::string m_passwd; |
| | | std::string m_db; |
| | | unsigned short m_port; |
| | | |
| | | int m_max_conn; |
| | | int m_min_conn; |
| | | |
| | | int m_timeout; // è¿æ¥è¶
æ¶æ¶é´ |
| | | int max_del_time; // æå¤§å 餿¶é´( è¿æ¥ç©ºé²æ¶é´è¶
è¿è¿ä¸ª,å°±ç»å½åè¿æ¥å
³é ) |
| | | std::queue<MysqlConn*>m_connkQueue ; // è¿æ¥éå |
| | | std::mutex m_mutex; // äºæ¥é |
| | | std::condition_variable m_cond; // æ¡ä»¶åé |
| | | }; |
| | | |
| | |
| | | #include "stdafx.h" |
| | | #include "MysqlConn.h" |
| | | #include <regex> |
| | | |
| | | MysqlConn::MysqlConn()//åå§åæ°æ®åº |
| | | { |
| | | m_result = nullptr; |
| | | m_mysqlRow = nullptr; |
| | | // ä¼ å
¥nullptr空æéæ¶ï¼ä¼èªå¨åé
ä¸ä¸ªMYSQL对象 |
| | | m_conn = mysql_init(nullptr); |
| | | } |
| | | MysqlConn::~MysqlConn()//éæ¾æ°æ®åºè¿æ¥ |
| | | { |
| | | freeRes(); // éæ¾ç»æé |
| | | if (m_conn != nullptr) { |
| | | mysql_close(m_conn); |
| | | m_conn = nullptr; |
| | | } |
| | | } |
| | | void MysqlConn::freeRes()//ç»æééæ¾ |
| | | { |
| | | if (m_result) { |
| | | mysql_free_result(m_result); |
| | | m_result = nullptr; |
| | | } |
| | | } |
| | | bool MysqlConn::connect(const string user, const string passwd, \ |
| | | const string dbName, string ip, \ |
| | | const unsigned short port)//è¿æ¥æ°æ®åº |
| | | { |
| | | MYSQL* res = mysql_real_connect(m_conn, ip.c_str(), user.c_str(), \ |
| | | passwd.c_str(), dbName.c_str(), port, nullptr, 0); |
| | | // ä¿®æ¹ç¼ç |
| | | mysql_set_character_set(m_conn, "gb2312"); |
| | | return res != nullptr; |
| | | } |
| | | bool MysqlConn::update(const string sql) const |
| | | { |
| | | // æ§è¡æåè¿å0ï¼ |
| | | int res = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned int>(sql.size())); |
| | | if (res != 0) { |
| | | return false; // æç¤º |
| | | } |
| | | return true; |
| | | } |
| | | bool MysqlConn::query(const string sql) |
| | | { |
| | | freeRes(); |
| | | int res = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned int>(sql.size())); |
| | | if (res != 0) { |
| | | return false; // æç¤º |
| | | } |
| | | m_result = mysql_store_result(m_conn); |
| | | return true; |
| | | } |
| | | bool MysqlConn::getRes() |
| | | { |
| | | if (m_result != nullptr) { |
| | | // char** è·ååè¡è®°å½ |
| | | m_mysqlRow = mysql_fetch_row(m_result); |
| | | if (m_mysqlRow != nullptr) { |
| | | return true; |
| | | } |
| | | freeRes(); |
| | | } |
| | | return false; |
| | | } |
| | | string MysqlConn::getValue(const int fieldIndex) const |
| | | { |
| | | int fieldCount = mysql_num_fields(m_result); |
| | | if (fieldIndex >= fieldCount || fieldIndex < 0) { |
| | | return string(); // æç¤º |
| | | } |
| | | char* value = m_mysqlRow[fieldIndex]; |
| | | // å¾å°ä¸ä¸ªä¿åååæ®µå¼é¿åº¦çæ°ç» |
| | | unsigned long* len = mysql_fetch_lengths(m_result); |
| | | unsigned long length = len[fieldIndex]; |
| | | // 鲿¢ç»æä¸åå¨\0å¯¼è´æ°æ®ä¸¢å¤± |
| | | return string(value, length); |
| | | } |
| | | bool MysqlConn::selectDB(const string dbName) const |
| | | { |
| | | int res = mysql_select_db(m_conn, dbName.c_str()); |
| | | if (res != 0) { |
| | | return false; // æç¤º |
| | | } |
| | | return true; |
| | | } |
| | | void MysqlConn::backupCurrentDB(const string path) |
| | | { |
| | | string sql = "show tables"; |
| | | int r = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned long>(sql.size())); |
| | | if (r != 0) { |
| | | return; // æç¤º |
| | | } |
| | | MYSQL_RES* tableRes = mysql_store_result(m_conn); |
| | | for (int i = 0; i < mysql_num_rows(tableRes); ++i) { |
| | | MYSQL_ROW tableName = mysql_fetch_row(tableRes); |
| | | backupCurrentTable(path, tableName[0]); |
| | | } |
| | | } |
| | | void MysqlConn::backupCurrentTable(const string path, const string tableName) |
| | | { |
| | | string file = path + tableName + ".sql"; |
| | | ofstream ofs(file); |
| | | if (!ofs.is_open()) { |
| | | return; // æç¤º |
| | | } |
| | | // è¡¨ç»æåå
¥ |
| | | string showCreate = "show create table " + tableName + ";"; |
| | | bool res = query(showCreate); |
| | | if (!res) { |
| | | return; // æç¤º |
| | | } |
| | | if (getRes()) { |
| | | string writeSQL = getValue(1) + ";\n"; |
| | | ofs.write(writeSQL.c_str(), writeSQL.size()); |
| | | // cout << writeSQL << endl; |
| | | } |
| | | // è¡¨æ°æ®åå
¥ |
| | | string sql = "select * from " + tableName + ";"; |
| | | res = query(sql); |
| | | if (!res) { |
| | | return; // æç¤º |
| | | } |
| | | while (getRes()) { |
| | | string writeSQL = "insert into `" + tableName + "` values("; |
| | | for (int i = 0; !getValue(i).empty(); ++i) { |
| | | if (i != 0) { |
| | | writeSQL += ","; |
| | | } |
| | | MYSQL_FIELD* valueType = mysql_fetch_field_direct(m_result, i); |
| | | if (valueType->type == MYSQL_TYPE_DECIMAL |
| | | || valueType->type == MYSQL_TYPE_TINY |
| | | || valueType->type == MYSQL_TYPE_SHORT |
| | | || valueType->type == MYSQL_TYPE_LONG |
| | | || valueType->type == MYSQL_TYPE_FLOAT |
| | | || valueType->type == MYSQL_TYPE_DOUBLE |
| | | || valueType->type == MYSQL_TYPE_TIMESTAMP |
| | | || valueType->type == MYSQL_TYPE_LONGLONG |
| | | || valueType->type == MYSQL_TYPE_INT24) { |
| | | writeSQL += getValue(i); |
| | | } |
| | | else { |
| | | writeSQL += "'" + getValue(i) + "'"; |
| | | } |
| | | } |
| | | writeSQL += ");\n"; |
| | | ofs.write(writeSQL.c_str(), writeSQL.size()); |
| | | } |
| | | ofs.close(); |
| | | } |
| | | bool MysqlConn::transaction() const |
| | | { |
| | | // å°äºå¡æäº¤è®¾ç½®ä¸ºæå¨æäº¤ |
| | | return mysql_autocommit(m_conn, false); |
| | | } |
| | | bool MysqlConn::commit() const |
| | | { |
| | | return mysql_commit(m_conn); |
| | | } |
| | | bool MysqlConn::rollback() const |
| | | { |
| | | return mysql_rollback(m_conn); |
| | | } |
| | | void MysqlConn::refreashAliveTime() |
| | | { |
| | | m_alivetime = steady_clock::now(); |
| | | } |
| | | ll MysqlConn::getAliveTime() |
| | | { |
| | | // æ¯«ç§ <<= 纳ç§:精度éä½ |
| | | milliseconds res = duration_cast<milliseconds>(steady_clock::now() - m_alivetime); |
| | | return res.count(); |
| | | |
| | | // åå§åè¿æ¥ |
| | | MysqlConn::MysqlConn() { |
| | | mysql_ = mysql_init(mysql_); |
| | | // 设置å符é |
| | | if (mysql_) mysql_set_character_set(mysql_, "gbk"); |
| | | } |
| | | |
| | | // è¿æ¥æ°æ®åº |
| | | bool MysqlConn::connect(std::string ip, std::string userName, std::string passwd, std::string db, int port) { |
| | | mysql_ = mysql_real_connect(mysql_, ip.c_str(), userName.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0); |
| | | if (!mysql_) { |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | // éæ¾èµæº |
| | | MysqlConn::~MysqlConn() { |
| | | if (mysql_) { |
| | | mysql_close(mysql_); |
| | | mysql_ = nullptr; |
| | | } |
| | | freeRes(); |
| | | } |
| | | |
| | | // æ´æ°æ°æ® |
| | | bool MysqlConn::update(std::string sql) { |
| | | // åæ°åæ¥è¯¢ä¼ååçå®å
¨æ£æ¥ |
| | | MYSQL_STMT* stmt = mysql_stmt_init(mysql_); |
| | | if (!stmt) { |
| | | return false; |
| | | } |
| | | if (mysql_stmt_prepare(stmt, sql.c_str(), sql.length())) { |
| | | mysql_stmt_close(stmt); |
| | | return false; |
| | | } |
| | | int paramCount = mysql_stmt_param_count(stmt); |
| | | if (paramCount > 0) { |
| | | // 妿æåæ°ï¼éè¦è¿è¡åæ°ç»å®çæä½ï¼è¿éæä¸å®ç° |
| | | mysql_stmt_close(stmt); |
| | | return false; |
| | | } |
| | | if (mysql_stmt_execute(stmt)) { |
| | | mysql_stmt_close(stmt); |
| | | return false; |
| | | } |
| | | mysql_stmt_close(stmt); |
| | | return true; |
| | | } |
| | | |
| | | // æ¥è¯¢æ°æ®åº |
| | | bool MysqlConn::query(std::string sql) { |
| | | freeRes(); |
| | | // åæ°åæ¥è¯¢ä¼ååçå®å
¨æ£æ¥ |
| | | MYSQL_STMT* stmt = mysql_stmt_init(mysql_); |
| | | if (!stmt) { |
| | | return false; |
| | | } |
| | | if (mysql_stmt_prepare(stmt, sql.c_str(), sql.length())) { |
| | | mysql_stmt_close(stmt); |
| | | return false; |
| | | } |
| | | int paramCount = mysql_stmt_param_count(stmt); |
| | | if (paramCount > 0) { |
| | | // 妿æåæ°ï¼éè¦è¿è¡åæ°ç»å®çæä½ï¼è¿éæä¸å®ç° |
| | | mysql_stmt_close(stmt); |
| | | return false; |
| | | } |
| | | if (mysql_stmt_execute(stmt)) { |
| | | mysql_stmt_close(stmt); |
| | | return false; |
| | | } |
| | | res_ = mysql_stmt_result_metadata(stmt); |
| | | if (!res_) { |
| | | mysql_stmt_close(stmt); |
| | | return false; |
| | | } |
| | | mysql_stmt_close(stmt); |
| | | return true; |
| | | } |
| | | |
| | | // å¾å°ç»æé |
| | | bool MysqlConn::getResult() { |
| | | if (res_) { |
| | | row_ = mysql_fetch_row(res_); |
| | | if (row_) return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | // è·åç»æéçåæ®µ |
| | | std::string MysqlConn::getField(int index) { |
| | | int cols = mysql_num_fields(res_); |
| | | if (index >= cols || index < 0) return std::string(""); |
| | | |
| | | char* value = row_[index]; |
| | | unsigned long len = mysql_fetch_lengths(res_)[index]; |
| | | return std::string(value, len); |
| | | } |
| | | |
| | | // äºå¡æä½ |
| | | bool MysqlConn::transaction() { |
| | | return mysql_autocommit(mysql_, false); |
| | | } |
| | | |
| | | // æäº¤äºå¡ |
| | | bool MysqlConn::commit() { |
| | | return mysql_commit(mysql_); |
| | | } |
| | | |
| | | // äºå¡åæ» |
| | | bool MysqlConn::rollback() { |
| | | return mysql_rollback(mysql_); |
| | | } |
| | | |
| | | void MysqlConn::refreshActiveTime() { |
| | | activeTime_ = std::chrono::steady_clock::now(); |
| | | } |
| | | |
| | | long long MysqlConn::getActiveTime() { |
| | | // 纳米 |
| | | std::chrono::nanoseconds nased = std::chrono::steady_clock::now() - activeTime_; |
| | | // è½¬æ¢ææ¯«ç±³ |
| | | std::chrono::microseconds millsed = std::chrono::duration_cast<std::chrono::microseconds>(nased); |
| | | return millsed.count(); // å¤å°æ¯«ç§ |
| | | } |
| | | |
| | | // å®å
¨æ ¡éªå®ç°ï¼è¿éç®åä½¿ç¨æ£å表达å¼å¤ææ¯å¦å
å«å±é©å符 |
| | | bool MysqlConn::isSqlSafe(const std::string& sql) { |
| | | std::regex dangerousPattern(".*(['\";\\-+=]).*"); |
| | | return!std::regex_search(sql, dangerousPattern); |
| | | } |
| | | |
| | | void MysqlConn::freeRes() { |
| | | if (res_) { |
| | | mysql_free_result(res_); |
| | | res_ = nullptr; |
| | | } |
| | | } |
| | |
| | | #pragma once |
| | | #include<iostream> |
| | | #include <memory> |
| | | #include <string> |
| | | #include <mysql.h> |
| | | #include <chrono> // æ¶é |
| | | #include <fstream> |
| | | |
| | | #pragma comment(lib, "./lib/libmysql.lib") // å è½½æ°æ®åºåºæä»¶ |
| | | using namespace std; |
| | | using namespace chrono; |
| | | typedef long long ll; |
| | | #include <string> |
| | | #include <WinSock2.h> |
| | | //#include <mysql.h> |
| | | #include "MySQL/include/mysql.h" |
| | | #include <string.h> |
| | | #include <chrono> |
| | | |
| | | #pragma comment(lib,"./MySQL/lib/libmysql.lib") |
| | | |
| | | class MysqlConn |
| | | { |
| | | private: |
| | | // ç»å¯¹æ¶é |
| | | steady_clock::time_point m_alivetime; |
| | | // è¿æ¥ |
| | | MYSQL* m_conn; |
| | | // æ¥è¯¢çç»æé |
| | | MYSQL_RES* m_result; |
| | | // åè®°å½ç»æé |
| | | MYSQL_ROW m_mysqlRow; |
| | | |
| | | // ç»æééæ¾ |
| | | void freeRes(); |
| | | // å¯¼åºæä¸å¼ 表ä¸çæ°æ® |
| | | void backupCurrentTable(const string path, const string tableName); |
| | | public: |
| | | // åå§åæ°æ®åº |
| | | // åå§åè¿æ¥ |
| | | MysqlConn(); |
| | | // æ°æ®åºè¿æ¥éæ¾ |
| | | ~MysqlConn(); |
| | | // è¿æ¥æ°æ®åº, éæä¾ç¨æ· å¯ç æ°æ®åºåç§° ip ç«¯å£ |
| | | bool connect(const string user, const string passwd, \ |
| | | const string dbName, string ip, \ |
| | | const unsigned short port = 3306U); |
| | | // æ´æ°æ°æ®åº:å¢å æ¹æä½ |
| | | bool update(const string sql) const; |
| | | // è¿æ¥æ°æ®åº |
| | | bool connect(std::string ip, std::string userName, std::string passwd, std::string db , int port = 3306); |
| | | // éæ¾èµæº |
| | | ~MysqlConn( ); |
| | | // æ´æ°æ°æ®åº ( insert update delete ) |
| | | bool update(std::string sql); |
| | | // æ¥è¯¢æ°æ®åº |
| | | bool query(const string sql); |
| | | // éåæ¥è¯¢ç»æé |
| | | bool getRes(); |
| | | // è·åç»æéä¸çåæ®µå¼ |
| | | string getValue(const int fieldIndex) const; |
| | | // åæ¢æ°æ®åº |
| | | bool selectDB(const string dbName) const; |
| | | // å»ºåº |
| | | //bool createDB(const string dbName) const; |
| | | // å¤ä»½æä¸ªåº |
| | | void backupCurrentDB(const string path); |
| | | bool query(std::string sql); |
| | | // å¾å°ç»æé |
| | | bool getResult(); |
| | | // è·åç»æéçåæ®µ |
| | | std::string getField(int index); |
| | | // äºå¡æä½ |
| | | bool transaction() const; |
| | | bool transaction(); |
| | | // æäº¤äºå¡ |
| | | bool commit() const; |
| | | bool commit( ); |
| | | // äºå¡åæ» |
| | | bool rollback() const; |
| | | // å·æ°èµ·å§çç©ºé²æ¶é´ç¹ |
| | | void refreashAliveTime(); |
| | | // 计ç®åæ´»æ»æ¶é¿ |
| | | ll getAliveTime(); |
| | | bool rollback(); |
| | | |
| | | void refreshActiveTime( ); // å·æ°æ´»è·æ¶é´ |
| | | long long getActiveTime(); // è·åå½åæ´»è·çæ¶é´é´é |
| | | // å®å
¨æ ¡éªæ¥å£ |
| | | bool isSqlSafe(const std::string& sql); |
| | | |
| | | private: |
| | | |
| | | void freeRes(); |
| | | MYSQL* mysql_ = NULL ; |
| | | MYSQL_RES* res_ = NULL; |
| | | MYSQL_ROW row_ = nullptr; |
| | | std::chrono::steady_clock::time_point activeTime_; |
| | | }; |
| | | |
File was renamed from kunlun110401.sql |
| | |
| | | |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.data_info çæ°æ®ï¼~0 rows (大约) |
| | | |
| | | -- å¯¼åº è¡¨ mayi_kunlun.devices_management ç»æ |
| | | CREATE TABLE IF NOT EXISTS `devices_management` ( |
| | | `id` int NOT NULL, |
| | | -- å¯¼åº è¡¨ mayi_kunlun.devices_management_info ç»æ |
| | | CREATE TABLE IF NOT EXISTS `devices_management_info` ( |
| | | `id` int NOT NULL AUTO_INCREMENT, |
| | | `devices_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `devices_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `devices_serial_number` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `devices_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `area` varchar(50) DEFAULT NULL, |
| | | `longitude` double DEFAULT NULL, |
| | | `latitude` double DEFAULT NULL, |
| | | `purchasing_time` datetime DEFAULT NULL, |
| | | `install_time` datetime DEFAULT NULL, |
| | | `purchasing_time` varchar(50) DEFAULT NULL, |
| | | `install_time` varchar(50) DEFAULT NULL, |
| | | `manufacturer` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `mark_name` varchar(50) DEFAULT NULL, |
| | | `mark_time` datetime DEFAULT NULL, |
| | | `mark_time` varchar(50) DEFAULT NULL, |
| | | PRIMARY KEY (`id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.devices_management çæ°æ®ï¼~0 rows (大约) |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.devices_management_info çæ°æ®ï¼~3 rows (大约) |
| | | INSERT INTO `devices_management_info` (`id`, `devices_name`, `devices_type`, `devices_serial_number`, `devices_status`, `area`, `longitude`, `latitude`, `purchasing_time`, `install_time`, `manufacturer`, `mark_name`, `mark_time`) VALUES |
| | | (2, '12', '3', '2', '2', '3', 4, 6, '6', '3', '3', NULL, NULL), |
| | | (3, '3', '1', '3', '3', '1', 2, 5, '6', '3', '6', NULL, NULL), |
| | | (4, '10', '1', '3', '3', '1', 2, 5, '9', '3', '6', NULL, NULL); |
| | | |
| | | -- å¯¼åº è¡¨ mayi_kunlun.month_info ç»æ |
| | | CREATE TABLE IF NOT EXISTS `month_info` ( |
| | |
| | | |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.role_info çæ°æ®ï¼~0 rows (大约) |
| | | |
| | | -- å¯¼åº è¡¨ mayi_kunlun.student ç»æ |
| | | CREATE TABLE IF NOT EXISTS `student` ( |
| | | `id` int NOT NULL AUTO_INCREMENT, |
| | | `name` varchar(50) DEFAULT NULL, |
| | | `age` int DEFAULT NULL, |
| | | PRIMARY KEY (`id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.student çæ°æ®ï¼~0 rows (大约) |
| | | |
| | | -- å¯¼åº è¡¨ mayi_kunlun.threshold_info ç»æ |
| | | CREATE TABLE IF NOT EXISTS `threshold_info` ( |
| | | `id` int NOT NULL AUTO_INCREMENT, |
| | |
| | | -- å¯¼åº è¡¨ mayi_kunlun.user_info ç»æ |
| | | CREATE TABLE IF NOT EXISTS `user_info` ( |
| | | `id` int NOT NULL AUTO_INCREMENT, |
| | | `department` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `user_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `department` varchar(50) DEFAULT NULL, |
| | | `user_name` varchar(32) DEFAULT NULL, |
| | | `password` varchar(32) DEFAULT NULL, |
| | | `user_no` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, |
| | | `user_no` varchar(10) DEFAULT NULL, |
| | | `age` int DEFAULT NULL, |
| | | `sex` varchar(10) DEFAULT NULL, |
| | | `role_id` int DEFAULT NULL, |
| | | `email` varchar(32) DEFAULT NULL, |
| | | `telephone` varchar(32) DEFAULT NULL, |
| | | `status` int DEFAULT NULL, |
| | | `role_id` int DEFAULT NULL, |
| | | `login_time` datetime DEFAULT NULL, |
| | | `register_time` datetime DEFAULT NULL, |
| | | PRIMARY KEY (`id`) |
| | | PRIMARY KEY (`id`), |
| | | KEY `role_id` (`role_id`), |
| | | CONSTRAINT `user_info_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `role_info` (`id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.user_info çæ°æ®ï¼~0 rows (大约) |
| | |
| | | `c_filepath` varchar(256) NOT NULL, |
| | | `uploader` char(64) NOT NULL DEFAULT '', |
| | | PRIMARY KEY (`id`) |
| | | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.version_file çæ°æ®ï¼~3 rows (大约) |
| | | INSERT INTO `version_file` (`id`, `version_id`, `filename`, `fliesize`, `s_filepath`, `c_filepath`, `uploader`) VALUES |
| | | (1, '1.3', '1.jpd', 12555, './versoin', './2', ''), |
| | | (2, '1.4', '2.jpd', 1255, './', './2', ''), |
| | | (3, '1.5', '3.jpd', 122, './', './2', ''); |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.version_file çæ°æ®ï¼~0 rows (大约) |
| | | |
| | | -- å¯¼åº è¡¨ mayi_kunlun.version_info ç»æ |
| | | CREATE TABLE IF NOT EXISTS `version_info` ( |
| | |
| | | `version_description` char(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '', |
| | | `version_creatime` datetime NOT NULL, |
| | | PRIMARY KEY (`id`) |
| | | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; |
| | | |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.version_info çæ°æ®ï¼~3 rows (大约) |
| | | -- æ£å¨å¯¼åºè¡¨ mayi_kunlun.version_info çæ°æ®ï¼~2 rows (大约) |
| | | INSERT INTO `version_info` (`id`, `version_id`, `version_id_old`, `version_description`, `version_creatime`) VALUES |
| | | (1, '1.3', '1.3', '225', '2024-10-29 15:47:00'), |
| | | (2, '1.4', '1.4', '226', '2024-10-30 02:47:30'), |