PostgreSQL Source Code  git master
testlibpq4.c
Go to the documentation of this file.
1 /*
2  * src/test/examples/testlibpq4.c
3  *
4  *
5  * testlibpq4.c
6  * this test program shows to use LIBPQ to make multiple backend
7  * connections
8  *
9  */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "libpq-fe.h"
13 
14 static void
15 exit_nicely(PGconn *conn1, PGconn *conn2)
16 {
17  if (conn1)
18  PQfinish(conn1);
19  if (conn2)
20  PQfinish(conn2);
21  exit(1);
22 }
23 
24 static void
26 {
27  PGresult *res;
28 
29  /* check to see that the backend connection was successfully made */
30  if (PQstatus(conn) != CONNECTION_OK)
31  {
32  fprintf(stderr, "%s", PQerrorMessage(conn));
33  exit(1);
34  }
35 
36  /* Set always-secure search path, so malicious users can't take control. */
37  res = PQexec(conn,
38  "SELECT pg_catalog.set_config('search_path', '', false)");
39  if (PQresultStatus(res) != PGRES_TUPLES_OK)
40  {
41  fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
42  PQclear(res);
43  exit(1);
44  }
45  PQclear(res);
46 }
47 
48 int
49 main(int argc, char **argv)
50 {
51  char *pghost,
52  *pgport,
53  *pgoptions;
54  char *dbName1,
55  *dbName2;
56  char *tblName;
57  int nFields;
58  int i,
59  j;
60 
61  PGconn *conn1,
62  *conn2;
63 
64  /*
65  * PGresult *res1, *res2;
66  */
67  PGresult *res1;
68 
69  if (argc != 4)
70  {
71  fprintf(stderr, "usage: %s tableName dbName1 dbName2\n", argv[0]);
72  fprintf(stderr, " compares two tables in two databases\n");
73  exit(1);
74  }
75  tblName = argv[1];
76  dbName1 = argv[2];
77  dbName2 = argv[3];
78 
79 
80  /*
81  * begin, by setting the parameters for a backend connection if the
82  * parameters are null, then the system will try to use reasonable
83  * defaults by looking up environment variables or, failing that, using
84  * hardwired constants
85  */
86  pghost = NULL; /* host name of the backend */
87  pgport = NULL; /* port of the backend */
88  pgoptions = NULL; /* special options to start up the backend
89  * server */
90 
91  /* make a connection to the database */
92  conn1 = PQsetdb(pghost, pgport, pgoptions, NULL, dbName1);
93  check_prepare_conn(conn1, dbName1);
94 
95  conn2 = PQsetdb(pghost, pgport, pgoptions, NULL, dbName2);
96  check_prepare_conn(conn2, dbName2);
97 
98  /* start a transaction block */
99  res1 = PQexec(conn1, "BEGIN");
100  if (PQresultStatus(res1) != PGRES_COMMAND_OK)
101  {
102  fprintf(stderr, "BEGIN command failed\n");
103  PQclear(res1);
104  exit_nicely(conn1, conn2);
105  }
106 
107  /*
108  * make sure to PQclear() a PGresult whenever it is no longer needed to
109  * avoid memory leaks
110  */
111  PQclear(res1);
112 
113  /*
114  * fetch instances from the pg_database, the system catalog of databases
115  */
116  res1 = PQexec(conn1, "DECLARE myportal CURSOR FOR select * from pg_database");
117  if (PQresultStatus(res1) != PGRES_COMMAND_OK)
118  {
119  fprintf(stderr, "DECLARE CURSOR command failed\n");
120  PQclear(res1);
121  exit_nicely(conn1, conn2);
122  }
123  PQclear(res1);
124 
125  res1 = PQexec(conn1, "FETCH ALL in myportal");
126  if (PQresultStatus(res1) != PGRES_TUPLES_OK)
127  {
128  fprintf(stderr, "FETCH ALL command didn't return tuples properly\n");
129  PQclear(res1);
130  exit_nicely(conn1, conn2);
131  }
132 
133  /* first, print out the attribute names */
134  nFields = PQnfields(res1);
135  for (i = 0; i < nFields; i++)
136  printf("%-15s", PQfname(res1, i));
137  printf("\n\n");
138 
139  /* next, print out the instances */
140  for (i = 0; i < PQntuples(res1); i++)
141  {
142  for (j = 0; j < nFields; j++)
143  printf("%-15s", PQgetvalue(res1, i, j));
144  printf("\n");
145  }
146 
147  PQclear(res1);
148 
149  /* close the portal */
150  res1 = PQexec(conn1, "CLOSE myportal");
151  PQclear(res1);
152 
153  /* end the transaction */
154  res1 = PQexec(conn1, "END");
155  PQclear(res1);
156 
157  /* close the connections to the database and cleanup */
158  PQfinish(conn1);
159  PQfinish(conn2);
160 
161 /* fclose(debug); */
162  return 0;
163 }
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3256
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3642
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3334
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
const char * pghost
Definition: pgbench.c:280
#define printf(...)
Definition: port.h:223
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
#define fprintf
Definition: port.h:221
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
const char * dbName
Definition: pgbench.c:283
PGconn * conn
Definition: streamutil.c:54
static void exit_nicely(PGconn *conn1, PGconn *conn2)
Definition: testlibpq4.c:15
static void check_prepare_conn(PGconn *conn, const char *dbName)
Definition: testlibpq4.c:25
int main(int argc, char **argv)
Definition: testlibpq4.c:49
#define PQsetdb(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME)
Definition: libpq-fe.h:293
void PQclear(PGresult *res)
Definition: fe-exec.c:694
int i
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2193
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6691
const char * pgport
Definition: pgbench.c:281