Re: pg_dumpall -f option - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: pg_dumpall -f |
Date | |
Msg-id | 200701250331.l0P3V7t28703@momjian.us Whole thread Raw |
In response to |
pg_dumpall -f |
Responses |
Re: pg_dumpall -f |
List | pgsql-patches |
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 > > http://www.postgresql.org/about/donate -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. +
pgsql-patches by date: