バージョンごとのドキュメント一覧

34.4. 非同期コマンドの処理 #

<title>Asynchronous Command Processing</title>

The <xref linkend="libpq-PQexec"/> function is adequate for submitting commands in normal, synchronous applications. It has a few deficiencies, however, that can be of importance to some users: PQexec関数は普通の同期処理のアプリケーションにおけるコマンドの送信に適したものです。 しかし、一部のユーザにとって重要な問題となり得る、数個の問題があります。

Applications that do not like these limitations can instead use the underlying functions that <xref linkend="libpq-PQexec"/> is built from: <xref linkend="libpq-PQsendQuery"/> and <xref linkend="libpq-PQgetResult"/>. There are also <xref linkend="libpq-PQsendQueryParams"/>, <xref linkend="libpq-PQsendPrepare"/>, <xref linkend="libpq-PQsendQueryPrepared"/>, <xref linkend="libpq-PQsendDescribePrepared"/>, and <xref linkend="libpq-PQsendDescribePortal"/>, which can be used with <xref linkend="libpq-PQgetResult"/> to duplicate the functionality of <xref linkend="libpq-PQexecParams"/>, <xref linkend="libpq-PQprepare"/>, <xref linkend="libpq-PQexecPrepared"/>, <xref linkend="libpq-PQdescribePrepared"/>, and <xref linkend="libpq-PQdescribePortal"/> respectively. アプリケーションにとってこのような制限が望ましくない場合は、代わりにPQexecを構成する関数PQsendQueryPQgetResultを使用してください。 また、PQsendQueryParamsPQsendPreparePQsendQueryPreparedPQsendDescribePreparedPQsendDescribePortalもあり、PQgetResultを使用して、それぞれPQexecParamsPQpreparePQexecPreparedPQdescribePreparedPQdescribePortalと同等の機能を行うことができます。

PQsendQuery #

Submits a command to the server without waiting for the result(s). 1 is returned if the command was successfully dispatched and 0 if not (in which case, use <xref linkend="libpq-PQerrorMessage"/> to get more information about the failure). 結果を待つことなく、サーバにコマンドを発行します。 コマンドの登録に成功した場合1が、失敗した場合0が返されます。 (後者の場合、PQerrorMessageを使用して失敗についてのより多くの情報を取り出してください。)

int PQsendQuery(PGconn *conn, const char *command);

After successfully calling <xref linkend="libpq-PQsendQuery"/>, call <xref linkend="libpq-PQgetResult"/> one or more times to obtain the results. <xref linkend="libpq-PQsendQuery"/> cannot be called again (on the same connection) until <xref linkend="libpq-PQgetResult"/> has returned a null pointer, indicating that the command is done. PQsendQuery呼び出しが成功したら、PQgetResultを繰り返し呼び出して、実行結果を取得します。 PQgetResultがNULLポインタを返し、コマンドが完了したことを示すまでは、(同じ接続で)PQsendQueryを再度呼び出すことはできません。

In pipeline mode, this function is disallowed. パイプラインモードでは、この関数は使用できません。

PQsendQueryParams #

Submits a command and separate parameters to the server without waiting for the result(s). 結果を待つことなく、サーバにコマンドとパラメータとを分けて発行します。

int PQsendQueryParams(PGconn *conn,
                      const char *command,
                      int nParams,
                      const Oid *paramTypes,
                      const char * const *paramValues,
                      const int *paramLengths,
                      const int *paramFormats,
                      int resultFormat);

This is equivalent to <xref linkend="libpq-PQsendQuery"/> except that query parameters can be specified separately from the query string. The function's parameters are handled identically to <xref linkend="libpq-PQexecParams"/>. Like <xref linkend="libpq-PQexecParams"/>, it allows only one command in the query string. これは、問い合わせのパラメータが問い合わせ文字列と分けて指定できる点を除き、PQsendQueryと同じです。 この関数のパラメータはPQexecParamsと同様に扱われます。 PQexecParams同様、問い合わせ文字列には1つのコマンドしか指定できません。

PQsendPrepare #

Sends a request to create a prepared statement with the given parameters, without waiting for completion. 指定パラメータを持つプリペアド文の作成要求を送信します。 その完了を待ちません。

int PQsendPrepare(PGconn *conn,
                  const char *stmtName,
                  const char *query,
                  int nParams,
                  const Oid *paramTypes);

