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

Reply via email to