@@ -109,6 +109,44 @@ void SQLiteDatabase::Cleanup() noexcept
109
109
}
110
110
}
111
111
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
+
112
150
void SQLiteDatabase::Open ()
113
151
{
114
152
int flags = SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
@@ -468,7 +506,19 @@ bool ExistsSQLiteDatabase(const fs::path& path)
468
506
469
507
std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase (const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)
470
508
{
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
+ }
472
522
}
473
523
474
524
std::string SQLiteDatabaseVersion ()
0 commit comments