PostgreSQL Source Code git master
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 i++;
147 }
148
149 keywords[i] = "fallback_application_name";
150 values[i] = progname;
151 i++;
152
153 new_pass = false;
155
156 if (!conn)
157 pg_fatal("could not connect to database \"%s\"", dbname);
158
159 if (PQstatus(conn) == CONNECTION_BAD &&
161 !password &&
162 prompt_password != TRI_NO)
163 {
164 PQfinish(conn);
165 password = simple_prompt("Password: ", false);
166 new_pass = true;
167 }
168 } while (new_pass);
169
170 /* check to see that the backend connection was successfully made */
172 {
173 if (fail_on_error)
175 else
176 {
177 PQfinish(conn);
178
179 free(keywords);
180 free(values);
181 PQconninfoFree(conn_opts);
182
183 return NULL;
184 }
185 }
186
187 /*
188 * Ok, connected successfully. If requested, remember the options used, in
189 * the form of a connection string.
190 */
191 if (connstr)
193
194 free(keywords);
195 free(values);
196 PQconninfoFree(conn_opts);
197
198 /* Check version */
199 remoteversion_str = PQparameterStatus(conn, "server_version");
200 if (!remoteversion_str)
201 pg_fatal("could not get server version");
202
203 server_version_temp = PQserverVersion(conn);
204 if (server_version_temp == 0)
205 pg_fatal("could not parse server version \"%s\"",
206 remoteversion_str);
207
208 /* If requested, then copy server version to out variable. */
209 if (server_version)
210 *server_version = server_version_temp;
211
212 my_version = PG_VERSION_NUM;
213
214 /*
215 * We allow the server to be back to 9.2, and up to any minor release of
216 * our own major version. (See also version check in pg_dump.c.)
217 */
218 if (my_version != server_version_temp
219 && (server_version_temp < 90200 ||
220 (server_version_temp / 100) > (my_version / 100)))
221 {
222 pg_log_error("aborting because of server version mismatch");
223 pg_log_error_detail("server version: %s; %s version: %s",
224 remoteversion_str, progname, PG_VERSION);
225 exit_nicely(1);
226 }
227
229
230 return conn;
231}
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:245
PGresult * executeQuery(PGconn *conn, const char *query)
Definition: connectdb.c:278
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 245 of file connectdb.c.

246{
248 char *connstr;
249 int i;
250 bool firstkeyword = true;
251
252 /* Construct a new connection string in key='value' format. */
253 for (i = 0; keywords[i] != NULL; i++)
254 {
255 if (strcmp(keywords[i], "dbname") == 0 ||
256 strcmp(keywords[i], "password") == 0 ||
257 strcmp(keywords[i], "fallback_application_name") == 0)
258 continue;
259
260 if (!firstkeyword)
262 firstkeyword = false;
265 }
266
267 connstr = pg_strdup(buf->data);
269 return connstr;
270}
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 
)