feat(cdclient): make a new CDServer.sqlite off-thread and swap tables in place

CDClientSnapshot converts a copy of the client's fdb into its own
CDServer-<hash>.sqlite with the cdserver migrations applied, on its own
connection. CDClientDatabase::Reconnect opens the new file before letting go
of the old one; CDClientManager::Reload empties every table (old entries kept
alive so references from spawned objects stay valid), retires the old fdb view
and loads again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 22:50:20 -05:00
parent 1e0fc92f2e
commit 27a4564fec
13 changed files with 390 additions and 2 deletions

View File

@@ -67,6 +67,23 @@ void CDClientDatabase::Connect(const std::string& filename) {
sqlite3_trace_v2(conn->handle(), SQLITE_TRACE_STMT | SQLITE_TRACE_PROFILE, Trace, nullptr);
}
void CDClientDatabase::Reconnect(const std::string& filename) {
auto* next = new CppSQLite3DB();
try {
next->open(filename.c_str());
} catch (...) {
delete next;
throw;
}
sqlite3_trace_v2(next->handle(), SQLITE_TRACE_STMT | SQLITE_TRACE_PROFILE, Trace, nullptr);
g_Running.clear();
auto* old = std::exchange(conn, next);
isConnected = true;
// close_v2 waits for statements still open on the old file (a query a caller holds) before it really closes. The
// wrapper is left behind on purpose: its destructor would close the handle a second time
sqlite3_close_v2(old->handle());
}
//! Queries the CDClient
CppSQLite3Query CDClientDatabase::ExecuteQuery(const std::string& query) {
return conn->execQuery(query.c_str());