Skip to content

Commit 727e6b2

Browse files
committed
Implement SQLiteDatabase::Verify
1 parent b4df8fd commit 727e6b2

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

src/wallet/sqlite.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,44 @@ void SQLiteDatabase::Cleanup() noexcept
109109
}
110110
}
111111

112+
bool SQLiteDatabase::Verify(bilingual_str& error)
113+
{
114+
assert(m_db);
115+
116+
sqlite3_stmt* stmt{nullptr};
117+
ret = sqlite3_prepare_v2(m_db, "PRAGMA integrity_check", -1, &stmt, nullptr);
118+
if (ret != SQLITE_OK) {
119+
sqlite3_finalize(stmt);
120+
error = strprintf(_("SQLiteDatabase: Failed to prepare statement to verify database: %s"), sqlite3_errstr(ret));
121+
return false;
122+
}
123+
while (true) {
124+
ret = sqlite3_step(stmt);
125+
if (ret == SQLITE_DONE) {
126+
break;
127+
}
128+
if (ret != SQLITE_ROW) {
129+
error = strprintf(_("SQLiteDatabase: Failed to execute statement to verify database: %s"), sqlite3_errstr(ret));
130+
break;
131+
}
132+
const char* msg = (const char*)sqlite3_column_text(stmt, 0);
133+
if (!msg) {
134+
error = strprintf(_("SQLiteDatabase: Failed to read database verification error: %s"), sqlite3_errstr(ret));
135+
break;
136+
}
137+
std::string str_msg(msg);
138+
if (str_msg == "ok") {
139+
continue;
140+
}
141+
if (error.empty()) {
142+
error = _("Failed to verify database") + Untranslated("\n");
143+
}
144+
error += Untranslated(strprintf("%s\n", str_msg));
145+
}
146+
sqlite3_finalize(stmt);
147+
return error.empty();
148+
}
149+
112150
void SQLiteDatabase::Open()
113151
{
114152
int flags = SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
@@ -468,7 +506,19 @@ bool ExistsSQLiteDatabase(const fs::path& path)
468506

469507
std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)
470508
{
471-
return MakeUnique<SQLiteDatabase>(path, path / DATABASE_FILENAME);
509+
const fs::path file = path / DATABASE_FILENAME;
510+
try {
511+
auto db = MakeUnique<SQLiteDatabase>(path, file);
512+
if (options.verify && !db->Verify(error)) {
513+
status = DatabaseStatus::FAILED_VERIFY;
514+
return nullptr;
515+
}
516+
return db;
517+
} catch (const std::runtime_error& e) {
518+
status = DatabaseStatus::FAILED_LOAD;
519+
error.original = e.what();
520+
return nullptr;
521+
}
472522
}
473523

474524
std::string SQLiteDatabaseVersion()

src/wallet/sqlite.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class SQLiteDatabase : public WalletDatabase
7171

7272
~SQLiteDatabase();
7373

74+
bool Verify(bilingual_str& error);
75+
7476
/** Open the database if it is not already opened */
7577
void Open() override;
7678

0 commit comments

Comments
 (0)