This is an asynchronous version of <xref linkend="libpq-PQprepare"/>: it returns 1 if it was able to dispatch the request, and 0 if not. After a successful call, call <xref linkend="libpq-PQgetResult"/> to determine whether the server successfully created the prepared statement. The function's parameters are handled identically to <xref linkend="libpq-PQprepare"/>. これはPQprepareの非同期版です。 要求の登録に成功した場合1が、失敗した場合0が返されます。 呼び出しの成功の後、サーバがプリペアド文の生成に成功したかを確認するためにはPQgetResultを呼び出してください。 この関数のパラメータはPQprepareと同様に扱われます。

PQsendQueryPrepared #

Sends a request to execute a prepared statement with given parameters, without waiting for the result(s). 結果を待つことなく、指定したパラメータでプリペアド文の実行要求を送信します。

int PQsendQueryPrepared(PGconn *conn,
                        const char *stmtName,
                        int nParams,
                        const char * const *paramValues,
                        const int *paramLengths,
                        const int *paramFormats,
                        int resultFormat);

This is similar to <xref linkend="libpq-PQsendQueryParams"/>, but the command to be executed is specified by naming a previously-prepared statement, instead of giving a query string. The function's parameters are handled identically to <xref linkend="libpq-PQexecPrepared"/>. これはPQsendQueryParamsと似ていますが、実行されるコマンドは問い合わせ文字列ではなく、事前に準備された文の名前で指定されます。 この関数のパラメータはPQexecPreparedと同様に扱われます。

PQsendDescribePrepared #

Submits a request to obtain information about the specified prepared statement, without waiting for completion. 指定したプリペアド文に関する情報入手要求を送ります。 入手完了まで待機しません。

int PQsendDescribePrepared(PGconn *conn, const char *stmtName);

This is an asynchronous version of <xref linkend="libpq-PQdescribePrepared"/>: it returns 1 if it was able to dispatch the request, and 0 if not. After a successful call, call <xref linkend="libpq-PQgetResult"/> to obtain the results. The function's parameters are handled identically to <xref linkend="libpq-PQdescribePrepared"/>. これはPQdescribePreparedの非同期版です。 要求の登録に成功した場合1が、失敗した場合0が返されます。 呼び出しに成功した後、PQgetResultを呼び出して結果を入手してください。 この関数のパラメータはPQdescribePreparedと同じように扱われます。

PQsendDescribePortal #

Submits a request to obtain information about the specified portal, without waiting for completion. 指定したポータルに関する情報入手要求を送信します。 完了まで待機しません。

int PQsendDescribePortal(PGconn *conn, const char *portalName);

This is an asynchronous version of <xref linkend="libpq-PQdescribePortal"/>: it returns 1 if it was able to dispatch the request, and 0 if not. After a successful call, call <xref linkend="libpq-PQgetResult"/> to obtain the results. The function's parameters are handled identically to <xref linkend="libpq-PQdescribePortal"/>. これはPQdescribePortalの非同期版です。 要求の登録に成功した場合1が、失敗した場合0が返されます。 呼び出しに成功した後、PQgetResultを呼び出して結果を入手してください。 この関数のパラメータはPQdescribePortalと同じように扱われます。

PQgetResult #

Waits for the next result from a prior <xref linkend="libpq-PQsendQuery"/>, <xref linkend="libpq-PQsendQueryParams"/>, <xref linkend="libpq-PQsendPrepare"/>, <xref linkend="libpq-PQsendQueryPrepared"/>, <xref linkend="libpq-PQsendDescribePrepared"/>, <xref linkend="libpq-PQsendDescribePortal"/>, or <xref linkend="libpq-PQpipelineSync"/> call, and returns it. A null pointer is returned when the command is complete and there will be no more results. 以前に呼び出したPQsendQueryPQsendQueryParamsPQsendPreparePQsendQueryPreparedPQsendDescribePreparedPQsendDescribePortalPQpipelineSyncから次の結果を待ち、その結果を返します。 コマンドが完了し、これ以上結果がない場合は、NULLポインタが返されます。

PGresult *PQgetResult(PGconn *conn);

