PostgreSQL Source Code  git master
testlibpq.c
Go to the documentation of this file.
1 /*
2  * src/test/examples/testlibpq.c
3  *
4  *
5  * testlibpq.c
6  *
7  * Test the C version of libpq, the PostgreSQL frontend library.
8  */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include "libpq-fe.h"
12 
13 static void
15 {
16  PQfinish(conn);
17  exit(1);
18 }
19 
20 int
21 main(int argc, char **argv)
22 {
23  const char *conninfo;
24  PGconn *conn;
25  PGresult *res;
26  int nFields;
27  int i,
28  j;
29 
30  /*
31  * If the user supplies a parameter on the command line, use it as the
32  * conninfo string; otherwise default to setting dbname=postgres and using
33  * environment variables or defaults for all other connection parameters.
34  */
35  if (argc > 1)
36  conninfo = argv[1];
37  else
38  conninfo = "dbname = postgres";
39 
40  /* Make a connection to the database */
41  conn = PQconnectdb(conninfo);
42 
43  /* Check to see that the backend connection was successfully made */
44  if (PQstatus(conn) != CONNECTION_OK)
45  {
46  fprintf(stderr, "%s", PQerrorMessage(conn));
47  exit_nicely(conn);
48  }
49 
50  /* Set always-secure search path, so malicious users can't take control. */
51  res = PQexec(conn,
52  "SELECT pg_catalog.set_config('search_path', '', false)");
53  if (PQresultStatus(res) != PGRES_TUPLES_OK)
54  {
55  fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
56  PQclear(res);
57  exit_nicely(conn);
58  }
59 
60  /*
61  * Should PQclear PGresult whenever it is no longer needed to avoid memory
62  * leaks
63  */
64  PQclear(res);
65 
66  /*
67  * Our test case here involves using a cursor, for which we must be inside
68  * a transaction block. We could do the whole thing with a single
69  * PQexec() of "select * from pg_database", but that's too trivial to make
70  * a good example.
71  */
72 
73  /* Start a transaction block */
74  res = PQexec(conn, "BEGIN");
75  if (PQresultStatus(res) != PGRES_COMMAND_OK)
76  {
77  fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
78  PQclear(res);
79  exit_nicely(conn);
80  }
81  PQclear(res);
82 
83  /*
84  * Fetch rows from pg_database, the system catalog of databases
85  */
86  res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
87  if (PQresultStatus(res) != PGRES_COMMAND_OK)
88  {
89  fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
90  PQclear(res);
91  exit_nicely(conn);
92  }
93  PQclear(res);
94 
95  res = PQexec(conn, "FETCH ALL in myportal");
96  if (PQresultStatus(res) != PGRES_TUPLES_OK)
97  {
98  fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
99  PQclear(res);
100  exit_nicely(conn);
101  }
102 
103  /* first, print out the attribute names */
104  nFields = PQnfields(res);
105  for (i = 0; i < nFields; i++)
106  printf("%-15s", PQfname(res, i));
107  printf("\n\n");
108 
109  /* next, print out the rows */
110  for (i = 0; i < PQntuples(res); i++)
111  {
112  for (j = 0; j < nFields; j++)
113  printf("%-15s", PQgetvalue(res, i, j));
114  printf("\n");
115  }
116 
117  PQclear(res);
118 
119  /* close the portal ... we don't bother to check for errors ... */
120  res = PQexec(conn, "CLOSE myportal");
121  PQclear(res);
122 
123  /* end the transaction */
124  res = PQexec(conn, "END");
125  PQclear(res);
126 
127  /* close the connection to the database and cleanup */
128  PQfinish(conn);
129 
130  return 0;
131 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3175
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6735
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3253
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
#define printf(...)
Definition: port.h:222
int main(int argc, char **argv)
Definition: testlibpq.c:21
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
#define fprintf
Definition: port.h:220
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3097
PGconn * conn
Definition: streamutil.c:54
static void exit_nicely(PGconn *conn)
Definition: testlibpq.c:14
void PQclear(PGresult *res)
Definition: fe-exec.c:680
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2142
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6682
PGconn * PQconnectdb(const char *conninfo)
Definition: fe-connect.c:718