add TransactionScope
This commit is contained in:
parent
3ab6d1d312
commit
ac41dc912d
@ -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);
|
||||
|
||||
101
src/database.cc
101
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Result && !ExecInternal("COMMIT")){
|
||||
LOG_ERR("Failed to commit schema transaction");
|
||||
Result = false;
|
||||
if(!Tx.Commit()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Result && !ExecInternal("ROLLBACK")){
|
||||
LOG_ERR("Failed to rollback schema transaction");
|
||||
}
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Result && !ExecInternal("COMMIT")){
|
||||
LOG_ERR("Failed to commit upgrade transaction");
|
||||
Result = false;
|
||||
}
|
||||
|
||||
if(!Result && !ExecInternal("ROLLBACK")){
|
||||
LOG_ERR("Failed to rollback upgrade transaction");
|
||||
if(!Tx.Commit()){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckDatabaseSchema(void){
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user