Skip to content

Commit 050d093

Browse files
committed
Added option to get row fields as array
1 parent 8567e18 commit 050d093

File tree

5 files changed

+59
-8
lines changed

5 files changed

+59
-8
lines changed

async_postgres.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@
9090
---@field escapeBytea fun(self: PGconn, str: string): string
9191
---@field unescapeBytea fun(self: PGconn, str: string): string
9292
---@field setNotifyCallback fun(self: PGconn, callback: fun(channel: string, payload: string, backendPID: number))
93+
---@field getNotifyCallback fun(self: PGconn): fun(channel: string, payload: string, backendPID: number)
94+
---@field setArrayResult fun(self: PGconn, enabled: boolean)
95+
---@field getArrayResult fun(self: PGconn): boolean
9396

9497
---@class PGResult
9598
---@field fields { name: string, type: number }[] list of fields in the result
@@ -161,6 +164,7 @@ end
161164
---@field url string **readonly** connection url
162165
---@field connecting boolean **readonly** is client connecting to the database
163166
---@field closed boolean **readonly** is client closed (to change it to true use `:close()`)
167+
---@field array_result boolean option to receive PGResult row fields as array instead of table (default: false)
164168
---@field private conn PGconn native connection object (do not use it directly, otherwise be careful not to store it anywhere else, otherwise closing connection will be impossible)
165169
---@field private queries { push: fun(self, q: PGQuery), prepend: fun(self, q: PGQuery), pop: (fun(self): PGQuery), size: fun(self): number } list of queries
166170
---@field package acquired boolean
@@ -275,7 +279,17 @@ end
275279
---@private
276280
---@param query PGQuery
277281
function Client:runQuery(query)
282+
local array_result = self.array_result
283+
if array_result then
284+
self.conn:setArrayResult(true)
285+
end
286+
278287
local function callback(ok, result, errdata)
288+
if array_result and not self.conn:querying() then
289+
-- final query, reset array result
290+
self.conn:setArrayResult(false)
291+
end
292+
279293
xpcall(query.callback, ErrorNoHaltWithStack, ok, result, errdata)
280294
self:processQueue()
281295
end
@@ -934,6 +948,7 @@ function Pool:describePortal(name, callback)
934948
end)
935949
end
936950

951+
---@async
937952
local function transactionThread(client, callback)
938953
xpcall(function()
939954
local ctx = TransactionContext.new(client)

source/async_postgres.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ namespace async_postgres {
113113
std::shared_ptr<Query> query;
114114
std::shared_ptr<ResetEvent> reset_event;
115115
GLua::AutoReference on_notify;
116+
bool array_result = false;
116117

117118
Connection(GLua::ILuaInterface* lua, pg::conn&& conn);
118119
~Connection();
@@ -139,7 +140,8 @@ namespace async_postgres {
139140
void process_query(GLua::ILuaInterface* lua, Connection* state);
140141

141142
// result.cpp
142-
void create_result_table(GLua::ILuaInterface* lua, PGresult* result);
143+
void create_result_table(GLua::ILuaInterface* lua, PGresult* result,
144+
bool array_result);
143145

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

source/main.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,15 @@ namespace async_postgres::lua {
198198
return 0;
199199
}
200200

201+
lua_protected_fn(getNotifyCallback) {
202+
lua->CheckType(1, async_postgres::connection_meta);
203+
auto state = lua_connection_state();
204+
if (!state->on_notify.Push()) {
205+
lua->PushNil();
206+
}
207+
return 1;
208+
}
209+
201210
lua_protected_fn(wait) {
202211
lua->CheckType(1, async_postgres::connection_meta);
203212

@@ -263,6 +272,21 @@ namespace async_postgres::lua {
263272
lua->PushBool(!!state->reset_event);
264273
return 1;
265274
}
275+
276+
lua_protected_fn(setArrayResult) {
277+
lua->CheckType(1, async_postgres::connection_meta);
278+
lua->CheckType(2, GLua::Type::Bool);
279+
auto state = lua_connection_state();
280+
state->array_result = lua->GetBool(2);
281+
return 0;
282+
}
283+
284+
lua_protected_fn(getArrayResult) {
285+
lua->CheckType(1, async_postgres::connection_meta);
286+
auto state = lua_connection_state();
287+
lua->PushBool(state->array_result);
288+
return 1;
289+
}
266290
} // namespace async_postgres::lua
267291

268292
#define register_lua_fn(name) \
@@ -284,10 +308,13 @@ void register_connection_mt(GLua::ILuaInterface* lua) {
284308
register_lua_fn(describePortal);
285309
register_lua_fn(reset);
286310
register_lua_fn(setNotifyCallback);
311+
register_lua_fn(getNotifyCallback);
287312
register_lua_fn(wait);
288313
register_lua_fn(isBusy);
289314
register_lua_fn(querying);
290315
register_lua_fn(resetting);
316+
register_lua_fn(setArrayResult);
317+
register_lua_fn(getArrayResult);
291318

292319
async_postgres::register_misc_connection_functions(lua);
293320

source/query.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ inline void create_result_error_table(GLua::ILuaInterface* lua,
9494
}
9595

9696
void query_result(GLua::ILuaInterface* lua, pg::result&& result,
97-
GLua::AutoReference& callback) {
97+
GLua::AutoReference& callback, bool array_result) {
9898
if (callback.Push()) {
9999
if (!bad_result(result.get())) {
100100
lua->PushBool(true);
101-
create_result_table(lua, result.get());
101+
create_result_table(lua, result.get(), array_result);
102102
pcall(lua, 2, 0);
103103
} else {
104104
lua->PushBool(false);
@@ -144,19 +144,22 @@ void async_postgres::process_result(GLua::ILuaInterface* lua, Connection* state,
144144
auto query = state->query;
145145
state->query.reset();
146146

147-
query_result(lua, std::move(result), query->callback);
147+
query_result(lua, std::move(result), query->callback,
148+
state->array_result);
148149

149150
// callback might added another query, process it rightaway
150151
process_query(lua, state);
151152
} else {
152153
// query is not done, but also since we own next result
153154
// we need to call query callback and process next result
154-
query_result(lua, std::move(result), state->query->callback);
155+
query_result(lua, std::move(result), state->query->callback,
156+
state->array_result);
155157
process_result(lua, state, std::move(next_result));
156158
}
157159
} else {
158160
// query is not done, but we don't need to process next result
159-
query_result(lua, std::move(result), state->query->callback);
161+
query_result(lua, std::move(result), state->query->callback,
162+
state->array_result);
160163
}
161164
}
162165

source/result.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct FieldInfo {
1010
};
1111

1212
void async_postgres::create_result_table(GLua::ILuaInterface* lua,
13-
PGresult* result) {
13+
PGresult* result, bool array_result) {
1414
lua->CreateTable();
1515

1616
std::vector<FieldInfo> fields;
@@ -46,7 +46,11 @@ void async_postgres::create_result_table(GLua::ILuaInterface* lua,
4646
// skip NULL values
4747
if (!PQgetisnull(result, i, j)) {
4848
// field name
49-
lua->PushString(fields[j].name);
49+
if (!array_result) {
50+
lua->PushString(fields[j].name);
51+
} else {
52+
lua->PushNumber(j + 1);
53+
}
5054

5155
// field value
5256
lua->PushString(PQgetvalue(result, i, j),

0 commit comments

Comments
 (0)