Intro:
You could use this code (it works fine either via well-done libs or via game's sources) to create the relative functions in lua: mysql_direct_query, get_table_postfix, mysql_escape_string
The mysql_direct_query returns two values: the first one contains the count of how many rows had been affected (works fine for select, insert, update queries, and so on) and the second one a table containing all the information retrieved by a select query (empty if not).
The field type will be auto-detected, which means:
Example Quest #1: (Use CTRL+Q and CTRL+K on notepad++ to de/comment quickly)
[Only registered and activated users can see links. Click Here To Register...]
[Only registered and activated users can see links. Click Here To Register...]
How To:
Paste 'em into questlua_global.cpp outside the namespace quest:
Paste 'em into questlua_global.cpp inside the namespace quest:
Inside global_functions:
Changelog:
What To Know:
You could use this code (it works fine either via well-done libs or via game's sources) to create the relative functions in lua: mysql_direct_query, get_table_postfix, mysql_escape_string
The mysql_direct_query returns two values: the first one contains the count of how many rows had been affected (works fine for select, insert, update queries, and so on) and the second one a table containing all the information retrieved by a select query (empty if not).
The field type will be auto-detected, which means:
- A numeric field will be pushed as lua number
- A BLOB one will be pushed as table byte per byte
- A NULL field will be pushed as nil (not displayed in iteration)
- The other ones will be pushed as strings (be aware of this)
Example Quest #1: (Use CTRL+Q and CTRL+K on notepad++ to de/comment quickly)
Code:
-- local res1, res2 = mysql_direct_query("select player.name, player.level from player.player limit 2;")
local res1, res2 = mysql_direct_query("select * from player.player limit 1;")
-- local res1, res2 = mysql_direct_query("select name, skill_level from player.player limit 1;")
syschat(res2[1].name)
-- syschat(string.format("count(%d)", res1))
-- for i1=1, res1 do
-- syschat(string.format("\tindex(%d)", i1))
-- syschat(string.format("\t\tname(%s), level(%d)", res2[i1].name, res2[i1].level))
-- end
-- local res1, res2 = mysql_direct_query("select * from player.guild_comment;")
-- local res1, res2 = mysql_direct_query("INSERT INTO `guild_comment` (`id`) VALUES ('1');")
-- local res1, res2 = mysql_direct_query("INSERT INTO `guild_comment` (`guild_id`, `name`, `notice`, `content`, `time`) VALUES ('1', 'martytest', '0', 'blabla', NOW());")
syschat(string.format("count(%d)", res1))
for num1, str1 in ipairs(res2) do
syschat(string.format("\tindex(%d)", num1))
for key1, val1 in pairs(str1) do
-- syschat(string.format("\t\tkey(%s), value(%s)", key1, val1))
-- syschat(string.format("\t\tkey(%s), value(%s) type(%s)", key1, val1, type(val1)))
if (type(val1)=="table") then
syschat(string.format("\t\tkey(%s), size(%d), type(%s)", key1, table.getn(val1), type(val1)))
-- syschat(string.format("\t\tkey(%s), type(%s)", key1, type(val1)))
-- for num2, str2 in ipairs(val1) do
-- syschat(string.format("\t\t\tidx(%s), value(%s), type(%s)", num2, str2, type(num2)))
-- end
-- syschat(string.format("\t\tkey(%s), value(%s), type(%s)", key1, table.concat(val1, ", "), type(val1))) --client will crash
else
syschat(string.format("\t\tkey(%s), value(%s), type(%s)", key1, val1, type(val1)))
end
end
end
-- syschat(mysql_escape_string("abyy"))
-- syschat(mysql_escape_string("'schure'")) --\'schure\'
syschat(mysql_escape_string("'\"lewd'\"")) --\'\"lewd\'\"
-- syschat(mysql_escape_string("`\n``\t`"))
syschat(mysql_escape_string([["aww'omg"<?'3]])) --\"aww\'omg\"<?\'3
[Only registered and activated users can see links. Click Here To Register...]
How To:
Paste 'em into questlua_global.cpp outside the namespace quest:
Code:
#include "db.h"
Code:
int _get_table_postfix(lua_State* L)
{
lua_pushstring(L, get_table_postfix());
return 1;
}
#ifdef _MSC_VER
#define INFINITY (DBL_MAX+DBL_MAX)
#define NAN (INFINITY-INFINITY)
#endif
int _mysql_direct_query(lua_State* L)
{
if (!lua_isstring(L, 1))
return 0;
int i=0, m=1;
MYSQL_ROW row;
MYSQL_FIELD * field;
MYSQL_RES * result;
std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("%s", lua_tostring(L, 1)));
if (pMsg.get())
{
// ret1 (number of affected rows)
lua_pushnumber(L, pMsg->Get()->uiAffectedRows);
//-1 if error such as duplicate occurs (-2147483648 via lua)
// if wrong syntax error occurs (4294967295 via lua)
// ret2 (table of affected rows)
lua_newtable(L);
if ((result = pMsg->Get()->pSQLResult) &&
!(pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1))
{
while((row = mysql_fetch_row(result)))
{
lua_pushnumber(L, m);
lua_newtable(L);
while((field = mysql_fetch_field(result)))
{
lua_pushstring(L, field->name);
if (!(field->flags & NOT_NULL_FLAG) && (row[i]==NULL))
{
// lua_pushstring(L, "NULL");
lua_pushnil(L);
}
else if (IS_NUM(field->type))
{
double val = NAN;
lua_pushnumber(L, (sscanf(row[i],"%lf",&val)==1)?val:NAN);
}
else if (field->type == MYSQL_TYPE_BLOB)
{
lua_newtable(L);
for (DWORD iBlob=0; iBlob < field->max_length; iBlob++)
{
lua_pushnumber(L, row[i][iBlob]);
lua_rawseti(L, -2, iBlob+1);
}
}
else
lua_pushstring(L, row[i]);
lua_rawset(L, -3);
i++;
}
mysql_field_seek(result, 0);
i=0;
lua_rawset(L, -3);
m++;
}
}
}
else {lua_pushnumber(L, 0); lua_newtable(L);}
return 2;
}
int _mysql_escape_string(lua_State* L)
{
char szQuery[1024] = {0};
if (!lua_isstring(L, 1))
return 0;
DBManager::instance().EscapeString(szQuery, sizeof(szQuery), lua_tostring(L, 1), strlen(lua_tostring(L, 1)));
lua_pushstring(L, szQuery);
return 1;
}
Code:
{ "get_table_postfix", _get_table_postfix },
{ "mysql_direct_query", _mysql_direct_query },
{ "mysql_escape_string", _mysql_escape_string },
- 2013/02/?: First draft was written by xXDarkAnimaXx (v0.1)
- 2013/02/?: A fixed and working draft was released by me (v1.0)
- 2014/07/03: Added: Auto-detecting mysql types, a return value of how many rows had been affected, and other two functions for general purpose (v3.0)
- 2016/07/28: Solved the little "%%" issue for mysql_direct_query and cleaned some comments (v4.810)
What To Know:
- [Only registered and activated users can see links. Click Here To Register...]
- [Only registered and activated users can see links. Click Here To Register...]