#include "opmysql.h" #include #include #include #include #include #include #include #include #include #include #include "openjson.h" OpDatabase OpDatabase::m_instance; OpDatabase::OpDatabase() :m_pDbConnection(nullptr) { } OpDatabase::~OpDatabase() { //CloseDatabase(); } std::string OpDatabase::CalculateMD5(const std::string& data) { char md5_str[33] = { 0 }; hv_md5_hex((unsigned char*)data.c_str(), data.size(), md5_str, 33); std::string smd5(md5_str); std::transform(smd5.begin(), smd5.end(), smd5.begin(), [](unsigned char c) { return std::toupper(c); }); return smd5; } OpDatabase* OpDatabase::getInstance() { return &m_instance; } bool OpDatabase::OpenDatabase(const std::string& server, const std::string& dbuser, const std::string& database) { // 打开数据库 try { // 数据库连接配置 //std::string server = "tcp://127.0.0.1:3306"; //std::string dbuser = "root"; std::string password = "Hj57471000"; //std::string database = "hjems"; // 创建连接 sql::mysql::MySQL_Driver* driver; driver = sql::mysql::get_mysql_driver_instance(); //m_pDbConnection.reset(driver->connect(server, dbuser, password)); m_pDbConnection = driver->connect(server, dbuser, password); if (!m_pDbConnection) { hloge("Failed to connect to database."); return false; } // 设置为使用指定数据库 m_pDbConnection->setSchema(database); return true; } catch (sql::SQLException& e) { std::ostringstream ss; ss << "SQLException: " << e.what(); ss<< " (MySQL error code: " << e.getErrorCode(); ss << ", SQLState: " << e.getSQLState() << " )"; hloge("Failed to connect to database: %s",ss.str().c_str()); return false; } } // 关闭数据库连接 void OpDatabase::CloseDatabase() { m_pDbConnection->close(); //delete m_pDbConnection; } void OpDatabase::InsertMessage(const std::string& ts, const std::string& msg_type, const std::string& fsu, const std::string& content, int topic, int dev_id) { const char* insertSql = "INSERT INTO tbl_data (data_timestamp, data_type, FsuCode, data_content, topic, device_id) VALUES (?,?,?,?,?,?);"; // 创建预编译的prepared statement std::unique_ptr insertStmt(m_pDbConnection->prepareStatement(insertSql)); // 绑定插入数据的参数 insertStmt->setString(1, ts); insertStmt->setString(2, msg_type); insertStmt->setString(3, fsu); insertStmt->setString(4, content); insertStmt->setInt(5, topic); insertStmt->setInt(6, dev_id); // 执行插入操作 int rowsAffected = insertStmt->executeUpdate(); // 检查插入操作是否成功 if (rowsAffected > 0) { hlogi( "New message inserted successfully." ); } else { hloge( "No rows affected during insert operation." ); } } bool OpDatabase::queryUser(const std::string& user_id, const std::string& passwd_md5, std::string& jsonResult) { try { #if 0 // 数据库连接配置 std::string server = "tcp://127.0.0.1:3306"; std::string dbuser = "root"; std::string password = "Hj57471000"; std::string database = "hjems"; // 创建连接 sql::mysql::MySQL_Driver* driver; driver = sql::mysql::get_mysql_driver_instance(); //m_pDbConnection.reset(driver->connect(server, dbuser, password)); sql::Connection* pDbConnection = driver->connect(server, dbuser, password); if (!pDbConnection) { hloge("Failed to connect to database."); return false; } // 设置为使用指定数据库 pDbConnection->setSchema(database); hloge("%s : %s", user_id.c_str(), passwd_md5.c_str()); #endif // 准备SQL查询语句 std::string sql = "SELECT uid,uname, upasswd,usalt,email,mobile1,mobile2,memo FROM tbl_user WHERE uid = ?"; // 创建预编译的prepared statement std::unique_ptr pstmt(m_pDbConnection->prepareStatement(sql)); // 绑定参数 pstmt->setString(1, user_id); // 替换为你要查询的用户名 // 执行查询 std::unique_ptr res(pstmt->executeQuery()); bool ret = false; OpenJson json; auto& nodeRoot = json["user"]; int i = 0; // 处理结果集 while (res->next()) { auto& node = nodeRoot[i++]; node["valid"] = 0; node["uid"] = res->getString("uid"); // 假设username和password都是字符串类型 std::string pass = res->getString("upasswd"); std::string salt = res->getString("usalt"); //计算passwd和salt之间的关系 //!passwd=md5(passwd_md5+salt+salt) // passwd_md5 是大写的,需要确保一下 std::string tmp2(passwd_md5); std::transform(tmp2.begin(), tmp2.end(), tmp2.begin(), [](unsigned char c) { return std::toupper(c); }); std::string tmp = tmp2 + salt + salt; std::string smd5 = CalculateMD5(tmp); if (pass == smd5) { node["valid"] = 1; node["uname"] = res->getString("uname"); node["email"] = res->getString("email"); node["mobile1"] = res->getString("mobile1"); node["mobile2"] = res->getString("mobile2"); node["memo"] = res->getString("memo"); ret = true; break; } else { hloge("upass=[%s],calc=[%s],src=[%s]", pass.c_str(), smd5.c_str(), tmp.c_str()); } } jsonResult = json.encode(); //pDbConnection->close(); //delete pDbConnection; return ret; } catch (sql::SQLException& e) { std::ostringstream ss; ss << "SQLException: " << e.what(); ss << " (MySQL error code: " << e.getErrorCode(); ss << ", SQLState: " << e.getSQLState() << " )"; hloge("Failed to connect to database: %s", ss.str().c_str()); return false; } } bool OpDatabase::queryInnerDevice(int dev_id, std::string& jsonResult) { try { #if 0 // 数据库连接配置 std::string server = "tcp://127.0.0.1:3306"; std::string dbuser = "root"; std::string password = "Hj57471000"; std::string database = "hjems"; // 创建连接 sql::mysql::MySQL_Driver* driver; driver = sql::mysql::get_mysql_driver_instance(); //m_pDbConnection.reset(driver->connect(server, dbuser, password)); sql::Connection* pDbConnection = driver->connect(server, dbuser, password); if( !pDbConnection ) { hloge("Failed to connect to database."); return false; } // 设置为使用指定数据库 pDbConnection->setSchema(database); hloge("%s : %s", user_id.c_str(), passwd_md5.c_str()); #endif // 准备SQL查询语句 std::string sql = "SELECT uid,uname, upasswd,usalt,email,mobile1,mobile2,memo FROM tbl_user WHERE uid = ?"; // 创建预编译的prepared statement std::unique_ptr pstmt(m_pDbConnection->prepareStatement(sql)); // 绑定参数 pstmt->setString(1, user_id); // 替换为你要查询的用户名 // 执行查询 std::unique_ptr res(pstmt->executeQuery()); bool ret = false; OpenJson json; auto& nodeRoot = json["user"]; int i = 0; // 处理结果集 while( res->next() ) { auto& node = nodeRoot[i++]; node["valid"] = 0; node["uid"] = res->getString("uid"); // 假设username和password都是字符串类型 std::string pass = res->getString("upasswd"); std::string salt = res->getString("usalt"); //计算passwd和salt之间的关系 //!passwd=md5(passwd_md5+salt+salt) // passwd_md5 是大写的,需要确保一下 std::string tmp2(passwd_md5); std::transform(tmp2.begin(), tmp2.end(), tmp2.begin(), [](unsigned char c) { return std::toupper(c); }); std::string tmp = tmp2 + salt + salt; std::string smd5 = CalculateMD5(tmp); if( pass == smd5 ) { node["valid"] = 1; node["uname"] = res->getString("uname"); node["email"] = res->getString("email"); node["mobile1"] = res->getString("mobile1"); node["mobile2"] = res->getString("mobile2"); node["memo"] = res->getString("memo"); ret = true; break; } else { hloge("upass=[%s],calc=[%s],src=[%s]", pass.c_str(), smd5.c_str(), tmp.c_str()); } } jsonResult = json.encode(); //pDbConnection->close(); //delete pDbConnection; return ret; } catch( sql::SQLException& e ) { std::ostringstream ss; ss << "SQLException: " << e.what(); ss << " (MySQL error code: " << e.getErrorCode(); ss << ", SQLState: " << e.getSQLState() << " )"; hloge("Failed to connect to database: %s", ss.str().c_str()); return false; } }