30.11. 警告処理

サーバにより生成された通知と警告メッセージは問い合わせ実行関数では、問い合わせの失敗を意味していないので返されません。その代わり、それらは通知処理関数に渡され、ハンドラ戻りの後も継続して実行されます。デフォルトの通知処理関数はstderrにメッセージを出力しますが、アプリケーションは自身の処理関数を提供することでこの動作を書き換えることが可能です。

歴史的理由で、通知受領者と通知プロセッサと呼ばれる2階層の通知処理が存在します。デフォルトの動作は、通知受領者が通知を書式化し、出力のため通知プロセッサに文字列を渡します。しかし、自身の通知受領者の提供を選択したアプリケーションは、通知プロセッサ層を通常無視し、全ての作業を単に通知受領者で行います。

関数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);
   

各関数は、以前の警告レシーバもしくは警告プロセッサ用の関数へのポインタを返し、新しい値を設定します。 関数ポインタにNULLを渡した場合、何も変更されず、現在のポインタが返されるだけです。

サーバから注意/警告メッセージを受け取ると、あるいは、libpq内部で注意/警告メッセージが生成されると、警告レシーバ関数が呼び出されます。 PGRES_NONFATAL_ERROR PGresultという形でメッセージが渡されます。 (これにより、レシーバはPQresultErrorFieldを使用して個々のフィールドを取り出すことや、PQresultErrorMessageを使用して事前に整形された完全なメッセージを取り出すことができます。) PQsetNoticeReceiverに渡されたvoidポインタと同じものも渡されます。 (このポインタを使用して、必要に応じてアプリケーション特有の状態にアクセスすることができます。)

デフォルトの警告レシーバは単に(PQresultErrorMessageを使用して)メッセージを取り出し、それを警告プロセッサに渡すだけです。

警告プロセッサは、テキスト形式で与えられた注意/警告メッセージの取扱いに責任を持ちます。 メッセージは(最後改行を含む)文字列テキストで渡され、更に、PQsetNoticeProcessorに渡したものと同じvoidポインタも渡されます。 (このポインタを使用して、必要に応じてアプリケーション特有の状態にアクセスすることができます。)

デフォルトの警告プロセッサは以下のような単純なものです。

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

一旦警告レシーバや警告プロセッサを設定したら、PGconnオブジェクトか、それから生成されたPGresultオブジェクトが存在している間は、その関数が呼び出される可能性があると考えておくべきです。 PGresultの生成時には、PGconnの現在の警告処理用のポインタが、PQgetvalueのような関数で使用可能であるように、PGresultへコピーされます。