Header And Logo

PostgreSQL
| The world's most advanced open source database.

testlibpq2.c

Go to the documentation of this file.
00001 /*
00002  * src/test/examples/testlibpq2.c
00003  *
00004  *
00005  * testlibpq2.c
00006  *      Test of the asynchronous notification interface
00007  *
00008  * Start this program, then from psql in another window do
00009  *   NOTIFY TBL2;
00010  * Repeat four times to get this program to exit.
00011  *
00012  * Or, if you want to get fancy, try this:
00013  * populate a database with the following commands
00014  * (provided in src/test/examples/testlibpq2.sql):
00015  *
00016  *   CREATE TABLE TBL1 (i int4);
00017  *
00018  *   CREATE TABLE TBL2 (i int4);
00019  *
00020  *   CREATE RULE r1 AS ON INSERT TO TBL1 DO
00021  *     (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
00022  *
00023  * and do this four times:
00024  *
00025  *   INSERT INTO TBL1 VALUES (10);
00026  */
00027 
00028 #ifdef WIN32
00029 #include <windows.h>
00030 #endif
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <errno.h>
00035 #include <sys/time.h>
00036 #include <sys/types.h>
00037 #include "libpq-fe.h"
00038 
00039 static void
00040 exit_nicely(PGconn *conn)
00041 {
00042     PQfinish(conn);
00043     exit(1);
00044 }
00045 
00046 int
00047 main(int argc, char **argv)
00048 {
00049     const char *conninfo;
00050     PGconn     *conn;
00051     PGresult   *res;
00052     PGnotify   *notify;
00053     int         nnotifies;
00054 
00055     /*
00056      * If the user supplies a parameter on the command line, use it as the
00057      * conninfo string; otherwise default to setting dbname=postgres and using
00058      * environment variables or defaults for all other connection parameters.
00059      */
00060     if (argc > 1)
00061         conninfo = argv[1];
00062     else
00063         conninfo = "dbname = postgres";
00064 
00065     /* Make a connection to the database */
00066     conn = PQconnectdb(conninfo);
00067 
00068     /* Check to see that the backend connection was successfully made */
00069     if (PQstatus(conn) != CONNECTION_OK)
00070     {
00071         fprintf(stderr, "Connection to database failed: %s",
00072                 PQerrorMessage(conn));
00073         exit_nicely(conn);
00074     }
00075 
00076     /*
00077      * Issue LISTEN command to enable notifications from the rule's NOTIFY.
00078      */
00079     res = PQexec(conn, "LISTEN TBL2");
00080     if (PQresultStatus(res) != PGRES_COMMAND_OK)
00081     {
00082         fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
00083         PQclear(res);
00084         exit_nicely(conn);
00085     }
00086 
00087     /*
00088      * should PQclear PGresult whenever it is no longer needed to avoid memory
00089      * leaks
00090      */
00091     PQclear(res);
00092 
00093     /* Quit after four notifies are received. */
00094     nnotifies = 0;
00095     while (nnotifies < 4)
00096     {
00097         /*
00098          * Sleep until something happens on the connection.  We use select(2)
00099          * to wait for input, but you could also use poll() or similar
00100          * facilities.
00101          */
00102         int         sock;
00103         fd_set      input_mask;
00104 
00105         sock = PQsocket(conn);
00106 
00107         if (sock < 0)
00108             break;              /* shouldn't happen */
00109 
00110         FD_ZERO(&input_mask);
00111         FD_SET(sock, &input_mask);
00112 
00113         if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
00114         {
00115             fprintf(stderr, "select() failed: %s\n", strerror(errno));
00116             exit_nicely(conn);
00117         }
00118 
00119         /* Now check for input */
00120         PQconsumeInput(conn);
00121         while ((notify = PQnotifies(conn)) != NULL)
00122         {
00123             fprintf(stderr,
00124                     "ASYNC NOTIFY of '%s' received from backend PID %d\n",
00125                     notify->relname, notify->be_pid);
00126             PQfreemem(notify);
00127             nnotifies++;
00128         }
00129     }
00130 
00131     fprintf(stderr, "Done.\n");
00132 
00133     /* close the connection to the database and cleanup */
00134     PQfinish(conn);
00135 
00136     return 0;
00137 }