Lua rework almost done
This commit is contained in:
parent
26833a556a
commit
fd245cb2ac
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,4 +10,5 @@
|
||||
.vscode
|
||||
*.zip
|
||||
cmake-build-debug
|
||||
.idea
|
||||
.idea
|
||||
.vs
|
@ -1,15 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(MySQLOO)
|
||||
project(mysqloo)
|
||||
add_subdirectory(GmodLUA)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
file(GLOB_RECURSE MySQLOO_SRC "src/*.h" "src/*.cpp")
|
||||
set(SOURCE_FILES ${MySQLOO_SRC} src/Main.cpp)
|
||||
file(GLOB_RECURSE MYSQLOO_SRC "src/*.h" "src/*.cpp")
|
||||
set(SOURCE_FILES ${MYSQLOO_SRC} src/Main.cpp)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
add_executable(MySQLOO ${SOURCE_FILES})
|
||||
target_link_libraries(MySQLOO gmod-module-base)
|
||||
add_library(mysqloo SHARED ${SOURCE_FILES})
|
||||
target_link_libraries(mysqloo gmod-module-base)
|
||||
|
||||
target_include_directories(MySQLOO PRIVATE MySQL/include)
|
||||
target_include_directories(mysqloo PRIVATE MySQL/include)
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
if (WIN32)
|
||||
@ -30,11 +30,11 @@ elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(MySQLOO ${MARIADB_CLIENT_LIB} crypt32 ws2_32 shlwapi bcrypt secur32)
|
||||
target_link_libraries(mysqloo ${MARIADB_CLIENT_LIB} crypt32 ws2_32 shlwapi bcrypt secur32)
|
||||
else ()
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(MySQLOO ${MARIADB_CLIENT_LIB} ${SSL_LIB} ${CRYPTO_LIB} Threads::Threads ${CMAKE_DL_LIBS})
|
||||
target_link_libraries(mysqloo ${MARIADB_CLIENT_LIB} ${SSL_LIB} ${CRYPTO_LIB} Threads::Threads ${CMAKE_DL_LIBS})
|
||||
endif ()
|
||||
|
||||
|
||||
set_gmod_suffix_prefix(MySQLOO)
|
||||
set_gmod_suffix_prefix(mysqloo)
|
@ -28,30 +28,6 @@ GMOD_MODULE_CLOSE() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Connects to the database and returns a Database instance that can be used
|
||||
* as an interface to the mysql server.
|
||||
*/
|
||||
LUA_FUNCTION(mysqlooConnect) {
|
||||
LUA->CheckType(1, GarrysMod::Lua::Type::String);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::String);
|
||||
LUA->CheckType(3, GarrysMod::Lua::Type::String);
|
||||
LUA->CheckType(4, GarrysMod::Lua::Type::String);
|
||||
std::string host = LUA->GetString(1);
|
||||
std::string username = LUA->GetString(2);
|
||||
std::string pw = LUA->GetString(3);
|
||||
std::string database = LUA->GetString(4);
|
||||
unsigned int port = 3306;
|
||||
std::string unixSocket;
|
||||
if (LUA->IsType(5, GarrysMod::Lua::Type::Number)) {
|
||||
port = (int)LUA->GetNumber(5);
|
||||
}
|
||||
if (LUA->IsType(6, GarrysMod::Lua::Type::String)) {
|
||||
unixSocket = LUA->GetString(6);
|
||||
}
|
||||
auto object = Database::createDatabase(host, username, pw, database, port, unixSocket);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns the amount of LuaObjectBase objects that are currently in use
|
||||
* This includes Database and Query instances
|
||||
*/
|
||||
@ -91,13 +67,13 @@ static void printMessage(GarrysMod::Lua::ILuaBase* LUA, const char* str, int r,
|
||||
LUA->ReferenceFree(ref);
|
||||
}
|
||||
|
||||
static int printOutdatatedVersion(lua_State* state) {
|
||||
static int printOutdatedVersion(lua_State* state) {
|
||||
GarrysMod::Lua::ILuaBase* LUA = state->luabase;
|
||||
LUA->SetState(state);
|
||||
printMessage(LUA, "Your server is using an outdated mysqloo9 version\n", 255, 0, 0);
|
||||
printMessage(LUA, "Download the latest version from here:\n", 255, 0, 0);
|
||||
printMessage(LUA, "https://github.com/FredyH/MySQLOO/releases\n", 86, 156, 214);
|
||||
runInTimer(LUA, 300, printOutdatatedVersion);
|
||||
runInTimer(LUA, 300, printOutdatedVersion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -107,7 +83,7 @@ static int fetchSuccessful(lua_State* state) {
|
||||
std::string version = LUA->GetString(1);
|
||||
//version.size() < 3 so that the 404 response gets ignored
|
||||
if (version != MYSQLOO_MINOR_VERSION && version.size() <= 3) {
|
||||
printOutdatatedVersion(state);
|
||||
printOutdatedVersion(state);
|
||||
} else {
|
||||
printMessage(LUA, "Your server is using the latest mysqloo9 version\n", 0, 255, 0);
|
||||
}
|
||||
@ -151,12 +127,18 @@ static int doVersionCheck(lua_State* state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO List:
|
||||
// - memory leak with queries because sometimes first data is not cleared
|
||||
// - onData callbacks
|
||||
// - PreparedQueries do not properly clear their results
|
||||
|
||||
GMOD_MODULE_OPEN() {
|
||||
if (mysql_library_init(0, nullptr, nullptr)) {
|
||||
LUA->ThrowError("Could not initialize mysql library.");
|
||||
}
|
||||
|
||||
//Creating MetaTables
|
||||
LuaObject::createUserDataMetaTable(LUA);
|
||||
LuaDatabase::createMetaTable(LUA);
|
||||
LuaQuery::createMetaTable(LUA);
|
||||
LuaPreparedQuery::createMetaTable(LUA);
|
||||
@ -194,7 +176,7 @@ GMOD_MODULE_OPEN() {
|
||||
LUA->PushNumber(OPTION_NAMED_FIELDS); LUA->SetField(-2, "OPTION_NAMED_FIELDS"); //Not used anymore
|
||||
LUA->PushNumber(OPTION_CACHE); LUA->SetField(-2, "OPTION_CACHE"); //Not used anymore
|
||||
|
||||
LUA->PushCFunction(mysqlooConnect); LUA->SetField(-2, "connect");
|
||||
LUA->PushCFunction(LuaDatabase::create); LUA->SetField(-2, "connect");
|
||||
LUA->PushCFunction(objectCount); LUA->SetField(-2, "objectCount");
|
||||
|
||||
LUA->SetField(-2, "mysqloo");
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
static void pushLuaObjectTable(ILuaBase *LUA, void *data, int type) {
|
||||
LUA->CreateTable();
|
||||
LUA->PushUserType(data, type);
|
||||
LUA->PushUserType(data, LuaObject::TYPE_USERDATA);
|
||||
LUA->SetField(-2, "__CppObject");
|
||||
LUA->PushMetaTable(type);
|
||||
LUA->SetMetaTable(-2);
|
||||
@ -37,7 +37,7 @@ LUA_CLASS_FUNCTION(LuaDatabase, create) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(query) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::String);
|
||||
unsigned int outLen = 0;
|
||||
const char *queryStr = LUA->GetString(2, &outLen);
|
||||
@ -49,7 +49,7 @@ MYSQLOO_LUA_FUNCTION(query) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(prepare) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::String);
|
||||
unsigned int outLen = 0;
|
||||
const char *queryStr = LUA->GetString(2, &outLen);
|
||||
@ -61,7 +61,7 @@ MYSQLOO_LUA_FUNCTION(prepare) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(createTransaction) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
auto transaction = Transaction::create(database->m_database);
|
||||
auto luaTransaction = LuaTransaction::create(transaction);
|
||||
|
||||
@ -70,7 +70,7 @@ MYSQLOO_LUA_FUNCTION(createTransaction) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(connect) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
if (database->m_tableReference == 0) {
|
||||
LUA->Push(1);
|
||||
database->m_tableReference = LUA->ReferenceCreate();
|
||||
@ -80,7 +80,7 @@ MYSQLOO_LUA_FUNCTION(connect) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(escape) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
unsigned int nQueryLength;
|
||||
const char *sQuery = LUA->GetString(2, &nQueryLength);
|
||||
auto escaped = database->m_database->escape(std::string(sQuery, nQueryLength));
|
||||
@ -89,7 +89,7 @@ MYSQLOO_LUA_FUNCTION(escape) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setCharacterSet) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::String);
|
||||
const char *charset = LUA->GetString(2);
|
||||
bool success = database->m_database->setCharacterSet(charset);
|
||||
@ -99,7 +99,7 @@ MYSQLOO_LUA_FUNCTION(setCharacterSet) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setSSLSettings) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
SSLSettings sslSettings;
|
||||
if (LUA->IsType(2, GarrysMod::Lua::Type::String)) {
|
||||
sslSettings.key = LUA->GetString(2);
|
||||
@ -121,7 +121,7 @@ MYSQLOO_LUA_FUNCTION(setSSLSettings) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(disconnect) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
bool wait = false;
|
||||
if (LUA->IsType(2, GarrysMod::Lua::Type::Bool)) {
|
||||
wait = LUA->GetBool(2);
|
||||
@ -131,52 +131,52 @@ MYSQLOO_LUA_FUNCTION(disconnect) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(status) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->PushNumber(database->m_database->m_status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(serverVersion) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->PushNumber(database->m_database->serverVersion());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(serverInfo) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->PushString(database->m_database->serverInfo().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(hostInfo) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->PushString(database->m_database->hostInfo().c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setAutoReconnect) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Bool);
|
||||
database->m_database->setAutoReconnect(LUA->GetBool(2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setMultiStatements) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Bool);
|
||||
database->m_database->setMultiStatements(LUA->GetBool(2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setCachePreparedStatements) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Bool);
|
||||
database->m_database->setCachePreparedStatements(LUA->GetBool(2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(abortAllQueries) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
auto abortedQueries = database->m_database->abortAllQueries();
|
||||
for (auto pair: abortedQueries) {
|
||||
//TODO:
|
||||
@ -187,19 +187,19 @@ MYSQLOO_LUA_FUNCTION(abortAllQueries) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(queueSize) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->PushNumber((double) database->m_database->queueSize());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(ping) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
LUA->PushBool(database->m_database->ping());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(wait) {
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA, LuaObject::TYPE_DATABASE);
|
||||
auto database = LuaObject::getLuaObject<LuaDatabase>(LUA);
|
||||
database->m_database->wait();
|
||||
return 0;
|
||||
}
|
||||
@ -277,7 +277,7 @@ void LuaDatabase::think(ILuaBase *LUA) {
|
||||
LUA->GetField(-1, "onConnected");
|
||||
if (LUA->GetType(-1) == GarrysMod::Lua::Type::Function) {
|
||||
LUA->ReferencePush(this->m_tableReference);
|
||||
pcallWithErrorReporter(LUA, 1, 0);
|
||||
pcallWithErrorReporter(LUA, 1);
|
||||
}
|
||||
LUA->Pop(); //Callback function
|
||||
} else {
|
||||
@ -286,7 +286,7 @@ void LuaDatabase::think(ILuaBase *LUA) {
|
||||
LUA->ReferencePush(this->m_tableReference);
|
||||
auto error = database->connectionError();
|
||||
LUA->PushString(error.c_str());
|
||||
pcallWithErrorReporter(LUA, 2, 0);
|
||||
pcallWithErrorReporter(LUA, 2);
|
||||
}
|
||||
LUA->Pop(); //Callback function
|
||||
}
|
||||
@ -300,10 +300,9 @@ void LuaDatabase::think(ILuaBase *LUA) {
|
||||
auto finishedQueries = database->takeFinishedQueries();
|
||||
for (auto &pair: finishedQueries) {
|
||||
auto data = pair.second;
|
||||
auto query = pair.first;
|
||||
if (data->m_tableReference != 0) {
|
||||
LUA->ReferencePush(data->m_tableReference);
|
||||
auto luaQuery = LuaIQuery::getLuaIQuery(LUA, -1);
|
||||
auto luaQuery = LuaIQuery::getLuaObject<LuaIQuery>(LUA, -1);
|
||||
LUA->Pop();
|
||||
luaQuery->runCallback(LUA, data);
|
||||
}
|
||||
|
@ -4,14 +4,14 @@
|
||||
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(start) {
|
||||
auto query = LuaIQuery::getLuaIQuery(LUA);
|
||||
auto queryData = query->buildQueryData(nullptr, 0);
|
||||
auto query = LuaIQuery::getLuaObject<LuaIQuery>(LUA);
|
||||
auto queryData = query->buildQueryData(LUA, 1);
|
||||
query->m_query->start(queryData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(error) {
|
||||
auto query = LuaIQuery::getLuaIQuery(LUA);
|
||||
auto query = LuaIQuery::getLuaObject<LuaIQuery>(LUA);
|
||||
LUA->PushString(query->m_query->error().c_str());
|
||||
return 1;
|
||||
}
|
||||
@ -21,13 +21,13 @@ MYSQLOO_LUA_FUNCTION(wait) {
|
||||
if (LUA->IsType(2, GarrysMod::Lua::Type::Bool)) {
|
||||
shouldSwap = LUA->GetBool(2);
|
||||
}
|
||||
auto query = LuaIQuery::getLuaIQuery(LUA);
|
||||
auto query = LuaIQuery::getLuaObject<LuaIQuery>(LUA);
|
||||
query->m_query->wait(shouldSwap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setOption) {
|
||||
auto query = LuaIQuery::getLuaIQuery(LUA);
|
||||
auto query = LuaIQuery::getLuaObject<LuaIQuery>(LUA);
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Number);
|
||||
bool set = true;
|
||||
int option = (int) LUA->GetNumber(2);
|
||||
@ -41,13 +41,13 @@ MYSQLOO_LUA_FUNCTION(setOption) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(isRunning) {
|
||||
auto query = LuaIQuery::getLuaIQuery(LUA);
|
||||
auto query = LuaIQuery::getLuaObject<LuaIQuery>(LUA);
|
||||
LUA->PushBool(query->m_query->isRunning());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(abort) {
|
||||
auto query = LuaIQuery::getLuaIQuery(LUA);
|
||||
auto query = LuaIQuery::getLuaObject<LuaIQuery>(LUA);
|
||||
auto abortedData = query->m_query->abort();
|
||||
for (auto &data: abortedData) {
|
||||
LuaIQuery::runAbortedCallback(LUA, data);
|
||||
@ -58,25 +58,25 @@ MYSQLOO_LUA_FUNCTION(abort) {
|
||||
void LuaIQuery::runAbortedCallback(ILuaBase *LUA, const std::shared_ptr<IQueryData> &data) {
|
||||
if (data->m_tableReference == 0) return;
|
||||
|
||||
if (!LuaIQuery::getCallbackReference(LUA, data->m_abortReference, data->m_tableReference,
|
||||
"onAborted", data->isFirstData())) {
|
||||
if (!LuaIQuery::pushCallbackReference(LUA, data->m_abortReference, data->m_tableReference,
|
||||
"onAborted", data->isFirstData())) {
|
||||
return;
|
||||
}
|
||||
LUA->ReferencePush(data->m_tableReference);
|
||||
LuaObject::pcallWithErrorReporter(LUA, 1, 0);
|
||||
LuaObject::pcallWithErrorReporter(LUA, 1);
|
||||
}
|
||||
|
||||
void LuaIQuery::runErrorCallback(ILuaBase *LUA, const std::shared_ptr<IQueryData> &data) {
|
||||
if (data->m_tableReference == 0) return;
|
||||
|
||||
if (!LuaIQuery::getCallbackReference(LUA, data->m_errorReference, data->m_tableReference,
|
||||
"onError", data->isFirstData())) {
|
||||
if (!LuaIQuery::pushCallbackReference(LUA, data->m_errorReference, data->m_tableReference,
|
||||
"onError", data->isFirstData())) {
|
||||
return;
|
||||
}
|
||||
LUA->ReferencePush(data->m_tableReference);
|
||||
auto error = data->getError();
|
||||
LUA->PushString(error.c_str());
|
||||
LuaObject::pcallWithErrorReporter(LUA, 2, 0);
|
||||
LuaObject::pcallWithErrorReporter(LUA, 2);
|
||||
}
|
||||
|
||||
void LuaIQuery::addMetaTableFunctions(ILuaBase *LUA) {
|
||||
|
@ -31,19 +31,6 @@ public:
|
||||
|
||||
void finishQueryData(ILuaBase *LUA, const std::shared_ptr<IQueryData>& data) const;
|
||||
|
||||
static LuaIQuery *getLuaIQuery(ILuaBase *LUA, int stackPos = 1) {
|
||||
int type = LuaObject::getLuaObjectType(LUA, stackPos);
|
||||
if (type != LuaObject::TYPE_QUERY && type != LuaObject::TYPE_PREPARED_QUERY &&
|
||||
type != LuaObject::TYPE_TRANSACTION) {
|
||||
LUA->ThrowError("[MySQLOO] Expected MySQLOO table");
|
||||
}
|
||||
auto *returnValue = LuaObject::getLuaObject<LuaIQuery>(LUA, type, stackPos);
|
||||
if (returnValue == nullptr) {
|
||||
LUA->ThrowError("[MySQLOO] Expected MySQLOO table");
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit LuaIQuery(std::shared_ptr<IQuery> query, std::string className) : LuaObject(std::move(className)),
|
||||
m_query(std::move(query)) {}
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include <algorithm>
|
||||
#include "LuaObject.h"
|
||||
#include "LuaDatabase.h"
|
||||
#include <iostream>
|
||||
|
||||
int LuaObject::TYPE_USERDATA = 0;
|
||||
int LuaObject::TYPE_DATABASE = 0;
|
||||
int LuaObject::TYPE_QUERY = 0;
|
||||
int LuaObject::TYPE_TRANSACTION = 0;
|
||||
@ -10,29 +12,14 @@ int LuaObject::TYPE_PREPARED_QUERY = 0;
|
||||
std::deque<std::shared_ptr<LuaObject>> LuaObject::luaObjects = {};
|
||||
std::deque<std::shared_ptr<LuaDatabase>> LuaObject::luaDatabases = {};
|
||||
|
||||
std::string LuaObject::toString() {
|
||||
std::stringstream ss;
|
||||
ss << s_className << " " << this;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::shared_ptr<LuaObject> LuaObject::checkMySQLOOType(ILuaBase *lua, int position) {
|
||||
int type = lua->GetType(position);
|
||||
if (type != LuaObject::TYPE_DATABASE && type != LuaObject::TYPE_PREPARED_QUERY &&
|
||||
type != LuaObject::TYPE_QUERY && type != LuaObject::TYPE_TRANSACTION) {
|
||||
lua->ThrowError("Provided argument is not a valid MySQLOO object");
|
||||
}
|
||||
return lua->GetUserType<LuaObject>(position, type)->shared_from_this();
|
||||
}
|
||||
|
||||
LUA_FUNCTION(luaObjectGc) {
|
||||
auto luaObject = LuaObject::checkMySQLOOType(LUA);
|
||||
auto luaObject = LUA->GetUserType<LuaObject>(1, LuaObject::TYPE_USERDATA);
|
||||
LuaObject::luaDatabases.erase(
|
||||
std::remove(LuaObject::luaDatabases.begin(), LuaObject::luaDatabases.end(), luaObject),
|
||||
std::remove(LuaObject::luaDatabases.begin(), LuaObject::luaDatabases.end(), luaObject->shared_from_this()),
|
||||
LuaObject::luaDatabases.end()
|
||||
);
|
||||
LuaObject::luaObjects.erase(
|
||||
std::remove(LuaObject::luaObjects.begin(), LuaObject::luaObjects.end(), luaObject),
|
||||
std::remove(LuaObject::luaObjects.begin(), LuaObject::luaObjects.end(), luaObject->shared_from_this()),
|
||||
LuaObject::luaObjects.end()
|
||||
);
|
||||
//After this function this object should be deleted.
|
||||
@ -41,13 +28,6 @@ LUA_FUNCTION(luaObjectGc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LUA_FUNCTION(luaObjectToString) {
|
||||
auto luaObject = LuaObject::checkMySQLOOType(LUA);
|
||||
auto str = luaObject->toString();
|
||||
LUA->PushString(str.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
LUA_CLASS_FUNCTION(LuaObject, luaObjectThink) {
|
||||
std::deque<std::shared_ptr<LuaDatabase>> databasesCopy = LuaObject::luaDatabases;
|
||||
for (auto &database: databasesCopy) {
|
||||
@ -56,16 +36,33 @@ LUA_CLASS_FUNCTION(LuaObject, luaObjectThink) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LuaObject::createUserDataMetaTable(GarrysMod::Lua::ILuaBase *LUA) {
|
||||
TYPE_USERDATA = LUA->CreateMetaTable("MySQLOO UserData");
|
||||
LUA->PushCFunction(luaObjectGc);
|
||||
LUA->SetField(-2, "__gc");
|
||||
LUA->Pop();
|
||||
}
|
||||
|
||||
void LuaObject::addMetaTableFunctions(GarrysMod::Lua::ILuaBase *lua) {
|
||||
lua->Push(-1);
|
||||
lua->SetField(-2, "__index");
|
||||
std::string LuaObject::toString() {
|
||||
std::stringstream ss;
|
||||
ss << m_className << " " << this;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
lua->PushCFunction(luaObjectGc);
|
||||
lua->SetField(-2, "__gc");
|
||||
LUA_FUNCTION(luaObjectToString) {
|
||||
LUA->GetUserType<LuaObject>(1, LuaObject::TYPE_USERDATA);
|
||||
auto luaObject = LuaObject::getLuaObject<LuaObject>(LUA);
|
||||
auto str = luaObject->toString();
|
||||
LUA->PushString(str.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua->PushCFunction(luaObjectToString);
|
||||
lua->SetField(-2, "__tostring");
|
||||
void LuaObject::addMetaTableFunctions(GarrysMod::Lua::ILuaBase *LUA) {
|
||||
LUA->Push(-1);
|
||||
LUA->SetField(-2, "__index");
|
||||
|
||||
LUA->PushCFunction(luaObjectToString);
|
||||
LUA->SetField(-2, "__tostring");
|
||||
}
|
||||
|
||||
LUA_FUNCTION(errorReporter) {
|
||||
@ -75,31 +72,42 @@ LUA_FUNCTION(errorReporter) {
|
||||
|
||||
if (LUA->IsType(-1, GarrysMod::Lua::Type::Function)) {
|
||||
LUA->Push(1);
|
||||
LUA->Call(1, 1);
|
||||
LUA->Call(1, 1); //The resulting stack trace will be returned
|
||||
} else {
|
||||
LUA->Pop(3); // global, traceback
|
||||
LUA->PushString("MySQLOO Error");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LuaObject::pcallWithErrorReporter(ILuaBase *LUA, int nargs, int nresults) {
|
||||
void LuaObject::pcallWithErrorReporter(ILuaBase *LUA, int nargs) {
|
||||
LUA->PushCFunction(errorReporter);
|
||||
int errorHandlerIndex = LUA->Top() - nargs - 2;
|
||||
LUA->Insert(-nargs - 2);
|
||||
LUA->PCall(nargs, nresults, errorHandlerIndex);
|
||||
int errorHandlerIndex = LUA->Top() - nargs - 1;
|
||||
LUA->Insert(errorHandlerIndex);
|
||||
int pcallResult = LUA->PCall(nargs, 0, errorHandlerIndex);
|
||||
if (pcallResult == 2) { //LUA_ERRRUN, we now have a stack trace on the stack
|
||||
LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB);
|
||||
LUA->GetField(-1, "ErrorNoHalt");
|
||||
if (LUA->IsType(-1, GarrysMod::Lua::Type::Function)) {
|
||||
LUA->Push(-3); //Stack trace
|
||||
LUA->Call(1, 0);
|
||||
LUA->Pop(2); //Stack trace, global
|
||||
} else {
|
||||
LUA->Pop(3); //Stack trace, global, nil
|
||||
}
|
||||
}
|
||||
LUA->Pop(); //Error reporter
|
||||
}
|
||||
|
||||
bool LuaObject::getCallbackReference(ILuaBase *LUA, int functionReference, int tableReference,
|
||||
const std::string &callbackName, bool allowCallback) {
|
||||
bool LuaObject::pushCallbackReference(ILuaBase *LUA, int functionReference, int tableReference,
|
||||
const std::string &callbackName, bool allowCallback) {
|
||||
//Push function reference
|
||||
if (functionReference != 0) {
|
||||
LUA->ReferencePush(functionReference);
|
||||
return true;
|
||||
} else if (allowCallback && tableReference != 0) {
|
||||
LUA->ReferencePush(tableReference);
|
||||
LUA->GetField(-1, callbackName.c_str());
|
||||
LUA->Remove(-2);
|
||||
LUA->Remove(LUA->Top() - 2);
|
||||
if (LUA->IsType(-1, GarrysMod::Lua::Type::Function)) {
|
||||
return true;
|
||||
} else {
|
||||
@ -109,7 +117,6 @@ bool LuaObject::getCallbackReference(ILuaBase *LUA, int functionReference, int t
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,67 +10,67 @@
|
||||
#include "GarrysMod/Lua/Interface.h"
|
||||
#include "../mysql/MySQLOOException.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class LuaDatabase;
|
||||
|
||||
using namespace GarrysMod::Lua;
|
||||
|
||||
class LuaObject : public std::enable_shared_from_this<LuaObject> {
|
||||
public:
|
||||
virtual ~LuaObject() = default;
|
||||
|
||||
std::string toString();
|
||||
|
||||
static std::deque<std::shared_ptr<LuaObject>> luaObjects;
|
||||
static std::deque<std::shared_ptr<LuaDatabase>> luaDatabases;
|
||||
|
||||
static std::shared_ptr<LuaObject> checkMySQLOOType(ILuaBase *lua, int position = 1);
|
||||
|
||||
static int TYPE_USERDATA;
|
||||
static int TYPE_DATABASE;
|
||||
static int TYPE_QUERY;
|
||||
static int TYPE_PREPARED_QUERY;
|
||||
static int TYPE_TRANSACTION;
|
||||
|
||||
static void addMetaTableFunctions(ILuaBase *lua);
|
||||
static void addMetaTableFunctions(ILuaBase *LUA);
|
||||
|
||||
static void createUserDataMetaTable(ILuaBase *lua);
|
||||
|
||||
//Lua functions
|
||||
static int luaObjectThink(lua_State *L);
|
||||
|
||||
static void pcallWithErrorReporter(ILuaBase *LUA, int nargs, int nresults);
|
||||
static void pcallWithErrorReporter(ILuaBase *LUA, int nargs);
|
||||
|
||||
static bool getCallbackReference(ILuaBase *LUA, int functionReference, int tableReference,
|
||||
const std::string &callbackName, bool allowCallback);
|
||||
static bool pushCallbackReference(ILuaBase *LUA, int functionReference, int tableReference,
|
||||
const std::string &callbackName, bool allowCallback);
|
||||
|
||||
static int getLuaObjectType(ILuaBase *LUA, int stackPos = 1) {
|
||||
LUA->CheckType(stackPos, GarrysMod::Lua::Type::Table);
|
||||
LUA->GetField(stackPos, "__CppObject");
|
||||
int type = LUA->GetType(-1);
|
||||
LUA->Pop();
|
||||
return type;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T *getLuaObject(ILuaBase *LUA, int type, int stackPos = 1) {
|
||||
template<class T>
|
||||
static T *getLuaObject(ILuaBase *LUA, int stackPos = 1) {
|
||||
LUA->CheckType(stackPos, GarrysMod::Lua::Type::Table);
|
||||
LUA->GetField(stackPos, "__CppObject");
|
||||
|
||||
T *returnValue = LUA->GetUserType<T>(-1, type);
|
||||
if (returnValue == nullptr) {
|
||||
auto *luaObject = LUA->GetUserType<LuaObject>(-1, TYPE_USERDATA);
|
||||
if (luaObject == nullptr) {
|
||||
LUA->ThrowError("[MySQLOO] Expected MySQLOO table");
|
||||
}
|
||||
T *returnValue = dynamic_cast<T*>(luaObject);
|
||||
if (returnValue == nullptr) {
|
||||
LUA->ThrowError("[MySQLOO] Invalid CPP Object");
|
||||
}
|
||||
LUA->Pop();
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static int getFunctionReference(ILuaBase *LUA, int stackPosition, const char* fieldName);
|
||||
static int getFunctionReference(ILuaBase *LUA, int stackPosition, const char *fieldName);
|
||||
|
||||
protected:
|
||||
explicit LuaObject(std::string className) : s_className(std::move(className)) {
|
||||
explicit LuaObject(std::string className) : m_className(std::move(className)) {
|
||||
|
||||
}
|
||||
|
||||
std::string s_className;
|
||||
std::string m_className;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#define MYSQLOO_LUA_FUNCTION(FUNC) \
|
||||
static int FUNC##__Imp( GarrysMod::Lua::ILuaBase* LUA ); \
|
||||
static int FUNC( lua_State* L ) \
|
||||
|
@ -1,8 +1,7 @@
|
||||
#include "LuaPreparedQuery.h"
|
||||
#include "../mysql/PreparedQuery.h"
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setNumber) {
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA, LuaObject::TYPE_PREPARED_QUERY);
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA);
|
||||
auto query = (PreparedQuery *) luaQuery->m_query.get();
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Number);
|
||||
LUA->CheckType(3, GarrysMod::Lua::Type::Number);
|
||||
@ -15,7 +14,7 @@ MYSQLOO_LUA_FUNCTION(setNumber) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setString) {
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA, LuaObject::TYPE_PREPARED_QUERY);
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA);
|
||||
auto query = (PreparedQuery *) luaQuery->m_query.get();
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Number);
|
||||
LUA->CheckType(3, GarrysMod::Lua::Type::String);
|
||||
@ -28,7 +27,7 @@ MYSQLOO_LUA_FUNCTION(setString) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setBoolean) {
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA, LuaObject::TYPE_PREPARED_QUERY);
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA);
|
||||
auto query = (PreparedQuery *) luaQuery->m_query.get();
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Number);
|
||||
LUA->CheckType(3, GarrysMod::Lua::Type::Bool);
|
||||
@ -40,7 +39,7 @@ MYSQLOO_LUA_FUNCTION(setBoolean) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(setNull) {
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA, LuaObject::TYPE_PREPARED_QUERY);
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA);
|
||||
auto query = (PreparedQuery *) luaQuery->m_query.get();
|
||||
LUA->CheckType(2, GarrysMod::Lua::Type::Number);
|
||||
double index = LUA->GetNumber(2);
|
||||
@ -50,14 +49,14 @@ MYSQLOO_LUA_FUNCTION(setNull) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(putNewParameters) {
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA, LuaObject::TYPE_PREPARED_QUERY);
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA);
|
||||
auto query = (PreparedQuery *) luaQuery->m_query.get();
|
||||
query->putNewParameters();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(clearParameters) {
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA, LuaObject::TYPE_PREPARED_QUERY);
|
||||
auto luaQuery = LuaObject::getLuaObject<LuaPreparedQuery>(LUA);
|
||||
auto query = (PreparedQuery *) luaQuery->m_query.get();
|
||||
query->clearParameters();
|
||||
return 0;
|
||||
|
@ -39,7 +39,6 @@ static void dataToLua(Query &query,
|
||||
} else {
|
||||
LUA->SetField(-2, columnName);
|
||||
}
|
||||
LUA->Pop();
|
||||
}
|
||||
|
||||
//Stores the data associated with the current result set of the query
|
||||
@ -74,33 +73,33 @@ int LuaQuery::createDataReference(GarrysMod::Lua::ILuaBase *LUA, Query &query, Q
|
||||
void LuaQuery::runSuccessCallback(ILuaBase *LUA, const std::shared_ptr<IQueryData> &data) {
|
||||
auto query = std::dynamic_pointer_cast<Query>(m_query);
|
||||
auto queryData = std::dynamic_pointer_cast<QueryData>(data);
|
||||
int tableReference = LuaQuery::createDataReference(LUA, *query, *queryData);
|
||||
int dataReference = LuaQuery::createDataReference(LUA, *query, *queryData);
|
||||
|
||||
if (!LuaIQuery::getCallbackReference(LUA, data->m_successReference, data->m_tableReference,
|
||||
"onSuccess", data->isFirstData())) {
|
||||
if (!LuaIQuery::pushCallbackReference(LUA, data->m_successReference, data->m_tableReference,
|
||||
"onSuccess", data->isFirstData())) {
|
||||
return;
|
||||
}
|
||||
LUA->ReferencePush(data->m_tableReference);
|
||||
LUA->ReferencePush(tableReference);
|
||||
LuaObject::pcallWithErrorReporter(LUA, 2, 0);
|
||||
LUA->ReferencePush(dataReference);
|
||||
LuaObject::pcallWithErrorReporter(LUA, 2);
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(affectedRows) {
|
||||
auto luaQuery = LuaQuery::getLuaQuery(LUA);
|
||||
auto luaQuery = LuaQuery::getLuaObject<LuaQuery>(LUA);
|
||||
auto query = (Query *) luaQuery->m_query.get();
|
||||
LUA->PushNumber((double) query->affectedRows());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(lastInsert) {
|
||||
auto luaQuery = LuaQuery::getLuaQuery(LUA);
|
||||
auto luaQuery = LuaQuery::getLuaObject<LuaQuery>(LUA);
|
||||
auto query = (Query *) luaQuery->m_query.get();
|
||||
LUA->PushNumber((double) query->lastInsert());
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(getData) {
|
||||
auto luaQuery = LuaQuery::getLuaQuery(LUA);
|
||||
auto luaQuery = LuaQuery::getLuaObject<LuaQuery>(LUA);
|
||||
auto query = (Query *) luaQuery->m_query.get();
|
||||
if (!query->hasCallbackData() || query->callbackQueryData->getResultStatus() == QUERY_ERROR) {
|
||||
LUA->PushNil();
|
||||
@ -112,14 +111,14 @@ MYSQLOO_LUA_FUNCTION(getData) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(hasMoreResults) {
|
||||
auto luaQuery = LuaQuery::getLuaQuery(LUA);
|
||||
auto luaQuery = LuaQuery::getLuaObject<LuaQuery>(LUA);
|
||||
auto query = (Query *) luaQuery->m_query.get();
|
||||
LUA->PushBool(query->hasMoreResults());
|
||||
return 1;
|
||||
}
|
||||
|
||||
LUA_FUNCTION(getNextResults) {
|
||||
auto luaQuery = LuaQuery::getLuaQuery(LUA);
|
||||
auto luaQuery = LuaQuery::getLuaObject<LuaQuery>(LUA);
|
||||
auto query = (Query *) luaQuery->m_query.get();
|
||||
query->getNextResults();
|
||||
return 0;
|
||||
|
@ -15,18 +15,6 @@ public:
|
||||
|
||||
static void createMetaTable(ILuaBase *LUA);
|
||||
|
||||
static LuaQuery *getLuaQuery(ILuaBase *LUA, int stackPos = 1) {
|
||||
int type = LuaObject::getLuaObjectType(LUA, stackPos);
|
||||
if (type != LuaObject::TYPE_QUERY && type != LuaObject::TYPE_PREPARED_QUERY) {
|
||||
LUA->ThrowError("[MySQLOO] Expected MySQLOO query");
|
||||
}
|
||||
auto *returnValue = LuaObject::getLuaObject<LuaQuery>(LUA, type, stackPos);
|
||||
if (returnValue == nullptr) {
|
||||
LUA->ThrowError("[MySQLOO] Expected MySQLOO table");
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
static std::shared_ptr<LuaQuery> create(const std::shared_ptr<Query> &query) {
|
||||
auto instance = std::shared_ptr<LuaQuery>(new LuaQuery(query, "MySQLOO Query"));
|
||||
LuaObject::luaObjects.push_back(instance);
|
||||
|
@ -3,10 +3,9 @@
|
||||
#include "../mysql/Transaction.h"
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(addQuery) {
|
||||
auto luaTransaction = LuaObject::getLuaObject<LuaTransaction>(LUA, LuaObject::TYPE_TRANSACTION);
|
||||
auto luaTransaction = LuaObject::getLuaObject<LuaTransaction>(LUA);
|
||||
|
||||
auto addedLuaQuery = LuaQuery::getLuaQuery(LUA, 2);
|
||||
auto addedQuery = (Query *) addedLuaQuery->m_query.get();
|
||||
auto addedLuaQuery = LuaQuery::getLuaObject<LuaQuery>(LUA, 2);
|
||||
LUA->Push(1);
|
||||
LUA->GetField(-1, "__queries");
|
||||
if (LUA->IsType(-1, GarrysMod::Lua::Type::Nil)) {
|
||||
@ -36,7 +35,7 @@ MYSQLOO_LUA_FUNCTION(getQueries) {
|
||||
}
|
||||
|
||||
MYSQLOO_LUA_FUNCTION(clearQueries) {
|
||||
auto luaTransaction = LuaObject::getLuaObject<LuaTransaction>(LUA, LuaObject::TYPE_TRANSACTION);
|
||||
auto luaTransaction = LuaObject::getLuaObject<LuaTransaction>(LUA);
|
||||
|
||||
LUA->Push(1);
|
||||
LUA->CreateTable();
|
||||
@ -63,23 +62,24 @@ void LuaTransaction::createMetaTable(ILuaBase *LUA) {
|
||||
|
||||
std::shared_ptr<IQueryData> LuaTransaction::buildQueryData(ILuaBase *LUA, int stackPosition) {
|
||||
LUA->GetField(stackPosition, "__queries");
|
||||
|
||||
std::deque<std::pair<std::shared_ptr<Query>, std::shared_ptr<IQueryData>>> queries;
|
||||
|
||||
for (int i = 0; i < this->m_addedQueryData.size(); i++) {
|
||||
auto& queryData = this->m_addedQueryData[i];
|
||||
LUA->PushNumber((double) (i + 1));
|
||||
LUA->RawGet(-2);
|
||||
if (!LUA->IsType(-1, GarrysMod::Lua::Type::Table)) {
|
||||
LUA->Pop();
|
||||
break;
|
||||
if (LUA->GetType(-1) != GarrysMod::Lua::Type::Nil) {
|
||||
for (int i = 0; i < this->m_addedQueryData.size(); i++) {
|
||||
auto &queryData = this->m_addedQueryData[i];
|
||||
LUA->PushNumber((double) (i + 1));
|
||||
LUA->RawGet(-2);
|
||||
if (!LUA->IsType(-1, GarrysMod::Lua::Type::Table)) {
|
||||
LUA->Pop(); //Nil or whatever else is on the stack
|
||||
break;
|
||||
}
|
||||
auto luaQuery = LuaQuery::getLuaObject<LuaQuery>(LUA, -1);
|
||||
auto query = std::dynamic_pointer_cast<Query>(luaQuery->m_query);
|
||||
query->addQueryData(queryData);
|
||||
queries.emplace_back(query, queryData);
|
||||
LUA->Pop(); //Query
|
||||
}
|
||||
auto luaQuery = LuaQuery::getLuaQuery(LUA, -1);
|
||||
auto query = std::dynamic_pointer_cast<Query>(luaQuery->m_query);
|
||||
query->addQueryData(queryData);
|
||||
queries.emplace_back(query, queryData);
|
||||
}
|
||||
|
||||
LUA->Pop(); //Queries table
|
||||
auto data = Transaction::buildQueryData(queries);
|
||||
LuaIQuery::referenceCallbacks(LUA, stackPosition, *data);
|
||||
return data;
|
||||
@ -87,29 +87,37 @@ std::shared_ptr<IQueryData> LuaTransaction::buildQueryData(ILuaBase *LUA, int st
|
||||
|
||||
void LuaTransaction::runSuccessCallback(ILuaBase *LUA, const std::shared_ptr<IQueryData> &data) {
|
||||
auto transactionData = std::dynamic_pointer_cast<TransactionData>(data);
|
||||
if (transactionData->m_tableReference == 0) return;
|
||||
transactionData->setStatus(QUERY_COMPLETE);
|
||||
std::vector<int> queryTableRefs;
|
||||
for (auto& pair : transactionData->m_queries) {
|
||||
LUA->CreateTable();
|
||||
int index = 0;
|
||||
for (auto &pair: transactionData->m_queries) {
|
||||
LUA->PushNumber((double) (++index));
|
||||
auto query = pair.first;
|
||||
//So we get the current data rather than caching it, if the same query is added multiple times.
|
||||
query->m_dataReference = 0;
|
||||
if (query->m_dataReference != 0) {
|
||||
query->m_dataReference = 0;
|
||||
LUA->ReferenceFree(query->m_dataReference);
|
||||
}
|
||||
auto queryData = std::dynamic_pointer_cast<QueryData>(pair.second);
|
||||
query->setCallbackData(pair.second);
|
||||
int ref = LuaQuery::createDataReference(LUA, *query, *queryData);
|
||||
queryTableRefs.push_back(ref);
|
||||
}
|
||||
LUA->CreateTable();
|
||||
for (size_t i = 0; i < queryTableRefs.size(); i++) {
|
||||
LUA->PushNumber((double) (i + 1));
|
||||
LUA->ReferencePush(queryTableRefs[i]);
|
||||
LUA->ReferencePush(ref);
|
||||
LUA->SetTable(-3);
|
||||
//The last data reference can stay cached in the query and will be free'd once the query is gc'ed
|
||||
}
|
||||
int dataRef = LUA->ReferenceCreate();
|
||||
if (data->getSuccessReference() != 0) {
|
||||
|
||||
} else if (data->isFirstData()) {
|
||||
|
||||
if (!LuaIQuery::pushCallbackReference(LUA, data->m_successReference, data->m_tableReference,
|
||||
"onSuccess", data->isFirstData())) {
|
||||
LUA->Pop(); //Table of results
|
||||
return;
|
||||
}
|
||||
LUA->ReferencePush(transactionData->m_tableReference);
|
||||
LUA->Push(-3); //Table of results
|
||||
LuaObject::pcallWithErrorReporter(LUA, 2);
|
||||
|
||||
LUA->ReferenceFree(dataRef);
|
||||
LUA->Pop(); //Table of results
|
||||
|
||||
for (auto &pair: transactionData->m_queries) {
|
||||
LuaIQuery::finishQueryData(LUA, pair.second);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user