240717班级,工业化控制系统,煤矿相关行业,昆仑系统
jhc
2024-11-05 e654f4b7e6b45b20f0ee969161d461704cc41894
上传日志
6个文件已修改
14个文件已添加
1 文件已重命名
739 ■■■■ 已修改文件
Client/刘子航/log/日志_刘子航_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/宋昊昳/log/日志_宋昊昳_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/朱航/log/朱航1104.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/李宵增/log/历史查询_李宵增_1102.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/王鑫鑫/log/日志_王鑫鑫_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/申烜/log/日志_申烜_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/郑凯文/log/郑凯文1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Client/龚启祥/log/日志模板_龚启祥_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/李转转/log/配置管理_李转转_1105.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/ConnectionPool.cpp 204 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/ConnectionPool.h 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/MysqlConn.cpp 310 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/code/MysqlConn.h 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Server/王琨元/log/日志模板_王琨元_1104.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/胡家明/log/日志_胡家明_1103.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/陈楚丹/log/日志_陈楚丹_1104.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/马渝杭/log/20241105昆仑日报.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/马渝杭/log/日志_马渝杭_20241104.doc 补丁 | 查看 | 原始文档 | blame | 历史
Server/马渝杭/log/日志_马渝杭_20241105.doc 补丁 | 查看 | 原始文档 | blame | 历史
kunlun.sql 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
~$表.docx 补丁 | 查看 | 原始文档 | blame | 历史
Client/Áõ×Óº½/log/ÈÕÖ¾_Áõ×Óº½_1105.doc
Binary files differ
Client/ËÎ껕i/log/ÈÕÖ¾_ËÎ껕i_1105.doc
Binary files differ
Client/Ö캽/log/Ö캽1104.doc
Binary files differ
Client/ÀîÏüÔö/log/ÀúÊ·²éѯ_ÀîÏüÔö_1102.doc
Binary files differ
Client/ÍõöÎöÎ/log/ÈÕÖ¾_ÍõöÎöÎ_1105.doc
Binary files differ
Client/ÉêŸ@/log/ÈÕÖ¾_ÉêŸ@_1105.doc
Binary files differ
Client/Ö£¿­ÎÄ/log/Ö£¿­ÎÄ1105.doc
Binary files differ
Client/¹¨ÆôÏé/log/ÈÕ־ģ°å_¹¨ÆôÏé_1105.doc
Binary files differ
Server/Àîתת/log/ÅäÖùÜÀí_Àîתת_1105.doc
Binary files differ
Server/ÍõçûÔª/code/ConnectionPool.cpp
@@ -1,95 +1,102 @@
#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;
@@ -97,35 +104,22 @@
        }
    }
}
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;
}
Server/ÍõçûÔª/code/ConnectionPool.h
@@ -1,54 +1,50 @@
#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;   // æ¡ä»¶å˜é‡
};
Server/ÍõçûÔª/code/MysqlConn.cpp
@@ -1,174 +1,144 @@
#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;
    }
}
Server/ÍõçûÔª/code/MysqlConn.h
@@ -1,63 +1,49 @@
#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_;
};
Server/ÍõçûÔª/log/ÈÕ־ģ°å_ÍõçûÔª_1104.doc
Binary files differ
Server/ºú¼ÒÃ÷/log/ÈÕÖ¾_ºú¼ÒÃ÷_1103.doc
Binary files differ
Server/³Â³þµ¤/log/ÈÕÖ¾_³Â³þµ¤_1104.doc
Binary files differ
Server/ÂíÓ庼/log/20241105À¥ÂØÈÕ±¨.doc
Binary files differ
Server/ÂíÓ庼/log/ÈÕÖ¾_ÂíÓ庼_20241104.doc
Binary files differ
Server/ÂíÓ庼/log/ÈÕÖ¾_ÂíÓ庼_20241105.doc
Binary files differ
kunlun.sql
File was renamed from kunlun110401.sql
@@ -31,24 +31,29 @@
-- æ­£åœ¨å¯¼å‡ºè¡¨  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` (
@@ -112,6 +117,16 @@
-- æ­£åœ¨å¯¼å‡ºè¡¨  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,
@@ -128,19 +143,21 @@
-- å¯¼å‡º  è¡¨ 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 (大约)
@@ -155,13 +172,9 @@
  `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` (
@@ -171,9 +184,9 @@
  `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'),
~$±í.docx
Binary files differ