@@ -39,6 +39,32 @@ void query_failed(GLua::ILuaInterface* lua, Connection* state) {
39
39
}
40
40
}
41
41
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
+
42
68
// returns true if poll was successful
43
69
// returns false if there was an error
44
70
inline bool poll_query (PGconn* conn, Query& query) {
@@ -55,15 +81,39 @@ inline bool poll_query(PGconn* conn, Query& query) {
55
81
return true ;
56
82
}
57
83
58
- bool bad_result (PGresult* result) {
84
+ void process_result (GLua::ILuaInterface* lua, Connection* state,
85
+ pg::result&& result) {
86
+ // query is done
59
87
if (!result) {
60
- return true ;
88
+ state->query .reset ();
89
+ return process_query (lua, state);
61
90
}
62
91
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 ();
64
102
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
+ }
67
117
}
68
118
69
119
void async_postgres::process_query (GLua::ILuaInterface* lua,
@@ -90,26 +140,8 @@ void async_postgres::process_query(GLua::ILuaInterface* lua,
90
140
return process_query (lua, state);
91
141
}
92
142
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 ));
114
146
}
115
147
}
0 commit comments