| PostgreSQL 7.4.30 Documentation | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 27. libpq - C Library | Fast Forward | Next | 
The PQexec function is adequate
  for submitting commands in normal, synchronous applications. It
  has a couple of deficiencies, however, that can be of importance
  to some users:
PQexec waits for the command
      to be completed. The application may have other work to do
      (such as maintaining a user interface), in which case it
      won't want to block waiting for the response.
Since the execution of the client application is suspended while it waits for the result, it is hard for the application to decide that it would like to try to cancel the ongoing command. (It can be done from a signal handler, but not otherwise.)
PQexec can return only one
      PGresult structure. If the
      submitted command string contains multiple SQL commands, all but the last PGresult are discarded by PQexec.
Applications that do not like these limitations can instead
  use the underlying functions that PQexec is built from: PQsendQuery and PQgetResult. There are also PQsendQueryParams and PQsendQueryPrepared, which can be used with
  PQgetResult to duplicate the
  functionality of PQexecParams and
  PQexecPrepared respectively.
PQsendQuerySubmits 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 PQerrorMessage to get more information
        about the failure).
int PQsendQuery(PGconn *conn, const char *command);
After successfully calling PQsendQuery, call PQgetResult one or more times to obtain
        the results. PQsendQuery may
        not be called again (on the same connection) until
        PQgetResult has returned a
        null pointer, indicating that the command is done.
PQsendQueryParamsSubmits 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 PQsendQuery except that query parameters
        can be specified separately from the query string. The
        function's parameters are handled identically to
        PQexecParams. Like
        PQexecParams, it will not
        work on 2.0-protocol connections, and it allows only one
        command in the query string.
PQsendQueryPreparedSends 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 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 PQexecPrepared. Like PQexecPrepared, it will not work on
        2.0-protocol connections.
PQgetResultWaits for the next result from a prior PQsendQuery, PQsendQueryParams, or PQsendQueryPrepared call, and returns it.
        A null pointer is returned when the command is complete and
        there will be no more results.
PGresult *PQgetResult(PGconn *conn);
PQgetResult must be called
        repeatedly until it returns a null pointer, indicating that
        the command is done. (If called when no command is active,
        PQgetResult will just return
        a null pointer at once.) Each non-null result from
        PQgetResult should be
        processed using the same PGresult accessor functions previously
        described. Don't forget to free each result object with
        PQclear when done with it.
        Note that PQgetResult will
        block only if a command is active and the necessary
        response data has not yet been read by PQconsumeInput.
Using PQsendQuery and
  PQgetResult solves one of
  PQexec's problems: If a command
  string contains multiple SQL
  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.) However, calling PQgetResult will still cause the client to
  block until the server completes the next SQL command. This can be avoided by proper
  use of two more functions:
PQconsumeInputIf input is available from the server, consume it.
int PQconsumeInput(PGconn *conn);
PQconsumeInput normally
        returns 1 indicating "no error",
        but returns 0 if there was some kind of trouble (in which
        case PQerrorMessage can be
        consulted). Note that the result does not say whether any
        input data was actually collected. After calling
        PQconsumeInput, the
        application may check PQisBusy and/or PQnotifies to see if their state has
        changed.
PQconsumeInput may 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
        select() read-ready
        indication to go away. The application can thus use
        PQconsumeInput to clear the
        select() condition
        immediately, and then examine the results at leisure.
PQisBusyReturns 1 if a command is busy, that is, PQgetResult would block waiting for
        input. A 0 return indicates that PQgetResult can be called with assurance
        of not blocking.
int PQisBusy(PGconn *conn);
PQisBusy will not itself
        attempt to read data from the server; therefore
        PQconsumeInput must be
        invoked first, or the busy state will never end.
A typical application using these functions will have a main
  loop that uses select() or
  poll() 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 select() means readable data on the file
  descriptor identified by PQsocket.
  When the main loop detects input ready, it should call
  PQconsumeInput to read the input.
  It can then call PQisBusy, followed
  by PQgetResult if PQisBusy returns false (0). It can also call
  PQnotifies to detect NOTIFY messages (see Section 27.6).
A client that uses PQsendQuery/PQgetResult can also attempt to cancel a
  command that is still being processed by the server.
PQrequestCancelRequests that the server abandon processing of the current command.
int PQrequestCancel(PGconn *conn);
The return value is 1 if the cancel request was
        successfully dispatched and 0 if not. (If not, PQerrorMessage tells why not.) Successful
        dispatch is no guarantee that the request will have any
        effect, however. Regardless of the return value of
        PQrequestCancel, the
        application must continue with the normal result-reading
        sequence using PQgetResult.
        If the cancellation is effective, the current command will
        terminate early and return an error result. If the
        cancellation fails (say, because the server was already
        done processing the command), then there will be no visible
        result at all.
Note that if the current command is part of a transaction block, cancellation will abort the whole transaction.
PQrequestCancel can safely
        be invoked from a signal handler. So, it is also possible
        to use it in conjunction with plain PQexec, if the decision to cancel can be
        made in a signal handler. For example, psql invokes PQrequestCancel from a SIGINT signal handler, thus allowing
        interactive cancellation of commands that it issues through
        PQexec.
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 COPY IN, however.) To prevent this possibility and achieve completely nonblocking database operation, the following additional functions may be used.
PQsetnonblockingSets the nonblocking status of the connection.
int PQsetnonblocking(PGconn *conn, int arg);
Sets the state of the connection to nonblocking if arg is 1, or blocking if arg is 0. Returns 0 if OK, -1 if error.
In the nonblocking state, calls to PQsendQuery, PQputline, PQputnbytes, and PQendcopy will not block but instead
        return an error if they need to be called again.
Note that PQexec does not
        honor nonblocking mode; if it is called, it will act in
        blocking fashion anyway.
PQisnonblockingReturns 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.
PQflushAttempts 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).
int PQflush(PGconn *conn);
After sending any command or data on a nonblocking connection,
  call PQflush. If it returns 1, wait
  for the socket to be write-ready and call it again; repeat until
  it returns 0. Once PQflush returns
  0, wait for the socket to be read-ready and then read the
  response as described above.