31.12. 通知处理

服务器生成的通知和警告消息都不会由查询执行函数返回,因为他们并不蕴涵着查询的失败。 它们会被传递给一个通知处理函数,然后在该处理返回之后继续正常执行。 缺省的通知处理函数在stderr上打印该信息, 但是应用可以通过提供自己的处理函数来覆盖这个行为。

由于历史原因,系统里存在两个级别的通知处理,分别叫做通知接收器和通知处理器。 缺省的行为是通知接收器格式化通知然后传递给通知处理器一个字串进行打印。 不过,对于自行处理这些事情的应用而言,通常是忽略通知处理器层,而只是在通知接收器里完成所有动作。

函数PQsetNoticeReceiver 为一个连接对象设置或者检查当前的通知接收器。 类似的是PQsetNoticeProcessor 设置或者检查当前的通知处理器。

typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);

PQnoticeReceiver
PQsetNoticeReceiver(PGconn *conn,
                    PQnoticeReceiver proc,
                    void *arg);

typedef void (*PQnoticeProcessor) (void *arg, const char *message);

PQnoticeProcessor
PQsetNoticeProcessor(PGconn *conn,
                     PQnoticeProcessor proc,
                     void *arg);

这些函数都返回前一个通知接收器或者处理器函数指针,然后设置新的数值。 如果你提供一个空函数指针,那么就不会执行任何动作,但是返回当前指针。

当我们从服务器获取一个注意或者警告消息的时候,或者是收到libpq 内部生成的类似信息时,通知接收器函数将被调用。消息会以一个PGRES_NONFATAL_ERRORPGresult的形式传递。(这就允许接收器用 PQresultErrorField 抽取独立的字段,或者用PQresultErrorMessage完成预先格式化好的信息。) 传递给PQsetNoticeReceiver的同一个 void 指针也同样传递给该函数。 (必要时,这个指针可以用来访问应用相关的状态。)

缺省的通知接收器只是简单的抽取信息(使用PQresultErrorMessage) 然后传递给通知处理器。

通知处理器负责处理一个以文本形式给出的注意或者警告消息。系统传递给他消息的字串文本 (包括结尾的新行符),加上一个和传递给PQsetNoticeProcessor 一样的 void (无类型)指针。(必要时,这个指针可以用来访问应用相关的状态。)

缺省的通知处理器就是:

static void
defaultNoticeProcessor(void *arg, const char *message)
{
    fprintf(stderr, "%s", message);
}

一旦你设置了注意消息接收器或者处理器,那么你就应该准备好在PGconn 对象或者PGresult对象开始存在的时候起就有人调用它们。在创建 PGresult的时候,PGconn的当前通知处理指针被拷贝到 PGresult,以便被类似PQgetvalue这样的函数使用。