chatgui settings: add Database tab with integrity check (quick/full) and optimize
This commit is contained in:
1 parent
03310db2cd
commit
c4d1f984bd
8 files changed
+320
-12
No files matched your search
@@ -0,0 +1,204 @@
|
||||
// databasesettingspage.cpp — Database maintenance page in settings
|
||||
#include "databasesettingspage.h"
|
||||
#include "../db/db_manager.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QFormLayout>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QFileInfo>
|
||||
#include <QTimer>
|
||||
|
||||
DatabaseSettingsPage::DatabaseSettingsPage(DbManager* db, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_db(db)
|
||||
{
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
layout->setSpacing(10);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
auto* title = new QLabel("Database Maintenance", this);
|
||||
title->setStyleSheet("font-weight: bold; font-size: 13px;");
|
||||
layout->addWidget(title);
|
||||
|
||||
// --- DB info ---
|
||||
auto* infoLayout = new QFormLayout();
|
||||
infoLayout->setSpacing(4);
|
||||
|
||||
QString dbPath = "—";
|
||||
QString dbSize = "—";
|
||||
QString walSize = "—";
|
||||
if (m_db && m_db->m_db) {
|
||||
const char* fname = sqlite3_db_filename(m_db->m_db, "main");
|
||||
if (fname && fname[0]) {
|
||||
dbPath = QString::fromUtf8(fname);
|
||||
QFileInfo fi(dbPath);
|
||||
if (fi.exists()) {
|
||||
qint64 sz = fi.size();
|
||||
if (sz < 1024) dbSize = QString("%1 B").arg(sz);
|
||||
else if (sz < 1024 * 1024) dbSize = QString("%1 KB").arg(sz / 1024);
|
||||
else dbSize = QString("%1 MB").arg(sz / (1024.0 * 1024.0), 0, 'f', 2);
|
||||
}
|
||||
QFileInfo walFi(dbPath + "-wal");
|
||||
if (walFi.exists()) {
|
||||
qint64 wsz = walFi.size();
|
||||
if (wsz < 1024) walSize = QString("%1 B").arg(wsz);
|
||||
else if (wsz < 1024 * 1024) walSize = QString("%1 KB").arg(wsz / 1024);
|
||||
else walSize = QString("%1 MB").arg(wsz / (1024.0 * 1024.0), 0, 'f', 2);
|
||||
} else {
|
||||
walSize = "n/a";
|
||||
}
|
||||
}
|
||||
}
|
||||
m_filePathLabel = new QLabel(dbPath, this);
|
||||
m_filePathLabel->setStyleSheet("font-size: 11px; color: gray;");
|
||||
m_filePathLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
infoLayout->addRow("File:", m_filePathLabel);
|
||||
|
||||
m_fileSizeLabel = new QLabel(dbSize, this);
|
||||
m_fileSizeLabel->setStyleSheet("font-size: 11px;");
|
||||
infoLayout->addRow("Size:", m_fileSizeLabel);
|
||||
|
||||
m_walSizeLabel = new QLabel(walSize, this);
|
||||
m_walSizeLabel->setStyleSheet("font-size: 11px;");
|
||||
infoLayout->addRow("WAL:", m_walSizeLabel);
|
||||
|
||||
layout->addLayout(infoLayout);
|
||||
|
||||
// --- Separator ---
|
||||
auto* sep = new QFrame(this);
|
||||
sep->setFrameShape(QFrame::HLine);
|
||||
sep->setFrameShadow(QFrame::Sunken);
|
||||
layout->addWidget(sep);
|
||||
|
||||
// --- Buttons ---
|
||||
auto* btnLayout = new QVBoxLayout();
|
||||
btnLayout->setSpacing(6);
|
||||
|
||||
auto* quickRow = new QHBoxLayout();
|
||||
m_quickBtn = new QPushButton("Quick Check", this);
|
||||
m_quickBtn->setStyleSheet(
|
||||
"QPushButton { border: 1px solid palette(mid); border-radius: 4px;"
|
||||
" padding: 5px 14px; font-size: 12px; background: palette(button); }"
|
||||
"QPushButton:hover { background: palette(light); }");
|
||||
connect(m_quickBtn, &QPushButton::clicked, this, &DatabaseSettingsPage::onQuickCheck);
|
||||
quickRow->addWidget(m_quickBtn);
|
||||
auto* quickDesc = new QLabel("Scans structure without verifying indexes (fast)", this);
|
||||
quickDesc->setStyleSheet("color: gray; font-size: 11px;");
|
||||
quickRow->addWidget(quickDesc, 1);
|
||||
btnLayout->addLayout(quickRow);
|
||||
|
||||
auto* fullRow = new QHBoxLayout();
|
||||
m_fullBtn = new QPushButton("Full Check", this);
|
||||
m_fullBtn->setStyleSheet(m_quickBtn->styleSheet());
|
||||
connect(m_fullBtn, &QPushButton::clicked, this, &DatabaseSettingsPage::onFullCheck);
|
||||
fullRow->addWidget(m_fullBtn);
|
||||
auto* fullDesc = new QLabel("Verifies all data structures and indexes (thorough)", this);
|
||||
fullDesc->setStyleSheet("color: gray; font-size: 11px;");
|
||||
fullRow->addWidget(fullDesc, 1);
|
||||
btnLayout->addLayout(fullRow);
|
||||
|
||||
auto* optRow = new QHBoxLayout();
|
||||
m_optimizeBtn = new QPushButton("Optimize", this);
|
||||
m_optimizeBtn->setStyleSheet(m_quickBtn->styleSheet());
|
||||
connect(m_optimizeBtn, &QPushButton::clicked, this, &DatabaseSettingsPage::onOptimize);
|
||||
optRow->addWidget(m_optimizeBtn);
|
||||
auto* optDesc = new QLabel("Update query planner statistics for better performance", this);
|
||||
optDesc->setStyleSheet("color: gray; font-size: 11px;");
|
||||
optRow->addWidget(optDesc, 1);
|
||||
btnLayout->addLayout(optRow);
|
||||
|
||||
layout->addLayout(btnLayout);
|
||||
|
||||
// --- Status ---
|
||||
m_statusLabel = new QLabel("", this);
|
||||
m_statusLabel->setStyleSheet("font-size: 12px; margin-top: 4px;");
|
||||
layout->addWidget(m_statusLabel);
|
||||
|
||||
// --- Results ---
|
||||
m_resultText = new QPlainTextEdit(this);
|
||||
m_resultText->setReadOnly(true);
|
||||
m_resultText->setMaximumHeight(120);
|
||||
m_resultText->setStyleSheet(
|
||||
"QPlainTextEdit { font-family: monospace; font-size: 11px;"
|
||||
" background: palette(base); border: 1px solid palette(mid); border-radius: 4px;"
|
||||
" padding: 4px; }");
|
||||
m_resultText->setPlaceholderText("Run a check to see results...");
|
||||
layout->addWidget(m_resultText);
|
||||
|
||||
layout->addStretch();
|
||||
}
|
||||
|
||||
void DatabaseSettingsPage::setBusy(bool busy) {
|
||||
m_quickBtn->setEnabled(!busy);
|
||||
m_fullBtn->setEnabled(!busy);
|
||||
m_optimizeBtn->setEnabled(!busy);
|
||||
if (busy) {
|
||||
m_statusLabel->setText("Checking...");
|
||||
m_statusLabel->setStyleSheet("font-size: 12px; margin-top: 4px; color: gray;");
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseSettingsPage::onQuickCheck() {
|
||||
if (!m_db || !m_db->m_db) {
|
||||
m_statusLabel->setText("Database not open");
|
||||
m_statusLabel->setStyleSheet("font-size: 12px; color: red;");
|
||||
return;
|
||||
}
|
||||
setBusy(true);
|
||||
QTimer::singleShot(50, this, [this]() {
|
||||
IntegrityResult r = m_db->integrityCheckQuick();
|
||||
showResult("Quick Check", r);
|
||||
});
|
||||
}
|
||||
|
||||
void DatabaseSettingsPage::onFullCheck() {
|
||||
if (!m_db || !m_db->m_db) {
|
||||
m_statusLabel->setText("Database not open");
|
||||
m_statusLabel->setStyleSheet("font-size: 12px; color: red;");
|
||||
return;
|
||||
}
|
||||
setBusy(true);
|
||||
QTimer::singleShot(50, this, [this]() {
|
||||
IntegrityResult r = m_db->integrityCheckFull();
|
||||
showResult("Full Check", r);
|
||||
});
|
||||
}
|
||||
|
||||
void DatabaseSettingsPage::onOptimize() {
|
||||
if (!m_db || !m_db->m_db) {
|
||||
m_statusLabel->setText("Database not open");
|
||||
m_statusLabel->setStyleSheet("font-size: 12px; color: red;");
|
||||
return;
|
||||
}
|
||||
setBusy(true);
|
||||
QTimer::singleShot(50, this, [this]() {
|
||||
IntegrityResult r = m_db->integrityOptimize();
|
||||
showResult("Optimize", r);
|
||||
});
|
||||
}
|
||||
|
||||
void DatabaseSettingsPage::showResult(const QString& checkName, const IntegrityResult& result) {
|
||||
m_quickBtn->setEnabled(true);
|
||||
m_fullBtn->setEnabled(true);
|
||||
m_optimizeBtn->setEnabled(true);
|
||||
|
||||
if (result.ok) {
|
||||
m_statusLabel->setText(QString("%1: OK (%2 ms)")
|
||||
.arg(checkName).arg(result.elapsedMs));
|
||||
m_statusLabel->setStyleSheet("font-size: 12px; font-weight: bold; color: green;");
|
||||
} else {
|
||||
m_statusLabel->setText(QString("%1: FAILED (%2 ms)")
|
||||
.arg(checkName).arg(result.elapsedMs));
|
||||
m_statusLabel->setStyleSheet("font-size: 12px; font-weight: bold; color: red;");
|
||||
}
|
||||
|
||||
if (result.errors.isEmpty()) {
|
||||
m_resultText->setPlainText(result.message.isEmpty() ? "ok" : result.message);
|
||||
} else {
|
||||
QStringList lines;
|
||||
lines.append(result.message);
|
||||
lines.append(result.errors);
|
||||
m_resultText->setPlainText(lines.join('\n'));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user