サーバで生成される注意/警告メッセージは、問い合わせ実行関数では返されません。 これらは問い合わせの失敗を意味するものではないからです。 その代わりに、これらは警告処理関数に渡され、ハンドラが戻った後、通常は実行が継続されます。 デフォルトの警告処理関数は、メッセージを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);
各関数は、以前の警告レシーバもしくは警告プロセッサ用の関数へのポインタを返し、新しい値を設定します。 関数ポインタにヌルを渡した場合、何も変更されず、現在のポインタが返されるだけです。
サーバから注意/警告メッセージを受け取ると、あるいは、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へコピーされます。