Reorganized and cleaned up the solution.

This commit is contained in:
HikikoMarmy
2026-03-02 12:37:07 +00:00
parent 8012f30170
commit d4dfbddf69
175 changed files with 1516 additions and 1136 deletions

View File

@@ -0,0 +1,92 @@
#pragma once
#include <memory>
#include <mutex>
#include <string>
#include <tuple>
#include <chrono>
#include <map>
#include <sqlite3.h>
#include "Transaction.hpp"
#include "Game/RealmCharacter.hpp"
#include "Game/RealmCharacterMetaKV.hpp"
enum class QueryID {
CreateAccount,
VerifyAccount,
LoadAccount,
LoadCharacterSlots,
CreateNewCharacter,
SaveCharacter,
LoadCharacter,
SaveFriend,
RemoveFriend,
LoadFriendList,
SaveIgnore,
RemoveIgnore,
LoadIgnoreList,
};
class Database {
private:
static inline std::unique_ptr<Database> m_instance;
static inline std::mutex m_mutex;
sqlite3 *m_db = nullptr;
std::unordered_map< QueryID, sqlite3_stmt * > m_statements;
public:
static Database &Get()
{
std::lock_guard<std::mutex> lock( m_mutex );
if( !m_instance )
m_instance.reset( new Database() );
return *m_instance;
}
Database( const Database & ) = delete;
Database &operator=( const Database & ) = delete;
Database();
~Database();
public:
int64_t CreateNewAccount( const std::string &username,
const std::string &password,
const std::string &email_address,
const std::string &date_of_birth,
const std::string &chat_handle );
std::tuple< bool, int64_t, std::wstring > VerifyAccount( const std::wstring &username, const std::wstring &password );
uint32_t CreateNewCharacter( const int64_t account_id,
const CharacterSlotData meta,
const std::vector< uint8_t > &blob );
bool SaveCharacter( const int64_t account_id,
const int32_t character_id,
const CharacterSlotData meta,
const std::vector< uint8_t > &blob );
std::map< uint32_t, CharacterSlotData > LoadCharacterSlots( const int64_t account_id );
sptr_realm_character LoadCharacterData( const int64_t account_id, const int32_t character_id );
bool SaveFriend( const int64_t account_id, const std::wstring &friend_handle );
bool RemoveFriend( const int64_t account_id, const std::wstring &friend_handle );
std::vector< std::wstring > LoadFriends( const int64_t account_id );
bool SaveIgnore( const int64_t account_id, const std::wstring &ignore_handle );
bool RemoveIgnore( const int64_t account_id, const std::wstring &ignore_handle );
std::vector< std::wstring > LoadIgnores( const int64_t account_id );
private:
void CreateTables();
void PrepareStatements();
void FinalizeStatements();
void Execute( const char *sql );
};

View File

@@ -0,0 +1,68 @@
#pragma once
#include <sqlite3.h>
#include <stdexcept>
class SQLiteTransaction {
sqlite3 *m_db = nullptr;
bool m_committed = false;
public:
explicit SQLiteTransaction( sqlite3 *db )
: m_db( db )
{
if( !m_db )
throw std::invalid_argument( "Null SQLite database pointer" );
if( sqlite3_exec( m_db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr ) != SQLITE_OK )
throw std::runtime_error( "Failed to begin transaction: " + std::string( sqlite3_errmsg( m_db ) ) );
}
~SQLiteTransaction()
{
if( m_committed || !m_db )
return;
sqlite3_exec( m_db, "ROLLBACK;", nullptr, nullptr, nullptr );
}
SQLiteTransaction( const SQLiteTransaction & ) = delete;
SQLiteTransaction &operator=( const SQLiteTransaction & ) = delete;
SQLiteTransaction( SQLiteTransaction &&other ) noexcept
: m_db( other.m_db ), m_committed( other.m_committed )
{
other.m_db = nullptr;
}
SQLiteTransaction &operator=( SQLiteTransaction &&other ) noexcept
{
if( this != &other )
{
rollbackOnError();
m_db = other.m_db;
m_committed = other.m_committed;
other.m_db = nullptr;
}
return *this;
}
void commit()
{
if( m_committed || !m_db )
return;
if( sqlite3_exec( m_db, "COMMIT;", nullptr, nullptr, nullptr ) != SQLITE_OK )
throw std::runtime_error( "Failed to commit transaction: " + std::string( sqlite3_errmsg( m_db ) ) );
m_committed = true;
}
private:
void rollbackOnError()
{
if( m_committed || !m_db )
return;
sqlite3_exec( m_db, "ROLLBACK;", nullptr, nullptr, nullptr );
}
};