diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-07-11 12:30:22 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-07-11 12:30:22 -0300 |
| commit | ac41dc912dbdee28a01a4db0404bdb363d5530dc (patch) | |
| tree | 30b026b1cfa17fa1e6b9650184ae20503f3d7f5f | |
| parent | 3ab6d1d312e2b1ecbd858be56bd7a5d6bc451a85 (diff) | |
| download | querymanager-ac41dc912dbdee28a01a4db0404bdb363d5530dc.tar.gz querymanager-ac41dc912dbdee28a01a4db0404bdb363d5530dc.zip | |
add `TransactionScope`
| -rw-r--r-- | src/connections.cc | 27 | ||||
| -rw-r--r-- | src/database.cc | 101 | ||||
| -rw-r--r-- | src/querymanager.hh | 19 |
3 files changed, 105 insertions, 42 deletions
diff --git a/src/connections.cc b/src/connections.cc index b2b3daf..cfb0a01 100644 --- a/src/connections.cc +++ b/src/connections.cc @@ -623,9 +623,11 @@ void ProcessInsertHousesQuery(TConnection *Connection, TReadBuffer *Buffer){ return; } - // TODO(fusion): Have some TransactionGuard type that will either commit or - // rollback a transaction when we leave its scope, based on whether some - // `Commit` function was called. + TransactionScope Tx("UpdateHouses"); + if(!Tx.Begin()){ + SendQueryStatusFailed(Connection); + return; + } if(!DeleteHouses(Connection->WorldID)){ SendQueryStatusFailed(Connection); @@ -654,6 +656,11 @@ void ProcessInsertHousesQuery(TConnection *Connection, TReadBuffer *Buffer){ } } + if(!Tx.Commit()){ + SendQueryStatusFailed(Connection); + return; + } + SendQueryStatusOk(Connection); } @@ -680,9 +687,12 @@ void ProcessCreatePlayerlistQuery(TConnection *Connection, TReadBuffer *Buffer){ return; } - // TODO(fusion): Have some TransactionGuard type that will either commit or - // rollback a transaction when we leave its scope, based on whether some - // `Commit` function was called. + + TransactionScope Tx("OnlineList"); + if(!Tx.Begin()){ + SendQueryStatusFailed(Connection); + return; + } if(!DeleteOnlineCharacters(Connection->WorldID)){ SendQueryStatusFailed(Connection); @@ -710,6 +720,11 @@ void ProcessCreatePlayerlistQuery(TConnection *Connection, TReadBuffer *Buffer){ } } + if(!Tx.Commit()){ + SendQueryStatusFailed(Connection); + return; + } + TWriteBuffer WriteBuffer = PrepareResponse(Connection, QUERY_STATUS_OK); WriteBuffer.WriteFlag(NewRecord); SendResponse(Connection, &WriteBuffer); diff --git a/src/database.cc b/src/database.cc index 429f357..1064547 100644 --- a/src/database.cc +++ b/src/database.cc @@ -98,6 +98,49 @@ void ExitStatementCache(void){ } } +// TransactionScope +//============================================================================== +TransactionScope::TransactionScope(const char *Context){ + m_Context = (Context != NULL ? Context : "NOCONTEXT"); + m_Running = false; +} + +TransactionScope::~TransactionScope(void){ + if(m_Running && !ExecInternal("ROLLBACK")){ + LOG_ERR("Failed to rollback transaction (%s)", m_Context); + } +} + +bool TransactionScope::Begin(void){ + if(m_Running){ + LOG_ERR("Transaction (%s) already running", m_Context); + return false; + } + + if(!ExecInternal("BEGIN")){ + LOG_ERR("Failed to begin transaction (%s)", m_Context); + return false; + } + + m_Running = true; + return true; +} + +bool TransactionScope::Commit(void){ + if(!m_Running){ + LOG_ERR("Transaction (%s) not running", m_Context); + return false; + } + + if(!ExecInternal("COMMIT")){ + LOG_ERR("Failed to commit transaction (%s)", m_Context); + return false; + } + + m_Running = false; + return true; +} + // Queries //============================================================================== bool LoadWorldID(const char *WorldName, int *WorldID){ @@ -467,7 +510,6 @@ bool ExecFile(const char *FileName){ return Result; } -bool ExecInternal(const char *Format, ...) ATTR_PRINTF(1, 2); bool ExecInternal(const char *Format, ...){ va_list ap; va_start(ap, Format); @@ -510,38 +552,31 @@ bool GetPragmaInt(const char *Name, int *OutValue){ } bool InitDatabaseSchema(void){ - bool Result = true; - - if(Result && !ExecInternal("BEGIN")){ - LOG_ERR("Failed to start schema transaction"); - Result = false; + TransactionScope Tx("SchemaInit"); + if(!Tx.Begin()){ + return false; } - if(Result && !ExecFile("sql/schema.sql")){ + if(!ExecFile("sql/schema.sql")){ LOG_ERR("Failed to execute \"sql/schema.sql\""); - Result = false; + return false; } - if(Result && !ExecInternal("PRAGMA application_id = %d", g_ApplicationID)){ + if(!ExecInternal("PRAGMA application_id = %d", g_ApplicationID)){ LOG_ERR("Failed to set application id"); - Result = false; + return false; } - if(Result && !ExecInternal("PRAGMA user_version = 1")){ + if(!ExecInternal("PRAGMA user_version = 1")){ LOG_ERR("Failed to set user version"); - Result = false; - } - - if(Result && !ExecInternal("COMMIT")){ - LOG_ERR("Failed to commit schema transaction"); - Result = false; + return false; } - if(!Result && !ExecInternal("ROLLBACK")){ - LOG_ERR("Failed to rollback schema transaction"); + if(!Tx.Commit()){ + return false; } - return Result; + return true; } bool UpgradeDatabaseSchema(int UserVersion){ @@ -556,40 +591,34 @@ bool UpgradeDatabaseSchema(int UserVersion){ } } - bool Result = true; if(UserVersion != NewVersion){ LOG("Upgrading database schema to version %d", NewVersion); - if(Result && !ExecInternal("BEGIN")){ - LOG_ERR("Failed to start upgrade transaction"); - Result = false; + TransactionScope Tx("SchemaUpgrade"); + if(!Tx.Begin()){ + return false; } - while(Result && UserVersion < NewVersion){ + while(UserVersion < NewVersion){ snprintf(FileName, sizeof(FileName), "upgrade-%d.sql", UserVersion); if(!ExecFile(FileName)){ LOG_ERR("Failed to execute \"%s\"", FileName); - Result = false; + return false; } UserVersion += 1; } - if(Result && !ExecInternal("PRAGMA user_version = %d", UserVersion)){ + if(!ExecInternal("PRAGMA user_version = %d", UserVersion)){ LOG_ERR("Failed to set user version"); - Result = false; - } - - if(Result && !ExecInternal("COMMIT")){ - LOG_ERR("Failed to commit upgrade transaction"); - Result = false; + return false; } - if(!Result && !ExecInternal("ROLLBACK")){ - LOG_ERR("Failed to rollback upgrade transaction"); + if(!Tx.Commit()){ + return false; } } - return Result; + return true; } bool CheckDatabaseSchema(void){ diff --git a/src/querymanager.hh b/src/querymanager.hh index 2eab216..ad8c78b 100644 --- a/src/querymanager.hh +++ b/src/querymanager.hh @@ -688,6 +688,18 @@ struct TWorldConfig{ int PremiumNewbieBuffer; }; +struct TransactionScope{ +private: + const char *m_Context; + bool m_Running; + +public: + TransactionScope(const char *Context); + ~TransactionScope(void); + bool Begin(void); + bool Commit(void); +}; + bool LoadWorldID(const char *WorldName, int *WorldID); //bool DecrementIsOnline(int WorldID, int CharacterID); bool LoadHouseOwners(int WorldID, DynamicArray<THouseOwner> *HouseOwners); @@ -701,6 +713,13 @@ bool LoadCharacterIndex(int WorldID, int MinimumCharacterID, int MaxEntries, int *NumEntries, TCharacterIndexEntry *Entries); bool LoadWorldConfig(int WorldID, TWorldConfig *WorldConfig); +bool FileExists(const char *FileName); +bool ExecFile(const char *FileName); +bool ExecInternal(const char *Format, ...) ATTR_PRINTF(1, 2); +bool GetPragmaInt(const char *Name, int *OutValue); +bool InitDatabaseSchema(void); +bool UpgradeDatabaseSchema(int UserVersion); +bool CheckDatabaseSchema(void); bool InitDatabase(void); void ExitDatabase(void); |
