gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

531 lines
17KB

  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>33.21. 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 V1.79.1" /><link rel="prev" href="libpq-build.html" title="33.20. Building libpq Programs" /><link rel="next" href="largeobjects.html" title="Chapter 34. Large Objects" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">33.21. Example Programs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-build.html" title="33.20. Building libpq Programs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 33. libpq - C Library">Up</a></td><th width="60%" align="center">Chapter 33. <span xmlns="http://www.w3.org/1999/xhtml" class="application">libpq</span> - C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="largeobjects.html" title="Chapter 34. Large Objects">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="LIBPQ-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">33.21. Example Programs</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
  5. distribution.
  6. </p><div class="example" id="LIBPQ-EXAMPLE-1"><p class="title"><strong>Example 33.1. <span class="application">libpq</span> Example Program 1</strong></p><div class="example-contents"><pre class="programlisting">
  7. /*
  8. * src/test/examples/testlibpq.c
  9. *
  10. *
  11. * testlibpq.c
  12. *
  13. * Test the C version of libpq, the PostgreSQL frontend library.
  14. */
  15. #include &lt;stdio.h&gt;
  16. #include &lt;stdlib.h&gt;
  17. #include "libpq-fe.h"
  18. static void
  19. exit_nicely(PGconn *conn)
  20. {
  21. PQfinish(conn);
  22. exit(1);
  23. }
  24. int
  25. main(int argc, char **argv)
  26. {
  27. const char *conninfo;
  28. PGconn *conn;
  29. PGresult *res;
  30. int nFields;
  31. int i,
  32. j;
  33. /*
  34. * If the user supplies a parameter on the command line, use it as the
  35. * conninfo string; otherwise default to setting dbname=postgres and using
  36. * environment variables or defaults for all other connection parameters.
  37. */
  38. if (argc &gt; 1)
  39. conninfo = argv[1];
  40. else
  41. conninfo = "dbname = postgres";
  42. /* Make a connection to the database */
  43. conn = PQconnectdb(conninfo);
  44. /* Check to see that the backend connection was successfully made */
  45. if (PQstatus(conn) != CONNECTION_OK)
  46. {
  47. fprintf(stderr, "Connection to database failed: %s",
  48. PQerrorMessage(conn));
  49. exit_nicely(conn);
  50. }
  51. /* Set always-secure search path, so malicious users can't take control. */
  52. res = PQexec(conn,
  53. "SELECT pg_catalog.set_config('search_path', '', false)");
  54. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  55. {
  56. fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
  57. PQclear(res);
  58. exit_nicely(conn);
  59. }
  60. /*
  61. * Should PQclear PGresult whenever it is no longer needed to avoid memory
  62. * leaks
  63. */
  64. PQclear(res);
  65. /*
  66. * Our test case here involves using a cursor, for which we must be inside
  67. * a transaction block. We could do the whole thing with a single
  68. * PQexec() of "select * from pg_database", but that's too trivial to make
  69. * a good example.
  70. */
  71. /* Start a transaction block */
  72. res = PQexec(conn, "BEGIN");
  73. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  74. {
  75. fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
  76. PQclear(res);
  77. exit_nicely(conn);
  78. }
  79. PQclear(res);
  80. /*
  81. * Fetch rows from pg_database, the system catalog of databases
  82. */
  83. res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
  84. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  85. {
  86. fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
  87. PQclear(res);
  88. exit_nicely(conn);
  89. }
  90. PQclear(res);
  91. res = PQexec(conn, "FETCH ALL in myportal");
  92. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  93. {
  94. fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
  95. PQclear(res);
  96. exit_nicely(conn);
  97. }
  98. /* first, print out the attribute names */
  99. nFields = PQnfields(res);
  100. for (i = 0; i &lt; nFields; i++)
  101. printf("%-15s", PQfname(res, i));
  102. printf("\n\n");
  103. /* next, print out the rows */
  104. for (i = 0; i &lt; PQntuples(res); i++)
  105. {
  106. for (j = 0; j &lt; nFields; j++)
  107. printf("%-15s", PQgetvalue(res, i, j));
  108. printf("\n");
  109. }
  110. PQclear(res);
  111. /* close the portal ... we don't bother to check for errors ... */
  112. res = PQexec(conn, "CLOSE myportal");
  113. PQclear(res);
  114. /* end the transaction */
  115. res = PQexec(conn, "END");
  116. PQclear(res);
  117. /* close the connection to the database and cleanup */
  118. PQfinish(conn);
  119. return 0;
  120. }
  121. </pre></div></div><br class="example-break" /><div class="example" id="LIBPQ-EXAMPLE-2"><p class="title"><strong>Example 33.2. <span class="application">libpq</span> Example Program 2</strong></p><div class="example-contents"><pre class="programlisting">
  122. /*
  123. * src/test/examples/testlibpq2.c
  124. *
  125. *
  126. * testlibpq2.c
  127. * Test of the asynchronous notification interface
  128. *
  129. * Start this program, then from psql in another window do
  130. * NOTIFY TBL2;
  131. * Repeat four times to get this program to exit.
  132. *
  133. * Or, if you want to get fancy, try this:
  134. * populate a database with the following commands
  135. * (provided in src/test/examples/testlibpq2.sql):
  136. *
  137. * CREATE SCHEMA TESTLIBPQ2;
  138. * SET search_path = TESTLIBPQ2;
  139. * CREATE TABLE TBL1 (i int4);
  140. * CREATE TABLE TBL2 (i int4);
  141. * CREATE RULE r1 AS ON INSERT TO TBL1 DO
  142. * (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
  143. *
  144. * Start this program, then from psql do this four times:
  145. *
  146. * INSERT INTO TESTLIBPQ2.TBL1 VALUES (10);
  147. */
  148. #ifdef WIN32
  149. #include &lt;windows.h&gt;
  150. #endif
  151. #include &lt;stdio.h&gt;
  152. #include &lt;stdlib.h&gt;
  153. #include &lt;string.h&gt;
  154. #include &lt;errno.h&gt;
  155. #include &lt;sys/time.h&gt;
  156. #include &lt;sys/types.h&gt;
  157. #ifdef HAVE_SYS_SELECT_H
  158. #include &lt;sys/select.h&gt;
  159. #endif
  160. #include "libpq-fe.h"
  161. static void
  162. exit_nicely(PGconn *conn)
  163. {
  164. PQfinish(conn);
  165. exit(1);
  166. }
  167. int
  168. main(int argc, char **argv)
  169. {
  170. const char *conninfo;
  171. PGconn *conn;
  172. PGresult *res;
  173. PGnotify *notify;
  174. int nnotifies;
  175. /*
  176. * If the user supplies a parameter on the command line, use it as the
  177. * conninfo string; otherwise default to setting dbname=postgres and using
  178. * environment variables or defaults for all other connection parameters.
  179. */
  180. if (argc &gt; 1)
  181. conninfo = argv[1];
  182. else
  183. conninfo = "dbname = postgres";
  184. /* Make a connection to the database */
  185. conn = PQconnectdb(conninfo);
  186. /* Check to see that the backend connection was successfully made */
  187. if (PQstatus(conn) != CONNECTION_OK)
  188. {
  189. fprintf(stderr, "Connection to database failed: %s",
  190. PQerrorMessage(conn));
  191. exit_nicely(conn);
  192. }
  193. /* Set always-secure search path, so malicious users can't take control. */
  194. res = PQexec(conn,
  195. "SELECT pg_catalog.set_config('search_path', '', false)");
  196. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  197. {
  198. fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
  199. PQclear(res);
  200. exit_nicely(conn);
  201. }
  202. /*
  203. * Should PQclear PGresult whenever it is no longer needed to avoid memory
  204. * leaks
  205. */
  206. PQclear(res);
  207. /*
  208. * Issue LISTEN command to enable notifications from the rule's NOTIFY.
  209. */
  210. res = PQexec(conn, "LISTEN TBL2");
  211. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  212. {
  213. fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
  214. PQclear(res);
  215. exit_nicely(conn);
  216. }
  217. PQclear(res);
  218. /* Quit after four notifies are received. */
  219. nnotifies = 0;
  220. while (nnotifies &lt; 4)
  221. {
  222. /*
  223. * Sleep until something happens on the connection. We use select(2)
  224. * to wait for input, but you could also use poll() or similar
  225. * facilities.
  226. */
  227. int sock;
  228. fd_set input_mask;
  229. sock = PQsocket(conn);
  230. if (sock &lt; 0)
  231. break; /* shouldn't happen */
  232. FD_ZERO(&amp;input_mask);
  233. FD_SET(sock, &amp;input_mask);
  234. if (select(sock + 1, &amp;input_mask, NULL, NULL, NULL) &lt; 0)
  235. {
  236. fprintf(stderr, "select() failed: %s\n", strerror(errno));
  237. exit_nicely(conn);
  238. }
  239. /* Now check for input */
  240. PQconsumeInput(conn);
  241. while ((notify = PQnotifies(conn)) != NULL)
  242. {
  243. fprintf(stderr,
  244. "ASYNC NOTIFY of '%s' received from backend PID %d\n",
  245. notify-&gt;relname, notify-&gt;be_pid);
  246. PQfreemem(notify);
  247. nnotifies++;
  248. PQconsumeInput(conn);
  249. }
  250. }
  251. fprintf(stderr, "Done.\n");
  252. /* close the connection to the database and cleanup */
  253. PQfinish(conn);
  254. return 0;
  255. }
  256. </pre></div></div><br class="example-break" /><div class="example" id="LIBPQ-EXAMPLE-3"><p class="title"><strong>Example 33.3. <span class="application">libpq</span> Example Program 3</strong></p><div class="example-contents"><pre class="programlisting">
  257. /*
  258. * src/test/examples/testlibpq3.c
  259. *
  260. *
  261. * testlibpq3.c
  262. * Test out-of-line parameters and binary I/O.
  263. *
  264. * Before running this, populate a database with the following commands
  265. * (provided in src/test/examples/testlibpq3.sql):
  266. *
  267. * CREATE SCHEMA testlibpq3;
  268. * SET search_path = testlibpq3;
  269. * CREATE TABLE test1 (i int4, t text, b bytea);
  270. * INSERT INTO test1 values (1, 'joe''s place', '\\000\\001\\002\\003\\004');
  271. * INSERT INTO test1 values (2, 'ho there', '\\004\\003\\002\\001\\000');
  272. *
  273. * The expected output is:
  274. *
  275. * tuple 0: got
  276. * i = (4 bytes) 1
  277. * t = (11 bytes) 'joe's place'
  278. * b = (5 bytes) \000\001\002\003\004
  279. *
  280. * tuple 0: got
  281. * i = (4 bytes) 2
  282. * t = (8 bytes) 'ho there'
  283. * b = (5 bytes) \004\003\002\001\000
  284. */
  285. #ifdef WIN32
  286. #include &lt;windows.h&gt;
  287. #endif
  288. #include &lt;stdio.h&gt;
  289. #include &lt;stdlib.h&gt;
  290. #include &lt;stdint.h&gt;
  291. #include &lt;string.h&gt;
  292. #include &lt;sys/types.h&gt;
  293. #include "libpq-fe.h"
  294. /* for ntohl/htonl */
  295. #include &lt;netinet/in.h&gt;
  296. #include &lt;arpa/inet.h&gt;
  297. static void
  298. exit_nicely(PGconn *conn)
  299. {
  300. PQfinish(conn);
  301. exit(1);
  302. }
  303. /*
  304. * This function prints a query result that is a binary-format fetch from
  305. * a table defined as in the comment above. We split it out because the
  306. * main() function uses it twice.
  307. */
  308. static void
  309. show_binary_results(PGresult *res)
  310. {
  311. int i,
  312. j;
  313. int i_fnum,
  314. t_fnum,
  315. b_fnum;
  316. /* Use PQfnumber to avoid assumptions about field order in result */
  317. i_fnum = PQfnumber(res, "i");
  318. t_fnum = PQfnumber(res, "t");
  319. b_fnum = PQfnumber(res, "b");
  320. for (i = 0; i &lt; PQntuples(res); i++)
  321. {
  322. char *iptr;
  323. char *tptr;
  324. char *bptr;
  325. int blen;
  326. int ival;
  327. /* Get the field values (we ignore possibility they are null!) */
  328. iptr = PQgetvalue(res, i, i_fnum);
  329. tptr = PQgetvalue(res, i, t_fnum);
  330. bptr = PQgetvalue(res, i, b_fnum);
  331. /*
  332. * The binary representation of INT4 is in network byte order, which
  333. * we'd better coerce to the local byte order.
  334. */
  335. ival = ntohl(*((uint32_t *) iptr));
  336. /*
  337. * The binary representation of TEXT is, well, text, and since libpq
  338. * was nice enough to append a zero byte to it, it'll work just fine
  339. * as a C string.
  340. *
  341. * The binary representation of BYTEA is a bunch of bytes, which could
  342. * include embedded nulls so we have to pay attention to field length.
  343. */
  344. blen = PQgetlength(res, i, b_fnum);
  345. printf("tuple %d: got\n", i);
  346. printf(" i = (%d bytes) %d\n",
  347. PQgetlength(res, i, i_fnum), ival);
  348. printf(" t = (%d bytes) '%s'\n",
  349. PQgetlength(res, i, t_fnum), tptr);
  350. printf(" b = (%d bytes) ", blen);
  351. for (j = 0; j &lt; blen; j++)
  352. printf("\\%03o", bptr[j]);
  353. printf("\n\n");
  354. }
  355. }
  356. int
  357. main(int argc, char **argv)
  358. {
  359. const char *conninfo;
  360. PGconn *conn;
  361. PGresult *res;
  362. const char *paramValues[1];
  363. int paramLengths[1];
  364. int paramFormats[1];
  365. uint32_t binaryIntVal;
  366. /*
  367. * If the user supplies a parameter on the command line, use it as the
  368. * conninfo string; otherwise default to setting dbname=postgres and using
  369. * environment variables or defaults for all other connection parameters.
  370. */
  371. if (argc &gt; 1)
  372. conninfo = argv[1];
  373. else
  374. conninfo = "dbname = postgres";
  375. /* Make a connection to the database */
  376. conn = PQconnectdb(conninfo);
  377. /* Check to see that the backend connection was successfully made */
  378. if (PQstatus(conn) != CONNECTION_OK)
  379. {
  380. fprintf(stderr, "Connection to database failed: %s",
  381. PQerrorMessage(conn));
  382. exit_nicely(conn);
  383. }
  384. /* Set always-secure search path, so malicious users can't take control. */
  385. res = PQexec(conn, "SET search_path = testlibpq3");
  386. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  387. {
  388. fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
  389. PQclear(res);
  390. exit_nicely(conn);
  391. }
  392. PQclear(res);
  393. /*
  394. * The point of this program is to illustrate use of PQexecParams() with
  395. * out-of-line parameters, as well as binary transmission of data.
  396. *
  397. * This first example transmits the parameters as text, but receives the
  398. * results in binary format. By using out-of-line parameters we can avoid
  399. * a lot of tedious mucking about with quoting and escaping, even though
  400. * the data is text. Notice how we don't have to do anything special with
  401. * the quote mark in the parameter value.
  402. */
  403. /* Here is our out-of-line parameter value */
  404. paramValues[0] = "joe's place";
  405. res = PQexecParams(conn,
  406. "SELECT * FROM test1 WHERE t = $1",
  407. 1, /* one param */
  408. NULL, /* let the backend deduce param type */
  409. paramValues,
  410. NULL, /* don't need param lengths since text */
  411. NULL, /* default to all text params */
  412. 1); /* ask for binary results */
  413. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  414. {
  415. fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
  416. PQclear(res);
  417. exit_nicely(conn);
  418. }
  419. show_binary_results(res);
  420. PQclear(res);
  421. /*
  422. * In this second example we transmit an integer parameter in binary form,
  423. * and again retrieve the results in binary form.
  424. *
  425. * Although we tell PQexecParams we are letting the backend deduce
  426. * parameter type, we really force the decision by casting the parameter
  427. * symbol in the query text. This is a good safety measure when sending
  428. * binary parameters.
  429. */
  430. /* Convert integer value "2" to network byte order */
  431. binaryIntVal = htonl((uint32_t) 2);
  432. /* Set up parameter arrays for PQexecParams */
  433. paramValues[0] = (char *) &amp;binaryIntVal;
  434. paramLengths[0] = sizeof(binaryIntVal);
  435. paramFormats[0] = 1; /* binary */
  436. res = PQexecParams(conn,
  437. "SELECT * FROM test1 WHERE i = $1::int4",
  438. 1, /* one param */
  439. NULL, /* let the backend deduce param type */
  440. paramValues,
  441. paramLengths,
  442. paramFormats,
  443. 1); /* ask for binary results */
  444. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  445. {
  446. fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
  447. PQclear(res);
  448. exit_nicely(conn);
  449. }
  450. show_binary_results(res);
  451. PQclear(res);
  452. /* close the connection to the database and cleanup */
  453. PQfinish(conn);
  454. return 0;
  455. }
  456. </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">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="largeobjects.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">33.20. Building <span class="application">libpq</span> Programs </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 34. Large Objects</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1