mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-30 19:00:29 +08:00
Add 'output file' option for pg_dumpall, especially useful for Win32,
where output redirection of child processes (pg_dump) doesn't work. Dave Page
This commit is contained in:
parent
1b7d863f1d
commit
6441288ec9
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.61 2007/01/25 02:46:33 momjian Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.62 2007/01/25 03:30:43 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -129,6 +129,18 @@ PostgreSQL documentation
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-f <replaceable class="parameter">filename</replaceable></option></term>
|
||||
<term><option>--file=<replaceable class="parameter">filename</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Write the output to the specified file. This is particularly useful
|
||||
on Windows because output redirection does not work for child
|
||||
processes.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-g</option></term>
|
||||
<term><option>--globals-only</option></term>
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup.h,v 1.44 2006/10/14 23:07:22 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup.h,v 1.45 2007/01/25 03:30:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -46,6 +46,13 @@ typedef enum _archiveFormat
|
||||
archNull = 4
|
||||
} ArchiveFormat;
|
||||
|
||||
typedef enum _archiveMode
|
||||
{
|
||||
archModeAppend,
|
||||
archModeWrite,
|
||||
archModeRead
|
||||
} ArchiveMode;
|
||||
|
||||
/*
|
||||
* We may want to have some more user-readable data, but in the mean
|
||||
* time this gives us some abstraction and type checking.
|
||||
@ -166,7 +173,7 @@ extern Archive *OpenArchive(const char *FileSpec, const ArchiveFormat fmt);
|
||||
|
||||
/* Create a new archive */
|
||||
extern Archive *CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
|
||||
const int compression);
|
||||
const int compression, ArchiveMode mode);
|
||||
|
||||
/* The --list option */
|
||||
extern void PrintTOCSummary(Archive *AH, RestoreOptions *ropt);
|
||||
|
@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.139 2007/01/23 17:54:50 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.140 2007/01/25 03:30:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -86,10 +86,10 @@ static void ResetOutput(ArchiveHandle *AH, OutputContext savedContext);
|
||||
/* Public */
|
||||
Archive *
|
||||
CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
|
||||
const int compression)
|
||||
const int compression, ArchiveMode mode)
|
||||
|
||||
{
|
||||
ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, archModeWrite);
|
||||
ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, mode);
|
||||
|
||||
return (Archive *) AH;
|
||||
}
|
||||
@ -940,10 +940,20 @@ SetOutput(ArchiveHandle *AH, char *filename, int compression)
|
||||
else
|
||||
#endif
|
||||
{ /* Use fopen */
|
||||
if (AH->mode == archModeAppend)
|
||||
{
|
||||
if (fn >= 0)
|
||||
AH->OF = fdopen(dup(fn), PG_BINARY_A);
|
||||
else
|
||||
AH->OF = fopen(filename, PG_BINARY_A);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fn >= 0)
|
||||
AH->OF = fdopen(dup(fn), PG_BINARY_W);
|
||||
else
|
||||
AH->OF = fopen(filename, PG_BINARY_W);
|
||||
}
|
||||
AH->gzOut = 0;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.73 2006/10/04 00:30:05 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.h,v 1.74 2007/01/25 03:30:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -122,12 +122,6 @@ typedef void (*PrintTocDataPtr) (struct _archiveHandle * AH, struct _tocEntry *
|
||||
|
||||
typedef size_t (*CustomOutPtr) (struct _archiveHandle * AH, const void *buf, size_t len);
|
||||
|
||||
typedef enum _archiveMode
|
||||
{
|
||||
archModeWrite,
|
||||
archModeRead
|
||||
} ArchiveMode;
|
||||
|
||||
typedef struct _outputContext
|
||||
{
|
||||
void *OF;
|
||||
|
@ -12,7 +12,7 @@
|
||||
* by PostgreSQL
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.458 2007/01/23 17:54:50 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.459 2007/01/25 03:30:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -478,25 +478,31 @@ main(int argc, char **argv)
|
||||
/* open the output file */
|
||||
switch (format[0])
|
||||
{
|
||||
case 'a':
|
||||
case 'A':
|
||||
plainText = 1;
|
||||
g_fout = CreateArchive(filename, archNull, 0, archModeAppend);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
g_fout = CreateArchive(filename, archCustom, compressLevel);
|
||||
g_fout = CreateArchive(filename, archCustom, compressLevel, archModeWrite);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
g_fout = CreateArchive(filename, archFiles, compressLevel);
|
||||
g_fout = CreateArchive(filename, archFiles, compressLevel, archModeWrite);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
case 'P':
|
||||
plainText = 1;
|
||||
g_fout = CreateArchive(filename, archNull, 0);
|
||||
g_fout = CreateArchive(filename, archNull, 0, archModeWrite);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
g_fout = CreateArchive(filename, archTar, compressLevel);
|
||||
g_fout = CreateArchive(filename, archTar, compressLevel, archModeWrite);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.88 2007/01/25 02:46:33 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.89 2007/01/25 03:30:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -68,6 +68,8 @@ static int disable_triggers = 0;
|
||||
static int use_setsessauth = 0;
|
||||
static int server_version;
|
||||
|
||||
static FILE *OPF;
|
||||
static char *filename = NULL;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
@ -94,6 +96,7 @@ main(int argc, char *argv[])
|
||||
{"inserts", no_argument, NULL, 'd'},
|
||||
{"attribute-inserts", no_argument, NULL, 'D'},
|
||||
{"column-inserts", no_argument, NULL, 'D'},
|
||||
{"file", required_argument, NULL, 'f'},
|
||||
{"globals-only", no_argument, NULL, 'g'},
|
||||
{"host", required_argument, NULL, 'h'},
|
||||
{"ignore-version", no_argument, NULL, 'i'},
|
||||
@ -167,7 +170,7 @@ main(int argc, char *argv[])
|
||||
|
||||
pgdumpopts = createPQExpBuffer();
|
||||
|
||||
while ((c = getopt_long(argc, argv, "acdDgh:il:oOp:rsS:tU:vWxX:", long_options, &optindex)) != -1)
|
||||
while ((c = getopt_long(argc, argv, "acdDf:gh:il:oOp:rsS:tU:vWxX:", long_options, &optindex)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -185,6 +188,16 @@ main(int argc, char *argv[])
|
||||
appendPQExpBuffer(pgdumpopts, " -%c", c);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
filename = optarg;
|
||||
#ifndef WIN32
|
||||
appendPQExpBuffer(pgdumpopts, " -f '%s'", filename);
|
||||
#else
|
||||
appendPQExpBuffer(pgdumpopts, " -f \"%s\"", filename);
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
globals_only = true;
|
||||
break;
|
||||
@ -378,6 +391,22 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the output file if required, otherwise use stdout
|
||||
*/
|
||||
if (filename)
|
||||
{
|
||||
OPF = fopen(filename, PG_BINARY_W);
|
||||
if (!OPF)
|
||||
{
|
||||
fprintf(stderr, _("%s: could not open the output file \"%s\"\n"),
|
||||
progname, filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
OPF = stdout;
|
||||
|
||||
/*
|
||||
* Get the active encoding and the standard_conforming_strings setting, so
|
||||
* we know how to escape strings.
|
||||
@ -387,21 +416,21 @@ main(int argc, char *argv[])
|
||||
if (!std_strings)
|
||||
std_strings = "off";
|
||||
|
||||
printf("--\n-- PostgreSQL database cluster dump\n--\n\n");
|
||||
fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
|
||||
if (verbose)
|
||||
dumpTimestamp("Started on");
|
||||
|
||||
printf("\\connect postgres\n\n");
|
||||
fprintf(OPF, "\\connect postgres\n\n");
|
||||
|
||||
if (!data_only)
|
||||
{
|
||||
/* Replicate encoding and std_strings in output */
|
||||
printf("SET client_encoding = '%s';\n",
|
||||
fprintf(OPF, "SET client_encoding = '%s';\n",
|
||||
pg_encoding_to_char(encoding));
|
||||
printf("SET standard_conforming_strings = %s;\n", std_strings);
|
||||
fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
|
||||
if (strcmp(std_strings, "off") == 0)
|
||||
printf("SET escape_string_warning = 'off';\n");
|
||||
printf("\n");
|
||||
fprintf(OPF, "SET escape_string_warning = 'off';\n");
|
||||
fprintf(OPF, "\n");
|
||||
|
||||
if (!tablespaces_only)
|
||||
{
|
||||
@ -434,7 +463,10 @@ main(int argc, char *argv[])
|
||||
|
||||
if (verbose)
|
||||
dumpTimestamp("Completed on");
|
||||
printf("--\n-- PostgreSQL database cluster dump complete\n--\n\n");
|
||||
fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
|
||||
|
||||
if (filename)
|
||||
fclose(OPF);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@ -449,6 +481,7 @@ help(void)
|
||||
printf(_(" %s [OPTION]...\n"), progname);
|
||||
|
||||
printf(_("\nGeneral options:\n"));
|
||||
printf(_(" -f, --file=FILENAME output file name\n"));
|
||||
printf(_(" -i, --ignore-version proceed even when server version mismatches\n"
|
||||
" pg_dumpall version\n"));
|
||||
printf(_(" --help show this help, then exit\n"));
|
||||
@ -571,7 +604,7 @@ dumpRoles(PGconn *conn)
|
||||
i_rolcomment = PQfnumber(res, "rolcomment");
|
||||
|
||||
if (PQntuples(res) > 0)
|
||||
printf("--\n-- Roles\n--\n\n");
|
||||
fprintf(OPF, "--\n-- Roles\n--\n\n");
|
||||
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
@ -641,7 +674,7 @@ dumpRoles(PGconn *conn)
|
||||
appendPQExpBuffer(buf, ";\n");
|
||||
}
|
||||
|
||||
printf("%s", buf->data);
|
||||
fprintf(OPF, "%s", buf->data);
|
||||
|
||||
if (server_version >= 70300)
|
||||
dumpUserConfig(conn, rolename);
|
||||
@ -649,7 +682,7 @@ dumpRoles(PGconn *conn)
|
||||
|
||||
PQclear(res);
|
||||
|
||||
printf("\n\n");
|
||||
fprintf(OPF, "\n\n");
|
||||
|
||||
destroyPQExpBuffer(buf);
|
||||
}
|
||||
@ -678,7 +711,7 @@ dumpRoleMembership(PGconn *conn)
|
||||
"ORDER BY 1,2,3");
|
||||
|
||||
if (PQntuples(res) > 0)
|
||||
printf("--\n-- Role memberships\n--\n\n");
|
||||
fprintf(OPF, "--\n-- Role memberships\n--\n\n");
|
||||
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
@ -687,16 +720,16 @@ dumpRoleMembership(PGconn *conn)
|
||||
char *grantor = PQgetvalue(res, i, 2);
|
||||
char *option = PQgetvalue(res, i, 3);
|
||||
|
||||
printf("GRANT %s", fmtId(roleid));
|
||||
printf(" TO %s", fmtId(member));
|
||||
fprintf(OPF, "GRANT %s", fmtId(roleid));
|
||||
fprintf(OPF, " TO %s", fmtId(member));
|
||||
if (*option == 't')
|
||||
printf(" WITH ADMIN OPTION");
|
||||
printf(" GRANTED BY %s;\n", fmtId(grantor));
|
||||
fprintf(OPF, " WITH ADMIN OPTION");
|
||||
fprintf(OPF, " GRANTED BY %s;\n", fmtId(grantor));
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
|
||||
printf("\n\n");
|
||||
fprintf(OPF, "\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -718,7 +751,7 @@ dumpGroups(PGconn *conn)
|
||||
"SELECT groname, grolist FROM pg_group ORDER BY 1");
|
||||
|
||||
if (PQntuples(res) > 0)
|
||||
printf("--\n-- Role memberships\n--\n\n");
|
||||
fprintf(OPF, "--\n-- Role memberships\n--\n\n");
|
||||
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
@ -755,8 +788,8 @@ dumpGroups(PGconn *conn)
|
||||
if (strcmp(groname, usename) == 0)
|
||||
continue;
|
||||
|
||||
printf("GRANT %s", fmtId(groname));
|
||||
printf(" TO %s;\n", fmtId(usename));
|
||||
fprintf(OPF, "GRANT %s", fmtId(groname));
|
||||
fprintf(OPF, " TO %s;\n", fmtId(usename));
|
||||
}
|
||||
|
||||
PQclear(res2);
|
||||
@ -765,7 +798,7 @@ dumpGroups(PGconn *conn)
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(buf);
|
||||
|
||||
printf("\n\n");
|
||||
fprintf(OPF, "\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -799,7 +832,7 @@ dumpTablespaces(PGconn *conn)
|
||||
"ORDER BY 1");
|
||||
|
||||
if (PQntuples(res) > 0)
|
||||
printf("--\n-- Tablespaces\n--\n\n");
|
||||
fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
|
||||
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
@ -841,14 +874,14 @@ dumpTablespaces(PGconn *conn)
|
||||
appendPQExpBuffer(buf, ";\n");
|
||||
}
|
||||
|
||||
printf("%s", buf->data);
|
||||
fprintf(OPF, "%s", buf->data);
|
||||
|
||||
free(fspcname);
|
||||
destroyPQExpBuffer(buf);
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
printf("\n\n");
|
||||
fprintf(OPF, "\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -869,7 +902,7 @@ dumpCreateDB(PGconn *conn)
|
||||
PGresult *res;
|
||||
int i;
|
||||
|
||||
printf("--\n-- Database creation\n--\n\n");
|
||||
fprintf(OPF, "--\n-- Database creation\n--\n\n");
|
||||
|
||||
if (server_version >= 80100)
|
||||
res = executeQuery(conn,
|
||||
@ -998,7 +1031,7 @@ dumpCreateDB(PGconn *conn)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("%s", buf->data);
|
||||
fprintf(OPF, "%s", buf->data);
|
||||
|
||||
if (server_version >= 70300)
|
||||
dumpDatabaseConfig(conn, dbname);
|
||||
@ -1009,7 +1042,7 @@ dumpCreateDB(PGconn *conn)
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(buf);
|
||||
|
||||
printf("\n\n");
|
||||
fprintf(OPF, "\n\n");
|
||||
}
|
||||
|
||||
|
||||
@ -1121,7 +1154,7 @@ makeAlterConfigCommand(PGconn *conn, const char *arrayitem,
|
||||
appendStringLiteralConn(buf, pos + 1, conn);
|
||||
appendPQExpBuffer(buf, ";\n");
|
||||
|
||||
printf("%s", buf->data);
|
||||
fprintf(OPF, "%s", buf->data);
|
||||
destroyPQExpBuffer(buf);
|
||||
free(mine);
|
||||
}
|
||||
@ -1151,13 +1184,29 @@ dumpDatabases(PGconn *conn)
|
||||
if (verbose)
|
||||
fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);
|
||||
|
||||
printf("\\connect %s\n\n", fmtId(dbname));
|
||||
fprintf(OPF, "\\connect %s\n\n", fmtId(dbname));
|
||||
|
||||
if (filename)
|
||||
fclose(OPF);
|
||||
|
||||
ret = runPgDump(dbname);
|
||||
if (ret != 0)
|
||||
{
|
||||
fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (filename)
|
||||
{
|
||||
OPF = fopen(filename, PG_BINARY_A);
|
||||
if (!OPF)
|
||||
{
|
||||
fprintf(stderr, _("%s: could not re-open the output file \"%s\"\n"),
|
||||
progname, filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
@ -1179,13 +1228,28 @@ runPgDump(const char *dbname)
|
||||
* Win32 has to use double-quotes for args, rather than single quotes.
|
||||
* Strangely enough, this is the only place we pass a database name on the
|
||||
* command line, except "postgres" which doesn't need quoting.
|
||||
*
|
||||
* If we have a filename, use the undocumented plain-append pg_dump format.
|
||||
*/
|
||||
if (filename)
|
||||
{
|
||||
#ifndef WIN32
|
||||
appendPQExpBuffer(cmd, "%s\"%s\" %s -Fa '", SYSTEMQUOTE, pg_dump_bin,
|
||||
#else
|
||||
appendPQExpBuffer(cmd, "%s\"%s\" %s -Fa \"", SYSTEMQUOTE, pg_dump_bin,
|
||||
#endif
|
||||
pgdumpopts->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef WIN32
|
||||
appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp '", SYSTEMQUOTE, pg_dump_bin,
|
||||
#else
|
||||
appendPQExpBuffer(cmd, "%s\"%s\" %s -Fp \"", SYSTEMQUOTE, pg_dump_bin,
|
||||
#endif
|
||||
pgdumpopts->data);
|
||||
}
|
||||
|
||||
|
||||
/* Shell quoting is not quite like SQL quoting, so can't use fmtId */
|
||||
for (p = dbname; *p; p++)
|
||||
@ -1413,5 +1477,5 @@ dumpTimestamp(char *msg)
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
#endif
|
||||
localtime(&now)) != 0)
|
||||
printf("-- %s %s\n\n", msg, buf);
|
||||
fprintf(OPF, "-- %s %s\n\n", msg, buf);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/c.h,v 1.216 2007/01/11 02:39:52 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/c.h,v 1.217 2007/01/25 03:30:43 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -736,10 +736,12 @@ typedef NameData *Name;
|
||||
*/
|
||||
#if defined(WIN32) || defined(__CYGWIN__)
|
||||
#define PG_BINARY O_BINARY
|
||||
#define PG_BINARY_A "ab"
|
||||
#define PG_BINARY_R "rb"
|
||||
#define PG_BINARY_W "wb"
|
||||
#else
|
||||
#define PG_BINARY 0
|
||||
#define PG_BINARY_A "a"
|
||||
#define PG_BINARY_R "r"
|
||||
#define PG_BINARY_W "w"
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user