<xref linkend="libpq-PQgetResult"/> must be called repeatedly until it returns a null pointer, indicating that the command is done. (If called when no command is active, <xref linkend="libpq-PQgetResult"/> will just return a null pointer at once.) Each non-null result from <xref linkend="libpq-PQgetResult"/> should be processed using the same <structname>PGresult</structname> accessor functions previously described. Don't forget to free each result object with <xref linkend="libpq-PQclear"/> when done with it. Note that <xref linkend="libpq-PQgetResult"/> will block only if a command is active and the necessary response data has not yet been read by <xref linkend="libpq-PQconsumeInput"/>. PQgetResultは、コマンドの完了を示すNULLポインタが返るまで、繰り返し呼び出さなければなりません。 (コマンド実行中以外での呼び出しでは、PQgetResultは単にNULLポインタを返します。) PQgetResultの非NULLの結果はそれぞれ前述と同じPGresultアクセス用関数を使用して処理されなければなりません。 各結果オブジェクトに対する処理が終わったら、そのオブジェクトをPQclearを使用して解放することを忘れないでください。 コマンドが活動中、かつ、必要な応答データがまだPQconsumeInput で読み込まれていない場合にのみ、PQgetResultがブロックすることに注意してください。

In pipeline mode, <function>PQgetResult</function> will return normally unless an error occurs; for any subsequent query sent after the one that caused the error until (and excluding) the next synchronization point, a special result of type <literal>PGRES_PIPELINE_ABORTED</literal> will be returned, and a null pointer will be returned after it. When the pipeline synchronization point is reached, a result of type <literal>PGRES_PIPELINE_SYNC</literal> will be returned. The result of the next query after the synchronization point follows immediately (that is, no null pointer is returned after the synchronization point.) パイプラインモードでは、PQgetResultはエラーが発生しない限り通常通りに戻ります。 エラーを引き起こした問い合わせの後、次の同期点まで(そして次の同期点を除外して)送られた問い合わせに対しては、PGRES_PIPELINE_ABORTED型の特殊な結果が返され、その後にNULLポインタが返されます。 パイプライン同期点に到達すると、PGRES_PIPELINE_SYNC型の結果が返されます。 同期点の後の次の問い合わせの結果はすぐに続きます(つまり、同期点の後にNULLポインタは返されません)。

注記

Even when <xref linkend="libpq-PQresultStatus"/> indicates a fatal error, <xref linkend="libpq-PQgetResult"/> should be called until it returns a null pointer, to allow <application>libpq</application> to process the error information completely. PQresultStatusが致命的なエラーを示した場合であっても、libpqがエラー情報を完全に処理できるようにNULLポインタが返されるまでPQgetResultを呼び出さなければなりません。

Using <xref linkend="libpq-PQsendQuery"/> and <xref linkend="libpq-PQgetResult"/> solves one of <xref linkend="libpq-PQexec"/>'s problems: If a command string contains multiple <acronym>SQL</acronym> commands, the results of those commands can be obtained individually. (This allows a simple form of overlapped processing, by the way: the client can be handling the results of one command while the server is still working on later queries in the same command string.) PQsendQueryPQgetResultを使うことでPQexecの問題は1つ解決します。 つまり、コマンドが複数のSQLコマンドを含んでいる場合でも、これらのコマンドの結果を個々に得ることができるわけです (これは多重処理を単純な形で実現します。 単一のコマンド文字列に含まれる複数の問い合わせの内、後ろのものが処理中でもフロントエンドは先に完了した結果から扱うことができるからです)。

Another frequently-desired feature that can be obtained with <xref linkend="libpq-PQsendQuery"/> and <xref linkend="libpq-PQgetResult"/> is retrieving large query results a row at a time. This is discussed in <xref linkend="libpq-single-row-mode"/>. PQsendQueryおよびPQgetResultで得られる、その他のよく望まれる機能は多くの問い合わせ結果を一度に1行受け取ることです。 これについては34.6で説明します。

By itself, calling <xref linkend="libpq-PQgetResult"/> will still cause the client to block until the server completes the next <acronym>SQL</acronym> command. This can be avoided by proper use of two more functions: サーバが次のSQLコマンドの処理に入ると、それが完了するまでやはりPQgetResultの呼び出しがフロントエンドをブロックしてしまいます。 さらに以下の2つの関数をうまく使用してこれを防ぐことができます。

PQconsumeInput #

If input is available from the server, consume it. サーバからの入力が可能になった場合、それを吸い取ります。

int PQconsumeInput(PGconn *conn);

<xref linkend="libpq-PQconsumeInput"/> normally returns 1 indicating <quote>no error</quote>, but returns 0 if there was some kind of trouble (in which case <xref linkend="libpq-PQerrorMessage"/> can be consulted). Note that the result does not say whether any input data was actually collected. After calling <xref linkend="libpq-PQconsumeInput"/>, the application can check <xref linkend="libpq-PQisBusy"/> and/or <function>PQnotifies</function> to see if their state has changed. PQconsumeInput は通常、エラーなしを示す1を返しますが、何らかの障害があると0を返します(この場合は、PQerrorMessageを参考にしてください)。 この結果は、何らかの入力データが実際に収集されたかどうかを示しているのではないことに注意してください。 PQconsumeInput の呼び出し後、アプリケーションはPQisBusy、または必要があればPQnotifiesを呼び出して状態に変化がないか調べることができます。

