PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
connectdb.c File Reference
#include "postgres_fe.h"
#include "common/connect.h"
#include "common/logging.h"
#include "common/string.h"
#include "connectdb.h"
#include "dumputils.h"
#include "fe_utils/string_utils.h"
Include dependency graph for connectdb.c:

Go to the source code of this file.

Functions

static char * constructConnStr (const char **keywords, const char **values)
 
PGconnConnectDatabase (const char *dbname, const char *connection_string, const char *pghost, const char *pgport, const char *pguser, trivalue prompt_password, bool fail_on_error, const char *progname, const char **connstr, int *server_version, char *password, char *override_dbname)
 
PGresultexecuteQuery (PGconn *conn, const char *query)
 

Function Documentation

◆ ConnectDatabase()

PGconn * ConnectDatabase ( const char *  dbname,
const char *  connection_string,
const char *  pghost,
const char *  pgport,
const char *  pguser,
trivalue  prompt_password,
bool  fail_on_error,
const char *  progname,
const char **  connstr,
int *  server_version,
char *  password,
char *  override_dbname 
)

Definition at line 40 of file connectdb.c.

45{
46 PGconn *conn;
47 bool new_pass;
48 const char *remoteversion_str;
49 int my_version;
50 const char **keywords = NULL;
51 const char **values = NULL;
52 PQconninfoOption *conn_opts = NULL;
53 int server_version_temp;
54
55 if (prompt_password == TRI_YES && !password)
56 password = simple_prompt("Password: ", false);
57
58 /*
59 * Start the connection. Loop until we have a password if requested by
60 * backend.
61 */
62 do
63 {
64 int argcount = 8;
65 PQconninfoOption *conn_opt;
66 char *err_msg = NULL;
67 int i = 0;
68
70 free(values);
71 PQconninfoFree(conn_opts);
72
73 /*
74 * Merge the connection info inputs given in form of connection string
75 * and other options. Explicitly discard any dbname value in the
76 * connection string; otherwise, PQconnectdbParams() would interpret
77 * that value as being itself a connection string.
78 */
80 {
81 conn_opts = PQconninfoParse(connection_string, &err_msg);
82 if (conn_opts == NULL)
83 pg_fatal("%s", err_msg);
84
85 for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
86 {
87 if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
88 strcmp(conn_opt->keyword, "dbname") != 0)
89 argcount++;
90 }
91
92 keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
93 values = pg_malloc0((argcount + 1) * sizeof(*values));
94
95 for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
96 {
97 if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
98 strcmp(conn_opt->keyword, "dbname") != 0)
99 {
100 keywords[i] = conn_opt->keyword;
101 values[i] = conn_opt->val;
102 i++;
103 }
104 }
105 }
106 else
107 {
108 keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
109 values = pg_malloc0((argcount + 1) * sizeof(*values));
110 }
111
112 if (pghost)
113 {
114 keywords[i] = "host";
115 values[i] = pghost;
116 i++;
117 }
118 if (pgport)
119 {
120 keywords[i] = "port";
121 values[i] = pgport;
122 i++;
123 }
124 if (pguser)
125 {
126 keywords[i] = "user";
127 values[i] = pguser;
128 i++;
129 }
130 if (password)
131 {
132 keywords[i] = "password";
133 values[i] = password;
134 i++;
135 }
136 if (dbname)
137 {
138 keywords[i] = "dbname";
139 values[i] = dbname;
140 i++;
141 }
142 if (override_dbname)
143 {
144 keywords[i] = "dbname";
145 values[i++] = override_dbname;
146 }
147
148 keywords[i] = "fallback_application_name";
149 values[i] = progname;
150 i++;
151
152 new_pass = false;
154
155 if (!conn)
156 pg_fatal("could not connect to database \"%s\"", dbname);
157
158 if (PQstatus(conn) == CONNECTION_BAD &&
160 !password &&
161 prompt_password != TRI_NO)
162 {
163 PQfinish(conn);
164 password = simple_prompt("Password: ", false);
165 new_pass = true;
166 }
167 } while (new_pass);
168
169 /* check to see that the backend connection was successfully made */
171 {
172 if (fail_on_error)
174 else
175 {
176 PQfinish(conn);
177
178 free(keywords);
179 free(values);
180 PQconninfoFree(conn_opts);
181
182 return NULL;
183 }
184 }
185
186 /*
187 * Ok, connected successfully. If requested, remember the options used, in
188 * the form of a connection string.
189 */
190 if (connstr)
192
193 free(keywords);
194 free(values);
195 PQconninfoFree(conn_opts);
196
197 /* Check version */
198 remoteversion_str = PQparameterStatus(conn, "server_version");
199 if (!remoteversion_str)
200 pg_fatal("could not get server version");
201
202 server_version_temp = PQserverVersion(conn);
203 if (server_version_temp == 0)
204 pg_fatal("could not parse server version \"%s\"",
205 remoteversion_str);
206
207 /* If requested, then copy server version to out variable. */
208 if (server_version)
209 *server_version = server_version_temp;
210
211 my_version = PG_VERSION_NUM;
212
213 /*
214 * We allow the server to be back to 9.2, and up to any minor release of
215 * our own major version. (See also version check in pg_dump.c.)
216 */
217 if (my_version != server_version_temp
218 && (server_version_temp < 90200 ||
219 (server_version_temp / 100) > (my_version / 100)))
220 {
221 pg_log_error("aborting because of server version mismatch");
222 pg_log_error_detail("server version: %s; %s version: %s",
223 remoteversion_str, progname, PG_VERSION);
224 exit_nicely(1);
225 }
226
228
229 return conn;
230}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
static char * constructConnStr(const char **keywords, const char **values)
Definition: connectdb.c:244
PGresult * executeQuery(PGconn *conn, const char *query)
Definition: connectdb.c:277
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:7609
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:7434
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
Definition: fe-connect.c:6150
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:7574
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:7672
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:7556
void PQfinish(PGconn *conn)
Definition: fe-connect.c:5290
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:7619
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:758
void PQclear(PGresult *res)
Definition: fe-exec.c:721
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define free(a)
Definition: header.h:65
int i
Definition: isn.c:77
static const JsonPathKeyword keywords[]
@ CONNECTION_BAD
Definition: libpq-fe.h:85
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_detail(...)
Definition: logging.h:109
const char * progname
Definition: main.c:44
void exit_nicely(int code)
#define pg_fatal(...)
static const char * connstr
Definition: pg_dumpall.c:84
static int server_version
Definition: pg_dumpall.c:113
static const char * pghost
Definition: pgbench.c:295
static const char * pgport
Definition: pgbench.c:296
char * simple_prompt(const char *prompt, bool echo)
Definition: sprompt.c:38
static char * password
Definition: streamutil.c:51
char * connection_string
Definition: streamutil.c:45
char * dbname
Definition: streamutil.c:49
PGconn * conn
Definition: streamutil.c:52
@ TRI_YES
Definition: vacuumlo.c:38
@ TRI_NO
Definition: vacuumlo.c:37

