Skip to content

Commit

Permalink
Improve Database API to avoid memory leaks in the future, part 3.
Browse files Browse the repository at this point in the history
This commit reworks SqlQueryHolder to return a unique_ptr instead of a
raw pointer to the query's result in its API.

It also fixes a memory leak in Player::_LoadForgottenSkills() because
the incoming query result was not deleted.
  • Loading branch information
evil-at-wow committed Oct 21, 2023
1 parent af2a4f8 commit b634d26
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 155 deletions.
11 changes: 6 additions & 5 deletions src/framework/Utilities/Callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define MANGOS_CALLBACK_H

#include <functional>
#include <memory>

/// ---------- QUERY CALLBACKS -----------

Expand All @@ -33,7 +34,7 @@ namespace MaNGOS

virtual ~IQueryCallback() = default;
virtual void Execute() = 0;
virtual void SetResult(QueryResult* queryResult) = 0;
virtual void SetResult(std::unique_ptr<QueryResult> queryResult) = 0;
};

class QueryCallback : public IQueryCallback
Expand All @@ -54,18 +55,18 @@ namespace MaNGOS

void Execute() override
{
m_Callback(m_QueryResult);
m_Callback(m_QueryResult.release());
}

void SetResult(QueryResult* queryResult) override
void SetResult(std::unique_ptr<QueryResult> queryResult) override
{
m_QueryResult = queryResult;
m_QueryResult = std::move(queryResult);
}

private:

std::function<void(QueryResult*)> m_Callback;
QueryResult* m_QueryResult;
std::unique_ptr<QueryResult> m_QueryResult;
};
}

Expand Down
3 changes: 1 addition & 2 deletions src/game/Entities/CharacterHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,14 +600,13 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
SendOfflineNameQueryResponses();

// QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow());
QueryResult* resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD);
auto resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD);

if (resultGuild)
{
Field* fields = resultGuild->Fetch();
pCurrChar->SetInGuild(fields[0].GetUInt32());
pCurrChar->SetRank(fields[1].GetUInt32());
delete resultGuild;
}
else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about nonexistent membership
{
Expand Down

0 comments on commit b634d26

Please sign in to comment.