Files
eUi/include/eui_singleton/configCacheStore.h
T
RCiRoot e3f7733316 V20260829-2.6.1
完成框架目录和模块重构;新增核心、单例、工具、加密及框架 SDK;统一任务、相机和 RPC 接口,并增加离线检测、相机标定、备份恢复、版本管理、崩溃守护和心跳监控功能。
2026-09-20 16:01:09 +08:00

328 lines
10 KiB
C++

#include <eui_tools/sql/qSqlBase.h>
#pragma once
#pragma once
#include <QString>
#include <QDateTime>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <vector>
#include <map>
// 界面上运行时数据缓存
class runtimeDataCacheStore {
public:
// 表枚举(统一管理)
enum class Table {
RuntimeCache,//运行时数据缓存
Statistics//统计数据缓存
};
explicit runtimeDataCacheStore(sqliteConnection* dbIn)
: db(dbIn) {
initAllTables();
}
//设置
bool set(Table table,
const QString& className,
const int& okCount,
const int& ngCount,
const QMap<QString, int>& defects)
{
return set(table, className, okCount, ngCount, defects, {});
}
bool set(Table table,
const QString& className,
const int& okCount,
const int& ngCount,
const std::map<std::string, int>& defects)
{
QMap<QString, int> qDefects = toQMap(defects);
return set(table, className, okCount, ngCount, qDefects, {});
}
bool set(Table table,
const QString& className,
const int& okCount,
const int& ngCount,
const QMap<QString, int>& defects,
const QMap<QString, QMap<int, int>>& defectsByHour)
{
QString tableName = getTableName(table);
QString defectsJson = serializeDefects(defects);
QString defectsByHourJson = serializeDefectsByHour(defectsByHour);
QString sql = QString(R"(
INSERT INTO %1 (
class_name, ok_count, ng_count, defects, defects_by_hour, update_time
)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(class_name) DO UPDATE SET
ok_count = excluded.ok_count,
ng_count = excluded.ng_count,
defects = excluded.defects,
defects_by_hour = excluded.defects_by_hour,
update_time = excluded.update_time;
)").arg(tableName);
return db->execute(sql, {
className,
okCount,
ngCount,
defectsJson,
defectsByHourJson,
QDateTime::currentSecsSinceEpoch()
});
}
bool set(Table table,
const QString& className,
const int& okCount,
const int& ngCount,
const std::map<std::string, int>& defects,
const std::map<std::string, std::map<int, int>>& defectsByHour)
{
QMap<QString, int> qDefects = toQMap(defects);
QMap<QString, QMap<int, int>> qDefectsByHour = toHourQMap(defectsByHour);
return set(table, className, okCount, ngCount, qDefects, qDefectsByHour);
}
// 读取
bool get(Table table,
const QString& className,
int& okCount,
int& ngCount,
QMap<QString, int>& defects)
{
QMap<QString, QMap<int, int>> defectsByHour;
return get(table, className, okCount, ngCount, defects, defectsByHour);
}
bool get(Table table,
const QString& className,
int& okCount,
int& ngCount,
std::map<std::string, int>& defects)
{
QMap<QString, int> qDefects;
QMap<QString, QMap<int, int>> qDefectsByHour;
bool ret = get(table, className, okCount, ngCount, qDefects, qDefectsByHour);
if (!ret)
return false;
defects = toStdMap(qDefects);
return true;
}
bool get(Table table,
const QString& className,
int& okCount,
int& ngCount,
QMap<QString, int>& defects,
QMap<QString, QMap<int, int>>& defectsByHour)
{
QString tableName = getTableName(table);
auto results = db->_search(
tableName,
{ "ok_count", "ng_count", "defects", "defects_by_hour" },
{ {"class_name", className} }
);
if (results.empty())
return false;
const auto& row = results[0];
if (row.find("ok_count") != row.end())
okCount = row.at("ok_count").toInt();
if (row.find("ng_count") != row.end())
ngCount = row.at("ng_count").toInt();
if (row.find("defects") != row.end()) {
QString defectsJson = row.at("defects").toString();
defects = deserializeDefects(defectsJson);
}
if (row.find("defects_by_hour") != row.end()) {
QString defectsByHourJson = row.at("defects_by_hour").toString();
defectsByHour = deserializeDefectsByHour(defectsByHourJson);
}
return true;
}
bool get(Table table,
const QString& className,
int& okCount,
int& ngCount,
std::map<std::string, int>& defects,
std::map<std::string, std::map<int, int>>& defectsByHour)
{
QMap<QString, int> qDefects;
QMap<QString, QMap<int, int>> qDefectsByHour;
bool ret = get(table, className, okCount, ngCount, qDefects, qDefectsByHour);
if (!ret)
return false;
defects = toStdMap(qDefects);
defectsByHour = toHourStdMap(qDefectsByHour);
return true;
}
private:
sqliteConnection* db = nullptr;
// enum -> 表名映射(核心)
QString getTableName(Table table) const {
switch (table) {
case Table::RuntimeCache: return "runtime_cache_hide";//运行时数据缓存
case Table::Statistics: return "statistics_cache_hide";//统计数据缓存
default: return "unknow_cache_hide";
}
}
// 初始化所有表
void initAllTables() {
for (auto table : {Table::RuntimeCache, Table::Statistics }) {
initTable(getTableName(table));
}
}
void initTable(const QString& tableName) {
if (tableName == "unknow_cache_hide") {
qCritical() << "Attempted to initialize unknown table: " << tableName;
return;
}
db->createTable(tableName, {
{"class_name", "TEXT PRIMARY KEY"},
{"ok_count", "INTEGER"},
{"ng_count", "INTEGER"},
{"defects", "TEXT"},
{"defects_by_hour", "TEXT"},
{"update_time", "INTEGER"}
});
// 旧版本数据库可能缺少新列,CREATE TABLE IF NOT EXISTS 不会补列,需要显式迁移
ensureColumn(tableName, "defects_by_hour", "TEXT");
}
void ensureColumn(const QString& tableName, const QString& columnName, const QString& columnType) {
const auto columns = db->query(QString("PRAGMA table_info(%1)").arg(tableName));
for (const auto& column : columns) {
if (column.value("name").toString() == columnName)
return;
}
db->execute(QString("ALTER TABLE %1 ADD COLUMN %2 %3")
.arg(tableName, columnName, columnType));
}
// QMap -> JSON(更简洁版本)
QString serializeDefects(const QMap<QString, int>& defects) {
QJsonObject obj;
for (auto it = defects.begin(); it != defects.end(); ++it) {
obj[it.key()] = it.value();
}
return QJsonDocument(obj).toJson(QJsonDocument::Compact);
}
// JSON -> QMap
QMap<QString, int> deserializeDefects(const QString& json) {
QMap<QString, int> result;
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
if (!doc.isObject())
return result;
QJsonObject obj = doc.object();
for (auto it = obj.begin(); it != obj.end(); ++it) {
result[it.key()] = it.value().toInt();
}
return result;
}
QString serializeDefectsByHour(const QMap<QString, QMap<int, int>>& defectsByHour) {
QJsonObject obj;
for (auto it = defectsByHour.begin(); it != defectsByHour.end(); ++it) {
QJsonObject hourObj;
const auto& hourMap = it.value();
for (auto hourIt = hourMap.begin(); hourIt != hourMap.end(); ++hourIt) {
hourObj[QString::number(hourIt.key())] = hourIt.value();
}
obj[it.key()] = hourObj;
}
return QJsonDocument(obj).toJson(QJsonDocument::Compact);
}
QMap<QString, QMap<int, int>> deserializeDefectsByHour(const QString& json) {
QMap<QString, QMap<int, int>> result;
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
if (!doc.isObject())
return result;
QJsonObject obj = doc.object();
for (auto it = obj.begin(); it != obj.end(); ++it) {
if (!it.value().isObject())
continue;
QJsonObject hourObj = it.value().toObject();
QMap<int, int> hourMap;
for (auto hourIt = hourObj.begin(); hourIt != hourObj.end(); ++hourIt) {
bool ok = false;
const int hour = hourIt.key().toInt(&ok);
if (ok)
hourMap[hour] = hourIt.value().toInt();
}
result[it.key()] = hourMap;
}
return result;
}
// std::map -> QMap
QMap<QString, int> toQMap(const std::map<std::string, int>& in) {
QMap<QString, int> out;
for (const auto& [k, v] : in) {
out[QString::fromStdString(k)] = v;
}
return out;
}
// QMap -> std::map
std::map<std::string, int> toStdMap(const QMap<QString, int>& in) {
std::map<std::string, int> out;
for (auto it = in.begin(); it != in.end(); ++it) {
out[it.key().toStdString()] = it.value();
}
return out;
}
// std::map -> QMap
QMap<QString, QMap<int, int>> toHourQMap(const std::map<std::string, std::map<int, int>>& in) {
QMap<QString, QMap<int, int>> out;
for (const auto& [k, v] : in) {
QMap<int, int> hourMap;
for (const auto& [hour, count] : v) {
hourMap[hour] = count;
}
out[QString::fromStdString(k)] = hourMap;
}
return out;
}
// QMap -> std::map
std::map<std::string, std::map<int, int>> toHourStdMap(const QMap<QString, QMap<int, int>>& in) {
std::map<std::string, std::map<int, int>> out;
for (auto it = in.begin(); it != in.end(); ++it) {
std::map<int, int> hourMap;
const auto& qHourMap = it.value();
for (auto hourIt = qHourMap.begin(); hourIt != qHourMap.end(); ++hourIt) {
hourMap[hourIt.key()] = hourIt.value();
}
out[it.key().toStdString()] = hourMap;
}
return out;
}
};