From 9cf279f5a3e698e81f7e02852d18261a67bbc400 Mon Sep 17 00:00:00 2001 From: Marti Raudsepp Date: Tue, 13 Mar 2012 16:32:44 +0200 Subject: [PATCH] Run database integrity check on startup Update issue #2743 Integrity check now run on startup --- src/core/application.cpp | 2 ++ src/core/database.cpp | 42 ++++++++++++++++++++++++++++++++++++++++ src/core/database.h | 4 ++++ 3 files changed, 48 insertions(+) diff --git a/src/core/application.cpp b/src/core/application.cpp index f29486e2d..53f9298ae 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -89,6 +89,8 @@ Application::Application(QObject* parent) library_->Init(); library_->StartThreads(); + + QMetaObject::invokeMethod(database_, "DoBackup", Qt::QueuedConnection); } Application::~Application() { diff --git a/src/core/database.cpp b/src/core/database.cpp index a825509cc..e6db70019 100644 --- a/src/core/database.cpp +++ b/src/core/database.cpp @@ -21,6 +21,7 @@ #include "utilities.h" #include "core/application.h" #include "core/logging.h" +#include "core/taskmanager.h" #include #include @@ -634,3 +635,44 @@ bool Database::CheckErrors(const QSqlQuery& query) { return false; } + +bool Database::IntegrityCheck(QSqlDatabase db) { + int task_id = app_->task_manager()->StartTask(tr("Integrity check")); + + bool ok = false; + bool error_reported = false; + // Ask for 10 error messages at most. + QSqlQuery q(QString("PRAGMA integrity_check(10)"), db); + while (q.next()) { + QString message = q.value(0).toString(); + + // If no errors are found, a single row with the value "ok" is returned + if (message == "ok") { + ok = true; + break; + } else { + if (!error_reported) { + app_->AddError(tr("Database corruption detected. Please read " + "https://code.google.com/p/clementine-player/wiki/DatabaseCorruption " + "for instructions on how to recover your database")); + } + app_->AddError("Database: " + message); + error_reported = true; + } + } + + app_->task_manager()->SetTaskFinished(task_id); + + return ok; +} + +void Database::DoBackup() { + QSqlDatabase db(this->Connect()); + + // Before we overwrite anything, make sure the database is not corrupt + const bool ok = IntegrityCheck(db); + + if (ok) { + // TODO: Run database backup... + } +} diff --git a/src/core/database.h b/src/core/database.h index 145eeddf2..628d57993 100644 --- a/src/core/database.h +++ b/src/core/database.h @@ -64,12 +64,16 @@ class Database : public QObject { signals: void Error(const QString& message); + private slots: + void DoBackup(); + private: void UpdateMainSchema(QSqlDatabase* db); void UpdateDatabaseSchema(int version, QSqlDatabase& db); void UrlEncodeFilenameColumn(const QString& table, QSqlDatabase& db); QStringList SongsTables(QSqlDatabase& db, int schema_version) const; + bool IntegrityCheck(QSqlDatabase db); struct AttachedDatabase { AttachedDatabase() {}