Reputation: 10003
I'm writing a PostgreSQL library in Objective-C, based on libpq (written in C). While I've built a synchronous querying method that uses PQexec
sucessfully; my asynchronous method never receives the query's results. PQgetResult
always returns NULL
.
I've tried various combinations of connection- and query-checking, but none of them corrected the issue. The query itself is a SELECT
on a table with one row. I can swap out this asynchronous method for the synchronous method and have the desired behavior. I have also checked the conn
pointer I'm retaining is referencing the same object throughout.
I am not using single row mode.
+ (instancetype) resultSetWithQuery: (NSString*) query usingConnection: (PGConnection*) conn whenComplete: (Callback) callback {
PGResultSet* resultSet = [[PGResultSet alloc] init];
NSString* encoding = [conn encoding];
int success = PQsendQuery([conn conn], [query UTF8String]);
[resultSet setEncoding:encoding];
[resultSet setQuery:query];
[resultSet setConn:conn];
if(success){
NSTimeInterval timeInterval = 0.5;
NSTimer* checkStatus = [NSTimer scheduledTimerWithTimeInterval:timeInterval
target:resultSet
selector:@selector(checkIfComplete)
userInfo:nil
repeats:YES];
[resultSet setTimer:checkStatus];
[resultSet setCallback:callback];
}
return resultSet;
}
- (void)checkIfComplete{
if(!PQconsumeInput([[self conn] conn])){
[[self timer] invalidate];
}
if(PQisBusy([[self conn] conn])){
return;
}
// result is always NULL
PGresult* result = PQgetResult([[self conn] conn]);
// ...
}
Upvotes: 1
Views: 548
Reputation: 10003
To help debug the issue, I started the PostgreSQL server with a debug level setting:
$ postgres -d 2
After reviewing the log, I saw additional queries being executed on the same PGconn
connection instance.
I believe my issue was derived from this chain of events:
PQsendQuery
on a query.PQexec
on a new query.PQgetResult
expecting the results from PQsendQuery
.In this scenario, PQgetResult
will return NULL
despite a valid, successfully-executed query.
The solution: In a multithreaded or asynchronous environment, you need to create a queue to manage the queries to a connection instance; pqlib won't do this on your behalf. While it may go without saying this would be true with multiple asynchronous operations, this is also the case for a single synchronous and single asynchronous operation.
Upvotes: 1