PQcancelCreate
#キャンセル要求を送信できる接続を準備します。
PGcancelConn *PQcancelCreate(PGconn *conn);
PQcancelCreate
はPGcancelConn
オブジェクトを作成しますが、この接続を介して直ちにキャンセルリクエストを送信し始めることはありません。
キャンセル要求は、PQcancelBlocking
を使用してブロッキング方式で、あるいはPQcancelStart
を使用して非ブロッキング方式でこの接続を介して送信できます。
返り値はPQcancelStatus
に渡して、PGcancelConn
オブジェクトが正常に作成されたかどうかを調べることができます。
PGcancelConn
オブジェクトは、アプリケーションが直接アクセスすることを意図していない不透明な構造体です。
このPGcancelConn
オブジェクトは、スレッドセーフな方法で元の接続で実行中の問い合わせをキャンセルするために使用できます。
元のクライアントの多くの接続パラメータは、キャンセル要求の接続を設定するときに再利用されます。
重要な点として、元の接続が接続の暗号化とターゲットホストの検証(sslmode
またはgssencmode
を使用)を必要とする場合、キャンセル要求の接続はこれらの同じ要件を使用して作成されます。
ただし、クライアントの認証中または認証後にのみ使用される接続オプションは無視されます。取り消し要求では認証は必要なく、接続は取り消し要求が送信された直後に閉じられるためです。
PQcancelCreate
がNULL以外のポインタを返した場合、構造体と関連するメモリブロックを始末するために、PQcancelFinish
を呼び出す必要があります。
これは、キャンセル要求が失敗したか、あるいは放棄された場合でも必要です。
PQcancelBlocking
#サーバがブロック方式で現在のコマンドの処理を中止するように要求します。
int PQcancelBlocking(PGcancelConn *cancelConn);
この要求は、PQcancelCreate
で作成する必要がある指定されたPGcancel
を介して行われます。
取り消し要求が正常にディスパッチされた場合、PQcancelBlocking
の返却値は1です。
失敗した場合、エラーメッセージは
PQcancelErrorMessage
を使用して取得できます。
キャンセルの送信が成功しても、要求が有効になるとは限りません。 キャンセルが有効な場合、キャンセルされるコマンドは早期に終了し、エラー結果を返します。 キャンセルが失敗した場合 (サーバがコマンドの処理をすでに完了していた場合など)、目に見える結果はまったくありません。
PQcancelStart
PQcancelPoll
#サーバが非ブロッキング方式で現在のコマンドの処理を中止するように要求します。
int PQcancelStart(PGcancelConn *cancelConn); PostgresPollingStatusType PQcancelPoll(PGcancelConn *cancelConn);
この要求は、PQcancelCreate
を使用して作成する必要がある指定されたPGcancel
を介して行われます。
取り消し要求が開始できた場合、PQcancelStart
の返却値は1です。
開始できなかった場合、エラーメッセージは
PQcancelErrorMessage
を使用して取得できます。
PQcancelStart
が成功した場合、次の段階はlibpqをポーリングして、接続解除シーケンスを続行できるようにすることです。
データベース接続の基礎となるソケットの記述子を取得するには、PQcancelSocket
を使用します。
(注意: ソケットはPQcancelPoll
呼び出しの間は同じままだと仮定しないでください)。
ループを次のように実行します。
PQcancelPoll(cancelConn)
が最後にPGRES_POLLING_READING
を返した場合、ソケットが読み込みの準備ができるまで待ちます(select()
やpoll()
などのシステム関数で指定します)。
その後、再度PQcancelPoll(cancelConn)
を呼び出します。
逆に、PQcancelPoll(cancelConn)
が最後にPGRES_POLLING_WRITING
を返した場合、ソケットが書き込み可能になるまで待ってから、再度PQcancelPoll(cancelConn)
を呼び出します。
最初の反復では、つまりPQcancelPoll(cancelConn)
をまだ呼び出していない場合は、最後にPGRES_POLLING_WRITING
を返したかのように振る舞います。
接続手続きが失敗したことを示すPGRES_POLLING_FAILED
を返すか、または、PGRES_POLLING_OK
を返して、キャンセル要求が正常にディスパッチされたことを示すまで、このループを続けます。
キャンセルの送信が成功しても、要求が有効になるとは限りません。 キャンセルが有効な場合、キャンセルされるコマンドは早期に終了し、エラー結果を返します。 キャンセルが失敗した場合 (サーバがコマンドの処理をすでに完了していた場合など)、目に見える結果はまったくありません。
接続中はいつでも、PQcancelStatus
を呼び出すことで接続の状態を確認できます。
この呼び出しがCONNECTION_BAD
を返した場合、キャンセル手続きは失敗です。
この呼び出しがCONNECTION_OK
を返した場合、キャンセル要求は正常にディスパッチされました。
これらの状態はどちらも、上記のPQcancelPoll
の戻り値から等しく検出できます。
他の状態は、非同期接続手順の間(およびその間のみ)に発生することもあります。
これらは、接続手順の現在の段階を示し、例えばユーザにフィードバックを提供するのに有用です。
これらのステータスは次のとおりです。
CONNECTION_ALLOCATED
#
PQcancelStart
やPQcancelBlocking
への呼び出しを待って、実際にソケットを開いています。
これはPQcancelCreate
やPQcancelReset
を呼んだ直後の接続の状態です。
この時点ではサーバへの接続はまだ開始されていません。
実際にキャンセルリクエストの送信を開始するにはPQcancelStart
やPQcancelBlocking
を使います。
CONNECTION_STARTED
#接続の確立待ち状態です。
CONNECTION_MADE
#接続はOKです。送信待ち状態です。
CONNECTION_AWAITING_RESPONSE
#サーバからの応答待ち状態です。
CONNECTION_SSL_STARTUP
#SSL暗号化の調停状態です。
CONNECTION_GSS_STARTUP
#GSS暗号化の調停状態です。
これらの定数は(互換性を保つため)なくなることはありませんが、アプリケーションは、これらが特定の順で出現したり、本書に書いてある値のどれかに必ずステータス値が該当するということを決して当てにしてはいけません。 アプリケーションは、以下に示すようにするべきです。
switch(PQcancelStatus(conn)) { case CONNECTION_STARTED: feedback = "Connecting..."; break; case CONNECTION_MADE: feedback = "Connected to server..."; break; . . . default: feedback = "Connecting..."; }
PQcancelPoll
を使用する場合、connect_timeout
接続パラメータは無視されます。
経過時間が長過ぎるかどうかの判定はアプリケーションの責任で行ないます。
そうでない場合、PQcancelStart
とそれに続くPQcancelPoll
ループはPQcancelBlocking
と同等です。
PQcancelStatus
#キャンセル接続の状態を返します。
ConnStatusType PQcancelStatus(const PGcancelConn *cancelConn);
ステータスは、いくつかの値のいずれかになります。
しかし、非同期キャンセル手続きの外で見られるのは、CONNECTION_ALLOCATED
、CONNECTION_OK
、CONNECTION_BAD
の3つだけです。
PQcancelCreate
を使用して正常に作成されたPGcancelConn
の初期状態はCONNECTION_ALLOCATED
です。
正常にディスパッチされたキャンセル要求はCONNECTION_OK
の状態になります。
キャンセルが失敗した場合、状態CONNECTION_BAD
が通知されます。
PQcancelFinish
またはPQcancelReset
が呼び出されるまで、OK状態はそのまま残ります。
返される可能性がある他の状態コードについてはPQcancelStart
の項目を参照してください。
キャンセルの送信が成功しても、要求が有効になるとは限りません。 キャンセルが有効な場合、キャンセルされるコマンドは早期に終了し、エラー結果を返します。 キャンセルが失敗した場合 (サーバがコマンドの処理をすでに完了していた場合など)、目に見える結果はまったくありません。
PQcancelSocket
#サーバへのキャンセル接続ソケットのファイル記述子番号を取得する。
int PQcancelSocket(const PGcancelConn *cancelConn);
有効なディスクリプタは0以上です。
-1 の結果は、現在オープンしているサーバ接続がないことを示します。
このセクションの関数をPGcancelConn
(
PQcancelErrorMessage
とPQcancelSocket
自身を除く)で呼び出すと、この値が変わる可能性があります。
PQcancelErrorMessage
#接続解除操作で最後に生成されたエラーメッセージを返します。
char *PQcancelErrorMessage(const PGcancelConn *cancelconn);
PGcancelConn
を取得するlibpq関数のほとんどは、失敗した場合に
PQcancelErrorMessage
にメッセージを設定します。
libpqの規則では、空でない
PQcancelErrorMessage
結果は複数行からなる可能性があり、最後に改行を含むことに注意してください。
呼び出し元は、結果を直接解放しないでください。
関連するPGcancelConn
ハンドルがPQcancelFinish
に渡されると解放されます。
結果の文字列はPGcancelConn
構造体に対する操作を通じて同じままになることは期待されません。
PQcancelFinish
#
キャンセル接続を閉じます(キャンセル要求の送信がまだ完了していない場合)。
また、PGcancelConn
オブジェクトが使用するメモリを解放します。
void PQcancelFinish(PGcancelConn *cancelConn);
取り消しの試みが失敗した場合(PQcancelStatus
で示されるように)でも、アプリケーションはPQcancelFinish
を呼び出してPGcancelConn
オブジェクトが使用したメモリを解放するようにしてください。
PGcancelConn
ポインタはPQcancelFinish
が呼び出された後は再度使用してはなりません。
PQcancelReset
#
新しいキャンセル接続で再利用できるようにPGcancelConn
をリセットします。
void PQcancelReset(PGcancelConn *cancelConn);
PGcancelConn
が現在キャンセル要求を送信するために使用されている場合、この接続は閉じられます。
次に、新しいキャンセル要求を送信するために使用できるようにPGcancelConn
オブジェクトを準備します。
これはPGconn
に対して1つのPGcancelConn
を作成し、元のPGconn
の存続期間中に何度も再利用することができます。
これらの関数は古い方法でキャンセル要求を送信するものです。
これらはまだ動作しますが、元の接続が暗号化を要求するためにsslmode
またはgssencmode
を指定した場合でも、キャンセル要求を暗号化された方法で送信しないため、推奨されません。
したがって、これらの古い方法は新しいコードではほとんど使用されず、既存のコードを変更して新しい関数を使用することをお勧めします。
PQgetCancel
#
PQcancel
を使用してコマンドをキャンセルするために必要な情報を含むデータ構造体を作成します。
PGcancel *PQgetCancel(PGconn *conn);
PQgetCancel
はPGconn
接続オブジェクトを与えられたPGcancel
オブジェクトを作成します。
指定されたconn
がNULL
か、または無効な接続である場合、NULL
を返します。
PGcancel
オブジェクトは不透明な構造体で、アプリケーションが直接アクセスするためのものではありません。これはPQcancel
またはPQfreeCancel
に渡すことができるだけです。
PQfreeCancel
#
PQgetCancel
で作成されたデータ構造を解放します。
void PQfreeCancel(PGcancel *cancel);
PQfreeCancel
は事前にPQgetCancel
で作成されたデータオブジェクトを解放します。
PQcancel
#
PQcancel
は、PQcancelBlocking
の非推奨で安全でない変種ですが、シグナルハンドラ内から安全に使用できます。
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);
PQcancel
が存在するのは、下位互換性のためだけです。
代わりにPQcancelBlocking
を使用してください。
PQcancel
の唯一の利点は、errbuf
がシグナルハンドラ内のローカル変数である場合に、シグナルハンドラから安全に呼び出すことができることです。
しかし、一般的には、この関数が持つセキュリティ問題に見合うほど大きな利点とは考えられていません。
PGcancel
オブジェクトはPQcancel
に関しては読み取り専用であるため、PGconn
オブジェクトを操作するスレッドとは別のスレッドからも呼び出すことができます。
取り消し要求が正常にディスパッチされた場合、PQcancel
の戻り値は1で、そうでなければ0です。
ディスパッチされなかった場合、errbuf
に説明的なエラーメッセージが入ります。
errbuf
はerrbufsize
のサイズ(推奨サイズは256バイト)の文字配列でなければなりません。
PQrequestCancel
#
PQrequestCancel
は、PQcancelBlocking
の非推奨で安全でない変種です。
int PQrequestCancel(PGconn *conn);
PQrequestCancel
は下位互換性のために存在します。
代わりにPQcancelBlocking
を使用してください。
PQrequestCancel
をPQcancelBlocking
よりも使用する利益はありません。
サーバに現在のコマンドの廃棄処理を要求します。
これはPGconn
オブジェクトを直接扱い、また、失敗した場合エラーメッセージはPGconn
オブジェクト内に収納されます。
(
PQerrorMessage
により取り出すことができます。)
機能的には同一ですが、この方法は複数スレッドプログラムやシグナルハンドラでは安全ではありません。PGconn
のエラーメッセージが上書きされることにより、その接続で現在進行中の操作を台無しにする可能性があるからです。