aboutsummaryrefslogtreecommitdiff
path: root/src/test/examples/testlibpq2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/examples/testlibpq2.c')
-rw-r--r--src/test/examples/testlibpq2.c131
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;
}