1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>32.23. Example Programs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-build.html" title="32.22. Building libpq Programs" /><link rel="next" href="largeobjects.html" title="Chapter 33. Large Objects" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">32.23. Example Programs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-build.html" title="32.22. Building libpq Programs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 32. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 32. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="largeobjects.html" title="Chapter 33. Large Objects">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">32.23. Example Programs <a href="#LIBPQ-EXAMPLE" class="id_link">#</a></h2></div></div></div><p>
3 These examples and others can be found in the
4 directory <code class="filename">src/test/examples</code> in the source code
6 </p><div class="example" id="LIBPQ-EXAMPLE-1"><p class="title"><strong>Example 32.1. <span class="application">libpq</span> Example Program 1</strong></p><div class="example-contents"><pre class="programlisting">
9 * src/test/examples/testlibpq.c
14 * Test the C version of libpq, the PostgreSQL frontend library.
16 #include <stdio.h>
17 #include <stdlib.h>
21 exit_nicely(PGconn *conn)
28 main(int argc, char **argv)
38 * If the user supplies a parameter on the command line, use it as the
39 * conninfo string; otherwise default to setting dbname=postgres and using
40 * environment variables or defaults for all other connection parameters.
45 conninfo = "dbname = postgres";
47 /* Make a connection to the database */
48 conn = PQconnectdb(conninfo);
50 /* Check to see that the backend connection was successfully made */
51 if (PQstatus(conn) != CONNECTION_OK)
53 fprintf(stderr, "%s", PQerrorMessage(conn));
57 /* Set always-secure search path, so malicious users can't take control. */
59 "SELECT pg_catalog.set_config('search_path', '', false)");
60 if (PQresultStatus(res) != PGRES_TUPLES_OK)
62 fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
68 * Should PQclear PGresult whenever it is no longer needed to avoid memory
74 * Our test case here involves using a cursor, for which we must be inside
75 * a transaction block. We could do the whole thing with a single
76 * PQexec() of "select * from pg_database", but that's too trivial to make
80 /* Start a transaction block */
81 res = PQexec(conn, "BEGIN");
82 if (PQresultStatus(res) != PGRES_COMMAND_OK)
84 fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
91 * Fetch rows from pg_database, the system catalog of databases
93 res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
94 if (PQresultStatus(res) != PGRES_COMMAND_OK)
96 fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
102 res = PQexec(conn, "FETCH ALL in myportal");
103 if (PQresultStatus(res) != PGRES_TUPLES_OK)
105 fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
110 /* first, print out the attribute names */
111 nFields = PQnfields(res);
112 for (i = 0; i < nFields; i++)
113 printf("%-15s", PQfname(res, i));
116 /* next, print out the rows */
117 for (i = 0; i < PQntuples(res); i++)
119 for (j = 0; j < nFields; j++)
120 printf("%-15s", PQgetvalue(res, i, j));
126 /* close the portal ... we don't bother to check for errors ... */
127 res = PQexec(conn, "CLOSE myportal");
130 /* end the transaction */
131 res = PQexec(conn, "END");
134 /* close the connection to the database and cleanup */
140 </pre></div></div><br class="example-break" /><div class="example" id="LIBPQ-EXAMPLE-2"><p class="title"><strong>Example 32.2. <span class="application">libpq</span> Example Program 2</strong></p><div class="example-contents"><pre class="programlisting">
143 * src/test/examples/testlibpq2.c
147 * Test of the asynchronous notification interface
149 * Start this program, then from psql in another window do
151 * Repeat four times to get this program to exit.
153 * Or, if you want to get fancy, try this:
154 * populate a database with the following commands
155 * (provided in src/test/examples/testlibpq2.sql):
157 * CREATE SCHEMA TESTLIBPQ2;
158 * SET search_path = TESTLIBPQ2;
159 * CREATE TABLE TBL1 (i int4);
160 * CREATE TABLE TBL2 (i int4);
161 * CREATE RULE r1 AS ON INSERT TO TBL1 DO
162 * (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
164 * Start this program, then from psql do this four times:
166 * INSERT INTO TESTLIBPQ2.TBL1 VALUES (10);
170 #include <windows.h>
172 #include <stdio.h>
173 #include <stdlib.h>
174 #include <string.h>
175 #include <errno.h>
176 #include <sys/select.h>
177 #include <sys/time.h>
178 #include <sys/types.h>
180 #include "libpq-fe.h"
183 exit_nicely(PGconn *conn)
190 main(int argc, char **argv)
192 const char *conninfo;
199 * If the user supplies a parameter on the command line, use it as the
200 * conninfo string; otherwise default to setting dbname=postgres and using
201 * environment variables or defaults for all other connection parameters.
206 conninfo = "dbname = postgres";
208 /* Make a connection to the database */
209 conn = PQconnectdb(conninfo);
211 /* Check to see that the backend connection was successfully made */
212 if (PQstatus(conn) != CONNECTION_OK)
214 fprintf(stderr, "%s", PQerrorMessage(conn));
218 /* Set always-secure search path, so malicious users can't take control. */
220 "SELECT pg_catalog.set_config('search_path', '', false)");
221 if (PQresultStatus(res) != PGRES_TUPLES_OK)
223 fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
229 * Should PQclear PGresult whenever it is no longer needed to avoid memory
235 * Issue LISTEN command to enable notifications from the rule's NOTIFY.
237 res = PQexec(conn, "LISTEN TBL2");
238 if (PQresultStatus(res) != PGRES_COMMAND_OK)
240 fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
246 /* Quit after four notifies are received. */
248 while (nnotifies < 4)
251 * Sleep until something happens on the connection. We use select(2)
252 * to wait for input, but you could also use poll() or similar
258 sock = PQsocket(conn);
261 break; /* shouldn't happen */
263 FD_ZERO(&input_mask);
264 FD_SET(sock, &input_mask);
266 if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
268 fprintf(stderr, "select() failed: %s\n", strerror(errno));
272 /* Now check for input */
273 PQconsumeInput(conn);
274 while ((notify = PQnotifies(conn)) != NULL)
277 "ASYNC NOTIFY of '%s' received from backend PID %d\n",
278 notify->relname, notify->be_pid);
281 PQconsumeInput(conn);
285 fprintf(stderr, "Done.\n");
287 /* close the connection to the database and cleanup */
293 </pre></div></div><br class="example-break" /><div class="example" id="LIBPQ-EXAMPLE-3"><p class="title"><strong>Example 32.3. <span class="application">libpq</span> Example Program 3</strong></p><div class="example-contents"><pre class="programlisting">
296 * src/test/examples/testlibpq3.c
300 * Test out-of-line parameters and binary I/O.
302 * Before running this, populate a database with the following commands
303 * (provided in src/test/examples/testlibpq3.sql):
305 * CREATE SCHEMA testlibpq3;
306 * SET search_path = testlibpq3;
307 * SET standard_conforming_strings = ON;
308 * CREATE TABLE test1 (i int4, t text, b bytea);
309 * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004');
310 * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000');
312 * The expected output is:
316 * t = (11 bytes) 'joe's place'
317 * b = (5 bytes) \000\001\002\003\004
321 * t = (8 bytes) 'ho there'
322 * b = (5 bytes) \004\003\002\001\000
326 #include <windows.h>
329 #include <stdio.h>
330 #include <stdlib.h>
331 #include <stdint.h>
332 #include <string.h>
333 #include <sys/types.h>
334 #include "libpq-fe.h"
336 /* for ntohl/htonl */
337 #include <netinet/in.h>
338 #include <arpa/inet.h>
342 exit_nicely(PGconn *conn)
349 * This function prints a query result that is a binary-format fetch from
350 * a table defined as in the comment above. We split it out because the
351 * main() function uses it twice.
354 show_binary_results(PGresult *res)
362 /* Use PQfnumber to avoid assumptions about field order in result */
363 i_fnum = PQfnumber(res, "i");
364 t_fnum = PQfnumber(res, "t");
365 b_fnum = PQfnumber(res, "b");
367 for (i = 0; i < PQntuples(res); i++)
375 /* Get the field values (we ignore possibility they are null!) */
376 iptr = PQgetvalue(res, i, i_fnum);
377 tptr = PQgetvalue(res, i, t_fnum);
378 bptr = PQgetvalue(res, i, b_fnum);
381 * The binary representation of INT4 is in network byte order, which
382 * we'd better coerce to the local byte order.
384 ival = ntohl(*((uint32_t *) iptr));
387 * The binary representation of TEXT is, well, text, and since libpq
388 * was nice enough to append a zero byte to it, it'll work just fine
391 * The binary representation of BYTEA is a bunch of bytes, which could
392 * include embedded nulls so we have to pay attention to field length.
394 blen = PQgetlength(res, i, b_fnum);
396 printf("tuple %d: got\n", i);
397 printf(" i = (%d bytes) %d\n",
398 PQgetlength(res, i, i_fnum), ival);
399 printf(" t = (%d bytes) '%s'\n",
400 PQgetlength(res, i, t_fnum), tptr);
401 printf(" b = (%d bytes) ", blen);
402 for (j = 0; j < blen; j++)
403 printf("\\%03o", bptr[j]);
409 main(int argc, char **argv)
411 const char *conninfo;
414 const char *paramValues[1];
417 uint32_t binaryIntVal;
420 * If the user supplies a parameter on the command line, use it as the
421 * conninfo string; otherwise default to setting dbname=postgres and using
422 * environment variables or defaults for all other connection parameters.
427 conninfo = "dbname = postgres";
429 /* Make a connection to the database */
430 conn = PQconnectdb(conninfo);
432 /* Check to see that the backend connection was successfully made */
433 if (PQstatus(conn) != CONNECTION_OK)
435 fprintf(stderr, "%s", PQerrorMessage(conn));
439 /* Set always-secure search path, so malicious users can't take control. */
440 res = PQexec(conn, "SET search_path = testlibpq3");
441 if (PQresultStatus(res) != PGRES_COMMAND_OK)
443 fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
450 * The point of this program is to illustrate use of PQexecParams() with
451 * out-of-line parameters, as well as binary transmission of data.
453 * This first example transmits the parameters as text, but receives the
454 * results in binary format. By using out-of-line parameters we can avoid
455 * a lot of tedious mucking about with quoting and escaping, even though
456 * the data is text. Notice how we don't have to do anything special with
457 * the quote mark in the parameter value.
460 /* Here is our out-of-line parameter value */
461 paramValues[0] = "joe's place";
463 res = PQexecParams(conn,
464 "SELECT * FROM test1 WHERE t = $1",
466 NULL, /* let the backend deduce param type */
468 NULL, /* don't need param lengths since text */
469 NULL, /* default to all text params */
470 1); /* ask for binary results */
472 if (PQresultStatus(res) != PGRES_TUPLES_OK)
474 fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
479 show_binary_results(res);
484 * In this second example we transmit an integer parameter in binary form,
485 * and again retrieve the results in binary form.
487 * Although we tell PQexecParams we are letting the backend deduce
488 * parameter type, we really force the decision by casting the parameter
489 * symbol in the query text. This is a good safety measure when sending
493 /* Convert integer value "2" to network byte order */
494 binaryIntVal = htonl((uint32_t) 2);
496 /* Set up parameter arrays for PQexecParams */
497 paramValues[0] = (char *) &binaryIntVal;
498 paramLengths[0] = sizeof(binaryIntVal);
499 paramFormats[0] = 1; /* binary */
501 res = PQexecParams(conn,
502 "SELECT * FROM test1 WHERE i = $1::int4",
504 NULL, /* let the backend deduce param type */
508 1); /* ask for binary results */
510 if (PQresultStatus(res) != PGRES_TUPLES_OK)
512 fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
517 show_binary_results(res);
521 /* close the connection to the database and cleanup */
527 </pre></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-build.html" title="32.22. Building libpq Programs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 32. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="largeobjects.html" title="Chapter 33. Large Objects">Next</a></td></tr><tr><td width="40%" align="left" valign="top">32.22. Building <span class="application">libpq</span> Programs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 33. Large Objects</td></tr></table></div></body></html>