<xref linkend="libpq-PQconsumeInput"/> can be called even if the application is not prepared to deal with a result or notification just yet. The function will read available data and save it in a buffer, thereby causing a <function>select()</function> read-ready indication to go away. The application can thus use <xref linkend="libpq-PQconsumeInput"/> to clear the <function>select()</function> condition immediately, and then examine the results at leisure. PQconsumeInput は、結果や通知を扱うようにまだ準備していないアプリケーションからでも呼び出すことができます。 この関数は有効なデータを読み込んでバッファに保存し、結果としてselectによる読み込み準備完了の通知をリセットします。 従ってアプリケーションはPQconsumeInput を使うとselect()の検査条件をただちに満たすことができますから、あとはゆっくりと結果を調べてやればいいわけです。

PQisBusy #

Returns 1 if a command is busy, that is, <xref linkend="libpq-PQgetResult"/> would block waiting for input. A 0 return indicates that <xref linkend="libpq-PQgetResult"/> can be called with assurance of not blocking. この関数が1を返したのであれば、問い合わせは処理の最中で、PQgetResultも入力を待ったままブロック状態になってしまうでしょう。 0が返ったのであれば、PQgetResultを呼び出してもブロックされないことが保証されます。

int PQisBusy(PGconn *conn);

<xref linkend="libpq-PQisBusy"/> will not itself attempt to read data from the server; therefore <xref linkend="libpq-PQconsumeInput"/> must be invoked first, or the busy state will never end. PQisBusy自身はサーバからデータを読み込む操作をしません。 ですから、まず最初にPQconsumeInput を呼び出す必要があります。 そうしないとビジー状態がいつまでも続きます。

A typical application using these functions will have a main loop that uses <function>select()</function> or <function>poll()</function> to wait for all the conditions that it must respond to. One of the conditions will be input available from the server, which in terms of <function>select()</function> means readable data on the file descriptor identified by <xref linkend="libpq-PQsocket"/>. When the main loop detects input ready, it should call <xref linkend="libpq-PQconsumeInput"/> to read the input. It can then call <xref linkend="libpq-PQisBusy"/>, followed by <xref linkend="libpq-PQgetResult"/> if <xref linkend="libpq-PQisBusy"/> returns false (0). It can also call <function>PQnotifies</function> to detect <command>NOTIFY</command> messages (see <xref linkend="libpq-notify"/>). これら3関数を使用するアプリケーションは通常、select()もしくはpoll()を使用するメインループを持ち、対応しなければならないすべての状態を待機しています。 その内の1つの条件は、サーバからの利用可能な入力となるでしょう。 これは、select()の見地からは、PQsocketで識別されるファイル記述子上で読み込み可能なデータがあることを意味します。 メインループが入力準備完了を検出すると、その入力を読み込むためにPQconsumeInput を呼び出さなければなりません。 そして、PQisBusyを、更にPQisBusyが偽(0)を返す場合にPQgetResultも呼び出すことができます。 また、PQnotifiesを呼び出して、NOTIFYメッセージ(34.9を参照)を検出することもできます。

A client that uses <xref linkend="libpq-PQsendQuery"/>/<xref linkend="libpq-PQgetResult"/> can also attempt to cancel a command that is still being processed by the server; see <xref linkend="libpq-cancel"/>. But regardless of the return value of <xref linkend="libpq-PQcancel"/>, the application must continue with the normal result-reading sequence using <xref linkend="libpq-PQgetResult"/>. A successful cancellation will simply cause the command to terminate sooner than it would have otherwise. また、PQsendQuery/PQgetResultを使用するクライアントは、サーバで処理中のコマンドに対してキャンセルを試行することができます。 34.7を参照してください。 しかし、PQcancelの戻り値と関係なく、アプリケーションはPQgetResultを使用した通常の結果読み取り手順を続けなければなりません。 キャンセル手続きの成功は単に、そのコマンドを通常よりも早めに終わらせるだけです。

