pg_dumpall -f <filename> option
Per discussion on -hackers, the attached patch adds the option
-f, --file=FILENAME
to pg_dumpall. In order to support this, a new (undocumented) format
option (-Fa) is added to pg_dump which is identical to -Fp, except that
the output file is opened for append rather than write.
This patch should be applied over the top of my previous patch
(pg_dumpall_default_database3.diff).
Regards, Dave
Attachments:
pg_dumpall_to_file.difftext/plain; name=pg_dumpall_to_file.diff; x-mac-creator=0; x-mac-type=0Download+193-117
Patch applied. Thanks.
Docs updated to mention Win32:
Write the output to the specified file. This is particularly useful
on Windows because output redirection does not work for child
processes.
---------------------------------------------------------------------------
D ave Page wrote:
Per discussion on -hackers, the attached patch adds the option
-f, --file=FILENAME
to pg_dumpall. In order to support this, a new (undocumented) format
option (-Fa) is added to pg_dump which is identical to -Fp, except that
the output file is opened for append rather than write.This patch should be applied over the top of my previous patch
(pg_dumpall_default_database3.diff).Regards, Dave
diff -cr pgsql.orig/doc/src/sgml/ref/pg_dumpall.sgml pgsql.append/doc/src/sgml/ref/pg_dumpall.sgml *** pgsql.orig/doc/src/sgml/ref/pg_dumpall.sgml Tue Jan 16 09:36:33 2007 --- pgsql.append/doc/src/sgml/ref/pg_dumpall.sgml Tue Jan 16 11:19:05 2007 *************** *** 128,133 **** --- 128,143 ---- </para> </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. + </para> + </listitem> + </varlistentry><varlistentry> <term><option>-g</option></term> diff -cr pgsql.orig/src/bin/pg_dump/pg_backup.h pgsql.append/src/bin/pg_dump/pg_backup.h *** pgsql.orig/src/bin/pg_dump/pg_backup.h Mon Jan 15 12:54:05 2007 --- pgsql.append/src/bin/pg_dump/pg_backup.h Tue Jan 16 10:21:12 2007 *************** *** 46,51 **** --- 46,58 ---- 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,172 ****/* Create a new archive */
extern Archive *CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
! const int compression);/* The --list option */ extern void PrintTOCSummary(Archive *AH, RestoreOptions *ropt); --- 173,179 ----/* Create a new archive */
extern Archive *CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
! const int compression, ArchiveMode mode);/* The --list option */ extern void PrintTOCSummary(Archive *AH, RestoreOptions *ropt); diff -cr pgsql.orig/src/bin/pg_dump/pg_backup_archiver.c pgsql.append/src/bin/pg_dump/pg_backup_archiver.c *** pgsql.orig/src/bin/pg_dump/pg_backup_archiver.c Mon Jan 15 12:54:05 2007 --- pgsql.append/src/bin/pg_dump/pg_backup_archiver.c Tue Jan 16 11:10:16 2007 *************** *** 86,95 **** /* Public */ Archive * CreateArchive(const char *FileSpec, const ArchiveFormat fmt, ! const int compression){
! ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, archModeWrite);return (Archive *) AH; } --- 86,95 ---- /* Public */ Archive * CreateArchive(const char *FileSpec, const ArchiveFormat fmt, ! const int compression, ArchiveMode mode){
! ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, mode);return (Archive *) AH;
}
***************
*** 203,209 ****/*
* Setup the output file if necessary.
! */
if (ropt->filename || ropt->compression)
sav = SetOutput(AH, ropt->filename, ropt->compression);--- 203,209 ----/*
* Setup the output file if necessary.
! */
if (ropt->filename || ropt->compression)
sav = SetOutput(AH, ropt->filename, ropt->compression);***************
*** 940,949 ****
else
#endif
{ /* Use fopen */
! if (fn >= 0)
! AH->OF = fdopen(dup(fn), PG_BINARY_W);
else
! AH->OF = fopen(filename, PG_BINARY_W);
AH->gzOut = 0;
}--- 940,959 ---- 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; }diff -cr pgsql.orig/src/bin/pg_dump/pg_backup_archiver.h pgsql.append/src/bin/pg_dump/pg_backup_archiver.h *** pgsql.orig/src/bin/pg_dump/pg_backup_archiver.h Mon Jan 15 12:54:05 2007 --- pgsql.append/src/bin/pg_dump/pg_backup_archiver.h Tue Jan 16 10:20:54 2007 *************** *** 122,133 ****typedef size_t (*CustomOutPtr) (struct _archiveHandle * AH, const void *buf, size_t len);
- typedef enum _archiveMode - { - archModeWrite, - archModeRead - } ArchiveMode; - typedef struct _outputContext { void *OF; --- 122,127 ---- diff -cr pgsql.orig/src/bin/pg_dump/pg_dump.c pgsql.append/src/bin/pg_dump/pg_dump.c *** pgsql.orig/src/bin/pg_dump/pg_dump.c Mon Jan 15 12:54:05 2007 --- pgsql.append/src/bin/pg_dump/pg_dump.c Tue Jan 16 11:08:21 2007 *************** *** 477,501 **** /* open the output file */ switch (format[0]) { case 'c': case 'C': ! g_fout = CreateArchive(filename, archCustom, compressLevel); break;case 'f':
case 'F':
! g_fout = CreateArchive(filename, archFiles, compressLevel);
break;case 'p':
case 'P':
plainText = 1;
! g_fout = CreateArchive(filename, archNull, 0);
break;case 't':
case 'T':
! g_fout = CreateArchive(filename, archTar, compressLevel);
break;default: --- 477,507 ---- /* 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, archModeWrite); break;case 'f':
case 'F':
! g_fout = CreateArchive(filename, archFiles, compressLevel, archModeWrite);
break;case 'p':
case 'P':
plainText = 1;
! g_fout = CreateArchive(filename, archNull, 0, archModeWrite);
break;case 't':
case 'T':
! g_fout = CreateArchive(filename, archTar, compressLevel, archModeWrite);
break;default: diff -cr pgsql.orig/src/bin/pg_dump/pg_dumpall.c pgsql.append/src/bin/pg_dump/pg_dumpall.c *** pgsql.orig/src/bin/pg_dump/pg_dumpall.c Tue Jan 16 09:36:33 2007 --- pgsql.append/src/bin/pg_dump/pg_dumpall.c Tue Jan 16 11:19:44 2007 *************** *** 68,90 **** static int use_setsessauth = 0; static int server_version;int
main(int argc, char *argv[])
{
! char *pghost = NULL;
! char *pgport = NULL;
! char *pguser = NULL;
! char *pgdb = NULL;
bool force_password = false;
bool data_only = false;
bool globals_only = false;
bool roles_only = false;
bool tablespaces_only = false;
bool schema_only = false;
! PGconn *conn;
int encoding;
! const char *std_strings;
int c,
ret;--- 68,92 ---- static int use_setsessauth = 0; static int server_version;+ static FILE *OPF;
+ static char *filename = NULL;int
main(int argc, char *argv[])
{
! char *pghost = NULL;
! char *pgport = NULL;
! char *pguser = NULL;
! char *pgdb = NULL;
bool force_password = false;
bool data_only = false;
bool globals_only = false;
bool roles_only = false;
bool tablespaces_only = false;
bool schema_only = false;
! PGconn *conn;
int encoding;
! const char *std_strings;
int c,
ret;*************** *** 94,99 **** --- 96,102 ---- {"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,173 ****pgdumpopts = createPQExpBuffer();
! while ((c = getopt_long(argc, argv, "acdDgh:il:oOp:rsS:tU:vWxX:", long_options, &optindex)) != -1) { switch (c) { --- 170,176 ----pgdumpopts = createPQExpBuffer();
! while ((c = getopt_long(argc, argv, "acdDf:gh:il:oOp:rsS:tU:vWxX:", long_options, &optindex)) != -1) { switch (c) { *************** *** 184,189 **** --- 187,202 ---- case 'D': 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; *************** *** 377,382 **** --- 390,411 ---- exit(1); } } + + /* + * 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
***************
*** 387,407 ****
if (!std_strings)
std_strings = "off";! printf("--\n-- PostgreSQL database cluster dump\n--\n\n");
if (verbose)
dumpTimestamp("Started on");! printf("\\connect postgres\n\n");
if (!data_only)
{
/* Replicate encoding and std_strings in output */
! printf("SET client_encoding = '%s';\n",
pg_encoding_to_char(encoding));
! printf("SET standard_conforming_strings = %s;\n", std_strings);
if (strcmp(std_strings, "off") == 0)
! printf("SET escape_string_warning = 'off';\n");
! printf("\n");if (!tablespaces_only) { --- 416,436 ---- if (!std_strings) std_strings = "off";! fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
if (verbose)
dumpTimestamp("Started on");! fprintf(OPF, "\\connect postgres\n\n");
if (!data_only)
{
/* Replicate encoding and std_strings in output */
! fprintf(OPF, "SET client_encoding = '%s';\n",
pg_encoding_to_char(encoding));
! fprintf(OPF, "SET standard_conforming_strings = %s;\n", std_strings);
if (strcmp(std_strings, "off") == 0)
! fprintf(OPF, "SET escape_string_warning = 'off';\n");
! fprintf(OPF, "\n");if (!tablespaces_only)
{
***************
*** 434,440 ****if (verbose)
dumpTimestamp("Completed on");
! printf("--\n-- PostgreSQL database cluster dump complete\n--\n\n");exit(0); } --- 463,472 ----if (verbose)
dumpTimestamp("Completed on");
! fprintf(OPF, "--\n-- PostgreSQL database cluster dump complete\n--\n\n");
!
! if (filename)
! fclose(OPF);exit(0); } *************** *** 449,454 **** --- 481,487 ---- 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,577 ****
i_rolcomment = PQfnumber(res, "rolcomment");if (PQntuples(res) > 0)
! printf("--\n-- Roles\n--\n\n");for (i = 0; i < PQntuples(res); i++) { --- 604,610 ---- i_rolcomment = PQfnumber(res, "rolcomment");if (PQntuples(res) > 0)
! fprintf(OPF, "--\n-- Roles\n--\n\n");for (i = 0; i < PQntuples(res); i++)
{
***************
*** 641,647 ****
appendPQExpBuffer(buf, ";\n");
}! printf("%s", buf->data);
if (server_version >= 70300) dumpUserConfig(conn, rolename); --- 674,680 ---- appendPQExpBuffer(buf, ";\n"); }! fprintf(OPF, "%s", buf->data);
if (server_version >= 70300)
dumpUserConfig(conn, rolename);
***************
*** 649,655 ****PQclear(res);
! printf("\n\n");
destroyPQExpBuffer(buf); } --- 682,688 ----PQclear(res);
! fprintf(OPF, "\n\n");
destroyPQExpBuffer(buf);
}
***************
*** 678,684 ****
"ORDER BY 1,2,3");if (PQntuples(res) > 0)
! printf("--\n-- Role memberships\n--\n\n");for (i = 0; i < PQntuples(res); i++) { --- 711,717 ---- "ORDER BY 1,2,3");if (PQntuples(res) > 0)
! fprintf(OPF, "--\n-- Role memberships\n--\n\n");for (i = 0; i < PQntuples(res); i++)
{
***************
*** 687,702 ****
char *grantor = PQgetvalue(res, i, 2);
char *option = PQgetvalue(res, i, 3);! printf("GRANT %s", fmtId(roleid));
! printf(" TO %s", fmtId(member));
if (*option == 't')
! printf(" WITH ADMIN OPTION");
! printf(" GRANTED BY %s;\n", fmtId(grantor));
}PQclear(res);
! printf("\n\n");
}/* --- 720,735 ---- char *grantor = PQgetvalue(res, i, 2); char *option = PQgetvalue(res, i, 3);! fprintf(OPF, "GRANT %s", fmtId(roleid));
! fprintf(OPF, " TO %s", fmtId(member));
if (*option == 't')
! fprintf(OPF, " WITH ADMIN OPTION");
! fprintf(OPF, " GRANTED BY %s;\n", fmtId(grantor));
}PQclear(res);
! fprintf(OPF, "\n\n");
}/*
***************
*** 718,724 ****
"SELECT groname, grolist FROM pg_group ORDER BY 1");if (PQntuples(res) > 0)
! printf("--\n-- Role memberships\n--\n\n");for (i = 0; i < PQntuples(res); i++) { --- 751,757 ---- "SELECT groname, grolist FROM pg_group ORDER BY 1");if (PQntuples(res) > 0)
! fprintf(OPF, "--\n-- Role memberships\n--\n\n");for (i = 0; i < PQntuples(res); i++)
{
***************
*** 755,762 ****
if (strcmp(groname, usename) == 0)
continue;! printf("GRANT %s", fmtId(groname));
! printf(" TO %s;\n", fmtId(usename));
}PQclear(res2); --- 788,795 ---- if (strcmp(groname, usename) == 0) continue;! fprintf(OPF, "GRANT %s", fmtId(groname));
! fprintf(OPF, " TO %s;\n", fmtId(usename));
}PQclear(res2);
***************
*** 765,771 ****
PQclear(res);
destroyPQExpBuffer(buf);! printf("\n\n");
}/* --- 798,804 ---- PQclear(res); destroyPQExpBuffer(buf);! fprintf(OPF, "\n\n");
}/*
***************
*** 799,805 ****
"ORDER BY 1");if (PQntuples(res) > 0)
! printf("--\n-- Tablespaces\n--\n\n");for (i = 0; i < PQntuples(res); i++) { --- 832,838 ---- "ORDER BY 1");if (PQntuples(res) > 0)
! fprintf(OPF, "--\n-- Tablespaces\n--\n\n");for (i = 0; i < PQntuples(res); i++)
{
***************
*** 841,854 ****
appendPQExpBuffer(buf, ";\n");
}! printf("%s", buf->data);
free(fspcname);
destroyPQExpBuffer(buf);
}PQclear(res);
! printf("\n\n");
}/* --- 874,887 ---- appendPQExpBuffer(buf, ";\n"); }! fprintf(OPF, "%s", buf->data);
free(fspcname);
destroyPQExpBuffer(buf);
}PQclear(res);
! fprintf(OPF, "\n\n");
}/*
***************
*** 869,875 ****
PGresult *res;
int i;! printf("--\n-- Database creation\n--\n\n");
if (server_version >= 80100) res = executeQuery(conn, --- 902,908 ---- PGresult *res; int i;! fprintf(OPF, "--\n-- Database creation\n--\n\n");
if (server_version >= 80100)
res = executeQuery(conn,
***************
*** 998,1004 ****
exit(1);
}! printf("%s", buf->data);
if (server_version >= 70300) dumpDatabaseConfig(conn, dbname); --- 1031,1037 ---- exit(1); }! fprintf(OPF, "%s", buf->data);
if (server_version >= 70300)
dumpDatabaseConfig(conn, dbname);
***************
*** 1009,1015 ****
PQclear(res);
destroyPQExpBuffer(buf);! printf("\n\n");
}--- 1042,1048 ---- PQclear(res); destroyPQExpBuffer(buf);! fprintf(OPF, "\n\n");
}***************
*** 1121,1127 ****
appendStringLiteralConn(buf, pos + 1, conn);
appendPQExpBuffer(buf, ";\n");! printf("%s", buf->data); destroyPQExpBuffer(buf); free(mine); } --- 1154,1160 ---- appendStringLiteralConn(buf, pos + 1, conn); appendPQExpBuffer(buf, ";\n");! fprintf(OPF, "%s", buf->data);
destroyPQExpBuffer(buf);
free(mine);
}
***************
*** 1151,1163 ****
if (verbose)
fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname);! printf("\\connect %s\n\n", fmtId(dbname));
ret = runPgDump(dbname);
if (ret != 0)
{
fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname);
exit(1);
}
}PQclear(res); --- 1184,1212 ---- if (verbose) fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, 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,1191 **** --- 1228,1255 ---- * 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,1417 **** "%Y-%m-%d %H:%M:%S", #endif localtime(&now)) != 0) ! printf("-- %s %s\n\n", msg, buf); } --- 1477,1481 ---- "%Y-%m-%d %H:%M:%S", #endif localtime(&now)) != 0) ! fprintf(OPF, "-- %s %s\n\n", msg, buf); } diff -cr pgsql.orig/src/include/c.h pgsql.append/src/include/c.h *** pgsql.orig/src/include/c.h Mon Jan 15 12:54:26 2007 --- pgsql.append/src/include/c.h Mon Jan 15 21:42:26 2007 *************** *** 736,745 **** --- 736,747 ---- */ #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
---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at
--
Bruce Momjian bruce@momjian.us
EnterpriseDB http://www.enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +
Bruce Momjian wrote:
Patch applied. Thanks.
Docs updated to mention Win32:
Write the output to the specified file. This is particularly useful
on Windows because output redirection does not work for child
processes.
I didn't say that - I said that I couldn't redirect the output from the
child processes in pgAdmin which is a limitation of the way wxWidgets
works from what I can tell. It may (in fact, quite possibly does) apply
to *nix as well. pg_dumpall output can be redirected from a command
prompt on Windows without any problem.
The patch was proposed in this case because a) it gives pg_dumpall more
consistency with pg_dump allowing pgAdmin to use pg_duampall in the same
way it already uses pg_dump, and b) I have a vague chance of getting a
patch into pg_dumpall this century :-)
Regards, Dave.
Dave Page wrote:
Bruce Momjian wrote:
Patch applied. Thanks.
Docs updated to mention Win32:
Write the output to the specified file. This is particularly useful
on Windows because output redirection does not work for child
processes.I didn't say that - I said that I couldn't redirect the output from the
child processes in pgAdmin which is a limitation of the way wxWidgets
works from what I can tell. It may (in fact, quite possibly does) apply
to *nix as well. pg_dumpall output can be redirected from a command
prompt on Windows without any problem.The patch was proposed in this case because a) it gives pg_dumpall more
consistency with pg_dump allowing pgAdmin to use pg_duampall in the same
way it already uses pg_dump, and b) I have a vague chance of getting a
patch into pg_dumpall this century :-)
OK, thanks. I have copied the text from pg_dump -f option now.
--
Bruce Momjian bruce@momjian.us
EnterpriseDB http://www.enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +