Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3dee636

Browse files
committed
Add -d option to pg_dumpall, for specifying a connection string.
Like with pg_basebackup and pg_receivexlog, it's a bit strange to call theoption -d/--dbname, when in fact you cannot pass a database name in it.Original patch by Amit Kapila, heavily modified by me.
1 parent691e595 commit3dee636

File tree

2 files changed

+184
-44
lines changed

2 files changed

+184
-44
lines changed

‎doc/src/sgml/ref/pg_dumpall.sgml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,25 @@ PostgreSQL documentation
405405
The following command-line options control the database connection parameters.
406406

407407
<variablelist>
408+
<varlistentry>
409+
<term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
410+
<term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
411+
<listitem>
412+
<para>
413+
Specifies parameters used to connect to the server, as a connection
414+
string. See <xref linkend="libpq-connstring"> for more information.
415+
</para>
416+
<para>
417+
The option is called <literal>--dbname</> for consistency with other
418+
client applications, but because <application>pg_dumpall</application>
419+
needs to connect to many databases, database name in the connection
420+
string will be ignored. Use <literal>-l</literal> option to specify
421+
the name of the database used to dump global objects and to discover
422+
what other databases should be dumped.
423+
</para>
424+
</listitem>
425+
</varlistentry>
426+
408427
<varlistentry>
409428
<term><option>-h <replaceable>host</replaceable></option></term>
410429
<term><option>--host=<replaceable>host</replaceable></option></term>

‎src/bin/pg_dump/pg_dumpall.c

