@@ -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+
112150void 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
469507std::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
474524std::string SQLiteDatabaseVersion ()
0 commit comments