#include "stdafx.h"
|
#include "AlarmManager.h"
|
#include <sstream>
|
#include <fstream>
|
#include <iostream>
|
#include <stdexcept>
|
#include <ctime>
|
#include <iomanip>
|
#include <random>
|
|
// ³£Á¿
|
const std::string DATABASE_FILE = R"(AlarmManager.db)";
|
|
// ¾²Ì¬³ÉÔ±³õʼ»¯
|
std::mutex AlarmManager::m_mutex;
|
|
// »ñÈ¡µ¥ÀýʵÀý
|
AlarmManager& AlarmManager::getInstance() {
|
static AlarmManager instance;
|
return instance;
|
}
|
|
// ¹¹Ô캯Êý
|
AlarmManager::AlarmManager() {
|
m_pDB = new BL::SQLiteDatabase();
|
}
|
|
// Îö¹¹º¯Êý
|
AlarmManager::~AlarmManager() {
|
if (m_pDB != nullptr) {
|
delete m_pDB;
|
m_pDB = nullptr;
|
}
|
}
|
|
// ÉèÖÃÊý¾Ý¿âÁ¬½Ó
|
void AlarmManager::setDatabase(BL::Database* db) {
|
std::lock_guard<std::mutex> lock(m_mutex);
|
m_pDB = db;
|
}
|
|
// ³õʼ»¯±¨¾¯±í
|
bool AlarmManager::initAlarmTable() {
|
char path[MAX_PATH];
|
GetModuleFileName(NULL, path, MAX_PATH);
|
std::string exePath(path);
|
std::string dbFileDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB";
|
if (!CreateDirectory(dbFileDir.c_str(), NULL) && ERROR_ALREADY_EXISTS != GetLastError()) {
|
throw std::runtime_error("Failed to create database directory.");
|
}
|
|
std::string dbFilePath = dbFileDir + "\\" + DATABASE_FILE;
|
if (!m_pDB->connect(dbFilePath, true)) {
|
throw std::runtime_error("Failed to connect to database.");
|
}
|
|
// ´´½¨É豸±í
|
const std::string createDevicesTableQuery = R"(
|
CREATE TABLE IF NOT EXISTS devices (
|
device_id TEXT PRIMARY KEY NOT NULL,
|
device_name TEXT NOT NULL
|
)
|
)";
|
if (!m_pDB->executeQuery(createDevicesTableQuery)) {
|
return false;
|
}
|
|
// ´´½¨µ¥Ôª±í£¬É豸IDºÍµ¥ÔªID×éºÏ×÷ΪÖ÷¼ü
|
const std::string createUnitsTableQuery = R"(
|
CREATE TABLE IF NOT EXISTS units (
|
device_id TEXT NOT NULL,
|
unit_id TEXT NOT NULL,
|
unit_name TEXT NOT NULL,
|
PRIMARY KEY (device_id, unit_id),
|
FOREIGN KEY (device_id) REFERENCES devices(device_id)
|
)
|
)";
|
if (!m_pDB->executeQuery(createUnitsTableQuery)) {
|
return false;
|
}
|
|
// ´´½¨±¨¾¯±í£¬±¨¾¯¼Ç¼µÄalarm_event_idÊÇÖ÷¼ü
|
const std::string createAlarmsTableQuery = R"(
|
CREATE TABLE IF NOT EXISTS alarms (
|
alarm_event_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id TEXT NOT NULL,
|
severity_level INTEGER NOT NULL DEFAULT 0,
|
device_id TEXT NOT NULL ,
|
unit_id TEXT NOT NULL,
|
description TEXT NOT NULL,
|
start_time DATETIME NOT NULL,
|
end_time DATETIME,
|
FOREIGN KEY (device_id) REFERENCES devices(device_id),
|
FOREIGN KEY (unit_id) REFERENCES units(unit_id)
|
)
|
)";
|
return m_pDB->executeQuery(createAlarmsTableQuery);
|
}
|
|
// Ïú»Ù±¨¾¯±í
|
void AlarmManager::termAlarmTable() {
|
if (m_pDB != nullptr) {
|
m_pDB->disconnect();
|
}
|
}
|
|
// Ïú»Ù±¨¾¯±í
|
bool AlarmManager::destroyAlarmTable() {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
const std::string dropTableQuery = "DROP TABLE IF EXISTS alarms";
|
return m_pDB->executeQuery(dropTableQuery);
|
}
|
|
// ²åÈëÄ£ÄâÊý¾Ý
|
void AlarmManager::insertMockData() {
|
// ²åÈëÉ豸Êý¾Ý
|
for (int i = 1; i <= 3; ++i) {
|
std::string deviceName = "Device" + std::to_string(i);
|
std::stringstream query;
|
query << "INSERT INTO devices (device_id, device_name) VALUES (" << i << ", '" << deviceName << "');";
|
if (!m_pDB->executeQuery(query.str())) {
|
std::cerr << "Failed to insert device: " << i << std::endl;
|
}
|
}
|
|
// ²åÈëµ¥ÔªÊý¾Ý
|
for (int i = 1; i <= 3; ++i) {
|
for (int j = 0; j <= 3; ++j) {
|
int unitId = j;
|
std::string deviceId = std::to_string(i);
|
std::string unitName = "Unit" + std::to_string(j);
|
|
std::stringstream query;
|
query << "INSERT INTO units (device_id, unit_id, unit_name) VALUES ('"
|
<< deviceId << "', '" // ²åÈëÉ豸ID£¬È·±£ÊÇ×Ö·û´®
|
<< unitId << "', '" // ²åÈëµ¥ÔªID£¬È·±£ÊÇ×Ö·û´®
|
<< unitName << "');";
|
|
if (!m_pDB->executeQuery(query.str())) {
|
std::cerr << "Failed to insert unit: " << unitId << std::endl;
|
}
|
}
|
}
|
|
/*
|
// ³õʼ»¯Ëæ»úÊýÉú³ÉÆ÷
|
std::random_device rd;
|
std::mt19937 gen(rd());
|
std::uniform_int_distribution<> deviceDis(1, 3);
|
std::uniform_int_distribution<> unitDis(1, 3);
|
std::uniform_int_distribution<> errorCodeDis(1, 100);
|
std::uniform_int_distribution<> severityDis(0, 3);
|
std::vector<std::string> descriptions = { "Overheat", "Sensor failure", "Power outage" };
|
|
// ʱ¼äÏà¹Ø
|
auto now = std::chrono::system_clock::now();
|
auto start_time = std::chrono::system_clock::to_time_t(now);
|
auto end_time = std::chrono::system_clock::to_time_t(now + std::chrono::minutes(10));
|
|
std::tm start_tm = {};
|
std::tm end_tm = {};
|
localtime_s(&start_tm, &start_time);
|
localtime_s(&end_tm, &end_time);
|
|
// ²åÈëÄ£ÄâÊý¾Ý
|
for (int i = 0; i < 10; ++i) {
|
int deviceId = deviceDis(gen); // Ëæ»úÉ豸ID
|
int unitId = unitDis(gen); // Ëæ»úµ¥ÔªID
|
int errorCode = errorCodeDis(gen); // Ëæ»ú´íÎóÂë
|
int severityLevel = severityDis(gen); // Ëæ»úÉú³É±¨¾¯µÈ¼¶
|
std::string description = descriptions[errorCodeDis(gen) % descriptions.size()]; // Ëæ»ú±¨¾¯ÃèÊö
|
|
std::stringstream query;
|
query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) "
|
<< "VALUES (" << errorCode << ", " << severityLevel << ", " << deviceId << ", " << unitId << ", '" << description << "', "
|
<< "'" << std::put_time(&start_tm, "%Y-%m-%d %H:%M:%S") << "', "
|
<< "'" << std::put_time(&end_tm, "%Y-%m-%d %H:%M:%S") << "');";
|
|
if (!m_pDB->executeQuery(query.str())) {
|
std::cerr << "Failed to insert alarm data." << std::endl;
|
}
|
}
|
*/
|
}
|
|
// Ìí¼Ó±¨¾¯ÐÅÏ¢
|
bool AlarmManager::addAlarm(const AlarmData& alarmData, int& alarmEventId) {
|
if (!m_pDB) {
|
return false;
|
}
|
|
#if 0
|
// ¿ªÊ¼ÊÂÎñ
|
m_pDB->executeQuery("BEGIN TRANSACTION;");
|
|
// ¹¹½¨²åÈë²éѯ
|
std::ostringstream query;
|
query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) VALUES ("
|
<< alarmData.nId << ", " // ´íÎóÂë
|
<< alarmData.nSeverityLevel << ", " // ±¨¾¯µÈ¼¶
|
<< alarmData.nDeviceId << ", " // É豸ID
|
<< alarmData.nUnitId << ", '" // µ¥ÔªID
|
<< alarmData.strDescription << "', '" // ÃèÊö
|
<< alarmData.strStartTime << "', '" // ¿ªÊ¼Ê±¼ä
|
<< alarmData.strEndTime << "')"; // ½áÊøÊ±¼ä
|
|
// ʹÓÃËø±£»¤¶àḬ̈߳²È«
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
// Ö´ÐвåÈë²éѯ
|
bool result = m_pDB->executeQuery(query.str());
|
if (result) {
|
alarmEventId = getLastInsertId();
|
m_alarmCache[alarmEventId] = alarmData;
|
}
|
|
// Ìá½»ÊÂÎñ
|
m_pDB->executeQuery("COMMIT;");
|
|
return result;
|
#else
|
// ¹¹½¨²åÈë²éѯ²¢Ê¹Óà RETURNING »ñÈ¡²åÈëºóµÄ alarm_event_id
|
std::ostringstream query;
|
query << "INSERT INTO alarms (id, severity_level, device_id, unit_id, description, start_time, end_time) "
|
<< "VALUES (" << alarmData.nId << ", " << alarmData.nSeverityLevel << ", " << alarmData.nDeviceId << ", "
|
<< alarmData.nUnitId << ", '" << alarmData.strDescription << "', '" << alarmData.strStartTime << "', '"
|
<< alarmData.strEndTime << "') RETURNING alarm_event_id;";
|
|
// ʹÓÃËø±£»¤¶àḬ̈߳²È«
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
// Ö´Ðвéѯ²¢»ñÈ¡½á¹û
|
auto results = m_pDB->fetchResults(query.str());
|
if (!results.empty() && !results[0].empty()) {
|
try {
|
// ÌáÈ¡²¢×ª»» alarm_event_id
|
alarmEventId = std::stoi(results[0][0]);
|
// ½«²åÈëµÄ±¨¾¯Êý¾ÝÌí¼Óµ½»º´æ
|
m_mapCache[alarmEventId] = alarmData;
|
return true;
|
}
|
catch (const std::exception& e) {
|
std::cerr << "Error parsing alarm_event_id: " << e.what() << std::endl;
|
return false;
|
}
|
}
|
|
return false;
|
#endif
|
}
|
|
// ²éѯËùÓб¨¾¯Êý¾Ý
|
std::vector<AlarmData> AlarmManager::getAllAlarms() {
|
if (!m_pDB) {
|
return {};
|
}
|
|
// ²éѯËùÓб¨¾¯Êý¾Ý£¨°üÀ¨É豸Ãû³ÆºÍµ¥ÔªÃû³Æ£©
|
const std::string query = R"(
|
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
|
FROM alarms a
|
JOIN devices d ON a.device_id = d.device_id
|
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
|
)";
|
|
auto results = m_pDB->fetchResults(query);
|
|
// ±éÀú²éѯ½á¹û£¬Ìî³ä AlarmData ½á¹¹Ìå
|
std::vector<AlarmData> alarms;
|
for (const auto& row : results) {
|
AlarmData alarmData;
|
alarmData.nId = std::stoi(row[0]); // ´íÎóÂë
|
alarmData.nSeverityLevel = std::stoi(row[1]); // ±¨¾¯µÈ¼¶
|
alarmData.nDeviceId = std::stoi(row[2]); // É豸ID
|
alarmData.nUnitId = std::stoi(row[3]); // µ¥ÔªID
|
alarmData.strDeviceName = row[4]; // É豸Ãû³Æ
|
alarmData.strUnitName = row[5]; // µ¥ÔªÃû³Æ
|
alarmData.strDescription = row[6]; // ÃèÊö
|
alarmData.strStartTime = row[7]; // ¿ªÊ¼Ê±¼ä
|
alarmData.strEndTime = row[8]; // ½áÊøÊ±¼ä
|
|
alarms.push_back(alarmData);
|
}
|
|
return alarms;
|
}
|
|
// ¸ù¾Ý±¨¾¯ID²éѯ±¨¾¯
|
std::vector<AlarmData> AlarmManager::getAlarmsById(const std::string& id) {
|
if (!m_pDB) {
|
return {};
|
}
|
|
std::ostringstream query;
|
query << R"(
|
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
|
FROM alarms a
|
JOIN devices d ON a.device_id = d.device_id
|
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
|
WHERE a.id = ')" << id << "'";
|
|
auto results = m_pDB->fetchResults(query.str());
|
|
// ±éÀú²éѯ½á¹û£¬Ìî³ä AlarmData ½á¹¹Ìå
|
std::vector<AlarmData> alarms;
|
for (const auto& row : results) {
|
AlarmData alarmData;
|
alarmData.nId = std::stoi(row[0]); // ´íÎóÂë
|
alarmData.nSeverityLevel = std::stoi(row[1]); // ±¨¾¯µÈ¼¶
|
alarmData.nDeviceId = std::stoi(row[2]); // É豸ID
|
alarmData.nUnitId = std::stoi(row[3]); // µ¥ÔªID
|
alarmData.strDeviceName = row[4]; // É豸Ãû³Æ
|
alarmData.strUnitName = row[5]; // µ¥ÔªÃû³Æ
|
alarmData.strDescription = row[6]; // ÃèÊö
|
alarmData.strStartTime = row[7]; // ¿ªÊ¼Ê±¼ä
|
alarmData.strEndTime = row[8]; // ½áÊøÊ±¼ä
|
|
alarms.push_back(alarmData);
|
}
|
|
return alarms;
|
}
|
|
// ¸ù¾ÝÃèÊö²éѯ±¨¾¯
|
std::vector<AlarmData> AlarmManager::getAlarmsByDescription(const std::string& description) {
|
if (!m_pDB) {
|
return {};
|
}
|
|
std::ostringstream query;
|
query << R"(
|
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
|
FROM alarms a
|
JOIN devices d ON a.device_id = d.device_id
|
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
|
WHERE a.description LIKE '%)" << description << R"(%')";
|
|
auto results = m_pDB->fetchResults(query.str());
|
|
// ±éÀú²éѯ½á¹û£¬Ìî³ä AlarmData ½á¹¹Ìå
|
std::vector<AlarmData> alarms;
|
for (const auto& row : results) {
|
AlarmData alarmData;
|
alarmData.nId = std::stoi(row[0]); // ´íÎóÂë
|
alarmData.nSeverityLevel = std::stoi(row[1]); // ±¨¾¯µÈ¼¶
|
alarmData.nDeviceId = std::stoi(row[2]); // É豸ID
|
alarmData.nUnitId = std::stoi(row[3]); // µ¥ÔªID
|
alarmData.strDeviceName = row[4]; // É豸Ãû³Æ
|
alarmData.strUnitName = row[5]; // µ¥ÔªÃû³Æ
|
alarmData.strDescription = row[6]; // ÃèÊö
|
alarmData.strStartTime = row[7]; // ¿ªÊ¼Ê±¼ä
|
alarmData.strEndTime = row[8]; // ½áÊøÊ±¼ä
|
|
alarms.push_back(alarmData);
|
}
|
|
return alarms;
|
}
|
|
// ¸ù¾Ýʱ¼ä·¶Î§²éѯ±¨¾¯
|
std::vector<AlarmData> AlarmManager::getAlarmsByTimeRange(const std::string& startTime, const std::string& endTime) {
|
if (!m_pDB) {
|
return {};
|
}
|
|
std::ostringstream query;
|
query << R"(
|
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
|
FROM alarms a
|
JOIN devices d ON a.device_id = d.device_id
|
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
|
WHERE 1=1)";
|
|
if (!startTime.empty()) {
|
query << " AND a.start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND a.end_time <= '" << endTime << "'";
|
}
|
|
auto results = m_pDB->fetchResults(query.str());
|
|
// ±éÀú²éѯ½á¹û£¬Ìî³ä AlarmData ½á¹¹Ìå
|
std::vector<AlarmData> alarms;
|
for (const auto& row : results) {
|
AlarmData alarmData;
|
alarmData.nId = std::stoi(row[0]); // ´íÎóÂë
|
alarmData.nSeverityLevel = std::stoi(row[1]); // ±¨¾¯µÈ¼¶
|
alarmData.nDeviceId = std::stoi(row[2]); // É豸ID
|
alarmData.nUnitId = std::stoi(row[3]); // µ¥ÔªID
|
alarmData.strDeviceName = row[4]; // É豸Ãû³Æ
|
alarmData.strUnitName = row[5]; // µ¥ÔªÃû³Æ
|
alarmData.strDescription = row[6]; // ÃèÊö
|
alarmData.strStartTime = row[7]; // ¿ªÊ¼Ê±¼ä
|
alarmData.strEndTime = row[8]; // ½áÊøÊ±¼ä
|
|
alarms.push_back(alarmData);
|
}
|
|
return alarms;
|
}
|
|
// ¸ù¾ÝID¡¢¿ªÊ¼Ê±¼äºÍ½áÊøÊ±¼ä²éѯ±¨¾¯
|
std::vector<AlarmData> AlarmManager::getAlarmsByIdAndTimeRange(const std::string& id, const std::string& startTime, const std::string& endTime) {
|
if (!m_pDB) {
|
return {};
|
}
|
|
std::ostringstream query;
|
query << R"(
|
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
|
FROM alarms a
|
JOIN devices d ON a.device_id = d.device_id
|
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
|
WHERE a.id = ')" << id << "'";
|
|
if (!startTime.empty()) {
|
query << " AND a.start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND a.end_time <= '" << endTime << "'";
|
}
|
|
auto results = m_pDB->fetchResults(query.str());
|
|
// ±éÀú²éѯ½á¹û£¬Ìî³ä AlarmData ½á¹¹Ìå
|
std::vector<AlarmData> alarms;
|
for (const auto& row : results) {
|
AlarmData alarmData;
|
alarmData.nId = std::stoi(row[0]); // ´íÎóÂë
|
alarmData.nSeverityLevel = std::stoi(row[1]); // ±¨¾¯µÈ¼¶
|
alarmData.nDeviceId = std::stoi(row[2]); // É豸ID
|
alarmData.nUnitId = std::stoi(row[3]); // µ¥ÔªID
|
alarmData.strDeviceName = row[4]; // É豸Ãû³Æ
|
alarmData.strUnitName = row[5]; // µ¥ÔªÃû³Æ
|
alarmData.strDescription = row[6]; // ÃèÊö
|
alarmData.strStartTime = row[7]; // ¿ªÊ¼Ê±¼ä
|
alarmData.strEndTime = row[8]; // ½áÊøÊ±¼ä
|
|
alarms.push_back(alarmData);
|
}
|
|
return alarms;
|
}
|
|
// ·ÖÒ³²éѯ±¨¾¯Êý¾Ý
|
std::vector<AlarmData> AlarmManager::getAlarms(int startPosition, int count) {
|
if (!m_pDB) {
|
return {};
|
}
|
|
std::ostringstream query;
|
query << R"(
|
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
|
FROM alarms a
|
JOIN devices d ON a.device_id = d.device_id
|
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
|
LIMIT )" << count << " OFFSET " << startPosition;
|
|
auto results = m_pDB->fetchResults(query.str());
|
|
// ±éÀú²éѯ½á¹û£¬Ìî³ä AlarmData ½á¹¹Ìå
|
std::vector<AlarmData> alarms;
|
for (const auto& row : results) {
|
AlarmData alarmData;
|
alarmData.nId = std::stoi(row[0]); // ´íÎóÂë
|
alarmData.nSeverityLevel = std::stoi(row[1]); // ±¨¾¯µÈ¼¶
|
alarmData.nDeviceId = std::stoi(row[2]); // É豸ID
|
alarmData.nUnitId = std::stoi(row[3]); // µ¥ÔªID
|
alarmData.strDeviceName = row[4]; // É豸Ãû³Æ
|
alarmData.strUnitName = row[5]; // µ¥ÔªÃû³Æ
|
alarmData.strDescription = row[6]; // ÃèÊö
|
alarmData.strStartTime = row[7]; // ¿ªÊ¼Ê±¼ä
|
alarmData.strEndTime = row[8]; // ½áÊøÊ±¼ä
|
|
alarms.push_back(alarmData);
|
}
|
|
return alarms;
|
}
|
|
// ɸѡ±¨¾¯Êý¾Ý
|
std::vector<AlarmData> AlarmManager::getFilteredAlarms(
|
const std::string& id,
|
const std::string& severityLevel,
|
const std::string& deviceName,
|
const std::string& unitName,
|
const std::string& description,
|
const std::string& startTime,
|
const std::string& endTime,
|
int pageNumber,
|
int pageSize) {
|
|
if (!m_pDB) {
|
return {};
|
}
|
|
std::ostringstream query;
|
query << R"(
|
SELECT a.id, a.severity_level, a.device_id, a.unit_id, d.device_name, u.unit_name, a.description, a.start_time, a.end_time
|
FROM alarms a
|
JOIN devices d ON a.device_id = d.device_id
|
JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id
|
WHERE 1=1)";
|
|
// ´«ÈëµÄ¹ýÂËÌõ¼þ
|
if (!id.empty()) {
|
query << " AND a.id = '" << id << "'";
|
}
|
if (!severityLevel.empty()) {
|
query << " AND a.severity_level = '" << severityLevel << "'";
|
}
|
if (!deviceName.empty()) {
|
query << " AND d.device_name LIKE '%" << deviceName << "%'";
|
}
|
if (!unitName.empty()) {
|
query << " AND u.unit_name LIKE '%" << unitName << "%'";
|
}
|
if (!description.empty()) {
|
query << " AND a.description LIKE '%" << description << "%'";
|
}
|
if (!startTime.empty()) {
|
query << " AND a.start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND a.end_time <= '" << endTime << "'";
|
}
|
|
// ·ÖÒ³ÉèÖÃ
|
int offset = (pageNumber - 1) * pageSize;
|
query << " ORDER BY a.start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
|
|
auto results = m_pDB->fetchResults(query.str());
|
|
// ±éÀú²éѯ½á¹û£¬Ìî³ä AlarmData ½á¹¹Ìå
|
std::vector<AlarmData> alarms;
|
for (const auto& row : results) {
|
AlarmData alarmData;
|
alarmData.nId = std::stoi(row[0]); // ´íÎóÂë
|
alarmData.nSeverityLevel = std::stoi(row[1]); // ±¨¾¯µÈ¼¶ (×Ö·û´®)
|
alarmData.nDeviceId = std::stoi(row[2]); // É豸ID
|
alarmData.nUnitId = std::stoi(row[3]); // µ¥ÔªID
|
alarmData.strDeviceName = row[4]; // É豸Ãû³Æ
|
alarmData.strUnitName = row[5]; // µ¥ÔªÃû³Æ
|
alarmData.strDescription = row[6]; // ÃèÊö
|
alarmData.strStartTime = row[7]; // ¿ªÊ¼Ê±¼ä
|
alarmData.strEndTime = row[8]; // ½áÊøÊ±¼ä
|
|
alarms.push_back(alarmData);
|
}
|
|
return alarms;
|
}
|
|
// »ñÈ¡·ûºÏÌõ¼þµÄ±¨¾¯×ÜÊý
|
int AlarmManager::getTotalAlarmCount(
|
const std::string& id,
|
const std::string& severityLevel,
|
const std::string& deviceName,
|
const std::string& unitName,
|
const std::string& description,
|
const std::string& startTime,
|
const std::string& endTime) {
|
|
if (!m_pDB) {
|
return 0;
|
}
|
|
std::ostringstream query;
|
query << "SELECT COUNT(*) FROM alarms a "
|
<< "JOIN devices d ON a.device_id = d.device_id "
|
<< "JOIN units u ON a.device_id = u.device_id AND a.unit_id = u.unit_id "
|
<< "WHERE 1=1";
|
|
// Ìí¼Ó¹ýÂËÌõ¼þ
|
if (!id.empty()) {
|
query << " AND a.id = '" << id << "'";
|
}
|
if (!severityLevel.empty()) {
|
query << " AND a.severity_level = '" << severityLevel << "'";
|
}
|
if (!deviceName.empty()) {
|
query << " AND d.device_name LIKE '%" << deviceName << "%'";
|
}
|
if (!unitName.empty()) {
|
query << " AND u.unit_name LIKE '%" << unitName << "%'";
|
}
|
if (!description.empty()) {
|
query << " AND a.description LIKE '%" << description << "%'";
|
}
|
if (!startTime.empty()) {
|
query << " AND a.start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND a.end_time <= '" << endTime << "'";
|
}
|
|
auto results = m_pDB->fetchResults(query.str());
|
return (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0;
|
}
|
|
// ¸üб¨¾¯µÄ½áÊøÊ±¼ä
|
bool AlarmManager::updateAlarmEndTime(
|
const std::string& id,
|
const std::string& severityLevel,
|
const std::string& deviceId,
|
const std::string& unitId,
|
const std::string& description,
|
const std::string& startTime,
|
const std::string& newEndTime) {
|
|
if (!m_pDB) {
|
return false;
|
}
|
|
// ¸üб¨¾¯½áÊøÊ±¼ä
|
std::ostringstream updateQuery;
|
updateQuery << "UPDATE alarms SET end_time = '" << newEndTime << "'"
|
<< " WHERE id = '" << id << "'"
|
<< " AND severity_level = '" << severityLevel << "'"
|
<< " AND device_id = '" << deviceId << "'"
|
<< " AND unit_id = '" << unitId << "'"
|
<< " AND description = '" << description << "'"
|
<< " AND start_time = '" << startTime << "'";
|
|
return m_pDB->executeQuery(updateQuery.str());
|
}
|
|
// ÇåÀí¾É±¨¾¯Êý¾Ý
|
void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceId, const std::string& unitId) {
|
if (!m_pDB) {
|
return;
|
}
|
|
std::ostringstream query;
|
query << "DELETE FROM alarms WHERE end_time < datetime('now', '-" << daysToKeep << " days')";
|
|
if (!deviceId.empty()) {
|
query << " AND device_id = '" << deviceId << "'";
|
}
|
if (!unitId.empty()) {
|
query << " AND unit_id = '" << unitId << "'";
|
}
|
|
m_pDB->executeQuery(query.str());
|
}
|
|
// ͨ¹ýÉ豸ID»ñÈ¡É豸Ãû³Æ
|
std::string AlarmManager::getDeviceNameById(int deviceId) {
|
if (!m_pDB) {
|
return "";
|
}
|
|
std::ostringstream query;
|
query << "SELECT device_name FROM devices WHERE device_id = " << deviceId;
|
|
auto result = m_pDB->fetchResults(query.str());
|
if (result.empty()) {
|
return "";
|
}
|
|
return result[0][0]; // ·µ»Ø²éѯµ½µÄÉ豸Ãû³Æ
|
}
|
|
// ͨ¹ýÉ豸IDºÍµ¥ÔªID»ñÈ¡µ¥ÔªÃû³Æ
|
std::string AlarmManager::getUnitNameById(int deviceId, int unitId) {
|
if (!m_pDB) {
|
return "";
|
}
|
|
std::ostringstream query;
|
query << "SELECT unit_name FROM units WHERE device_id = " << deviceId
|
<< " AND unit_id = " << unitId;
|
|
auto result = m_pDB->fetchResults(query.str());
|
if (result.empty()) {
|
return "";
|
}
|
|
return result[0][0]; // ·µ»Ø²éѯµ½µÄµ¥ÔªÃû³Æ
|
}
|
|
// »ñÈ¡×î½ü²åÈëµÄ alarm_event_id
|
int AlarmManager::getLastInsertId() {
|
std::string query = "SELECT last_insert_rowid();";
|
auto results = m_pDB->fetchResults(query);
|
|
if (results.empty() || results[0].empty()) {
|
return -1;
|
}
|
|
// ´Ó²éѯ½á¹ûÖлñÈ¡×îºó²åÈëµÄ ID
|
int lastInsertId = std::stoi(results[0][0]);
|
return lastInsertId;
|
}
|
|
// ͨ¹ý alarm_event_id ½â³ý±¨¾¯£¨¸üнáÊøÊ±¼ä£©
|
bool AlarmManager::clearAlarmByEventId(int alarmEventId, const std::string& endTime) {
|
if (!m_pDB) {
|
return false;
|
}
|
|
bool result = true;
|
auto it = m_mapCache.find(alarmEventId);
|
if (it != m_mapCache.end()) {
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
std::ostringstream query;
|
query << "UPDATE alarms SET end_time = '" << endTime << "' WHERE alarm_event_id = " << alarmEventId << ";";
|
bool result = m_pDB->executeQuery(query.str());
|
if (result) {
|
m_mapCache.erase(it);
|
}
|
}
|
|
return result;
|
}
|
|
// ͨ¹ý¶à¸öÊôÐÔ²éÕÒ²¢½â³ý±¨¾¯£¨¸üнáÊøÊ±¼ä£©
|
bool AlarmManager::clearAlarmByAttributes(int nId, int nDeviceId, int nUnitId, const std::string& endTime) {
|
if (!m_pDB) {
|
return false;
|
}
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
// ÏÈÔÚ»º´æÖвéÕÒÆ¥ÅäµÄ alarm_event_id
|
int alarmEventId = -1;
|
for (AlarmDataMap::const_iterator it = m_mapCache.begin(); it != m_mapCache.end(); ++it) {
|
const AlarmData& alarm = it->second;
|
if (alarm.nId == nId &&
|
alarm.nDeviceId == nDeviceId &&
|
alarm.nUnitId == nUnitId) {
|
|
alarmEventId = it->first;
|
break;
|
}
|
}
|
|
// Èç¹ûûÕÒµ½Æ¥ÅäµÄ¼Ç¼£¬ÔòÖ±½Ó·µ»Ø false
|
if (alarmEventId == -1) {
|
return false;
|
}
|
|
// ¹¹½¨ SQL Óï¾ä£¬Ê¹ÓÃÕÒµ½µÄ alarm_event_id À´¸üнáÊøÊ±¼ä
|
std::ostringstream query;
|
query << "UPDATE alarms SET end_time = '" << endTime << "' WHERE alarm_event_id = " << alarmEventId << ";";
|
bool result = m_pDB->executeQuery(query.str());
|
if (result) {
|
m_mapCache.erase(alarmEventId);
|
}
|
|
return result;
|
}
|
|
// ¶ÁÈ¡±¨¾¯Îļþ
|
bool AlarmManager::readAlarmFile(const std::string& filename) {
|
std::ifstream file(filename);
|
std::string line;
|
bool first_line = true;
|
|
if (!file.is_open()) {
|
std::cerr << "Error opening file!" << std::endl;
|
return false;
|
}
|
|
while (std::getline(file, line)) {
|
if (first_line) {
|
first_line = false;
|
continue;
|
}
|
|
std::stringstream ss(line);
|
std::string cell;
|
AlarmInfo alarm;
|
|
std::getline(ss, cell, ',');
|
std::getline(ss, alarm.strUnitID, ',');
|
std::getline(ss, alarm.strUnitNo, ',');
|
std::getline(ss, cell, ',');
|
alarm.nAlarmLevel = std::stoi(cell);
|
std::getline(ss, cell, ',');
|
alarm.nAlarmCode = std::stoi(cell);
|
std::getline(ss, cell, ',');
|
alarm.nAlarmID = std::stoi(cell);
|
std::getline(ss, alarm.strAlarmText, ',');
|
std::getline(ss, alarm.strDescription, ',');
|
|
if (m_mapAlarm.find(alarm.nAlarmID) == m_mapAlarm.end()) {
|
m_mapAlarm[alarm.nAlarmID] = alarm;
|
}
|
else {
|
std::cerr << "Duplicate AlarmID: " << alarm.nAlarmID << std::endl;
|
}
|
}
|
|
file.close();
|
return true;
|
}
|
|
// ½«±¨¾¯Êý¾Ý±£´æµ½Îļþ
|
bool AlarmManager::saveAlarmFile(const std::string& filename) {
|
std::ofstream file(filename);
|
|
if (!file.is_open()) {
|
std::cerr << "´ò¿ªÎļþдÈëʧ°Ü!" << std::endl;
|
return false;
|
}
|
|
// дÈë±êÌâÐÐ
|
file << "No,UNIT ID,UNIT NO,Alarm Level,Alarm Code,AlarmID,Alarm Text,Description\n";
|
|
// дÈ뱨¾¯Êý¾Ý
|
int nIndex = 1;
|
for (const auto& pair : m_mapAlarm) {
|
const AlarmInfo& alarm = pair.second;
|
file << nIndex++ << ","
|
<< alarm.strUnitID << ","
|
<< alarm.strUnitNo << ","
|
<< alarm.nAlarmLevel << ","
|
<< alarm.nAlarmCode << ","
|
<< alarm.nAlarmID << ","
|
<< alarm.strAlarmText << ","
|
<< alarm.strDescription << "\n";
|
}
|
|
file.close();
|
return true;
|
}
|
|
// ͨ¹ý AlarmID ²éѯ¶ÔÓ¦µÄ±¨¾¯ÐÅÏ¢
|
const AlarmInfo* AlarmManager::getAlarmInfoByID(int nAlarmID) const {
|
auto it = m_mapAlarm.find(nAlarmID);
|
if (it != m_mapAlarm.end()) {
|
return &(it->second);
|
}
|
else {
|
std::cerr << "δÕÒµ½ AlarmID: " << nAlarmID << std::endl;
|
return nullptr;
|
}
|
}
|
|
// ͨ¹ý¶à¸ö AlarmID ²éѯ¶ÔÓ¦µÄ±¨¾¯ÐÅÏ¢
|
std::vector<AlarmInfo> AlarmManager::getAlarmsInfoByIDs(const std::vector<int>& alarmIDs) const {
|
std::vector<AlarmInfo> alarms;
|
|
for (int alarmID : alarmIDs) {
|
auto it = m_mapAlarm.find(alarmID);
|
if (it != m_mapAlarm.end()) {
|
alarms.push_back(it->second);
|
}
|
else {
|
std::cerr << "δÕÒµ½ AlarmID: " << alarmID << std::endl;
|
}
|
}
|
|
return alarms;
|
}
|