PQgetResult始终返回NULL

时间:2014-12-30 18:14:17

标签: objective-c c postgresql libpq

我正在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]);

    // ...
}

1 个答案:

答案 0 :(得分:1)

为了帮助调试问题,我使用调试级别设置启动了PostgreSQL服务器:

$ postgres -d 2

在查看日志之后,我看到在同一个PGconn连接实例上执行了其他查询。


我相信我的问题来自这一系列事件:

  1. 在查询中调用PQsendQuery
  2. 在新查询中调用PQexec
  3. 调用PQgetResult期待PQsendQuery的结果。
  4. 在这种情况下,PQgetResult将返回NULL,尽管有效的,成功执行的查询。

    解决方案:在多线程或异步环境中,您需要创建一个队列来管理对连接实例的查询; pqlib不会代表您这样做。虽然可以不用说多个异步操作也是如此,但单个同步和单个异步操作也是如此。