summaryrefslogtreecommitdiff
path: root/doc/manual/libpq.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual/libpq.html')
-rw-r--r--doc/manual/libpq.html815
1 files changed, 0 insertions, 815 deletions
diff --git a/doc/manual/libpq.html b/doc/manual/libpq.html
deleted file mode 100644
index 71f8e7a1502..00000000000
--- a/doc/manual/libpq.html
+++ /dev/null
@@ -1,815 +0,0 @@
-<HTML>
-<HEAD>
- <TITLE>The POSTGRES95 User Manual - LIBPQ</TITLE>
-</HEAD>
-
-<BODY>
-
-<font size=-1>
-<A HREF="pg95user.html">[ TOC ]</A>
-<A HREF="xindex.html">[ Previous ]</A>
-<A HREF="lobj.html">[ Next ]</A>
-</font>
-<HR>
-<H1>12. <B>LIBPQ</B></H1>
-<HR>
- <B>LIBPQ</B> is the application programming interface to POSTGRES.
- <B>LIBPQ</B> is a set of library routines which allows
- client programs to pass queries to the POSTGRES backend
- server and to receive the results of these queries.
- This version of the documentation describes the <B>C</B>
- interface library. Three short programs are included
- at the end of this section to show how to write programs that use <B>LIBPQ</B>.
- There are several examples of <B>LIBPQ</B> applications in the
- following directories:
-
-<pre> ../src/test/regress
- ../src/test/examples
- ../src/bin/psql
-</pre>
- Frontend programs which use <B>LIBPQ</B> must include the
- header file <CODE>libpq-fe.h</CODE> and must link with the <B>libpq</B>
- library.
-
-<H2><A NAME="control-and-initialization">12.1. Control and Initialization</A></H2>
- The following environment variables can be used to set
- up default environment values to avoid hard-coding
- database names into an application program:
-
-<UL>
- <LI><B>PGHOST</B> sets the default server name.
- <LI><B>PGOPTIONS</B> sets additional runtime options for the POSTGRES backend.
- <LI><B>PGPORT</B> sets the default port for communicating with the POSTGRES backend.
- <LI><B>PGTTY</B> sets the file or tty on which debugging messages from the backend server are displayed.
- <LI><B>PGDATABASE</B> sets the default POSTGRES database name.
- <LI><B>PGREALM</B> sets the Kerberos realm to use with POSTGRES, if it is different from the local realm. If
- <LI><B>PGREALM</B> is set, POSTGRES applications will attempt
- authentication with servers for this realm and use
- separate ticket files to avoid conflicts with local
- ticket files. This environment variable is only
- used if Kerberos authentication is enabled.
-</UL>
-
-<H2><A NAME="database-connection-functions">12.2. Database Connection Functions</A></H2>
- The following routines deal with making a connection to
- a backend from a <B>C</B> program.
-
- <DL>
- <DT><B>PQsetdb</B>
- <DD>Makes a new connection to a backend.
-<pre> PGconn &#42;PQsetdb(char &#42;pghost,
- char &#42;pgport,
- char &#42;pgoptions,
- char &#42;pgtty,
- char &#42;dbName);
-</pre>
- <DD>If any argument is NULL, then the corresponding
- environment variable is checked. If the environment variable is also not set, then hardwired
- defaults are used.
- <DD>PQsetdb always returns a valid PGconn pointer.
- <DD>The PQstatus (see below) command should be called
- to ensure that a connection was properly made
- before queries are sent via the connection. <B>LIBPQ</B>
- programmers should be careful to maintain the
- <DD>PGconn abstraction. Use the accessor functions
- below to get at the contents of PGconn. Avoid
- directly referencing the fields of the PGconn
- structure as they are subject to change in the
- future.<br>
- <DT><B>PQdb</B>
- <DD>Returns the database name of the connection.
-<pre> char &#42;PQdb(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQhost</B>
- <DD>Returns the host name of the connection.
-<pre> char &#42;PQhost(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQoptions</B>
- <DD>Returns the pgoptions used in the connection.
-<pre> char &#42;PQoptions(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQport</B>
- <DD>Returns the pgport of the connection.
-<pre> char &#42;PQport(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQtty</B>
- <DD>Returns the pgtty of the connection.
-<pre> char &#42;PQtty(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQstatus</B>
- <DD>Returns the status of the connection.
- <DD>The status can be CONNECTION_OK or CONNECTION_BAD.
-<pre> ConnStatusType &#42;PQstatus(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQerrorMessage</B>
- <DD>Returns the error message associated with the connection
-<pre> char &#42;PQerrorMessage(PGconn&#42; conn);
-</pre><br>
-
- <DT><B>PQfinish</B>
- <DD>Close the connection to the backend. Also frees
- memory used by the PGconn structure. The PGconn
- pointer should not be used after PQfinish has been
- called.
-<pre> void PQfinish(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQreset</B>
- <DD>Reset the communication port with the backend.
- This function will close the IPC socket connection
- to the backend and attempt to reestablish a new
- connection to the same backend.
-<pre> void PQreset(PGconn &#42;conn)
-</pre><br>
- <DT><B>PQtrace</B>
- <DD>Enables tracing of messages passed between the
- frontend and the backend. The messages are echoed
- to the debug_port file stream.
-<pre> void PQtrace(PGconn &#42;conn,
- FILE&#42; debug_port);
-</pre><br>
- <DT><B>PQuntrace</B>
- <DD>Disables tracing of messages passed between the
- frontend and the backend.
-<pre> void PQuntrace(PGconn &#42;conn);
-</pre><br>
-</DL>
-<H2><A NAME="query-execution-functions">12.3. Query Execution Functions</A></H2>
-<DL>
- <DT><B>PQexec</B>
- <DD>Submit a query to POSTGRES. Returns a PGresult
- pointer if the query was successful or a NULL otherwise. If a NULL is returned, PQerrorMessage can
- be used to get more information about the error.
-<pre> PGresult &#42;PQexec(PGconn &#42;conn,
- char &#42;query);
-</pre>
- <DD>The <B>PGresult</B> structure encapsulates the query
- result returned by the backend. <B>LIBPQ</B> programmers
- should be careful to maintain the PGresult
- abstraction. Use the accessor functions described
- below to retrieve the results of the query. Avoid
- directly referencing the fields of the PGresult
- structure as they are subject to change in the
- future.<br>
- <DT><B>PQresultStatus</B>
- <DD>Returns the result status of the query. PQresultStatus can return one of the following values:
-<pre> PGRES_EMPTY_QUERY,
- PGRES_COMMAND_OK, /&#42; the query was a command &#42;/
- PGRES_TUPLES_OK, /&#42; the query successfully returned tuples &#42;/
- PGRES_COPY_OUT,
- PGRES_COPY_IN,
- PGRES_BAD_RESPONSE, /&#42; an unexpected response was received &#42;/
- PGRES_NONFATAL_ERROR,
- PGRES_FATAL_ERROR
-</pre>
- <DD>If the result status is PGRES_TUPLES_OK, then the
- following routines can be used to retrieve the
- tuples returned by the query.<br>
- <DT><B>PQntuples</B> returns the number of tuples (instances)
- in the query result.
-
-<pre> int PQntuples(PGresult &#42;res);
-</pre><br>
- <DT><B>PQnfields</B>
- <DD>Returns the number of fields
- (attributes) in the query result.
-
-<pre> int PQnfields(PGresult &#42;res);
-</pre><br>
- <DT><B>PQfname</B>
- <DD>Returns the field (attribute) name associated with the given field index. Field indices
- start at 0.
-
-<pre> char &#42;PQfname(PGresult &#42;res,
- int field_index);
-</pre><br>
- <DT><B>PQfnumber</B>
- <DD>Returns the field (attribute) index
- associated with the given field name.
-
-<pre> int PQfnumber(PGresult &#42;res,
- char&#42; field_name);
-</pre><br>
- <DT><B>PQftype</B>
- <DD>Returns the field type associated with the
- given field index. The integer returned is an
- internal coding of the type. Field indices start
- at 0.
-
-<pre> Oid PQftype(PGresult &#42;res,
- int field_num);
-</pre><br>
- <DT><B>PQfsize</B>
- <DD>Returns the size in bytes of the field
- associated with the given field index. If the size
- returned is -1, the field is a variable length
- field. Field indices start at 0.
-
-<pre> int2 PQfsize(PGresult &#42;res,
- int field_index);
-</pre><br>
- <DT><B>PQgetvalue</B>
- <DD>Returns the field (attribute) value.
- For most queries, the value returned by PQgetvalue
- is a null-terminated ASCII string representation
- of the attribute value. If the query was a result
- of a <B>BINARY</B> cursor, then the value returned by
- PQgetvalue is the binary representation of the
- type in the internal format of the backend server.
- It is the programmer's responsibility to cast and
- convert the data to the correct C type. The value
- returned by PQgetvalue points to storage that is
- part of the PGresult structure. One must explicitly
- copy the value into other storage if it is to
- be used past the lifetime of the PGresult structure itself.
-
-<pre> char&#42; PQgetvalue(PGresult &#42;res,
- int tup_num,
- int field_num);
-</pre><br>
- <DT><B>PQgetlength</B>
- <DD>Returns the length of a field
- (attribute) in bytes. If the field is a struct
- varlena, the length returned here does not include
- the size field of the varlena, i.e., it is 4 bytes
- less.
-<pre> int PQgetlength(PGresult &#42;res,
- int tup_num,
- int field_num);
-</pre><br>
- <DT><B>PQcmdStatus</B>
- Returns the command status associated with the
- last query command.
-<pre>
- char &#42;PQcmdStatus(PGresult &#42;res);
-</pre><br>
- <DT><B>PQoidStatus</B>
- Returns a string with the object id of the tuple
- inserted if the last query is an INSERT command.
- Otherwise, returns an empty string.
-<pre> char&#42; PQoidStatus(PGresult &#42;res);
-</pre><br>
- <DT><B>PQprintTuples</B>
- Prints out all the tuples and, optionally, the
- attribute names to the specified output stream.
- The programs psql and monitor both use PQprintTuples for output.
-
-<pre> void PQprintTuples(
- PGresult&#42; res,
- FILE&#42; fout, /&#42; output stream &#42;/
- int printAttName,/&#42; print attribute names or not&#42;/
- int terseOutput, /&#42; delimiter bars or not?&#42;/
- int width /&#42; width of column, variable width if 0&#42;/
- );
-</pre><br>
-
- <DT><B>PQclear</B>
- Frees the storage associated with the PGresult.
- Every query result should be properly freed when
- it is no longer used. Failure to do this will
- result in memory leaks in the frontend application.
-<pre> void PQclear(PQresult &#42;res);
-</pre><br>
-</DL>
-<H2><A NAME="fast-path">12.4. Fast Path</A></H2>
- POSTGRES provides a fast path interface to send function calls to the backend. This is a trapdoor into
- system internals and can be a potential security hole.
- Most users will not need this feature.
-
-<pre> PGresult&#42; PQfn(PGconn&#42; conn,
- int fnid,
- int &#42;result_buf,
- int &#42;result_len,
- int result_is_int,
- PQArgBlock &#42;args,
- int nargs);
-</pre><br>
-
- The fnid argument is the object identifier of the function to be executed. result_buf is the buffer in which
- to load the return value. The caller must have allocated sufficient space to store the return value. The
- result length will be returned in the storage pointed
- to by result_len. If the result is to be an integer
- value, than result_is_int should be set to 1; otherwise
- it should be set to 0. args and nargs specify the
- arguments to the function.
-<pre> typedef struct {
- int len;
- int isint;
- union {
- int &#42;ptr;
- int integer;
- } u;
- } PQArgBlock;
-</pre>
- PQfn always returns a valid PGresult&#42;. The resultStatus should be checked before the result is used. The
- caller is responsible for freeing the PGresult with
- PQclear when it is not longer needed.
-<H2><A NAME="asynchronous-notification">12.5. Asynchronous Notification</A></H2>
- POSTGRES supports asynchronous notification via the
- LISTEN and NOTIFY commands. A backend registers its
- interest in a particular relation with the LISTEN command. All backends listening on a particular relation
- will be notified asynchronously when a NOTIFY of that
- relation name is executed by another backend. No
- additional information is passed from the notifier to
- the listener. Thus, typically, any actual data that
- needs to be communicated is transferred through the
- relation.
- <B>LIBPQ</B> applications are notified whenever a connected
- backend has received an asynchronous notification.
- However, the communication from the backend to the
- frontend is not asynchronous. Notification comes
- piggy-backed on other query results. Thus, an application must submit queries, even empty ones, in order to
- receive notice of backend notification. In effect, the
- <B>LIBPQ</B> application must poll the backend to see if there
- is any pending notification information. After the
- execution of a query, a frontend may call PQNotifies to
- see if any notification data is available from the
- backend.
-<DL>
- <DT><B>PQNotifies</B>
- <DD>returns the notification from a list of unhandled
- notifications from the backend. Returns NULL if
- there are no pending notifications from the backend. PQNotifies behaves like the popping of a
- stack. Once a notification is returned from PQnotifies, it is considered handled and will be
- removed from the list of notifications.
-<pre> PGnotify&#42; PQNotifies(PGconn &#42;conn);
-</pre><br>
-</DL>
- The second sample program gives an example of the use
- of asynchronous notification.
-<H2><A NAME="functions-associated-with-the-copy-command">12.6. Functions Associated with the COPY Command</A></H2>
- The copy command in POSTGRES has options to read from
- or write to the network connection used by <B>LIBPQ</B>.
- Therefore, functions are necessary to access this network connection directly so applications may take full
- advantage of this capability.
-<DL>
- <DT><B>PQgetline</B>
- <DD>Reads a newline-terminated line of characters
- (transmitted by the backend server) into a buffer
- string of size length. Like fgets(3), this routine copies up to length-1 characters into string.
- It is like gets(3), however, in that it converts
- the terminating newline into a null character.
- PQgetline returns EOF at EOF, 0 if the entire line
- has been read, and 1 if the buffer is full but the
- terminating newline has not yet been read.
- Notice that the application must check to see if a
- new line consists of the single character ".",
- which indicates that the backend server has finished sending the results of the copy command.
- Therefore, if the application ever expects to
- receive lines that are more than length-1 characters long, the application must be sure to check
- the return value of PQgetline very carefully.
- The code in
-
-<pre> ../src/bin/psql/psql.c
-</pre>
- contains routines that correctly handle the copy
- protocol.
-<pre> int PQgetline(PGconn &#42;conn,
- char &#42;string,
- int length)
-</pre><br>
- <DT><B>PQputline</B>
- <DD>Sends a null-terminated string to the backend
- server.
- The application must explicitly send the single
- character "." to indicate to the backend that it
- has finished sending its data.
-
-<pre> void PQputline(PGconn &#42;conn,
- char &#42;string);
-</pre><br>
- <DT><B>PQendcopy</B>
- <DD>Syncs with the backend. This function waits until
- the backend has finished the copy. It should
- either be issued when the last string has been
- sent to the backend using PQputline or when the
- last string has been received from the backend
- using PGgetline. It must be issued or the backend
- may get "out of sync" with the frontend. Upon
- return from this function, the backend is ready to
- receive the next query.
- The return value is 0 on successful completion,
- nonzero otherwise.
-<pre> int PQendcopy(PGconn &#42;conn);
-</pre><br>
- As an example:
-<pre> PQexec(conn, "create table foo (a int4, b char16, d float8)");
- PQexec(conn, "copy foo from stdin");
- PQputline(conn, "3&lt;TAB&gt;hello world&lt;TAB&gt;4.5\n");
- PQputline(conn,"4&lt;TAB&gt;goodbye world&lt;TAB&gt;7.11\n");
- ...
- PQputline(conn,".\n");
- PQendcopy(conn);
-</pre><br>
-</DL>
-<H2><A NAME="tracing-functions">12.7. <B>LIBPQ</B> Tracing Functions</A></H2>
-<DL>
- <DT><B>PQtrace</B>
- <DD>Enable tracing of the frontend/backend communication to a debugging file stream.
-<pre> void PQtrace(PGconn &#42;conn
- FILE &#42;debug_port)
-</pre><br>
-
- <DT><B>PQuntrace</B>
- <DD>Disable tracing started by PQtrace
-<pre> void PQuntrace(PGconn &#42;conn)
-</pre><br>
-</DL>
-<H2><A NAME="authentication-functions">12.8. User Authentication Functions</A></H2>
- If the user has generated the appropriate authentication credentials (e.g., obtaining <B>Kerberos</B> tickets),
- the frontend/backend authentication process is handled
- by <B>PQexec</B> without any further intervention. The following routines may be called by <B>LIBPQ</B> programs to tailor the behavior of the authentication process.
-<DL>
- <DT><B>fe_getauthname</B>
- <DD>Returns a pointer to static space containing whatever name the user has authenticated. Use of this
- routine in place of calls to getenv(3) or getpwuid(3) by applications is highly recommended, as
- it is entirely possible that the authenticated
- user name is not the same as value of the <B>USER</B>
- environment variable or the user's entry in
- <CODE>/etc/passwd</CODE>.
-
-<pre> char &#42;fe_getauthname(char&#42; errorMessage)
-</pre><br>
- <DT><B>fe_setauthsvc</B>
- <DD>Specifies that <B>LIBPQ</B> should use authentication
- service name rather than its compiled-in default.
- <DD>This value is typically taken from a command-line
- switch.
-<pre> void fe_setauthsvc(char &#42;name,
- char&#42; errorMessage)
-</pre>
- <DD>Any error messages from the authentication
- attempts are returned in the errorMessage argument.
-</DL>
-
-<H2><A NAME="bugs">12.9. BUGS</A></H2>
- The query buffer is 8192 bytes long, and queries over
- that length will be silently truncated.
-<H2><A NAME="sample-programs">12.10. Sample Programs</H2>
-<p>
-<H3><A NAME="sample-program-1">12.10.1. Sample Program 1</A></H3>
-<pre>
- /&#42;
- &#42; testlibpq.c
- &#42; Test the C version of LIBPQ, the POSTGRES frontend library.
- &#42;
- &#42;
- &#42;/
- #include &lt;stdio.h&gt;
- #include "libpq-fe.h"
-<p>
- void
- exit_nicely(PGconn&#42; conn)
- {
- PQfinish(conn);
- exit(1);
- }
-<p>
- main()
- {
- char &#42;pghost, &#42;pgport, &#42;pgoptions, &#42;pgtty;
- char&#42; dbName;
- int nFields;
- int i,j;
-<p>
- /&#42; FILE &#42;debug; &#42;/
-<p>
- PGconn&#42; conn;
- PGresult&#42; res;
-<p>
- /&#42; begin, by setting the parameters for a backend connection
- if the parameters are null, then the system will try to use
- reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants &#42;/
- pghost = NULL; /&#42; host name of the backend server &#42;/
- pgport = NULL; /&#42; port of the backend server &#42;/
- pgoptions = NULL; /&#42; special options to start up the backend server &#42;/
- pgtty = NULL; /&#42; debugging tty for the backend server &#42;/
- dbName = "template1";
-<p>
- /&#42; make a connection to the database &#42;/
- conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-<p>
- /&#42; check to see that the backend connection was successfully made &#42;/
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '&#37;s' failed.0, dbName);
- fprintf(stderr,"&#37;s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
-<p>
- /&#42; debug = fopen("/tmp/trace.out","w"); &#42;/
- /&#42; PQtrace(conn, debug); &#42;/
-<p>
- /&#42; start a transaction block &#42;/
-
- res = PQexec(conn,"BEGIN");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed0);
- PQclear(res);
- exit_nicely(conn);
- }
- /&#42; should PQclear PGresult whenever it is no longer needed to avoid
- memory leaks &#42;/
- PQclear(res);
-<p>
- /&#42; fetch instances from the pg_database, the system catalog of databases&#42;/
- res = PQexec(conn,"DECLARE myportal CURSOR FOR select &#42; from pg_database");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"DECLARE CURSOR command failed0);
- PQclear(res);
- exit_nicely(conn);
- }
- PQclear(res);
-<p>
- res = PQexec(conn,"FETCH ALL in myportal");
- if (PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"FETCH ALL command didn't return tuples properly0);
- PQclear(res);
- exit_nicely(conn);
- }
-<p>
- /&#42; first, print out the attribute names &#42;/
- nFields = PQnfields(res);
- for (i=0; i &lt; nFields; i++) {
- printf("&#37;-15s",PQfname(res,i));
- }
- printf("0);
-<p>
- /&#42; next, print out the instances &#42;/
- for (i=0; i &lt; PQntuples(res); i++) {
- for (j=0 ; j &lt; nFields; j++) {
- printf("&#37;-15s", PQgetvalue(res,i,j));
- }
- printf("0);
- }
-<p>
- PQclear(res);
-<p>
- /&#42; close the portal &#42;/
- res = PQexec(conn, "CLOSE myportal");
- PQclear(res);
-<p>
- /&#42; end the transaction &#42;/
- res = PQexec(conn, "END");
- PQclear(res);
-<p>
- /&#42; close the connection to the database and cleanup &#42;/
- PQfinish(conn);
-
- /&#42; fclose(debug); &#42;/
- }
-</pre>
-<p>
-<H3><A NAME="sample-program-2">12.10.2. Sample Program 2</A></H3>
-<pre>
- /&#42;
- &#42; testlibpq2.c
- &#42; Test of the asynchronous notification interface
- &#42;
- populate a database with the following:
-<p>
- CREATE TABLE TBL1 (i int4);
-<p>
- CREATE TABLE TBL2 (i int4);
-<p>
- CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
-<p>
- &#42; Then start up this program
- &#42; After the program has begun, do
-<p>
- INSERT INTO TBL1 values (10);
-<p>
- &#42;
- &#42;
- &#42;/
- #include &lt;stdio.h&gt;
- #include "libpq-fe.h"
-<p>
- void exit_nicely(PGconn&#42; conn)
- {
- PQfinish(conn);
- exit(1);
- }
-<p>
- main()
- {
- char &#42;pghost, &#42;pgport, &#42;pgoptions, &#42;pgtty;
- char&#42; dbName;
- int nFields;
- int i,j;
-<p>
- PGconn&#42; conn;
- PGresult&#42; res;
- PGnotify&#42; notify;
-<p>
- /&#42; begin, by setting the parameters for a backend connection
- if the parameters are null, then the system will try to use
- reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants &#42;/
- pghost = NULL; /&#42; host name of the backend server &#42;/
- pgport = NULL; /&#42; port of the backend server &#42;/
- pgoptions = NULL; /&#42; special options to start up the backend server &#42;/
- pgtty = NULL; /&#42; debugging tty for the backend server &#42;/
- dbName = getenv("USER"); /&#42; change this to the name of your test database&#42;/
-<p>
- /&#42; make a connection to the database &#42;/
- conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-
- /&#42; check to see that the backend connection was successfully made &#42;/
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '&#37;s' failed.0, dbName);
- fprintf(stderr,"&#37;s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
-<p>
- res = PQexec(conn, "LISTEN TBL2");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"LISTEN command failed0);
- PQclear(res);
- exit_nicely(conn);
- }
- /&#42; should PQclear PGresult whenever it is no longer needed to avoid
- memory leaks &#42;/
- PQclear(res);
-<p>
- while (1) {
- /&#42; async notification only come back as a result of a query&#42;/
- /&#42; we can send empty queries &#42;/
- res = PQexec(conn, " ");
- /&#42; printf("res-&gt;status = &#37;s0, pgresStatus[PQresultStatus(res)]); &#42;/
- /&#42; check for asynchronous returns &#42;/
- notify = PQnotifies(conn);
- if (notify) {
- fprintf(stderr,
- "ASYNC NOTIFY of '&#37;s' from backend pid '&#37;d' received0,
- notify-&gt;relname, notify-&gt;be_pid);
- free(notify);
- break;
- }
- PQclear(res);
- }
-<p>
- /&#42; close the connection to the database and cleanup &#42;/
- PQfinish(conn);
-<p>
- }
-</pre>
-<p>
-<H3><A NAME="sample-program-3">12.10.3. Sample Program 3</A></H3>
-<pre>
- /&#42;
- &#42; testlibpq3.c
- &#42; Test the C version of LIBPQ, the POSTGRES frontend library.
- &#42; tests the binary cursor interface
- &#42;
- &#42;
- &#42;
- populate a database by doing the following:
-<p>
- CREATE TABLE test1 (i int4, d float4, p polygon);
-<p>
- INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
-<p>
- INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
-<p>
- the expected output is:
-<p>
- tuple 0: got
- i = (4 bytes) 1,
- d = (4 bytes) 3.567000,
- p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
- tuple 1: got
- i = (4 bytes) 2,
- d = (4 bytes) 89.050003,
- p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
-<p>
- &#42;
- &#42;/
- #include &lt;stdio.h&gt;
- #include "libpq-fe.h"
- #include "utils/geo-decls.h" /&#42; for the POLYGON type &#42;/
-<p>
- void exit_nicely(PGconn&#42; conn)
- {
- PQfinish(conn);
- exit(1);
- }
-<p>
- main()
- {
- char &#42;pghost, &#42;pgport, &#42;pgoptions, &#42;pgtty;
- char&#42; dbName;
- int nFields;
- int i,j;
- int i_fnum, d_fnum, p_fnum;
-<p>
- PGconn&#42; conn;
- PGresult&#42; res;
-<p>
- /&#42; begin, by setting the parameters for a backend connection
- if the parameters are null, then the system will try to use
- reasonable defaults by looking up environment variables
- or, failing that, using hardwired constants &#42;/
- pghost = NULL; /&#42; host name of the backend server &#42;/
- pgport = NULL; /&#42; port of the backend server &#42;/
- pgoptions = NULL; /&#42; special options to start up the backend server &#42;/
- pgtty = NULL; /&#42; debugging tty for the backend server &#42;/
-<p>
- dbName = getenv("USER"); /&#42; change this to the name of your test database&#42;/
-<p>
- /&#42; make a connection to the database &#42;/
- conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
-<p>
- /&#42; check to see that the backend connection was successfully made &#42;/
- if (PQstatus(conn) == CONNECTION_BAD) {
- fprintf(stderr,"Connection to database '&#37;s' failed.0, dbName);
- fprintf(stderr,"&#37;s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
-<p>
- /&#42; start a transaction block &#42;/
- res = PQexec(conn,"BEGIN");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"BEGIN command failed0);
- PQclear(res);
- exit_nicely(conn);
- }
- /&#42; should PQclear PGresult whenever it is no longer needed to avoid
- memory leaks &#42;/
- PQclear(res);
-<p>
- /&#42; fetch instances from the pg_database, the system catalog of databases&#42;/
- res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select &#42; from test1");
- if (PQresultStatus(res) != PGRES_COMMAND_OK) {
- fprintf(stderr,"DECLARE CURSOR command failed0);
- PQclear(res);
- exit_nicely(conn);
- }
- PQclear(res);
-<p>
- res = PQexec(conn,"FETCH ALL in mycursor");
- if (PQresultStatus(res) != PGRES_TUPLES_OK) {
- fprintf(stderr,"FETCH ALL command didn't return tuples properly0);
- PQclear(res);
- exit_nicely(conn);
- }
-<p>
- i_fnum = PQfnumber(res,"i");
- d_fnum = PQfnumber(res,"d");
- p_fnum = PQfnumber(res,"p");
-<p>
- for (i=0;i&lt;3;i++) {
- printf("type[&#37;d] = &#37;d, size[&#37;d] = &#37;d0,
- i, PQftype(res,i),
- i, PQfsize(res,i));
- }
- for (i=0; i &lt; PQntuples(res); i++) {
- int &#42;ival;
- float &#42;dval;
- int plen;
- POLYGON&#42; pval;
- /&#42; we hard-wire this to the 3 fields we know about &#42;/
- ival = (int&#42;)PQgetvalue(res,i,i_fnum);
- dval = (float&#42;)PQgetvalue(res,i,d_fnum);
- plen = PQgetlength(res,i,p_fnum);
-<p>
- /&#42; plen doesn't include the length field so need to increment by VARHDSZ&#42;/
- pval = (POLYGON&#42;) malloc(plen + VARHDRSZ);
- pval-&gt;size = plen;
- memmove((char&#42;)&amp;pval-&gt;npts, PQgetvalue(res,i,p_fnum), plen);
- printf("tuple &#37;d: got0, i);
- printf(" i = (&#37;d bytes) &#37;d,0,
- PQgetlength(res,i,i_fnum), &#42;ival);
- printf(" d = (&#37;d bytes) &#37;f,0,
- PQgetlength(res,i,d_fnum), &#42;dval);
- printf(" p = (&#37;d bytes) &#37;d points boundbox = (hi=&#37;f/&#37;f, lo = &#37;f,&#37;f)0,
- PQgetlength(res,i,d_fnum),
- pval-&gt;npts,
- pval-&gt;boundbox.xh,
- pval-&gt;boundbox.yh,
- pval-&gt;boundbox.xl,
- pval-&gt;boundbox.yl);
- }
-<p>
- PQclear(res);
-<p>
- /&#42; close the portal &#42;/
- res = PQexec(conn, "CLOSE mycursor");
- PQclear(res);
-<p>
- /&#42; end the transaction &#42;/
- res = PQexec(conn, "END");
- PQclear(res);
-<p>
- /&#42; close the connection to the database and cleanup &#42;/
- PQfinish(conn);
-<p>
- }
-</pre>
-<HR>
-<font size=-1>
-<A HREF="pg95user.html">[ TOC ]</A>
-<A HREF="xindex.html">[ Previous ]</A>
-<A HREF="lobj.html">[ Next ]</A>
-</font>
-</BODY>
-</HTML>