Commit aa05c37e authored by Heikki Linnakangas's avatar Heikki Linnakangas

Add -d option to pg_basebackup and pg_receivexlog, for connection string.

Without this, there's no way to pass arbitrary libpq connection parameters
to these applications. It's a bit strange that the option is called
-d/--dbname, when in fact you can *not* pass a database name in it, but it's
consistent with other client applications where a connection string is also
passed using -d.

Original patch by Amit Kapila, heavily modified by me.
parent 786170d7
...@@ -358,6 +358,23 @@ PostgreSQL documentation ...@@ -358,6 +358,23 @@ PostgreSQL documentation
The following command-line options control the database connection parameters. The following command-line options control the database connection parameters.
<variablelist> <variablelist>
<varlistentry>
<term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
<term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
<listitem>
<para>
Specifies parameters used to connect to the server, as a connection
string. See <xref linkend="libpq-connstring"> for more information.
</para>
<para>
The option is called <literal>--dbname</> for consistency with other
client applications, but because <application>pg_basebackup</application>
doesn't connect to any particular database in the cluster, database
name in the connection string will be ignored.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>-h <replaceable class="parameter">host</replaceable></option></term> <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
<term><option>--host=<replaceable class="parameter">host</replaceable></option></term> <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
......
...@@ -122,6 +122,23 @@ PostgreSQL documentation ...@@ -122,6 +122,23 @@ PostgreSQL documentation
The following command-line options control the database connection parameters. The following command-line options control the database connection parameters.
<variablelist> <variablelist>
<varlistentry>
<term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
<term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
<listitem>
<para>
Specifies parameters used to connect to the server, as a connection
string. See <xref linkend="libpq-connstring"> for more information.
</para>
<para>
The option is called <literal>--dbname</> for consistency with other
client applications, but because <application>pg_basebackup</application>
doesn't connect to any particular database in the cluster, database
name in the connection string will be ignored.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>-h <replaceable class="parameter">host</replaceable></option></term> <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
<term><option>--host=<replaceable class="parameter">host</replaceable></option></term> <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
......
...@@ -126,6 +126,7 @@ usage(void) ...@@ -126,6 +126,7 @@ usage(void)
printf(_(" -V, --version output version information, then exit\n")); printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n")); printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n")); printf(_("\nConnection options:\n"));
printf(_(" -d, --dbname=CONNSTR connection string\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port number\n")); printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -s, --status-interval=INTERVAL\n" printf(_(" -s, --status-interval=INTERVAL\n"
...@@ -1540,6 +1541,7 @@ main(int argc, char **argv) ...@@ -1540,6 +1541,7 @@ main(int argc, char **argv)
{"gzip", no_argument, NULL, 'z'}, {"gzip", no_argument, NULL, 'z'},
{"compress", required_argument, NULL, 'Z'}, {"compress", required_argument, NULL, 'Z'},
{"label", required_argument, NULL, 'l'}, {"label", required_argument, NULL, 'l'},
{"dbname", required_argument, NULL, 'd'},
{"host", required_argument, NULL, 'h'}, {"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'}, {"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'}, {"username", required_argument, NULL, 'U'},
...@@ -1572,7 +1574,7 @@ main(int argc, char **argv) ...@@ -1572,7 +1574,7 @@ main(int argc, char **argv)
} }
} }
while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:c:h:p:U:s:wWvP", while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:d:c:h:p:U:s:wWvP",
long_options, &option_index)) != -1) long_options, &option_index)) != -1)
{ {
switch (c) switch (c)
...@@ -1663,6 +1665,9 @@ main(int argc, char **argv) ...@@ -1663,6 +1665,9 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
case 'd':
connection_string = pg_strdup(optarg);
break;
case 'h': case 'h':
dbhost = pg_strdup(optarg); dbhost = pg_strdup(optarg);
break; break;
......
...@@ -58,6 +58,7 @@ usage(void) ...@@ -58,6 +58,7 @@ usage(void)
printf(_(" -V, --version output version information, then exit\n")); printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n")); printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n")); printf(_("\nConnection options:\n"));
printf(_(" -d, --dbname=CONNSTR connection string\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port number\n")); printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -s, --status-interval=INTERVAL\n" printf(_(" -s, --status-interval=INTERVAL\n"
...@@ -306,6 +307,7 @@ main(int argc, char **argv) ...@@ -306,6 +307,7 @@ main(int argc, char **argv)
{"help", no_argument, NULL, '?'}, {"help", no_argument, NULL, '?'},
{"version", no_argument, NULL, 'V'}, {"version", no_argument, NULL, 'V'},
{"directory", required_argument, NULL, 'D'}, {"directory", required_argument, NULL, 'D'},
{"dbname", required_argument, NULL, 'd'},
{"host", required_argument, NULL, 'h'}, {"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'}, {"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'}, {"username", required_argument, NULL, 'U'},
...@@ -338,7 +340,7 @@ main(int argc, char **argv) ...@@ -338,7 +340,7 @@ main(int argc, char **argv)
} }
} }
while ((c = getopt_long(argc, argv, "D:h:p:U:s:nwWv", while ((c = getopt_long(argc, argv, "D:d:h:p:U:s:nwWv",
long_options, &option_index)) != -1) long_options, &option_index)) != -1)
{ {
switch (c) switch (c)
...@@ -346,6 +348,9 @@ main(int argc, char **argv) ...@@ -346,6 +348,9 @@ main(int argc, char **argv)
case 'D': case 'D':
basedir = pg_strdup(optarg); basedir = pg_strdup(optarg);
break; break;
case 'd':
connection_string = pg_strdup(optarg);
break;
case 'h': case 'h':
dbhost = pg_strdup(optarg); dbhost = pg_strdup(optarg);
break; break;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
const char *progname; const char *progname;
char *connection_string = NULL;
char *dbhost = NULL; char *dbhost = NULL;
char *dbuser = NULL; char *dbuser = NULL;
char *dbport = NULL; char *dbport = NULL;
...@@ -34,31 +35,67 @@ PGconn * ...@@ -34,31 +35,67 @@ PGconn *
GetConnection(void) GetConnection(void)
{ {
PGconn *tmpconn; PGconn *tmpconn;
int argcount = 4; /* dbname, replication, fallback_app_name, int argcount = 7; /* dbname, replication, fallback_app_name,
* password */ * host, user, port, password */
int i; int i;
const char **keywords; const char **keywords;
const char **values; const char **values;
char *password = NULL; char *password = NULL;
const char *tmpparam; const char *tmpparam;
PQconninfoOption *conn_opts = NULL;
PQconninfoOption *conn_opt;
char *err_msg = NULL;
if (dbhost) /*
argcount++; * Merge the connection info inputs given in form of connection string,
if (dbuser) * options and default values (dbname=replication, replication=true,
argcount++; * etc.)
if (dbport) */
i = 0;
if (connection_string)
{
conn_opts = PQconninfoParse(connection_string, &err_msg);
if (conn_opts == NULL)
{
fprintf(stderr, "%s: %s\n", progname, err_msg);
return NULL;
}
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
{
if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
argcount++; argcount++;
}
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords)); keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
values = pg_malloc0((argcount + 1) * sizeof(*values)); values = pg_malloc0((argcount + 1) * sizeof(*values));
keywords[0] = "dbname"; for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
values[0] = "replication"; {
keywords[1] = "replication"; if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
values[1] = "true"; {
keywords[2] = "fallback_application_name"; keywords[i] = conn_opt->keyword;
values[2] = progname; values[i] = conn_opt->val;
i = 3; i++;
}
}
}
else
{
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
values = pg_malloc0((argcount + 1) * sizeof(*values));
}
keywords[i] = "dbname";
values[i] = "replication";
i++;
keywords[i] = "replication";
values[i] = "true";
i++;
keywords[i] = "fallback_application_name";
values[i] = progname;
i++;
if (dbhost) if (dbhost)
{ {
keywords[i] = "host"; keywords[i] = "host";
...@@ -90,15 +127,15 @@ GetConnection(void) ...@@ -90,15 +127,15 @@ GetConnection(void)
* meaning this is the call for a second session to the same * meaning this is the call for a second session to the same
* database, so just forcibly reuse that password. * database, so just forcibly reuse that password.
*/ */
keywords[argcount - 1] = "password"; keywords[i] = "password";
values[argcount - 1] = dbpassword; values[i] = dbpassword;
dbgetpassword = -1; /* Don't try again if this fails */ dbgetpassword = -1; /* Don't try again if this fails */
} }
else if (dbgetpassword == 1) else if (dbgetpassword == 1)
{ {
password = simple_prompt(_("Password: "), 100, false); password = simple_prompt(_("Password: "), 100, false);
keywords[argcount - 1] = "password"; keywords[i] = "password";
values[argcount - 1] = password; values[i] = password;
} }
tmpconn = PQconnectdbParams(keywords, values, true); tmpconn = PQconnectdbParams(keywords, values, true);
...@@ -130,12 +167,16 @@ GetConnection(void) ...@@ -130,12 +167,16 @@ GetConnection(void)
PQfinish(tmpconn); PQfinish(tmpconn);
free(values); free(values);
free(keywords); free(keywords);
if (conn_opts)
PQconninfoFree(conn_opts);
return NULL; return NULL;
} }
/* Connection ok! */ /* Connection ok! */
free(values); free(values);
free(keywords); free(keywords);
if (conn_opts)
PQconninfoFree(conn_opts);
/* /*
* Ensure we have the same value of integer timestamps as the server * Ensure we have the same value of integer timestamps as the server
......
#include "libpq-fe.h" #include "libpq-fe.h"
extern const char *progname; extern const char *progname;
extern char *connection_string;
extern char *dbhost; extern char *dbhost;
extern char *dbuser; extern char *dbuser;
extern char *dbport; extern char *dbport;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment