diff options
Diffstat (limited to 'doc/manual/libpq.html')
-rw-r--r-- | doc/manual/libpq.html | 815 |
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 *PQsetdb(char *pghost, - char *pgport, - char *pgoptions, - char *pgtty, - char *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 *PQdb(PGconn *conn) -</pre><br> - <DT><B>PQhost</B> - <DD>Returns the host name of the connection. -<pre> char *PQhost(PGconn *conn) -</pre><br> - <DT><B>PQoptions</B> - <DD>Returns the pgoptions used in the connection. -<pre> char *PQoptions(PGconn *conn) -</pre><br> - <DT><B>PQport</B> - <DD>Returns the pgport of the connection. -<pre> char *PQport(PGconn *conn) -</pre><br> - <DT><B>PQtty</B> - <DD>Returns the pgtty of the connection. -<pre> char *PQtty(PGconn *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 *PQstatus(PGconn *conn) -</pre><br> - <DT><B>PQerrorMessage</B> - <DD>Returns the error message associated with the connection -<pre> char *PQerrorMessage(PGconn* 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 *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 *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 *conn, - FILE* debug_port); -</pre><br> - <DT><B>PQuntrace</B> - <DD>Disables tracing of messages passed between the - frontend and the backend. -<pre> void PQuntrace(PGconn *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 *PQexec(PGconn *conn, - char *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, /* the query was a command */ - PGRES_TUPLES_OK, /* the query successfully returned tuples */ - PGRES_COPY_OUT, - PGRES_COPY_IN, - PGRES_BAD_RESPONSE, /* an unexpected response was received */ - 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 *res); -</pre><br> - <DT><B>PQnfields</B> - <DD>Returns the number of fields - (attributes) in the query result. - -<pre> int PQnfields(PGresult *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 *PQfname(PGresult *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 *res, - char* 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 *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 *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* PQgetvalue(PGresult *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 *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 *PQcmdStatus(PGresult *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* PQoidStatus(PGresult *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* res, - FILE* fout, /* output stream */ - int printAttName,/* print attribute names or not*/ - int terseOutput, /* delimiter bars or not?*/ - int width /* width of column, variable width if 0*/ - ); -</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 *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* PQfn(PGconn* conn, - int fnid, - int *result_buf, - int *result_len, - int result_is_int, - PQArgBlock *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 *ptr; - int integer; - } u; - } PQArgBlock; -</pre> - PQfn always returns a valid PGresult*. 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* PQNotifies(PGconn *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 *conn, - char *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 *conn, - char *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 *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<TAB>hello world<TAB>4.5\n"); - PQputline(conn,"4<TAB>goodbye world<TAB>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 *conn - FILE *debug_port) -</pre><br> - - <DT><B>PQuntrace</B> - <DD>Disable tracing started by PQtrace -<pre> void PQuntrace(PGconn *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 *fe_getauthname(char* 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 *name, - char* 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> - /* - * testlibpq.c - * Test the C version of LIBPQ, the POSTGRES frontend library. - * - * - */ - #include <stdio.h> - #include "libpq-fe.h" -<p> - void - exit_nicely(PGconn* conn) - { - PQfinish(conn); - exit(1); - } -<p> - main() - { - char *pghost, *pgport, *pgoptions, *pgtty; - char* dbName; - int nFields; - int i,j; -<p> - /* FILE *debug; */ -<p> - PGconn* conn; - PGresult* res; -<p> - /* 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 */ - pghost = NULL; /* host name of the backend server */ - pgport = NULL; /* port of the backend server */ - pgoptions = NULL; /* special options to start up the backend server */ - pgtty = NULL; /* debugging tty for the backend server */ - dbName = "template1"; -<p> - /* make a connection to the database */ - conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); -<p> - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.0, dbName); - fprintf(stderr,"%s",PQerrorMessage(conn)); - exit_nicely(conn); - } -<p> - /* debug = fopen("/tmp/trace.out","w"); */ - /* PQtrace(conn, debug); */ -<p> - /* start a transaction block */ - - res = PQexec(conn,"BEGIN"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed0); - PQclear(res); - exit_nicely(conn); - } - /* should PQclear PGresult whenever it is no longer needed to avoid - memory leaks */ - PQclear(res); -<p> - /* fetch instances from the pg_database, the system catalog of databases*/ - res = PQexec(conn,"DECLARE myportal CURSOR FOR select * 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> - /* first, print out the attribute names */ - nFields = PQnfields(res); - for (i=0; i < nFields; i++) { - printf("%-15s",PQfname(res,i)); - } - printf("0); -<p> - /* next, print out the instances */ - for (i=0; i < PQntuples(res); i++) { - for (j=0 ; j < nFields; j++) { - printf("%-15s", PQgetvalue(res,i,j)); - } - printf("0); - } -<p> - PQclear(res); -<p> - /* close the portal */ - res = PQexec(conn, "CLOSE myportal"); - PQclear(res); -<p> - /* end the transaction */ - res = PQexec(conn, "END"); - PQclear(res); -<p> - /* close the connection to the database and cleanup */ - PQfinish(conn); - - /* fclose(debug); */ - } -</pre> -<p> -<H3><A NAME="sample-program-2">12.10.2. Sample Program 2</A></H3> -<pre> - /* - * testlibpq2.c - * Test of the asynchronous notification interface - * - 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> - * Then start up this program - * After the program has begun, do -<p> - INSERT INTO TBL1 values (10); -<p> - * - * - */ - #include <stdio.h> - #include "libpq-fe.h" -<p> - void exit_nicely(PGconn* conn) - { - PQfinish(conn); - exit(1); - } -<p> - main() - { - char *pghost, *pgport, *pgoptions, *pgtty; - char* dbName; - int nFields; - int i,j; -<p> - PGconn* conn; - PGresult* res; - PGnotify* notify; -<p> - /* 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 */ - pghost = NULL; /* host name of the backend server */ - pgport = NULL; /* port of the backend server */ - pgoptions = NULL; /* special options to start up the backend server */ - pgtty = NULL; /* debugging tty for the backend server */ - dbName = getenv("USER"); /* change this to the name of your test database*/ -<p> - /* make a connection to the database */ - conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.0, dbName); - fprintf(stderr,"%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); - } - /* should PQclear PGresult whenever it is no longer needed to avoid - memory leaks */ - PQclear(res); -<p> - while (1) { - /* async notification only come back as a result of a query*/ - /* we can send empty queries */ - res = PQexec(conn, " "); - /* printf("res->status = %s0, pgresStatus[PQresultStatus(res)]); */ - /* check for asynchronous returns */ - notify = PQnotifies(conn); - if (notify) { - fprintf(stderr, - "ASYNC NOTIFY of '%s' from backend pid '%d' received0, - notify->relname, notify->be_pid); - free(notify); - break; - } - PQclear(res); - } -<p> - /* close the connection to the database and cleanup */ - PQfinish(conn); -<p> - } -</pre> -<p> -<H3><A NAME="sample-program-3">12.10.3. Sample Program 3</A></H3> -<pre> - /* - * testlibpq3.c - * Test the C version of LIBPQ, the POSTGRES frontend library. - * tests the binary cursor interface - * - * - * - 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> - * - */ - #include <stdio.h> - #include "libpq-fe.h" - #include "utils/geo-decls.h" /* for the POLYGON type */ -<p> - void exit_nicely(PGconn* conn) - { - PQfinish(conn); - exit(1); - } -<p> - main() - { - char *pghost, *pgport, *pgoptions, *pgtty; - char* dbName; - int nFields; - int i,j; - int i_fnum, d_fnum, p_fnum; -<p> - PGconn* conn; - PGresult* res; -<p> - /* 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 */ - pghost = NULL; /* host name of the backend server */ - pgport = NULL; /* port of the backend server */ - pgoptions = NULL; /* special options to start up the backend server */ - pgtty = NULL; /* debugging tty for the backend server */ -<p> - dbName = getenv("USER"); /* change this to the name of your test database*/ -<p> - /* make a connection to the database */ - conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); -<p> - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.0, dbName); - fprintf(stderr,"%s",PQerrorMessage(conn)); - exit_nicely(conn); - } -<p> - /* start a transaction block */ - res = PQexec(conn,"BEGIN"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed0); - PQclear(res); - exit_nicely(conn); - } - /* should PQclear PGresult whenever it is no longer needed to avoid - memory leaks */ - PQclear(res); -<p> - /* fetch instances from the pg_database, the system catalog of databases*/ - res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select * 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<3;i++) { - printf("type[%d] = %d, size[%d] = %d0, - i, PQftype(res,i), - i, PQfsize(res,i)); - } - for (i=0; i < PQntuples(res); i++) { - int *ival; - float *dval; - int plen; - POLYGON* pval; - /* we hard-wire this to the 3 fields we know about */ - ival = (int*)PQgetvalue(res,i,i_fnum); - dval = (float*)PQgetvalue(res,i,d_fnum); - plen = PQgetlength(res,i,p_fnum); -<p> - /* plen doesn't include the length field so need to increment by VARHDSZ*/ - pval = (POLYGON*) malloc(plen + VARHDRSZ); - pval->size = plen; - memmove((char*)&pval->npts, PQgetvalue(res,i,p_fnum), plen); - printf("tuple %d: got0, i); - printf(" i = (%d bytes) %d,0, - PQgetlength(res,i,i_fnum), *ival); - printf(" d = (%d bytes) %f,0, - PQgetlength(res,i,d_fnum), *dval); - printf(" p = (%d bytes) %d points boundbox = (hi=%f/%f, lo = %f,%f)0, - PQgetlength(res,i,d_fnum), - pval->npts, - pval->boundbox.xh, - pval->boundbox.yh, - pval->boundbox.xl, - pval->boundbox.yl); - } -<p> - PQclear(res); -<p> - /* close the portal */ - res = PQexec(conn, "CLOSE mycursor"); - PQclear(res); -<p> - /* end the transaction */ - res = PQexec(conn, "END"); - PQclear(res); -<p> - /* close the connection to the database and cleanup */ - 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> |