diff options
Diffstat (limited to 'src/test/examples/testlibpq2.c')
-rw-r--r-- | src/test/examples/testlibpq2.c | 131 |
1 files changed, 75 insertions, 56 deletions
diff --git a/src/test/examples/testlibpq2.c b/src/test/examples/testlibpq2.c index 8f5a1ec3abb..51c9929df3d 100644 --- a/src/test/examples/testlibpq2.c +++ b/src/test/examples/testlibpq2.c @@ -2,24 +2,30 @@ * testlibpq2.c * Test of the asynchronous notification interface * - populate a database with the following: - -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]; - - * Then start up this program - * After the program has begun, do - -INSERT INTO TBL1 values (10); - + * 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 @@ -30,51 +36,43 @@ exit_nicely(PGconn *conn) } int -main() +main(int argc, char **argv) { - char *pghost, - *pgport, - *pgoptions, - *pgtty; - char *dbName; - - /* - * int nFields; int i, j; - */ - + const char *conninfo; PGconn *conn; PGresult *res; PGnotify *notify; + int nnotifies; /* - * 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 + * If the user supplies a parameter on the command line, use it as + * the conninfo string; otherwise default to setting dbname=template1 + * and using environment variables or defaults for all other connection + * parameters. */ - 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 */ - - /* 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) + if (argc > 1) + conninfo = argv[1]; + else + conninfo = "dbname = template1"; + + /* 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 '%s' failed.\n", dbName); + fprintf(stderr, "Connection to database '%s' failed.\n", PQdb(conn)); fprintf(stderr, "%s", 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\n"); + fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn)); PQclear(res); exit_nicely(conn); } @@ -85,27 +83,48 @@ main() */ PQclear(res); - while (1) + /* Quit after four notifies are received. */ + nnotifies = 0; + while (nnotifies < 4) { - /* async notification only come back as a result of a query */ - /* we can send empty queries */ - res = PQexec(conn, " "); -/* printf("res->status = %s\n", PQresStatus(PQresultStatus(res))); */ - /* check for asynchronous returns */ - notify = PQnotifies(conn); - if (notify) + /* + * 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, 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' from backend pid '%d' received\n", + "ASYNC NOTIFY of '%s' received from backend pid %d\n", notify->relname, notify->be_pid); PQfreemem(notify); - break; + nnotifies++; } - PQclear(res); } + fprintf(stderr, "Done.\n"); + /* close the connection to the database and cleanup */ PQfinish(conn); - return 0; /* Though PQfinish(conn1) has called - * exit(1) */ + + return 0; } |