#include "stdafx.h"
|
#include "AlarmManager.h"
|
#include <sstream>
|
#include <fstream>
|
#include <iostream>
|
#include <stdexcept>
|
#include <ctime>
|
|
// ³£Á¿
|
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 createTableQuery = R"(
|
CREATE TABLE IF NOT EXISTS alarms (
|
id TEXT NOT NULL,
|
device_name TEXT NOT NULL,
|
description TEXT NOT NULL,
|
start_time DATETIME NOT NULL,
|
end_time DATETIME NOT NULL
|
)
|
)";
|
|
return m_pDB->executeQuery(createTableQuery);
|
}
|
|
// Ïú»Ù±¨¾¯±í
|
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);
|
}
|
|
// Ìí¼Ó±¨¾¯
|
bool AlarmManager::addAlarm(const std::string& id, const std::string& deviceName, const std::string& description, const std::string& startTime, const std::string& endTime) {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "INSERT INTO alarms (id, device_name, description, start_time, end_time) VALUES ("
|
<< "'" << id << "', "
|
<< "'" << deviceName << "', "
|
<< "'" << description << "', "
|
<< "'" << startTime << "', "
|
<< "'" << endTime << "')";
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
return m_pDB->executeQuery(query.str());
|
}
|
|
// ²éѯËùÓб¨¾¯Êý¾Ý
|
std::vector<std::vector<std::string>> AlarmManager::getAllAlarms() {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
const std::string query = "SELECT id, device_name, description, start_time, end_time FROM alarms";
|
return m_pDB->fetchResults(query);
|
}
|
|
// ¸ù¾Ý±¨¾¯ID²éѯ±¨¾¯
|
std::vector<std::vector<std::string>> AlarmManager::getAlarmsById(const std::string& id) {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE id = '" << id << "'";
|
return m_pDB->fetchResults(query.str());
|
}
|
|
// ¸ù¾ÝÃèÊö²éѯ±¨¾¯
|
std::vector<std::vector<std::string>> AlarmManager::getAlarmsByDescription(const std::string& description) {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE description LIKE '%" << description << "%'";
|
return m_pDB->fetchResults(query.str());
|
}
|
|
// ¸ù¾Ýʱ¼ä·¶Î§²éѯ±¨¾¯
|
std::vector<std::vector<std::string>> AlarmManager::getAlarmsByTimeRange(
|
const std::string& startTime, const std::string& endTime) {
|
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE 1=1";
|
|
if (!startTime.empty()) {
|
query << " AND start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND end_time <= '" << endTime << "'";
|
}
|
|
return m_pDB->fetchResults(query.str());
|
}
|
|
// ¸ù¾ÝID¡¢¿ªÊ¼Ê±¼äºÍ½áÊøÊ±¼ä²éѯ±¨¾¯
|
std::vector<std::vector<std::string>> AlarmManager::getAlarmsByIdAndTimeRange(
|
const std::string& id, const std::string& startTime, const std::string& endTime) {
|
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE id = '" << id << "'";
|
|
if (!startTime.empty()) {
|
query << " AND start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND end_time <= '" << endTime << "'";
|
}
|
|
return m_pDB->fetchResults(query.str());
|
}
|
|
// ·ÖÒ³²éѯ±¨¾¯Êý¾Ý
|
std::vector<std::vector<std::string>> AlarmManager::getAlarms(int startPosition, int count) {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "SELECT id, device_name, description, start_time, end_time FROM alarms LIMIT " << count << " OFFSET " << startPosition;
|
return m_pDB->fetchResults(query.str());
|
}
|
|
// ɸѡ±¨¾¯Êý¾Ý
|
std::vector<std::vector<std::string>> AlarmManager::getFilteredAlarms(
|
const std::string& id,
|
const std::string& deviceName,
|
const std::string& description,
|
const std::string& startTime,
|
const std::string& endTime,
|
int pageNumber,
|
int pageSize) {
|
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "SELECT id, device_name, description, start_time, end_time FROM alarms WHERE 1=1";
|
|
if (!id.empty()) {
|
query << " AND id = '" << id << "'";
|
}
|
if (!deviceName.empty()) {
|
query << " AND device_name LIKE '%" << deviceName << "%'";
|
}
|
if (!description.empty()) {
|
query << " AND description LIKE '%" << description << "%'";
|
}
|
if (!startTime.empty()) {
|
query << " AND start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND end_time <= '" << endTime << "'";
|
}
|
|
int offset = (pageNumber - 1) * pageSize;
|
query << " ORDER BY start_time DESC LIMIT " << pageSize << " OFFSET " << offset;
|
|
return m_pDB->fetchResults(query.str());
|
}
|
|
// »ñÈ¡·ûºÏÌõ¼þµÄ±¨¾¯×ÜÊý
|
int AlarmManager::getTotalAlarmCount(
|
const std::string& id,
|
const std::string& deviceName,
|
const std::string& description,
|
const std::string& startTime,
|
const std::string& endTime) {
|
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "SELECT COUNT(*) FROM alarms WHERE 1=1";
|
|
if (!id.empty()) {
|
query << " AND id = '" << id << "'";
|
}
|
if (!deviceName.empty()) {
|
query << " AND device_name LIKE '%" << deviceName << "%'";
|
}
|
if (!description.empty()) {
|
query << " AND description LIKE '%" << description << "%'";
|
}
|
if (!startTime.empty()) {
|
query << " AND start_time >= '" << startTime << "'";
|
}
|
if (!endTime.empty()) {
|
query << " AND 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& deviceName, const std::string& description, const std::string& startTime, const std::string& newEndTime) {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "UPDATE alarms SET end_time = '" << newEndTime << "'"
|
<< " WHERE id = '" << id << "'"
|
<< " AND device_name = '" << deviceName << "'"
|
<< " AND description = '" << description << "'"
|
<< " AND start_time = '" << startTime << "'";
|
|
return m_pDB->executeQuery(query.str());
|
}
|
|
// ÇåÀí¾É±¨¾¯Êý¾Ý
|
void AlarmManager::cleanOldAlarms(int daysToKeep, const std::string& deviceName) {
|
if (!m_pDB) {
|
throw std::runtime_error("Database connection is not set.");
|
}
|
|
std::ostringstream query;
|
query << "DELETE FROM alarms WHERE end_time < datetime('now', '-" << daysToKeep << " days')";
|
|
if (!deviceName.empty()) {
|
query << " AND device_name = '" << deviceName << "'";
|
}
|
m_pDB->executeQuery(query.str());
|
}
|
|
// ¶ÁÈ¡±¨¾¯Îļþ
|
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;
|
}
|