| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| * $PostgreSQL: pgsql/src/test/examples/testlibpq2.c,v 1.15 2009/06/11 14:49:15 momjian Exp $ |
| * |
| * |
| * 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, 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); |
| } |
| |
| /* |
| * 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, 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; |
| } |