diff options
author | Andrew Chow <achow101-github@achow101.com> | 2020-05-26 20:54:00 -0400 |
---|---|---|
committer | Andrew Chow <achow101-github@achow101.com> | 2020-10-14 11:28:18 -0400 |
commit | 727e6b2a4ee5abb7f2dcbc9f7778291908dc28ad (patch) | |
tree | 60112fd51a448130edc2b4533c2ce5837a411def /src/wallet | |
parent | b4df8fdb19fcded7e6d491ecf0b705cac0ec76a1 (diff) |
Implement SQLiteDatabase::Verify
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/sqlite.cpp | 52 | ||||
-rw-r--r-- | src/wallet/sqlite.h | 2 |
2 files changed, 53 insertions, 1 deletions
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp index f9c4dfb2a5..bfdd859162 100644 --- a/src/wallet/sqlite.cpp +++ b/src/wallet/sqlite.cpp @@ -109,6 +109,44 @@ void SQLiteDatabase::Cleanup() noexcept } } +bool SQLiteDatabase::Verify(bilingual_str& error) +{ + assert(m_db); + + sqlite3_stmt* stmt{nullptr}; + ret = sqlite3_prepare_v2(m_db, "PRAGMA integrity_check", -1, &stmt, nullptr); + if (ret != SQLITE_OK) { + sqlite3_finalize(stmt); + error = strprintf(_("SQLiteDatabase: Failed to prepare statement to verify database: %s"), sqlite3_errstr(ret)); + return false; + } + while (true) { + ret = sqlite3_step(stmt); + if (ret == SQLITE_DONE) { + break; + } + if (ret != SQLITE_ROW) { + error = strprintf(_("SQLiteDatabase: Failed to execute statement to verify database: %s"), sqlite3_errstr(ret)); + break; + } + const char* msg = (const char*)sqlite3_column_text(stmt, 0); + if (!msg) { + error = strprintf(_("SQLiteDatabase: Failed to read database verification error: %s"), sqlite3_errstr(ret)); + break; + } + std::string str_msg(msg); + if (str_msg == "ok") { + continue; + } + if (error.empty()) { + error = _("Failed to verify database") + Untranslated("\n"); + } + error += Untranslated(strprintf("%s\n", str_msg)); + } + sqlite3_finalize(stmt); + return error.empty(); +} + void SQLiteDatabase::Open() { int flags = SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; @@ -468,7 +506,19 @@ bool ExistsSQLiteDatabase(const fs::path& path) std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error) { - return MakeUnique<SQLiteDatabase>(path, path / DATABASE_FILENAME); + const fs::path file = path / DATABASE_FILENAME; + try { + auto db = MakeUnique<SQLiteDatabase>(path, file); + if (options.verify && !db->Verify(error)) { + status = DatabaseStatus::FAILED_VERIFY; + return nullptr; + } + return db; + } catch (const std::runtime_error& e) { + status = DatabaseStatus::FAILED_LOAD; + error.original = e.what(); + return nullptr; + } } std::string SQLiteDatabaseVersion() diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h index dca6560abb..c6a3f7f503 100644 --- a/src/wallet/sqlite.h +++ b/src/wallet/sqlite.h @@ -71,6 +71,8 @@ public: ~SQLiteDatabase(); + bool Verify(bilingual_str& error); + /** Open the database if it is not already opened */ void Open() override; |