From 1e0fc92f2e2a6c2368c684f34b6d2223c1dda87a Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 29 Sep 2026 22:42:40 -0500 Subject: [PATCH] refactor(cdclient): FdbToSqlite can convert into a connection of its own So a worker can make a new CDServer.sqlite without touching the shared CDClient connection or the logger. Co-Authored-By: Claude Opus 5.5 --- dCommon/FdbToSqlite.cpp | 22 +++++++++++++++------- dCommon/FdbToSqlite.h | 20 +++++++++++++++++++- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/dCommon/FdbToSqlite.cpp b/dCommon/FdbToSqlite.cpp index 71f883136..1d9be54a8 100644 --- a/dCommon/FdbToSqlite.cpp +++ b/dCommon/FdbToSqlite.cpp @@ -28,21 +28,29 @@ FdbToSqlite::Convert::Convert(std::string binaryOutPath) { this->m_BinaryOutPath = binaryOutPath; } -bool FdbToSqlite::Convert::ConvertDatabase(AssetStream& buffer) { +FdbToSqlite::Convert::Convert(CppSQLite3DB& db) : m_Db(&db) {} + +void FdbToSqlite::Convert::ExecDML(const std::string& sql) { + if (m_Db) m_Db->execDML(sql.c_str()); + else CDClientDatabase::ExecuteDML(sql); +} + +bool FdbToSqlite::Convert::ConvertDatabase(std::istream& buffer) { if (m_ConversionStarted) return false; this->m_ConversionStarted = true; try { - CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite"); + if (!m_Db) CDClientDatabase::Connect(m_BinaryOutPath + "/CDServer.sqlite"); - CDClientDatabase::ExecuteQuery("BEGIN TRANSACTION;"); + ExecDML("BEGIN TRANSACTION;"); int32_t numberOfTables = ReadInt32(buffer); ReadTables(numberOfTables, buffer); - CDClientDatabase::ExecuteQuery("COMMIT;"); + ExecDML("COMMIT;"); } catch (CppSQLite3Exception& e) { - LOG("Encountered error %s converting FDB to SQLite", e.errorMessage()); + m_Error = e.errorMessage(); + if (!m_Db) LOG("Encountered error %s converting FDB to SQLite", e.errorMessage()); return false; } @@ -91,7 +99,7 @@ std::string FdbToSqlite::Convert::ReadColumnHeader(std::istream& cdClientBuffer) auto columns = ReadColumns(numberOfColumns, cdClientBuffer); std::string newTable = "CREATE TABLE IF NOT EXISTS '" + tableName + "' (" + columns + ");"; - CDClientDatabase::ExecuteDML(newTable); + ExecDML(newTable); cdClientBuffer.seekg(prevPosition); @@ -241,6 +249,6 @@ void FdbToSqlite::Convert::ReadRowValues(int32_t& numberOfColumns, std::string& insertedRow << ");"; auto copiedString = insertedRow.str(); - CDClientDatabase::ExecuteDML(copiedString); + ExecDML(copiedString); cdClientBuffer.seekg(prevPosition); } diff --git a/dCommon/FdbToSqlite.h b/dCommon/FdbToSqlite.h index b0d20aee3..c936467f5 100644 --- a/dCommon/FdbToSqlite.h +++ b/dCommon/FdbToSqlite.h @@ -11,6 +11,8 @@ enum class eSqliteDataType : int32_t; +#include "CppSQLite3.h" + namespace FdbToSqlite { class Convert { public: @@ -22,12 +24,21 @@ namespace FdbToSqlite { */ Convert(std::string binaryOutPath); + /** + * Converts into a connection of the caller's own instead of the shared CDClient one, so it can run on a + * worker thread. Nothing is logged; GetError says what went wrong. + */ + explicit Convert(CppSQLite3DB& db); + + // Why the last ConvertDatabase failed + [[nodiscard]] const std::string& GetError() const { return m_Error; } + /** * Converts the input file to sqlite. Calling multiple times is safe. * * @return true if the database was converted properly, false otherwise. */ - bool ConvertDatabase(AssetStream& buffer); + bool ConvertDatabase(std::istream& buffer); /** * @brief Reads a 32 bit int from the fdb file. @@ -139,6 +150,13 @@ namespace FdbToSqlite { * The path where the CDServer will be stored */ std::string m_BinaryOutPath{}; + + // The caller's own connection, or nullptr for the shared CDClient one + CppSQLite3DB* m_Db{}; + + std::string m_Error{}; + + void ExecDML(const std::string& sql); }; //! class FdbToSqlite }; //! namespace FdbToSqlite