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 ---- + + + + + + + Write the output to the specified file. + + + 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