关于libpq各个函数接口的说明,参考:http://www.postgres.cn/docs/9.3/libpq.html
例子1:
- /*
- * testlibpq.c
- *
- * Test the C version of libpq,the Postgresql frontend library.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <libpq-fe.h>
- static void
- exit_nicely(PGconn *conn)
- {
- PQfinish(conn);
- exit(1);
- }
- int
- main(int argc,char **argv)
- {
- const char *conninfo;
- PGconn *conn;
- PGresult *res;
- int nFields;
- int i,j;
- /*
- * If the user supplies a parameter on the command line,use it as the
- * conninfo string; otherwise default to setting dbname=postgres and using
- * environment variables or defaults for all other connection parameters.
- */
- if (argc > 1)
- conninfo = argv[1];
- else
- conninfo = "dbname = postgres";
- /* Make a connection to the database */
- conn = PQconnectdb(conninfo);
- /* Check to see that the backend connection was successfully made */
- if (PQstatus(conn) != CONNECTION_OK)
- {
- fprintf(stderr,"Connection to database Failed: %s",PQerrorMessage(conn));
- exit_nicely(conn);
- }
- /*
- * Our test case here involves using a cursor,for which we must be inside
- * a transaction block. We could do the whole thing with a single
- * PQexec() of "select * from pg_database",but that's too trivial to make
- * a good example.
- */
- /* Start a transaction block */
- res = PQexec(conn,"BEGIN");
- if (PQresultStatus(res) != PGRES_COMMAND_OK)
- {
- fprintf(stderr,"BEGIN command Failed: %s",PQerrorMessage(conn));
- PQclear(res);
- exit_nicely(conn);
- }
- /*
- * Should PQclear PGresult whenever it is no longer needed to avoid memory
- * leaks
- */
- PQclear(res);
- /*
- * Fetch rows from 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 Failed: %s",PQerrorMessage(conn));
- PQclear(res);
- exit_nicely(conn);
- }
- PQclear(res);
- res = PQexec(conn,"FETCH ALL in myportal");
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr,"FETCH ALL Failed: %s",PQerrorMessage(conn));
- PQclear(res);
- exit_nicely(conn);
- }
- /* first,print out the attribute names */
- nFields = PQnfields(res);
- for (i = 0; i < nFields; i++)
- printf("%-15s",PQfname(res,i));
- printf("\n\n");
- /* next,print out the rows */
- for (i = 0; i < PQntuples(res); i++)
- {
- for (j = 0; j < nFields; j++)
- printf("%-15s",PQgetvalue(res,i,j));
- printf("\n");
- }
- PQclear(res);
- /* close the portal ... we don't bother to check for errors ... */
- res = PQexec(conn,"CLOSE myportal");
- PQclear(res);
- /* end the transaction */
- res = PQexec(conn,"END");
- PQclear(res);
- /* close the connection to the database and cleanup */
- PQfinish(conn);
- return 0;
- }
例子2:
- /*
- * testlibpq2.c
- * Test of the asynchronous notification interface
- *
- * Start this program,then from psql in another window do
- * NOTIFY TBL2;
- * Repeat four times to get this program to exit.
- *
- * Or,if you want to get fancy,try this:
- * populate a database with the following commands
- * (provided in src/test/examples/testlibpq2.sql):
- *
- * CREATE TABLE TBL1 (i int4);
- *
- * CREATE TABLE TBL2 (i int4);
- *
- * CREATE RULE r1 AS ON INSERT TO TBL1 DO
- * (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
- *
- * and do this four times:
- *
- * INSERT INTO TBL1 VALUES (10);
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/time.h>
- #include <libpq-fe.h>
- static void
- exit_nicely(PGconn *conn)
- {
- PQfinish(conn);
- exit(1);
- }
- int
- main(int argc,char **argv)
- {
- const char *conninfo;
- PGconn *conn;
- PGresult *res;
- PGnotify *notify;
- int nnotifies;
- /*
- * If the user supplies a parameter on the command line,PQerrorMessage(conn));
- exit_nicely(conn);
- }
- /*
- * Issue LISTEN command to enable notifications from the rule's NOTIFY.
- */
- res = PQexec(conn,"LISTEN TBL2");
- if (PQresultStatus(res) != PGRES_COMMAND_OK)
- {
- fprintf(stderr,"LISTEN command Failed: %s",PQerrorMessage(conn));
- PQclear(res);
- exit_nicely(conn);
- }
- /*
- * should PQclear PGresult whenever it is no longer needed to avoid memory
- * leaks
- */
- PQclear(res);
- /* Quit after four notifies are received. */
- nnotifies = 0;
- while (nnotifies < 4)
- {
- /*
- * Sleep until something happens on the connection. We use select(2)
- * to wait for input,but you could also use poll() or similar
- * facilities.
- */
- int sock;
- fd_set input_mask;
- sock = PQsocket(conn);
- if (sock < 0)
- break; /* shouldn't happen */
- FD_ZERO(&input_mask);
- FD_SET(sock,&input_mask);
- if (select(sock + 1,&input_mask,NULL,NULL) < 0)
- {
- fprintf(stderr,"select() Failed: %s\n",strerror(errno));
- exit_nicely(conn);
- }
- /* Now check for input */
- PQconsumeInput(conn);
- while ((notify = PQnotifies(conn)) != NULL)
- {
- fprintf(stderr,"ASYNC NOTIFY of '%s' received from backend PID %d\n",notify->relname,notify->be_pid);
- PQfreemem(notify);
- nnotifies++;
- }
- }
- fprintf(stderr,"Done.\n");
- /* close the connection to the database and cleanup */
- PQfinish(conn);
- return 0;
- }
例子3:
- /*
- * testlibpq3.c
- * Test out-of-line parameters and binary I/O.
- *
- * Before running this,populate a database with the following commands
- * (provided in src/test/examples/testlibpq3.sql):
- *
- * CREATE TABLE test1 (i int4,t text,b bytea);
- *
- * INSERT INTO test1 values (1,'joe''s place','\\000\\001\\002\\003\\004');
- * INSERT INTO test1 values (2,'ho there','\\004\\003\\002\\001\\000');
- *
- * The expected output is:
- *
- * tuple 0: got
- * i = (4 bytes) 1
- * t = (11 bytes) 'joe's place'
- * b = (5 bytes) \000\001\002\003\004
- *
- * tuple 0: got
- * i = (4 bytes) 2
- * t = (8 bytes) 'ho there'
- * b = (5 bytes) \004\003\002\001\000
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <libpq-fe.h>
- /* for ntohl/htonl */
- #include <netinet/in.h>
- #include <arpa/inet.h>
- static void
- exit_nicely(PGconn *conn)
- {
- PQfinish(conn);
- exit(1);
- }
- /*
- * This function prints a query result that is a binary-format fetch from
- * a table defined as in the comment above. We split it out because the
- * main() function uses it twice.
- */
- static void
- show_binary_results(PGresult *res)
- {
- int i,j;
- int i_fnum,t_fnum,b_fnum;
- /* Use PQfnumber to avoid assumptions about field order in result */
- i_fnum = PQfnumber(res,"i");
- t_fnum = PQfnumber(res,"t");
- b_fnum = PQfnumber(res,"b");
- for (i = 0; i < PQntuples(res); i++)
- {
- char *iptr;
- char *tptr;
- char *bptr;
- int blen;
- int ival;
- /* Get the field values (we ignore possibility they are null!) */
- iptr = PQgetvalue(res,i_fnum);
- tptr = PQgetvalue(res,t_fnum);
- bptr = PQgetvalue(res,b_fnum);
- /*
- * The binary representation of INT4 is in network byte order,which
- * we'd better coerce to the local byte order.
- */
- ival = ntohl(*((uint32_t *) iptr));
- /*
- * The binary representation of TEXT is,well,text,and since libpq
- * was nice enough to append a zero byte to it,it'll work just fine
- * as a C string.
- *
- * The binary representation of BYTEA is a bunch of bytes,which could
- * include embedded nulls so we have to pay attention to field length.
- */
- blen = PQgetlength(res,b_fnum);
- printf("tuple %d: got\n",i);
- printf(" i = (%d bytes) %d\n",PQgetlength(res,i_fnum),ival);
- printf(" t = (%d bytes) '%s'\n",t_fnum),tptr);
- printf(" b = (%d bytes) ",blen);
- for (j = 0; j < blen; j++)
- printf("\\%03o",bptr[j]);
- printf("\n\n");
- }
- }
- int
- main(int argc,char **argv)
- {
- const char *conninfo;
- PGconn *conn;
- PGresult *res;
- const char *paramValues[1];
- int paramLengths[1];
- int paramFormats[1];
- uint32_t binaryIntVal;
- /*
- * If the user supplies a parameter on the command line,PQerrorMessage(conn));
- exit_nicely(conn);
- }
- /*
- * The point of this program is to illustrate use of PQexecParams() with
- * out-of-line parameters,as well as binary transmission of data.
- *
- * This first example transmits the parameters as text,but receives the
- * results in binary format. By using out-of-line parameters we can
- * avoid a lot of tedious mucking about with quoting and escaping,even
- * though the data is text. Notice how we don't have to do anything
- * special with the quote mark in the parameter value.
- */
- /* Here is our out-of-line parameter value */
- paramValues[0] = "joe's place";
- res = PQexecParams(conn,"SELECT * FROM test1 WHERE t = $1",1,/* one param */
- NULL,/* let the backend deduce param type */
- paramValues,/* don't need param lengths since text */
- NULL,/* default to all text params */
- 1); /* ask for binary results */
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr,"SELECT Failed: %s",PQerrorMessage(conn));
- PQclear(res);
- exit_nicely(conn);
- }
- show_binary_results(res);
- PQclear(res);
- /*
- * In this second example we transmit an integer parameter in binary
- * form,and again retrieve the results in binary form.
- *
- * Although we tell PQexecParams we are letting the backend deduce
- * parameter type,we really force the decision by casting the parameter
- * symbol in the query text. This is a good safety measure when sending
- * binary parameters.
- */
- /* Convert integer value "2" to network byte order */
- binaryIntVal = htonl((uint32_t) 2);
- /* Set up parameter arrays for PQexecParams */
- paramValues[0] = (char *) &binaryIntVal;
- paramLengths[0] = sizeof(binaryIntVal);
- paramFormats[0] = 1; /* binary */
- res = PQexecParams(conn,"SELECT * FROM test1 WHERE i = $1::int4",paramLengths,paramFormats,1); /* ask for binary results */
- if (PQresultStatus(res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr,PQerrorMessage(conn));
- PQclear(res);
- exit_nicely(conn);
- }
- show_binary_results(res);
- PQclear(res);
- /* close the connection to the database and cleanup */
- PQfinish(conn);
- return 0;
- }