References ALWAYS_SECURE_SEARCH_PATH_SQL, conn, CONNECTION_BAD, connection_string, connstr, constructConnStr(), dbname, executeQuery(), exit_nicely(), free, i, _PQconninfoOption::keyword, keywords, password, pg_fatal, pg_log_error, pg_log_error_detail, pg_malloc0(), pghost, pgport, PQclear(), PQconnectdbParams(), PQconnectionNeedsPassword(), PQconninfoFree(), PQconninfoParse(), PQerrorMessage(), PQfinish(), PQparameterStatus(), PQserverVersion(), PQstatus(), progname, server_version, simple_prompt(), TRI_NO, TRI_YES, _PQconninfoOption::val, and values.

Referenced by ConnectDatabaseAhx(), main(), and restore_all_databases().

◆ constructConnStr()

static char * constructConnStr ( const char **  keywords,
const char **  values 
)
static

Definition at line 244 of file connectdb.c.

245{
247 char *connstr;
248 int i;
249 bool firstkeyword = true;
250
251 /* Construct a new connection string in key='value' format. */
252 for (i = 0; keywords[i] != NULL; i++)
253 {
254 if (strcmp(keywords[i], "dbname") == 0 ||
255 strcmp(keywords[i], "password") == 0 ||
256 strcmp(keywords[i], "fallback_application_name") == 0)
257 continue;
258
259 if (!firstkeyword)
261 firstkeyword = false;
264 }
265
266 connstr = pg_strdup(buf->data);
268 return connstr;
269}
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static char * buf
Definition: pg_test_fsync.c:72
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:698

References appendConnStrVal(), appendPQExpBuffer(), appendPQExpBufferChar(), buf, connstr, createPQExpBuffer(), destroyPQExpBuffer(), i, keywords, pg_strdup(), and values.

Referenced by ConnectDatabase().

◆ executeQuery()

PGresult * executeQuery ( PGconn conn,
const char *  query 
)