Lines changed: 165 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,15 @@ static intrunPgDump(const char *dbname);
5656
staticvoidbuildShSecLabels(PGconn*conn,constchar*catalog_name,
5757
uint32objectId,PQExpBufferbuffer,
5858
constchar*target,constchar*objname);
59-
staticPGconn*connectDatabase(constchar*dbname,constchar*pghost,constchar*pgport,
59+
staticPGconn*connectDatabase(constchar*dbname,constchar*connstr,constchar*pghost,constchar*pgport,
6060
constchar*pguser,enumtrivalueprompt_password,boolfail_on_error);
61+
staticchar*constructConnStr(constchar**keywords,constchar**values);
6162
staticPGresult*executeQuery(PGconn*conn,constchar*query);
6263
staticvoidexecuteCommand(PGconn*conn,constchar*query);
6364

6465
staticcharpg_dump_bin[MAXPGPATH];
6566
staticPQExpBufferpgdumpopts;
67+
staticchar*connstr="";
6668
staticboolskip_acls= false;
6769
staticboolverbose= false;
6870

@@ -91,6 +93,7 @@ main(int argc, char *argv[])
9193
{"globals-only",no_argument,NULL,'g'},
9294
{"host",required_argument,NULL,'h'},
9395
{"ignore-version",no_argument,NULL,'i'},
96+
{"dbname",required_argument,NULL,'d'},
9497
{"database",required_argument,NULL,'l'},
9598
{"oids",no_argument,NULL,'o'},
9699
{"no-owner",no_argument,NULL,'O'},
@@ -188,7 +191,7 @@ main(int argc, char *argv[])
188191

189192
pgdumpopts=createPQExpBuffer();
190193

191-
while ((c=getopt_long(argc,argv,"acf:gh:il:oOp:rsS:tU:vwWx",long_options,&optindex))!=-1)
194+
while ((c=getopt_long(argc,argv,"acd:f:gh:i:l:oOp:rsS:tU:vwWx",long_options,&optindex))!=-1)
192195
{
193196
switch (c)
194197
{
@@ -201,6 +204,10 @@ main(int argc, char *argv[])
201204
output_clean= true;
202205
break;
203206

207+
case'd':
208+
connstr=pg_strdup(optarg);
209+
break;
210+
204211
case'f':
205212
filename=pg_strdup(optarg);
206213
appendPQExpBuffer(pgdumpopts," -f ");
@@ -213,8 +220,6 @@ main(int argc, char *argv[])
213220

214221
case'h':
215222
pghost=pg_strdup(optarg);
216-
appendPQExpBuffer(pgdumpopts," -h ");
217-
doShellQuoting(pgdumpopts,pghost);
218223
break;
219224

220225
case'i':
@@ -235,8 +240,6 @@ main(int argc, char *argv[])
235240

236241
case'p':
237242
pgport=pg_strdup(optarg);
238-
appendPQExpBuffer(pgdumpopts," -p ");
239-
doShellQuoting(pgdumpopts,pgport);
240243
break;
241244

242245
case'r':
@@ -258,8 +261,6 @@ main(int argc, char *argv[])
258261

259262
case'U':
260263
pguser=pg_strdup(optarg);
261-
appendPQExpBuffer(pgdumpopts," -U ");
262-
doShellQuoting(pgdumpopts,pguser);
263264
break;
264265

265266
case'v':
@@ -370,7 +371,7 @@ main(int argc, char *argv[])
370371
*/
371372
if (pgdb)
372373
{
373-
conn=connectDatabase(pgdb,pghost,pgport,pguser,
374+
conn=connectDatabase(pgdb,connstr,pghost,pgport,pguser,
374375
prompt_password, false);
375376

376377
if (!conn)
@@ -382,10 +383,10 @@ main(int argc, char *argv[])
382383
}
383384
else
384385
{
385-
conn=connectDatabase("postgres",pghost,pgport,pguser,
386+
conn=connectDatabase("postgres",connstr,pghost,pgport,pguser,
386387
prompt_password, false);
387388
if (!conn)
388-
conn=connectDatabase("template1",pghost,pgport,pguser,
389+
conn=connectDatabase("template1",connstr,pghost,pgport,pguser,
389390
prompt_password, true);
390391

391392
if (!conn)
@@ -568,6 +569,7 @@ help(void)
568569
" ALTER OWNER commands to set ownership\n"));
569570

570571
printf(_("\nConnection options:\n"));
572+
printf(_(" -d, --dbname=CONNSTR connect using connection string\n"));
571573
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
572574
printf(_(" -l, --database=DBNAME alternative default database\n"));
573575
printf(_(" -p, --port=PORT database server port number\n"));
@@ -1630,7 +1632,7 @@ dumpDatabases(PGconn *conn)
16301632
staticint
16311633
runPgDump(constchar*dbname)
16321634
{
1633-
PQExpBufferconnstr=createPQExpBuffer();
1635+
PQExpBufferconnstrbuf=createPQExpBuffer();
16341636
PQExpBuffercmd=createPQExpBuffer();
16351637
intret;
16361638

@@ -1647,16 +1649,13 @@ runPgDump(const char *dbname)
16471649
appendPQExpBuffer(cmd," -Fp ");
16481650

16491651
/*
1650-
* Construct a connection string from the database name, like
1651-
* dbname='<database name>'. pg_dump would usually also accept the
1652-
* database name as is, but if it contains any = characters, it would
1653-
* incorrectly treat it as a connection string.
1652+
* Append the database name to the already-constructed stem of connection
1653+
* string.
16541654
*/
1655-
appendPQExpBuffer(connstr,"dbname='");
1656-
doConnStrQuoting(connstr,dbname);
1657-
appendPQExpBuffer(connstr,"'");
1655+
appendPQExpBuffer(connstrbuf,"%s dbname=",connstr);
1656+
doConnStrQuoting(connstrbuf,dbname);
16581657

1659-
doShellQuoting(cmd,connstr->data);
1658+
doShellQuoting(cmd,connstrbuf->data);
16601659

16611660
appendPQExpBuffer(cmd,"%s",SYSTEMQUOTE);
16621661

@@ -1669,7 +1668,7 @@ runPgDump(const char *dbname)
16691668
ret=system(cmd->data);
16701669

16711670
destroyPQExpBuffer(cmd);
1672-
destroyPQExpBuffer(connstr);
1671+
destroyPQExpBuffer(connstrbuf);
16731672

16741673
returnret;
16751674
}
@@ -1703,16 +1702,23 @@ buildShSecLabels(PGconn *conn, const char *catalog_name, uint32 objectId,
17031702
*
17041703
* If fail_on_error is false, we return NULL without printing any message
17051704
* on failure, but preserve any prompted password for the next try.
1705+
*
1706+
* On success, the global variable 'connstr' is set to a connection string
1707+
* containing the options used.
17061708
*/
17071709
staticPGconn*
1708-
connectDatabase(constchar*dbname,constchar*pghost,constchar*pgport,
1709-
constchar*pguser,enumtrivalueprompt_password,boolfail_on_error)
1710+
connectDatabase(constchar*dbname,constchar*connection_string,
1711+
constchar*pghost,constchar*pgport,constchar*pguser,
1712+
enumtrivalueprompt_password,boolfail_on_error)
17101713
{
17111714
PGconn*conn;
17121715
boolnew_pass;
17131716
constchar*remoteversion_str;
17141717
intmy_version;
17151718
staticchar*password=NULL;
1719+
constchar**keywords=NULL;
1720+
constchar**values=NULL;
1721+
PQconninfoOption*conn_opts=NULL;
17161722

17171723
if (prompt_password==TRI_YES&& !password)
17181724
password=simple_prompt("Password: ",100, false);
@@ -1723,31 +1729,93 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
17231729
*/
17241730
do
17251731
{
1726-
#definePARAMS_ARRAY_SIZE7
1727-
constchar**keywords=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*keywords));
1728-
constchar**values=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*values));
1729-
1730-
keywords[0]="host";
1731-
values[0]=pghost;
1732-
keywords[1]="port";
1733-
values[1]=pgport;
1734-
keywords[2]="user";
1735-
values[2]=pguser;
1736-
keywords[3]="password";
1737-
values[3]=password;
1738-
keywords[4]="dbname";
1739-
values[4]=dbname;
1740-
keywords[5]="fallback_application_name";
1741-
values[5]=progname;
1742-
keywords[6]=NULL;
1743-
values[6]=NULL;
1732+
intargcount=6;
1733+
PQconninfoOption*conn_opt;
1734+
char*err_msg=NULL;
1735+
inti=0;
1736+
1737+
if (keywords)
1738+
free(keywords);
1739+
if (values)
1740+
free(values);
1741+
if (conn_opts)
1742+
PQconninfoFree(conn_opts);
1743+
1744+
/*
1745+
* Merge the connection info inputs given in form of connection string
1746+
* and other options.
1747+
*/
1748+
if (connection_string)
1749+
{
1750+
conn_opts=PQconninfoParse(connection_string,&err_msg);
1751+
if (conn_opts==NULL)
1752+
{
1753+
fprintf(stderr,"%s: %s\n",progname,err_msg);
1754+
exit_nicely(1);
1755+
}
1756+
1757+
for (conn_opt=conn_opts;conn_opt->keyword!=NULL;conn_opt++)
1758+
{
1759+
if (conn_opt->val!=NULL&&conn_opt->val[0]!='\0')
1760+
argcount++;
1761+
}
1762+
1763+
keywords=pg_malloc0((argcount+1)*sizeof(*keywords));
1764+
values=pg_malloc0((argcount+1)*sizeof(*values));
1765+
1766+
for (conn_opt=conn_opts;conn_opt->keyword!=NULL;conn_opt++)
1767+
{
1768+
if (conn_opt->val!=NULL&&conn_opt->val[0]!='\0')
1769+
{
1770+
keywords[i]=conn_opt->keyword;
1771+
values[i]=conn_opt->val;
1772+
i++;
1773+
}
1774+
}
1775+
}
1776+
else
1777+
{
1778+
keywords=pg_malloc0((argcount+1)*sizeof(*keywords));
1779+
values=pg_malloc0((argcount+1)*sizeof(*values));
1780+
}
1781+
1782+
if (pghost)
1783+
{
1784+
keywords[i]="host";
1785+
values[i]=pghost;
1786+
i++;
1787+
}
1788+
if (pgport)
1789+
{
1790+
keywords[i]="port";
1791+
values[i]=pgport;
1792+
i++;
1793+
}
1794+
if (pguser)
1795+
{
1796+
keywords[i]="user";
1797+
values[i]=pguser;
1798+
i++;
1799+
}
1800+
if (password)
1801+
{
1802+
keywords[i]="password";
1803+
values[i]=password;
1804+
i++;
1805+
}
1806+
if (dbname)
1807+
{
1808+
keywords[i]="dbname";
1809+
values[i]=dbname;
1810+
i++;
1811+
}
1812+
keywords[i]="fallback_application_name";
1813+
values[i]=progname;
1814+
i++;
17441815

17451816
new_pass= false;
17461817
conn=PQconnectdbParams(keywords,values, true);
17471818

1748-
free(keywords);
1749-
free(values);
1750-
17511819
if (!conn)
17521820
{
17531821
fprintf(stderr,_("%s: could not connect to database \"%s\"\n"),
@@ -1779,10 +1847,26 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
17791847
else
17801848
{
17811849
PQfinish(conn);
1850+
1851+
free(keywords);
1852+
free(values);
1853+
PQconninfoFree(conn_opts);
1854+
17821855
returnNULL;
17831856
}
17841857
}
17851858

1859+
/*
1860+
* Ok, connected successfully. Remember the options used, in the form of
1861+
* a connection string.
1862+
*/
1863+
connstr=constructConnStr(keywords,values);
1864+
1865+
free(keywords);
1866+
free(values);
1867+
PQconninfoFree(conn_opts);
1868+
1869+
/* Check version */
17861870
remoteversion_str=PQparameterStatus(conn,"server_version");
17871871
if (!remoteversion_str)
17881872
{
@@ -1829,6 +1913,43 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
18291913
returnconn;
18301914
}
18311915

1916+
/* ----------
1917+
* Construct a connection string from the given keyword/value pairs. It is
1918+
* used to pass the connection options to the pg_dump subprocess.
1919+
*
1920+
* The following parameters are excluded:
1921+
*dbname- varies in each pg_dump invocation
1922+
*password- it's not secure to pass a password on the command line
1923+
*fallback_application_name - we'll let pg_dump set it
1924+
* ----------
1925+
*/
1926+
staticchar*
1927+
constructConnStr(constchar**keywords,constchar**values)
1928+
{
1929+
PQExpBufferbuf=createPQExpBuffer();
1930+
char*connstr;
1931+
inti;
1932+
boolfirstkeyword= true;
1933+
1934+
/* Construct a new connection string in key='value' format. */
1935+
for (i=0;keywords[i]!=NULL;i++)
1936+
{
1937+
if (strcmp(keywords[i],"dbname")==0||
1938+
strcmp(keywords[i],"password")==0||
1939+
strcmp(keywords[i],"fallback_application_name")==0)
1940+
continue;
1941+
1942+
if (!firstkeyword)
1943+
appendPQExpBufferChar(buf,' ');
1944+
firstkeyword= false;
1945+
appendPQExpBuffer(buf,"%s=",keywords[i]);
1946+
doConnStrQuoting(buf,values[i]);
1947+
}
1948+
1949+
connstr=pg_strdup(buf->data);
1950+
destroyPQExpBuffer(buf);
1951+
returnconnstr;
1952+
}
18321953

18331954
/*
18341955
* Run a query, return the results, exit program on failure.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp