1
0
forked from BRT/arc
arc/database/dao/GeneralLogDAO.cpp
2026-04-08 15:43:59 +07:00

93 lines
3.8 KiB
C++

#include "GeneralLogDAO.h"
#include <QSqlQuery>
#include <QSqlError>
#include "DatabaseManager.h"
#include "time/DateUtils.h"
bool GeneralLogDAO::insert(const QString &level, const QString &source, const QString &message) {
return insert(level, source, message, {});
}
bool GeneralLogDAO::insert(const QString &level, const QString &source, const QString &message,
const QByteArray &screenshot) {
return insert(level, source, message, screenshot, {}, {});
}
bool GeneralLogDAO::insert(const QString &level, const QString &source, const QString &message,
const QByteArray &screenshot, const QString &requestBody,
const QString &responseBody) {
QSqlQuery q(DatabaseManager::instance().database());
q.prepare(R"(
INSERT INTO general_logs (level, source, message, timestamp, screenshot, request_body, response_body)
VALUES (:level, :source, :message, :timestamp, :screenshot, :request_body, :response_body)
)");
q.bindValue(":level", level);
q.bindValue(":source", source);
q.bindValue(":message", message);
q.bindValue(":timestamp", DateUtils::toUtcString(QDateTime::currentDateTimeUtc()));
q.bindValue(":screenshot", screenshot.isEmpty() ? QVariant(QMetaType(QMetaType::QByteArray)) : screenshot);
q.bindValue(":request_body", requestBody);
q.bindValue(":response_body", responseBody);
return q.exec();
}
static QString buildWhereClause(const QStringList &levels, int minutesBack = 0) {
QStringList conditions;
if (!levels.isEmpty()) {
QStringList placeholders;
for (int i = 0; i < levels.size(); ++i)
placeholders << QString(":lvl%1").arg(i);
conditions << "level IN (" + placeholders.join(',') + ")";
}
if (minutesBack > 0)
conditions << "timestamp >= :sinceTime";
if (conditions.isEmpty()) return {};
return " WHERE " + conditions.join(" AND ");
}
static void bindLevels(QSqlQuery &q, const QStringList &levels) {
for (int i = 0; i < levels.size(); ++i)
q.bindValue(QString(":lvl%1").arg(i), levels[i]);
}
QList<GeneralLogEntry> GeneralLogDAO::getLogs(int page, int pageSize, const QStringList &levels,
int minutesBack) {
QList<GeneralLogEntry> result;
QSqlQuery q(DatabaseManager::instance().database());
q.prepare(
"SELECT id, level, source, message, timestamp, screenshot, request_body, response_body FROM general_logs"
+ buildWhereClause(levels, minutesBack)
+ " ORDER BY id DESC LIMIT :limit OFFSET :offset"
);
bindLevels(q, levels);
if (minutesBack > 0)
q.bindValue(":sinceTime", DateUtils::toUtcString(
QDateTime::currentDateTimeUtc().addSecs(-minutesBack * 60)));
q.bindValue(":limit", pageSize);
q.bindValue(":offset", page * pageSize);
if (!q.exec()) return result;
while (q.next()) {
GeneralLogEntry e;
e.id = q.value("id").toInt();
e.level = q.value("level").toString();
e.source = q.value("source").toString();
e.message = q.value("message").toString();
e.timestamp = DateUtils::fromUtcString(q.value("timestamp").toString());
e.screenshot = q.value("screenshot").toByteArray();
e.requestBody = q.value("request_body").toString();
e.responseBody = q.value("response_body").toString();
result.append(e);
}
return result;
}
int GeneralLogDAO::getTotalCount(const QStringList &levels) {
QSqlQuery q(DatabaseManager::instance().database());
q.prepare("SELECT COUNT(*) FROM general_logs" + buildWhereClause(levels));
bindLevels(q, levels);
if (!q.exec() || !q.next()) return 0;
return q.value(0).toInt();
}