Skip to content

Commit 2b07410

Browse files
committed
Added queryParams
1 parent 4d7bc30 commit 2b07410

File tree

5 files changed

+67
-31
lines changed

5 files changed

+67
-31
lines changed

source/async_postgres.hpp

+21-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,24 @@ namespace GLua = GarrysMod::Lua;
4242
int name##__Imp([[maybe_unused]] GarrysMod::Lua::ILuaInterface* lua)
4343

4444
namespace async_postgres {
45+
typedef std::variant<std::nullptr_t, std::string, double, bool> ParamValue;
46+
47+
struct ParamValues {
48+
ParamValues(int n_params)
49+
: strings(n_params),
50+
values(n_params),
51+
lengths(n_params, 0),
52+
formats(n_params, 0) {}
53+
54+
inline int length() const { return strings.size(); }
55+
56+
std::vector<std::string> strings;
57+
// vectors below are used in PQexecParams-like functions
58+
std::vector<const char*> values;
59+
std::vector<int> lengths;
60+
std::vector<int> formats;
61+
};
62+
4563
struct SocketStatus {
4664
bool read_ready = false;
4765
bool write_ready = false;
@@ -54,7 +72,7 @@ namespace async_postgres {
5472

5573
struct ParameterizedCommand {
5674
std::string command;
57-
std::vector<std::string> values;
75+
ParamValues param;
5876
};
5977

6078
struct Query {
@@ -108,5 +126,7 @@ namespace async_postgres {
108126
// util.cpp
109127
std::string_view get_string(GLua::ILuaInterface* lua, int index = -1);
110128
void pcall(GLua::ILuaInterface* lua, int nargs, int nresults);
129+
// Converts a lua array at given index to a ParamValues
130+
ParamValues array_to_params(GLua::ILuaInterface* lua, int index);
111131
SocketStatus check_socket_status(PGconn* conn);
112132
}; // namespace async_postgres

source/main.cpp

+5-15
Original file line numberDiff line numberDiff line change
@@ -101,21 +101,10 @@ namespace async_postgres::lua {
101101

102102
auto state = lua_connection_state();
103103

104-
async_postgres::ParameterizedCommand command = {lua->GetString(2)};
105-
106-
lua->Push(3);
107-
for (int i = 1;; i++) {
108-
lua->PushNumber(i);
109-
lua->GetTable(-2);
110-
if (lua->IsType(-1, GLua::Type::Nil)) {
111-
lua->Pop(2);
112-
break;
113-
}
114-
115-
auto str = get_string(lua, -1);
116-
command.values.push_back({str.data(), str.size()});
117-
lua->Pop(1);
118-
}
104+
async_postgres::ParameterizedCommand command = {
105+
lua->GetString(2),
106+
async_postgres::array_to_params(lua, 3),
107+
};
119108

120109
async_postgres::Query query = {std::move(command)};
121110
query.callback = GLua::AutoReference(lua, 4);
@@ -150,6 +139,7 @@ void register_connection_mt(GLua::ILuaInterface* lua) {
150139
register_lua_fn(__newindex);
151140
register_lua_fn(__gc);
152141
register_lua_fn(query);
142+
register_lua_fn(queryParams);
153143
register_lua_fn(reset);
154144

155145
async_postgres::register_misc_connection_functions(lua);

source/misc.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,6 @@ namespace async_postgres::lua {
165165
PQfreemem(unescaped);
166166
return 1;
167167
}
168-
169-
// 34.3. Asynchronous Command Processing
170-
lua_bool_getter(isBusy, PQisBusy);
171168
} // namespace async_postgres::lua
172169

173170
#define register_lua_fn(name) \
@@ -197,5 +194,4 @@ void async_postgres::register_misc_connection_functions(
197194
register_lua_fn(escapeIdentifier);
198195
register_lua_fn(escapeBytea);
199196
register_lua_fn(unescapeBytea);
200-
register_lua_fn(isBusy);
201197
}

source/query.cpp

+5-11
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,11 @@ inline bool send_query(PGconn* conn, Query& query) {
99
return PQsendQuery(conn, command->command.c_str()) == 1;
1010
} else if (const auto* command =
1111
std::get_if<ParameterizedCommand>(&query.command)) {
12-
size_t nParams = command->values.size();
13-
std::vector<const char*> paramValues(nParams);
14-
for (size_t i = 0; i < nParams; i++) {
15-
paramValues[i] = command->values[i].c_str();
16-
}
17-
18-
bool success =
19-
PQsendQueryParams(conn, command->command.c_str(), nParams, nullptr,
20-
paramValues.data(), nullptr, nullptr, 0) == 1;
21-
22-
return success;
12+
return PQsendQueryParams(conn, command->command.c_str(),
13+
command->param.length(), nullptr,
14+
command->param.values.data(),
15+
command->param.lengths.data(),
16+
command->param.formats.data(), 0) == 1;
2317
}
2418
return false;
2519
}

source/util.cpp

+36
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,42 @@ void async_postgres::pcall(GLua::ILuaInterface* lua, int nargs, int nresults) {
3333
lua->Pop(); // ErrorNoHaltWithStack
3434
}
3535

36+
ParamValues async_postgres::array_to_params(GLua::ILuaInterface* lua,
37+
int index) {
38+
lua->Push(index);
39+
int len = lua->ObjLen(-1);
40+
41+
ParamValues param(len);
42+
for (int i = 0; i < len; i++) {
43+
lua->PushNumber(i + 1);
44+
lua->GetTable(-2);
45+
46+
auto type = lua->GetType(-1);
47+
if (type == GLua::Type::String) {
48+
auto value = get_string(lua, -1);
49+
param.strings[i] = std::string(value.data(), value.size());
50+
param.values[i] = param.strings[i].c_str();
51+
param.lengths[i] = value.length();
52+
param.formats[i] = 1;
53+
} else if (type == GLua::Type::Number) {
54+
param.strings[i] = std::to_string(lua->GetNumber(-1));
55+
param.values[i] = param.strings[i].c_str();
56+
} else if (type == GLua::Type::Bool) {
57+
param.values[i] = lua->GetBool(-1) ? "true" : "false";
58+
} else if (type == GLua::Type::Nil) {
59+
param.values[i] = nullptr;
60+
} else {
61+
throw std::runtime_error(
62+
"unsupported type given into params array");
63+
}
64+
65+
lua->Pop(1);
66+
}
67+
68+
lua->Pop(1);
69+
return param;
70+
}
71+
3672
#if SYSTEM_IS_WINDOWS
3773
#include <WinSock2.h>
3874
#define poll WSAPoll

0 commit comments

Comments
 (0)