194 lines
5.8 KiB
C++
194 lines
5.8 KiB
C++
/*
|
|
* @Description: file content
|
|
* @Author: why
|
|
* @version:
|
|
* @Date: 2025-02-25 11:02:37
|
|
* @LastEditors: why
|
|
* @LastEditTime: 2025-02-25 16:33:06
|
|
*/
|
|
#include <iostream>
|
|
#include <chrono>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <nlohmann/json.hpp>
|
|
#include "F_UpdateRecord.h"
|
|
using namespace std;
|
|
using json = nlohmann::json // for convenience
|
|
|
|
typedef struct topic{
|
|
|
|
std::string src;
|
|
std::string des;
|
|
std::string sid;
|
|
std::string fid;
|
|
} topic_type;
|
|
UpdateRecord::UpdateRecord(void){
|
|
handpara = nullptr;
|
|
initpara = nullptr;
|
|
}
|
|
|
|
UpdateRecord::~UpdateRecord(void){
|
|
}
|
|
std::string search_table_db(int afn,usignend init dataid){
|
|
std::string table;
|
|
return table;
|
|
}
|
|
void UpdateRecord::Init(initparam_t *param){
|
|
initpara = param;
|
|
}
|
|
std::string UpdateRecord::now_to_string() {
|
|
// 获取系统时钟时间点
|
|
auto time_now = std::chrono::system_clock::now();
|
|
|
|
// 将时间点转成time_t类型的值 (秒)
|
|
std::time_t tt = std::chrono::system_clock::to_time_t(time_now);
|
|
|
|
// 转换成tm结构体形式
|
|
struct tm* ptm = gmtime(&tt); // 或者 localtime(&tt) 如果想要本地时间
|
|
|
|
// 计算出毫秒部分
|
|
long milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
time_now.time_since_epoch()
|
|
).count() % 1000;
|
|
|
|
char buffer[40];
|
|
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", ptm);
|
|
|
|
// 添加上毫秒和时区信息
|
|
sprintf(buffer + strlen(buffer), ".%03ld+0000", milliseconds);
|
|
|
|
return std::string(buffer);
|
|
}
|
|
time_t UpdateRecord::string_to_now(std::string stamp) {
|
|
struct tm t;
|
|
std::istringstream ss(stamp);
|
|
ss >> std::get_time(&t,"%Y-%m-%dT%H:%M:%S");
|
|
if(ss.fail())return -1;
|
|
return mktime(&t);
|
|
}
|
|
|
|
int UpdateRecord::SQLBatch_exc(std::vector<std::string> &sql_list,std::vector<std::string> &result){
|
|
sqlite3 *db = handpara;
|
|
char *errMsg = nullptr;
|
|
const char *sql;
|
|
int rc;
|
|
int resp = 0;
|
|
// 开启事务
|
|
if (sqlite3_exec(db, "BEGIN TRANSACTION;", nullptr, nullptr, &errMsg) != SQLITE_OK) {
|
|
std::cerr << "事务开启失败: " << errMsg << std::endl;
|
|
sqlite3_free(errMsg);
|
|
return -1;
|
|
}
|
|
// 执行批量插入操作
|
|
sqlite3_stmt *stmt;
|
|
int idx = 0;
|
|
for(const auto &k:sql_list){
|
|
std::cout << "cmd:"<<k.c_str()<<std::endl;
|
|
if (sqlite3_prepare_v2(db, k.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
|
|
std::cerr << "准备语句失败: " << sqlite3_errmsg(db) << std::endl;
|
|
continue;
|
|
}
|
|
rc = sqlite3_step(stmt);
|
|
if (rc != SQLITE_DONE) {
|
|
std::cerr << "插入失败: " << sqlite3_errmsg(db) << std::endl;
|
|
result[idx] = "-1";
|
|
}else
|
|
result[idx] = "0"; //SUCCESS
|
|
sqlite3_reset(stmt); // 重置语句
|
|
}
|
|
// 提交事务
|
|
if (sqlite3_exec(db, "COMMIT;", nullptr, nullptr, &errMsg) != SQLITE_OK) {
|
|
std::cerr << "事务提交失败: " << errMsg << std::endl;
|
|
sqlite3_free(errMsg);
|
|
resp = -1;
|
|
}
|
|
// 清理
|
|
sqlite3_finalize(stmt);
|
|
return reponse;
|
|
}
|
|
|
|
int UpdateRecord::HandleMsg(const msg_t msg, handparam_t *param){
|
|
|
|
topic.clear();
|
|
topic_split(msg.topic,'/');
|
|
json value,resp;
|
|
int ret = 0;
|
|
int afn_flag = 0, update_flag = 0;;
|
|
std::vector<std::string> sql_list;
|
|
std::vector<std::string> result;
|
|
sql_list.clear();
|
|
result.clear();
|
|
std::string table_name ;
|
|
try{
|
|
value = json::prase(msg.payload)
|
|
}
|
|
catch(const std::expection &e){
|
|
std::cout << "topic "<<msg.topic.c_str()<<" prase error:"<<e.what();
|
|
return -1;//format fail
|
|
}
|
|
if(!value.is_object())return -1;
|
|
if(value.contains("token")){
|
|
resp["token"] = value["token"];
|
|
}
|
|
if(value.contains("time")){
|
|
;// value["time"]
|
|
}
|
|
if(value.contains("data")){
|
|
json subvalue = value["data"];
|
|
std::stringstream ss;
|
|
table_name =search_table_db(std::stoi(subvalue["afn"]),std::stoi(subvalue["dataid"]));
|
|
int afn = std::stoi(subvalue["afn"]);
|
|
if(!(afn==0x0d | afn==0x0e |afn == 0x12 |afn == 0x13))
|
|
{
|
|
afn_flag = -1;
|
|
goto resp_process;
|
|
}
|
|
if(std::stoi(subvalue["updatetype"] !=1){
|
|
update_flag = -1;
|
|
goto resp_process;
|
|
}
|
|
|
|
ss << "replace into " <<table_name.c_str() <<" (idx,metid,dataid,frozentime,createdtime,source,crcaux,databuff) values ("\
|
|
<< 0 << ","\
|
|
<<std::stoi(subvalue["metid"])<<","\
|
|
<<k["dataid"].c_str()<<","\
|
|
<<string_to_now(k["updatefilter"])<<","\
|
|
<<time(NULL)<<","\
|
|
<<std::stoi(k["crcaux"])<<","\
|
|
<<k["databuff"]<<");";
|
|
sql_list.pushback(ss.str());
|
|
ss.clear();
|
|
|
|
}
|
|
int ret = SQLBatch_exc(sql_list,result);
|
|
resp_process:
|
|
resp["time"]=now_to_string();
|
|
if(ret == -1 || afn_flag == -1 || update_flag = -1;)
|
|
resp["ack"]="false";
|
|
else if(ret == 0)
|
|
resp["ack"]="true";
|
|
|
|
resp["data"]["dataidex"]=result;
|
|
msg_t resp_msg;
|
|
std::stringstream ss;
|
|
ss << resp_msg.topic[1].c_str()<<"/"<<resp_msg.topic[0].c_str()<<"/"\
|
|
<<resp_msg.topic[2].c_str()<<"/"<<resp_msg.topic[3].c_str();
|
|
resp_msg.topic = ss.str();
|
|
resp_msg.timestamp = now_to_string();
|
|
resp_msg.payload = resp.dump();
|
|
return WriteResponseMsg(resp_msg);
|
|
}
|
|
const std::string UpdateRecord::GetFID(){
|
|
|
|
}
|
|
void UpdateRecord::topic_split(const std::string& str, char delimiter) {
|
|
std::string token; // 临时存储每个子字符串
|
|
std::istringstream tokenStream(str); // 使用字符串流处理输入字符串
|
|
// 按分隔符逐个读取子字符串
|
|
while (std::getline(tokenStream, token, delimiter)) {
|
|
topic.push_back(token); // 将子字符串添加到结果中
|
|
}
|
|
|
|
}
|