我正在Objective-C中编写一个PostgreSQL库,基于libpq(用C语言编写)。虽然我已经构建了一个成功使用PQexec
的同步查询方法;我的异步方法永远不会收到查询的结果。 PQgetResult
始终返回NULL
。
我尝试了各种连接和查询检查的组合,但没有一个能够纠正这个问题。查询本身是一行上的SELECT
。我可以为同步方法换出这个异步方法,并具有所需的行为。我还检查了我保留的conn
指针始终引用相同的对象。
我不使用单行模式。
+ (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]);
// ...
}
答案 0 :(得分:1)
为了帮助调试问题,我使用调试级别设置启动了PostgreSQL服务器:
$ postgres -d 2
在查看日志之后,我看到在同一个PGconn
连接实例上执行了其他查询。
我相信我的问题来自这一系列事件:
PQsendQuery
。PQexec
。PQgetResult
期待PQsendQuery
的结果。在这种情况下,PQgetResult
将返回NULL
,尽管有效的,成功执行的查询。
解决方案:在多线程或异步环境中,您需要创建一个队列来管理对连接实例的查询; pqlib不会代表您这样做。虽然可以不用说多个异步操作也是如此,但单个同步和单个异步操作也是如此。