Skip to content

Commit a60e658

Browse files
committed
Fully implemented result handling with removing query when it's done
1 parent 0318532 commit a60e658

File tree

2 files changed

+62
-26
lines changed

2 files changed

+62
-26
lines changed

source/query.cpp

+58-26
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,32 @@ void query_failed(GLua::ILuaInterface* lua, Connection* state) {
3939
}
4040
}
4141

42+
inline bool bad_result(PGresult* result) {
43+
if (!result) {
44+
return true;
45+
}
46+
47+
auto status = PQresultStatus(result);
48+
49+
return status == PGRES_BAD_RESPONSE || status == PGRES_NONFATAL_ERROR ||
50+
status == PGRES_FATAL_ERROR;
51+
}
52+
53+
void query_result(GLua::ILuaInterface* lua, pg::result&& result,
54+
GLua::AutoReference& callback) {
55+
if (callback.Push()) {
56+
if (!bad_result(result.get())) {
57+
lua->PushBool(true);
58+
create_result_table(lua, result.get());
59+
} else {
60+
lua->PushBool(false);
61+
lua->PushString(PQresultErrorMessage(result.get()));
62+
}
63+
64+
pcall(lua, 2, 0);
65+
}
66+
}
67+
4268
// returns true if poll was successful
4369
// returns false if there was an error
4470
inline bool poll_query(PGconn* conn, Query& query) {
@@ -55,15 +81,39 @@ inline bool poll_query(PGconn* conn, Query& query) {
5581
return true;
5682
}
5783

58-
bool bad_result(PGresult* result) {
84+
void process_result(GLua::ILuaInterface* lua, Connection* state,
85+
pg::result&& result) {
86+
// query is done
5987
if (!result) {
60-
return true;
88+
state->query.reset();
89+
return process_query(lua, state);
6190
}
6291

63-
auto status = PQresultStatus(result);
92+
// next result might be empty,
93+
// that means that query is done
94+
// and we need to remove query from the state
95+
// so callback can add another query
96+
if (!pg::isBusy(state->conn)) {
97+
auto next_result = pg::getResult(state->conn);
98+
if (!next_result) {
99+
// query is done, we need to remove query from the state
100+
Query query = std::move(*state->query);
101+
state->query.reset();
64102

65-
return status == PGRES_BAD_RESPONSE || status == PGRES_NONFATAL_ERROR ||
66-
status == PGRES_FATAL_ERROR;
103+
query_result(lua, std::move(result), query.callback);
104+
105+
// callback might added another query, process it rightaway
106+
process_query(lua, state);
107+
} else {
108+
// query is not done, but also since we own next result
109+
// we need to call query callback and process next result
110+
query_result(lua, std::move(result), state->query->callback);
111+
process_result(lua, state, std::move(next_result));
112+
}
113+
} else {
114+
// query is not done, but we don't need to process next result
115+
query_result(lua, std::move(result), state->query->callback);
116+
}
67117
}
68118

69119
void async_postgres::process_query(GLua::ILuaInterface* lua,
@@ -90,26 +140,8 @@ void async_postgres::process_query(GLua::ILuaInterface* lua,
90140
return process_query(lua, state);
91141
}
92142

93-
while (PQisBusy(state->conn.get()) == 0) {
94-
auto result = pg::getResult(state->conn);
95-
if (!result) {
96-
// query is done
97-
// TODO: remove query if we have a final result
98-
state->query.reset();
99-
return process_query(lua, state);
100-
}
101-
102-
if (query.callback) {
103-
query.callback.Push();
104-
if (!bad_result(result.get())) {
105-
lua->PushBool(true);
106-
create_result_table(lua, result.get());
107-
} else {
108-
lua->PushBool(false);
109-
lua->PushString(PQresultErrorMessage(result.get()));
110-
}
111-
112-
pcall(lua, 2, 0);
113-
}
143+
// ensure that getting result won't block
144+
if (!pg::isBusy(state->conn)) {
145+
return process_result(lua, state, pg::getResult(state->conn));
114146
}
115147
}

source/safe_pg.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ namespace async_postgres::pg {
2323
inline notify getNotify(conn& conn) {
2424
return notify(PQnotifies(conn.get()), &PQfreemem);
2525
}
26+
27+
// misc
28+
29+
inline bool isBusy(conn& conn) { return PQisBusy(conn.get()) == 1; }
2630
} // namespace async_postgres::pg

0 commit comments

Comments
 (0)