简体   繁体   English

PQgetResult总是返回NULL

[英]PQgetResult always returns NULL

I'm writing a PostgreSQL library in Objective-C, based on libpq (written in C). 我在Objective-C中基于libpq (用C编写)编写PostgreSQL库。 While I've built a synchronous querying method that uses PQexec sucessfully; 虽然我构建了成功使用PQexec的同步查询方法; my asynchronous method never receives the query's results. 我的异步方法从不接收查询结果。 PQgetResult always returns NULL . PQgetResult始终返回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. 查询本身是对具有一行的表的SELECT 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. 我还检查了我保留的conn指针是否始终引用同一对象。

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]);

    // ...
}

To help debug the issue, I started the PostgreSQL server with a debug level setting: 为了帮助调试问题,我使用调试级别设置启动了PostgreSQL服务器:

$ postgres -d 2

After reviewing the log, I saw additional queries being executed on the same PGconn connection instance. 查看日志后,我看到在同一PGconn连接实例上正在执行其他查询。


I believe my issue was derived from this chain of events: 我认为我的问题源于以下一系列事件:

  1. Invoke PQsendQuery on a query. 在查询上调用PQsendQuery
  2. Invoke PQexec on a new query. 在新查询上调用PQexec
  3. Invoke PQgetResult expecting the results from PQsendQuery . 调用PQgetResult期望从PQsendQuery获得结果。

In this scenario, PQgetResult will return NULL despite a valid, successfully-executed query. 在这种情况下,尽管有效执行查询成功,但PQgetResult将返回NULL

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. pqlib不会代表您执行此操作。 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. 尽管可以肯定的是,对于多个异步操作而言,这是正确的,但对于单个同步和单个异步操作,情况也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM