Eluna: Implement utility GetRow()

This commit is contained in:
Rochet2
2014-09-13 21:37:28 +03:00
parent 10c81df2cd
commit 42ffd8aff8
7 changed files with 290 additions and 228 deletions

236
ElunaQueryMethods.h Normal file
View File

@@ -0,0 +1,236 @@
/*
* Copyright (C) 2010 - 2014 Eluna Lua Engine <http://emudevs.com/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/
#ifndef QUERYMETHODS_H
#define QUERYMETHODS_H
#ifndef TRINITY
#define RESULT result
#else
#define RESULT (*result)
#endif
namespace LuaQuery
{
/* BOOLEAN */
int IsNull(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
#ifndef TRINITY
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].IsNULL());
#else
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].IsNull());
#endif
return 1;
}
/* GETTERS */
int GetColumnCount(lua_State* L, ElunaQuery* result)
{
Eluna::Push(L, RESULT->GetFieldCount());
return 1;
}
int GetRowCount(lua_State* L, ElunaQuery* result)
{
if (RESULT->GetRowCount() > (uint32)-1)
Eluna::Push(L, (uint32)-1);
else
Eluna::Push(L, RESULT->GetRowCount());
return 1;
}
int GetBool(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetBool());
return 1;
}
int GetUInt8(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt8());
return 1;
}
int GetUInt16(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt16());
return 1;
}
int GetUInt32(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt32());
return 1;
}
int GetUInt64(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt64());
return 1;
}
int GetInt8(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt8());
return 1;
}
int GetInt16(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt16());
return 1;
}
int GetInt32(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt32());
return 1;
}
int GetInt64(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt64());
return 1;
}
int GetFloat(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetFloat());
return 1;
}
int GetDouble(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetDouble());
return 1;
}
int GetString(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
#ifndef TRINITY
Eluna::Push(L, RESULT->Fetch()[col].GetCppString());
#else
Eluna::Push(L, RESULT->Fetch()[col].GetString());
#endif
return 1;
}
int GetCString(lua_State* L, ElunaQuery* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
#ifndef TRINITY
Eluna::Push(L, RESULT->Fetch()[col].GetString());
#else
Eluna::Push(L, RESULT->Fetch()[col].GetCString());
#endif
return 1;
}
/* OTHER */
/**
* Advances the ElunaQuery to the next row in the result returned.
* Returns false if there was no new row, otherwise true.
*
* @return bool hadNextRow
*/
int NextRow(lua_State* L, ElunaQuery* result)
{
Eluna::Push(L, RESULT->NextRow());
return 1;
}
/**
* Returns a table from the current row where keys are field names and values are the row's values.
* All numerical values will be numbers and everything else is returned as a string.
* For example `SELECT entry, name FROM creature_template` would result in a table of `{ entry = 123, name = "some creature name" }`
* To move to next row see [ElunaQuery:NextRow]
*
* @return table rowData : table filled with row columns and data where `T[column] = data`
*/
int GetRow(lua_State* L, ElunaQuery* result)
{
lua_newtable(L);
int tbl = lua_gettop(L);
uint32 col = RESULT->GetFieldCount();
Field* row = RESULT->Fetch();
#ifndef TRINITY
const QueryFieldNames& names = RESULT->GetFieldNames();
#endif
for (uint32 i = 0; i < col; ++i)
{
#ifdef TRINITY
Eluna::Push(L, RESULT->GetFieldName(i));
const char* str = row[i].GetCString();
if (row[i].IsNull() || !str)
Eluna::Push(L);
#else
Eluna::Push(L, names[i]);
const char* str = row[i].GetString();
if (row[i].IsNULL() || !str)
Eluna::Push(L);
#endif
else
{
// MYSQL_TYPE_LONGLONG Interpreted as string for lua
switch (row[i].GetType())
{
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
Eluna::Push(L, strtod(str, NULL));
break;
default:
Eluna::Push(L, str);
break;
}
}
lua_settable(L, tbl);
}
lua_settop(L, tbl);
return 1;
}
};
#undef RESULT
#endif

View File