By using the functions described above, it is possible to avoid blocking while waiting for input from the database server. However, it is still possible that the application will block waiting to send output to the server. This is relatively uncommon but can happen if very long SQL commands or data values are sent. (It is much more probable if the application sends data via <command>COPY IN</command>, however.) To prevent this possibility and achieve completely nonblocking database operation, the following additional functions can be used. 上述の関数を使用して、データベースサーバからの入力待ちのためのブロックを行わずに済みます。 しかしまだ、サーバへの出力送信を待つためにアプリケーションはブロックする可能性があります。 これは比較的あまり発生しませんが、非常に長いSQLコマンドやデータ値が送信される場合に発生することがあります。 (しかし、アプリケーションがCOPY IN経由でデータを送信する場合よく発生します。) この発生を防ぎ、完全な非ブロックのデータベース操作を行うためには、さらに以下の関数を使用してください。

PQsetnonblocking #

Sets the nonblocking status of the connection. 接続の非ブロック状態を設定します。

int PQsetnonblocking(PGconn *conn, int arg);

Sets the state of the connection to nonblocking if <parameter>arg</parameter> is 1, or blocking if <parameter>arg</parameter> is 0. Returns 0 if OK, -1 if error. argが1の場合、接続状態を非ブロックに設定します。 argが0の場合はブロックに設定します。 問題がなければ0が、エラー時は-1が返ります。

In the nonblocking state, calls to <xref linkend="libpq-PQsendQuery"/>, <xref linkend="libpq-PQputline"/>, <xref linkend="libpq-PQputnbytes"/>, <xref linkend="libpq-PQputCopyData"/>, and <xref linkend="libpq-PQendcopy"/> will not block but instead return an error if they need to be called again. 非ブロック状態ではPQsendQueryPQputlinePQputnbytesPQputCopyDataおよびPQendcopyの呼び出しはブロックされませんが、再度呼び出さなければならない場合、エラーが返ります。

Note that <xref linkend="libpq-PQexec"/> does not honor nonblocking mode; if it is called, it will act in blocking fashion anyway. PQexecは非ブロックモードにはしたがわないことに注意してください。 この関数の呼び出しは、必ずブロック方式で動作します。

PQisnonblocking #

Returns the blocking status of the database connection. データベース接続のブロック状態を返します。

int PQisnonblocking(const PGconn *conn);

Returns 1 if the connection is set to nonblocking mode and 0 if blocking. 接続が非ブロック状態の場合は1が、ブロック状態の場合は0が返ります。

PQflush #

Attempts to flush any queued output data to the server. Returns 0 if successful (or if the send queue is empty), -1 if it failed for some reason, or 1 if it was unable to send all the data in the send queue yet (this case can only occur if the connection is nonblocking). キューに蓄えられたサーバへの出力データのフラッシュを行います。 成功時(および送信キューが空の場合)は0が返ります。 何らかの原因で失敗した場合は-1が、送信キュー内のデータをすべて送信できなかった場合は1が返ります。 (これは接続が非ブロックの場合にのみ発生します。)

int PQflush(PGconn *conn);

After sending any command or data on a nonblocking connection, call <xref linkend="libpq-PQflush"/>. If it returns 1, wait for the socket to become read- or write-ready. If it becomes write-ready, call <xref linkend="libpq-PQflush"/> again. If it becomes read-ready, call <xref linkend="libpq-PQconsumeInput"/>, then call <xref linkend="libpq-PQflush"/> again. Repeat until <xref linkend="libpq-PQflush"/> returns 0. (It is necessary to check for read-ready and drain the input with <xref linkend="libpq-PQconsumeInput"/>, because the server can block trying to send us data, e.g., NOTICE messages, and won't read our data until we read its.) Once <xref linkend="libpq-PQflush"/> returns 0, wait for the socket to be read-ready and then read the response as described above. 非ブロック接続時にはコマンドやデータを送信した後に、PQflushを呼び出してください。 1が返った場合、ソケットの読み込みまたは書き込み準備ができるまで待ってください。 書き込み準備ができたら、PQflushを再度呼び出してください。 読み込み準備ができたら、PQconsumeInput を呼び出してから、PQflushを再度呼び出してください。 これをPQflushが0を返すまで繰り返してください。 (例えばNOTICEメッセージのように、こちらがそのデータを読むまで、サーバがデータを送ろうとするのを妨げ、こちらのデータを読もうとしないことがありますので、読み込み準備ができたことを確認してPQconsumeInput で入力をすべて抜き取ることが必要です。) PQflushが0を返した後は、ソケットの読み込み準備が整うまで待ち、上述のように応答を読み取ってください。