diff --git a/ElunaQueryMethods.h b/ElunaQueryMethods.h
new file mode 100644
index 0000000..5681a1f
--- /dev/null
+++ b/ElunaQueryMethods.h
@@ -0,0 +1,236 @@
+/*
+* Copyright (C) 2010 - 2014 Eluna Lua Engine
+* 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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
diff --git a/ElunaTemplate.h b/ElunaTemplate.h
index d6c4e02..64b9d98 100644
--- a/ElunaTemplate.h
+++ b/ElunaTemplate.h
@@ -27,13 +27,11 @@ template
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/
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
static void SetMethods(lua_State* L, ElunaRegister* methodTable)
{
- ASSERT(tname);
-
if (!methodTable)
return;
@@ -126,8 +122,6 @@ public:
// Remember special case ElunaTemplate::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(lua_touserdata(L, narg));
if (!ptrHold)
{
@@ -239,8 +229,6 @@ public:
static int thunk(lua_State* L)
{
- ASSERT(tname);
-
T* obj = Eluna::CHECKOBJ(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(L, 1); // get self
if (obj)
lua_pushfstring(L, "%s: (%p)", tname, obj);
diff --git a/ElunaUtility.h b/ElunaUtility.h
index 6a44dcf..ea73025 100644
--- a/ElunaUtility.h
+++ b/ElunaUtility.h
@@ -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()
diff --git a/GlobalMethods.h b/GlobalMethods.h
index 2dfa4bc..087e837 100644
--- a/GlobalMethods.h
+++ b/GlobalMethods.h
@@ -629,19 +629,20 @@ namespace LuaGlobalFunctions
{
const char* query = Eluna::CHECKVAL(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(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(L, 1);
+ const char* query = Eluna::CHECKVAL(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;
}
diff --git a/LuaFunctions.cpp b/LuaFunctions.cpp
index 753614f..293f90a 100644
--- a/LuaFunctions.cpp
+++ b/LuaFunctions.cpp
@@ -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 VehicleMethods[] =
#endif
#endif
-ElunaRegister QueryMethods[] =
+ElunaRegister 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::Register(L, "AuctionHouseObject");
ElunaTemplate::SetMethods(L, AuctionMethods);
+ ElunaTemplate::Register(L, "BattleGround");
+ ElunaTemplate::SetMethods(L, BattleGroundMethods);
+
ElunaTemplate::Register(L, "WorldPacket", true);
ElunaTemplate::SetMethods(L, PacketMethods);
- ElunaTemplate::Register(L, "QueryResult", true);
- ElunaTemplate::SetMethods(L, QueryMethods);
-
- ElunaTemplate::Register(L, "BattleGround");
- ElunaTemplate::SetMethods(L, BattleGroundMethods);
+ ElunaTemplate::Register(L, "ElunaQuery", true);
+ ElunaTemplate::SetMethods(L, QueryMethods);
}
diff --git a/QueryMethods.h b/QueryMethods.h
deleted file mode 100644
index 91a3591..0000000
--- a/QueryMethods.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-* Copyright (C) 2010 - 2014 Eluna Lua Engine
-* 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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
diff --git a/extensions/FunctionCache.ext b/extensions/FunctionCache.ext
index f80c0f3..d5c81de 100644
--- a/extensions/FunctionCache.ext
+++ b/extensions/FunctionCache.ext
@@ -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")