Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
dankmolot committed Nov 23, 2024
1 parent 25a6c5c commit 93ef1d7
Show file tree
Hide file tree
Showing 8 changed files with 467 additions and 238 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ jobs:
CMAKE_ARCH_FLAG: --preset=x86-windows
- os: ubuntu-20.04
arch: x64
CMAKE_ARCH_FLAG: --preset=unix
CMAKE_ARCH_FLAG: --preset=x64-linux
- os: ubuntu-20.04
arch: x86
CMAKE_ARCH_FLAG: --preset=unix -DCMAKE_C_FLAGS="-m32" -DCMAKE_CXX_FLAGS="-m32" -DVCPKG_TARGET_TRIPLET=x86-linux
CMAKE_ARCH_FLAG: --preset=x86-linux
- os: macos-13
arch: x64
CMAKE_ARCH_FLAG: --preset=unix
CMAKE_ARCH_FLAG: --preset=x64-macos

runs-on: ${{ matrix.os }}

Expand Down
20 changes: 18 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,25 @@
}
},
{
"name": "unix",
"name": "x64-linux",
"inherits": "vcpkg",
"generator": "Ninja"
"generator": "Ninja",
"architecture": "x64"
},
{
"name": "x86-linux",
"inherits": "vcpkg",
"generator": "Ninja",
"architecture": "x86"
},
{
"name": "x64-macos",
"inherits": "vcpkg",
"generator": "Ninja",
"architecture": "x64",
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "x64-osx"
}
}
]
}
25 changes: 24 additions & 1 deletion source/async_postgres.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#pragma once

#include <GarrysMod/Lua/AutoReference.h>
#include <GarrysMod/Lua/Interface.h>
#include <GarrysMod/Lua/LuaInterface.h>
#include <libpq-fe.h>

#include <algorithm>
#include <chrono>
#include <exception>
#include <memory>
#include <optional>
#include <queue>
#include <string_view>
#include <variant>
Expand Down Expand Up @@ -49,20 +51,34 @@ namespace async_postgres {
std::string command;
};

struct ParameterizedCommand {
std::string command;
std::vector<std::string> values;
};

struct Query {
std::variant<SimpleCommand> command;
std::variant<SimpleCommand, ParameterizedCommand> command;
GLua::AutoReference callback;
bool sent = false;
bool flushed = false;
};

struct ResetEvent {
std::vector<GLua::AutoReference> callbacks;
PostgresPollingStatusType status = PGRES_POLLING_WRITING;
};

using PGconnPtr = std::unique_ptr<PGconn, decltype(&PQfinish)>;

struct Connection {
PGconnPtr conn;
GLua::AutoReference lua_table;
std::queue<Query> queries;
std::optional<ResetEvent> reset_event;
bool receive_notifications =
false; // enabled if on_notify lua field is set

Connection(GLua::ILuaInterface* lua, PGconnPtr&& conn);
~Connection();
};

Expand All @@ -74,6 +90,10 @@ namespace async_postgres {
GLua::AutoReference&& callback);
void process_pending_connections(GLua::ILuaInterface* lua);

void reset(GLua::ILuaInterface* lua, Connection* state,
GLua::AutoReference&& callback);
void process_reset(GLua::ILuaInterface* lua, Connection* state);

// notifications.cpp
void process_notifications(GLua::ILuaInterface* lua, Connection* state);

Expand All @@ -83,6 +103,9 @@ namespace async_postgres {
// result.cpp
void create_result_table(GLua::ILuaInterface* lua, PGresult* result);

// misc.cpp
void register_misc_connection_functions(GLua::ILuaInterface* lua);

// util.cpp
std::string_view get_string(GLua::ILuaInterface* lua, int index = -1);
void pcall(GLua::ILuaInterface* lua, int nargs, int nresults);
Expand Down
72 changes: 63 additions & 9 deletions source/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ using namespace async_postgres;

std::vector<Connection*> async_postgres::connections = {};

Connection::Connection(GLua::ILuaInterface* lua, PGconnPtr&& conn)
: conn(std::move(conn)) {
lua->CreateTable();
this->lua_table = GLua::AutoReference(lua);

// add connection to global list
connections.push_back(this);
}

Connection::~Connection() {
// remove connection from global list
// so event loop doesn't try to process it
connections.erase(std::find(connections.begin(), connections.end(), this));
}

struct ConnectionEvent {
PGconnPtr conn;
GLua::AutoReference callback;
Expand Down Expand Up @@ -47,22 +62,14 @@ void async_postgres::connect(GLua::ILuaInterface* lua, std::string_view url,
inline bool poll_pending_connection(GLua::ILuaInterface* lua,
ConnectionEvent& event) {
if (!socket_is_ready(event.conn.get(), event.status)) {
lua->Msg("socket is not ready (%s)\n",
event.status == PGRES_POLLING_READING ? "reading" : "writing");
return false;
}

// TODO: handle reset

event.status = PQconnectPoll(event.conn.get());
lua->Msg("status: %d (%d)\n", event.status, PQstatus(event.conn.get()));
if (event.status == PGRES_POLLING_OK) {
auto state = new Connection{std::move(event.conn)};

lua->CreateTable();
state->lua_table = GLua::AutoReference(lua);

connections.push_back(state);
auto state = new Connection(lua, std::move(event.conn));

event.callback.Push();
lua->PushBool(true);
Expand Down Expand Up @@ -96,3 +103,50 @@ void async_postgres::process_pending_connections(GLua::ILuaInterface* lua) {
}
}
}

void async_postgres::reset(GLua::ILuaInterface* lua, Connection* state,
GLua::AutoReference&& callback) {
if (!state->reset_event) {
if (PQresetStart(state->conn.get()) == 0) {
throw std::runtime_error(PQerrorMessage(state->conn.get()));
}

state->reset_event = ResetEvent();
}

if (callback) {
state->reset_event->callbacks.push_back(std::move(callback));
}
}

void async_postgres::process_reset(GLua::ILuaInterface* lua,
Connection* state) {
if (!state->reset_event) {
return;
}

auto& event = state->reset_event.value();
if (!socket_is_ready(state->conn.get(), state->reset_event->status)) {
return;
}

event.status = PQresetPoll(state->conn.get());
if (event.status == PGRES_POLLING_OK) {
for (auto& callback : event.callbacks) {
callback.Push();
lua->PushBool(true);
pcall(lua, 1, 0);
}

state->reset_event.reset();
} else if (event.status == PGRES_POLLING_FAILED) {
for (auto& callback : event.callbacks) {
callback.Push();
lua->PushBool(false);
lua->PushString(PQerrorMessage(state->conn.get()));
pcall(lua, 2, 0);
}

state->reset_event.reset();
}
}
Loading

0 comments on commit 93ef1d7

Please sign in to comment.