mirror of
https://github.com/azerothcore/mod-ale
synced 2025-11-29 15:38:17 +08:00
feat: add support for parameterized SQL queries with argument escaping (#221)
This commit is contained in:
@@ -694,6 +694,48 @@ void Eluna::Push(lua_State* luastate, ObjectGuid const guid)
|
|||||||
ElunaTemplate<unsigned long long>::Push(luastate, new unsigned long long(guid.GetRawValue()));
|
ElunaTemplate<unsigned long long>::Push(luastate, new unsigned long long(guid.GetRawValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Eluna::FormatQuery(lua_State* L, const char* query)
|
||||||
|
{
|
||||||
|
int numArgs = lua_gettop(L);
|
||||||
|
std::string formattedQuery = query;
|
||||||
|
|
||||||
|
size_t position = 0;
|
||||||
|
for (int i = 2; i <= numArgs; ++i)
|
||||||
|
{
|
||||||
|
std::string arg;
|
||||||
|
|
||||||
|
if (lua_isnumber(L, i))
|
||||||
|
{
|
||||||
|
arg = std::to_string(lua_tonumber(L, i));
|
||||||
|
}
|
||||||
|
else if (lua_isstring(L, i))
|
||||||
|
{
|
||||||
|
std::string value = lua_tostring(L, i);
|
||||||
|
for (size_t pos = 0; (pos = value.find('\'', pos)) != std::string::npos; pos += 2)
|
||||||
|
{
|
||||||
|
value.insert(pos, "'");
|
||||||
|
}
|
||||||
|
arg = "'" + value + "'";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
luaL_error(L, "Unsupported argument type. Only numbers and strings are supported.");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
position = formattedQuery.find("?", position);
|
||||||
|
if (position == std::string::npos)
|
||||||
|
{
|
||||||
|
luaL_error(L, "Mismatch between placeholders and arguments.");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
formattedQuery.replace(position, 1, arg);
|
||||||
|
position += arg.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedQuery;
|
||||||
|
}
|
||||||
|
|
||||||
static int CheckIntegerRange(lua_State* luastate, int narg, int min, int max)
|
static int CheckIntegerRange(lua_State* luastate, int narg, int min, int max)
|
||||||
{
|
{
|
||||||
double value = luaL_checknumber(luastate, narg);
|
double value = luaL_checknumber(luastate, narg);
|
||||||
|
|||||||
@@ -262,6 +262,8 @@ public:
|
|||||||
{
|
{
|
||||||
ElunaTemplate<T>::Push(luastate, ptr);
|
ElunaTemplate<T>::Push(luastate, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string FormatQuery(lua_State* L, const char* query);
|
||||||
|
|
||||||
bool ExecuteCall(int params, int res);
|
bool ExecuteCall(int params, int res);
|
||||||
|
|
||||||
|
|||||||
@@ -1334,6 +1334,10 @@ namespace LuaGlobalFunctions
|
|||||||
{
|
{
|
||||||
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
||||||
|
|
||||||
|
int numArgs = lua_gettop(L);
|
||||||
|
if (numArgs > 1)
|
||||||
|
query = Eluna::FormatQuery(L, query).c_str();
|
||||||
|
|
||||||
ElunaQuery result = WorldDatabase.Query(query);
|
ElunaQuery result = WorldDatabase.Query(query);
|
||||||
if (result)
|
if (result)
|
||||||
Eluna::Push(L, new ElunaQuery(result));
|
Eluna::Push(L, new ElunaQuery(result));
|
||||||
@@ -1382,6 +1386,11 @@ namespace LuaGlobalFunctions
|
|||||||
int WorldDBExecute(lua_State* L)
|
int WorldDBExecute(lua_State* L)
|
||||||
{
|
{
|
||||||
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
||||||
|
|
||||||
|
int numArgs = lua_gettop(L);
|
||||||
|
if (numArgs > 1)
|
||||||
|
query = Eluna::FormatQuery(L, query).c_str();
|
||||||
|
|
||||||
WorldDatabase.Execute(query);
|
WorldDatabase.Execute(query);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1402,6 +1411,10 @@ namespace LuaGlobalFunctions
|
|||||||
{
|
{
|
||||||
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
||||||
|
|
||||||
|
int numArgs = lua_gettop(L);
|
||||||
|
if (numArgs > 1)
|
||||||
|
query = Eluna::FormatQuery(L, query).c_str();
|
||||||
|
|
||||||
QueryResult result = CharacterDatabase.Query(query);
|
QueryResult result = CharacterDatabase.Query(query);
|
||||||
if (result)
|
if (result)
|
||||||
Eluna::Push(L, new QueryResult(result));
|
Eluna::Push(L, new QueryResult(result));
|
||||||
@@ -1443,6 +1456,11 @@ namespace LuaGlobalFunctions
|
|||||||
int CharDBExecute(lua_State* L)
|
int CharDBExecute(lua_State* L)
|
||||||
{
|
{
|
||||||
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
||||||
|
|
||||||
|
int numArgs = lua_gettop(L);
|
||||||
|
if (numArgs > 1)
|
||||||
|
query = Eluna::FormatQuery(L, query).c_str();
|
||||||
|
|
||||||
CharacterDatabase.Execute(query);
|
CharacterDatabase.Execute(query);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1463,6 +1481,10 @@ namespace LuaGlobalFunctions
|
|||||||
{
|
{
|
||||||
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
||||||
|
|
||||||
|
int numArgs = lua_gettop(L);
|
||||||
|
if (numArgs > 1)
|
||||||
|
query = Eluna::FormatQuery(L, query).c_str();
|
||||||
|
|
||||||
QueryResult result = LoginDatabase.Query(query);
|
QueryResult result = LoginDatabase.Query(query);
|
||||||
if (result)
|
if (result)
|
||||||
Eluna::Push(L, new QueryResult(result));
|
Eluna::Push(L, new QueryResult(result));
|
||||||
@@ -1504,6 +1526,11 @@ namespace LuaGlobalFunctions
|
|||||||
int AuthDBExecute(lua_State* L)
|
int AuthDBExecute(lua_State* L)
|
||||||
{
|
{
|
||||||
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
|
||||||
|
|
||||||
|
int numArgs = lua_gettop(L);
|
||||||
|
if (numArgs > 1)
|
||||||
|
query = Eluna::FormatQuery(L, query).c_str();
|
||||||
|
|
||||||
LoginDatabase.Execute(query);
|
LoginDatabase.Execute(query);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user