Обсуждение: pg_dumpall -f 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
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
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. +
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. +