aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/connections.cc27
-rw-r--r--src/database.cc101
-rw-r--r--src/querymanager.hh19
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);