Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/sqlite.cpp
Show First 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | if (--g_sqlite_count == 0) { | ||||
int ret = sqlite3_shutdown(); | int ret = sqlite3_shutdown(); | ||||
if (ret != SQLITE_OK) { | if (ret != SQLITE_OK) { | ||||
LogPrintf("SQLiteDatabase: Failed to shutdown SQLite: %s\n", | LogPrintf("SQLiteDatabase: Failed to shutdown SQLite: %s\n", | ||||
sqlite3_errstr(ret)); | sqlite3_errstr(ret)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
bool SQLiteDatabase::Verify(bilingual_str &error) { | |||||
assert(m_db); | |||||
sqlite3_stmt *stmt{nullptr}; | |||||
int 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() { | void SQLiteDatabase::Open() { | ||||
int flags = | int flags = | ||||
SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; | ||||
if (m_mock) { | if (m_mock) { | ||||
// In memory database for mock db | // In memory database for mock db | ||||
flags |= SQLITE_OPEN_MEMORY; | flags |= SQLITE_OPEN_MEMORY; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 416 Lines • ▼ Show 20 Lines | |||||
bool ExistsSQLiteDatabase(const fs::path &path) { | bool ExistsSQLiteDatabase(const fs::path &path) { | ||||
return false; | return false; | ||||
} | } | ||||
std::unique_ptr<SQLiteDatabase> | std::unique_ptr<SQLiteDatabase> | ||||
MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, | MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, | ||||
DatabaseStatus &status, bilingual_str &error) { | DatabaseStatus &status, bilingual_str &error) { | ||||
return std::make_unique<SQLiteDatabase>(path, path / DATABASE_FILENAME); | const fs::path file = path / DATABASE_FILENAME; | ||||
try { | |||||
auto db = std::make_unique<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() { | std::string SQLiteDatabaseVersion() { | ||||
return std::string(sqlite3_libversion()); | return std::string(sqlite3_libversion()); | ||||
} | } |