@@ -27,13 +27,11 @@ template<typename T>
class ElunaTemplate
{
public:
static const char* tname = NULL;
static bool manageMemory = false;
static const char* tname;
static bool manageMemory;
static int typeT(lua_State* L)
{
ASSERT(tname);
lua_pushstring(L, tname);
return 1;
}
@@ -44,7 +42,7 @@ public:
// that will only be needed on lua side and will not be managed by TC/mangos/<core>
static void Register(lua_State* L, const char* name, bool gc = false)
{
ASSERT(!tname);
ASSERT(!tname || name);
tname = name;
manageMemory = gc;
@@ -90,8 +88,6 @@ public:
template<typename C>
static void SetMethods(lua_State* L, ElunaRegister<C>* methodTable)
{
ASSERT(tname);
if (!methodTable)
return;
@@ -126,8 +122,6 @@ public:
// Remember special case ElunaTemplate<Vehicle>::gcT
static int gcT(lua_State* L)
{
ASSERT(tname);
if (!manageMemory)
return 0;
@@ -140,8 +134,6 @@ public:
static int push(lua_State* L, T const* obj)
{
ASSERT(tname);
if (!obj)
{
lua_pushnil(L);
@@ -196,8 +188,6 @@ public:
static T* check(lua_State* L, int narg, bool error = true)
{
ASSERT(tname);
T** ptrHold = static_cast<T**>(lua_touserdata(L, narg));
if (!ptrHold)
{
@@ -239,8 +229,6 @@ public:
static int thunk(lua_State* L)
{
ASSERT(tname);
T* obj = Eluna::CHECKOBJ<T>(L, 1); // get self
if (!obj)
return 0;
@@ -259,8 +247,6 @@ public:
static int tostringT(lua_State* L)
{
ASSERT(tname);
T* obj = Eluna::CHECKOBJ<T>(L, 1); // get self
if (obj)
lua_pushfstring(L, "%s: (%p)", tname, obj);

View File

@@ -10,14 +10,17 @@
#include "Common.h"
#include "SharedDefines.h"
#ifdef TRINITY
#include "QueryResult.h"
#ifdef CATA
#include "Object.h"
#endif
#else
#include "ObjectGuid.h"
#include "Database/QueryResult.h"
#endif
#ifdef TRINITY
typedef QueryResult ElunaQuery;
#ifndef CATA
typedef uint64 ObjectGuid;
#endif
@@ -26,6 +29,7 @@ typedef uint64 ObjectGuid;
#define ELUNA_LOG_DEBUG(...) TC_LOG_DEBUG("eluna", __VA_ARGS__);
#define GET_GUID GetGUID
#else
typedef QueryNamedResult ElunaQuery;
#define MAKE_NEW_GUID(l, e, h) ObjectGuid(h, e, l)
#define GUID_ENPART(guid) ObjectGuid(guid).GetEntry()
#define GUID_LOPART(guid) ObjectGuid(guid).GetCounter()

View File

@@ -629,19 +629,20 @@ namespace LuaGlobalFunctions
{
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
QueryResult* result = NULL;
#ifndef TRINITY
result = WorldDatabase.Query(query);
#ifdef TRINITY
ElunaQuery result = WorldDatabase.Query(query);
if (result)
Eluna::Push(L, new ElunaQuery(result));
else
Eluna::Push(L);
#else
QueryResult res = WorldDatabase.Query(query);
if (res)
result = new QueryResult(res);
ElunaQuery* result = WorldDatabase.QueryNamed(query);
if (result)
Eluna::Push(L, result);
else
Eluna::Push(L);
#endif
if (result)
Eluna::Push(L, result);
else
Eluna::Push(L);
return 1;
return 1;
}
int WorldDBExecute(lua_State* L)
@@ -655,19 +656,20 @@ namespace LuaGlobalFunctions
{
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
QueryResult* result = NULL;
#ifndef TRINITY
result = CharacterDatabase.Query(query);
#ifdef TRINITY
QueryResult result = CharacterDatabase.Query(query);
if (result)
Eluna::Push(L, new QueryResult(result));
else
Eluna::Push(L);
#else
QueryResult res = CharacterDatabase.Query(query);
if (res)
result = new QueryResult(res);
QueryNamedResult* result = CharacterDatabase.QueryNamed(query);
if (result)
Eluna::Push(L, result);
else
Eluna::Push(L);
#endif
if (result)
Eluna::Push(L, result);
else
Eluna::Push(L);
return 1;
return 1;
}
int CharDBExecute(lua_State* L)
@@ -679,20 +681,21 @@ namespace LuaGlobalFunctions
int AuthDBQuery(lua_State* L)
{
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
const char* query = Eluna::CHECKVAL<const char*>(L, 1);
QueryResult* result = NULL;
#ifndef TRINITY
result = LoginDatabase.Query(query);
#ifdef TRINITY
QueryResult result = LoginDatabase.Query(query);
if (result)
Eluna::Push(L, new QueryResult(result));
else
Eluna::Push(L);
#else
QueryResult res = LoginDatabase.Query(query);
if (res)
result = new QueryResult(res);
QueryNamedResult* result = LoginDatabase.QueryNamed(query);
if (result)
Eluna::Push(L, result);
else
Eluna::Push(L);
#endif
if (result)
Eluna::Push(L, result);
else
Eluna::Push(L);
return 1;
}

View File

@@ -26,7 +26,7 @@ extern "C"
#include "GroupMethods.h"
#include "GuildMethods.h"
#include "GameObjectMethods.h"
#include "QueryMethods.h"
#include "ElunaQueryMethods.h"
#include "AuraMethods.h"
#include "ItemMethods.h"
#include "WorldPacketMethods.h"
@@ -1081,11 +1081,12 @@ ElunaRegister<Vehicle> VehicleMethods[] =
#endif
#endif
ElunaRegister<QueryResult> QueryMethods[] =
ElunaRegister<ElunaQuery> QueryMethods[] =
{
{ "NextRow", &LuaQuery::NextRow }, // :NextRow() - Advances to next rown in the query. Returns true if there is a next row, otherwise false
{ "GetColumnCount", &LuaQuery::GetColumnCount }, // :GetColumnCount() - Gets the column count of the query
{ "GetRowCount", &LuaQuery::GetRowCount }, // :GetRowCount() - Gets the row count of the query
{ "GetRow", &LuaQuery::GetRow },
{ "GetBool", &LuaQuery::GetBool }, // :GetBool(column) - returns a bool from a number column (for example tinyint)
{ "GetUInt8", &LuaQuery::GetUInt8 }, // :GetUInt8(column) - returns the value of an unsigned tinyint column
@@ -1318,12 +1319,12 @@ void RegisterFunctions(lua_State* L)
ElunaTemplate<AuctionHouseObject>::Register(L, "AuctionHouseObject");
ElunaTemplate<AuctionHouseObject>::SetMethods(L, AuctionMethods);
ElunaTemplate<BattleGround>::Register(L, "BattleGround");
ElunaTemplate<BattleGround>::SetMethods(L, BattleGroundMethods);
ElunaTemplate<WorldPacket>::Register(L, "WorldPacket", true);
ElunaTemplate<WorldPacket>::SetMethods(L, PacketMethods);
ElunaTemplate<QueryResult>::Register(L, "QueryResult", true);
ElunaTemplate<QueryResult>::SetMethods(L, QueryMethods);
ElunaTemplate<BattleGround>::Register(L, "BattleGround");
ElunaTemplate<BattleGround>::SetMethods(L, BattleGroundMethods);
ElunaTemplate<ElunaQuery>::Register(L, "ElunaQuery", true);
ElunaTemplate<ElunaQuery>::SetMethods(L, QueryMethods);
}

View File

@@ -1,168 +0,0 @@
/*
* Copyright (C) 2010 - 2014 Eluna Lua Engine <http://emudevs.com/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/
#ifndef QUERYMETHODS_H
#define QUERYMETHODS_H
#ifndef TRINITY
#define RESULT result
#else
#define RESULT (*result)
#endif
namespace LuaQuery
{
/* BOOLEAN */
int IsNull(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
#ifndef TRINITY
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].IsNULL());
#else
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].IsNull());
#endif
return 1;
}
/* GETTERS */
int GetColumnCount(lua_State* L, QueryResult* result)
{
Eluna::Push(L, RESULT->GetFieldCount());
return 1;
}
int GetRowCount(lua_State* L, QueryResult* result)
{
if (RESULT->GetRowCount() > (uint32)-1)
Eluna::Push(L, (uint32)-1);
else
Eluna::Push(L, RESULT->GetRowCount());
return 1;
}
int GetBool(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetBool());
return 1;
}
int GetUInt8(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt8());
return 1;
}
int GetUInt16(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt16());
return 1;
}
int GetUInt32(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt32());
return 1;
}
int GetUInt64(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetUInt64());
return 1;
}
int GetInt8(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt8());
return 1;
}
int GetInt16(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt16());
return 1;
}
int GetInt32(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt32());
return 1;
}
int GetInt64(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetInt64());
return 1;
}
int GetFloat(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetFloat());
return 1;
}
int GetDouble(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
Eluna::Push(L, RESULT->Fetch()[col].GetDouble());
return 1;
}
int GetString(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
#ifndef TRINITY
Eluna::Push(L, RESULT->Fetch()[col].GetCppString());
#else
Eluna::Push(L, RESULT->Fetch()[col].GetString());
#endif
return 1;
}
int GetCString(lua_State* L, QueryResult* result)
{
uint32 col = Eluna::CHECKVAL<uint32>(L, 2);
if (col < RESULT->GetFieldCount())
#ifndef TRINITY
Eluna::Push(L, RESULT->Fetch()[col].GetString());
#else
Eluna::Push(L, RESULT->Fetch()[col].GetCString());
#endif
return 1;
}
/* OTHER */
int NextRow(lua_State* L, QueryResult* result)
{
Eluna::Push(L, RESULT->NextRow());
return 1;
}
};
#undef RESULT
#endif

View File

@@ -122,9 +122,9 @@ if (GetCoreExpansion() >= 2) then
table.insert(T.Vehicle, "GetEntry")
end
T.QueryResult = {}
table.insert(T.QueryResult, "GetColumnCount")
table.insert(T.QueryResult, "GetRowCount")
T.ElunaQuery = {}
table.insert(T.ElunaQuery, "GetColumnCount")
table.insert(T.ElunaQuery, "GetRowCount")
T.WorldPacket = {}
table.insert(T.WorldPacket, "GetSize")