diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index e96a443e0c..fbfdcb3c2a 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1,5 +1,5 @@ @@ -112,13 +112,13 @@ PostgreSQL documentation does not block other users accessing the database (readers or writers). + - - Options + + Options - - pg_dump accepts the following command - line arguments. (Long option forms are only available on some platforms.) + + The following command-line options are used to control the output format. @@ -408,7 +408,9 @@ PostgreSQL documentation - Specifies verbose mode. + Specifies verbose mode. This will cause + pg_dump to print progress messages + to standard error. @@ -499,13 +501,11 @@ PostgreSQL documentation - - + - pg_dump also accepts - the following command line arguments for connection parameters: + The following command-line options control the database connection parameters. @@ -555,8 +555,10 @@ PostgreSQL documentation - + + Long option forms are only available on some platforms. + diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index 9f46b43a82..869f480a34 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -1,5 +1,5 @@ @@ -12,18 +12,13 @@ PostgreSQL documentation pg_dumpall - extract all PostgreSQL databases into a script file + extract a PostgreSQL database cluster into a script file pg_dumpall - -c--clean - -g--globals-only - -h host - -p port - -U username - -W + options @@ -66,97 +61,161 @@ PostgreSQL documentation The SQL script will be written to the standard output. Shell operators should be used to redirect it into a file. - - - - pg_dumpall will need to connect several times to the - PostgreSQL server, asking for the password each - time. It will probably be very convenient to have a PGPASSWORDFILE in that case. - - Options - - pg_dumpall accepts the following - command line arguments: + + The following command-line options are used to control the output format. - - - -c, --clean - - + + + -c, --clean + + Include SQL commands to clean (drop) database objects before recreating them. (This option is fairly useless, since the output script expects to create the databases themselves; they would always be empty upon creation.) - - - + + + - - -g, --globals-only - - + + + + + + Dump data as INSERT commands (rather + than COPY). This will make restoration very + slow, but it makes the output more portable to other RDBMS + packages. + + + + + + + + + + + Dump data as INSERT commands with explicit + column names (INSERT INTO + table + (column, ...) VALUES + ...). This will make restoration very slow, + but it is necessary if you desire to rearrange column ordering. + + + + + + -g, --globals-only + + Only dump global objects (users and groups), no databases. - - - + + + - - -h host - - + + + + + + Ignore version mismatch between + pg_dumpall and the database server. + Since pg_dumpall knows a great deal + about system catalogs, any given version of + pg_dumpall is only intended to work + with the corresponding release of the database server. Use + this option if you need to override the version check (and if + pg_dumpall then fails, don't say + you weren't warned). + + + + + + + + + + Dump object identifiers (OIDs) for every + table. Use this option if your application references the OID + columns in some way (e.g., in a foreign key constraint). + Otherwise, this option should not be used. + + + + + + + + + + Specifies verbose mode. This will cause + pg_dumpall to print progress + messages to standard error. + + + + + + + + The following command-line options control the database connection parameters. + + + + -h host + + Specifies the host name of the machine on which the database server is running. If host begins with a slash, it is used as the directory for the Unix domain socket. The default is taken from the PGHOST environment variable, if set, else a Unix domain socket connection is attempted. - - - + + + - - -p port - - + + -p port + + The port number on which the server is listening. Defaults to the PGPORT environment variable, if set, or a compiled-in default. - - - + + + - - -U username - - + + -U username + + Connect as the given user. - - - + + + - - -W - - + + -W + + Force a password prompt. This should happen automatically if the server requires password authentication. - - - + + + - Any other command line parameters are passed to the underlying - - calls. This is useful to control some aspects of the output - format, but some options such as , - , , and dbname should be avoided. + Long options are only available on some platforms. @@ -180,6 +239,26 @@ PostgreSQL documentation + + Notes + + + Since pg_dumpall calls + pg_dump internally, some diagnostic + messages will refer to pg_dump. + + + + pg_dumpall will need to connect several + times to the PostgreSQL server. If password + authentication is configured, it will ask for a password each time. In + that case it would be convenient to set up a password file. + + + But where is that password file documented? + + + Examples diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile index 069fd45d3e..f18280b958 100644 --- a/src/bin/pg_dump/Makefile +++ b/src/bin/pg_dump/Makefile @@ -5,7 +5,7 @@ # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.37 2002/08/18 09:36:25 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/pg_dump/Makefile,v 1.38 2002/08/27 18:57:26 petere Exp $ # #------------------------------------------------------------------------- @@ -14,11 +14,12 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \ - pg_backup_files.o pg_backup_null.o pg_backup_tar.o sprompt.o + pg_backup_files.o pg_backup_null.o pg_backup_tar.o \ + sprompt.o dumputils.o EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o -override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) +override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DBINDIR=\"$(bindir)\" all: submake-libpq submake-libpgport submake-backend pg_dump pg_restore pg_dumpall @@ -29,12 +30,8 @@ pg_dump: pg_dump.o common.o $(OBJS) $(libpq_builddir)/libpq.a pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a $(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@ -pg_dumpall: pg_dumpall.sh - sed -e 's,@VERSION@,$(VERSION),g' \ - -e 's,@MULTIBYTE@,$(MULTIBYTE),g' \ - -e 's,@bindir@,$(bindir),g' \ - $< >$@ - chmod a+x $@ +pg_dumpall: pg_dumpall.o $(libpq_builddir)/libpq.a + $(CC) $(CFLAGS) pg_dumpall.o dumputils.o sprompt.o $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@ .PHONY: submake-backend submake-backend: @@ -44,13 +41,13 @@ submake-backend: install: all installdirs $(INSTALL_PROGRAM) pg_dump$(X) $(DESTDIR)$(bindir)/pg_dump$(X) $(INSTALL_PROGRAM) pg_restore$(X) $(DESTDIR)$(bindir)/pg_restore$(X) - $(INSTALL_SCRIPT) pg_dumpall $(DESTDIR)$(bindir)/pg_dumpall + $(INSTALL_PROGRAM) pg_dumpall$(X) $(DESTDIR)$(bindir)/pg_dumpall$(X) installdirs: $(mkinstalldirs) $(DESTDIR)$(bindir) uninstall: - rm -f $(addprefix $(DESTDIR)$(bindir)/, pg_dump$(X) pg_restore$(X) pg_dumpall) + rm -f $(addprefix $(DESTDIR)$(bindir)/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X)) clean distclean maintainer-clean: - rm -f pg_dump$(X) pg_restore$(X) $(OBJS) pg_dump.o common.o pg_restore.o pg_dumpall + rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_restore.o pg_dumpall.o diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c new file mode 100644 index 0000000000..314cf88b5c --- /dev/null +++ b/src/bin/pg_dump/dumputils.c @@ -0,0 +1,131 @@ +/*------------------------------------------------------------------------- + * + * Utility routines for SQL dumping + * + * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v 1.1 2002/08/27 18:57:26 petere Exp $ + * + *------------------------------------------------------------------------- + */ + +#include "postgres_fe.h" + +#include "dumputils.h" + +#include "parser/keywords.h" + + + +/* + * Quotes input string if it's not a legitimate SQL identifier as-is. + * + * Note that the returned string must be used before calling fmtId again, + * since we re-use the same return buffer each time. Non-reentrant but + * avoids memory leakage. + */ +const char * +fmtId(const char *rawid) +{ + static PQExpBuffer id_return = NULL; + const char *cp; + bool need_quotes = false; + + if (id_return) /* first time through? */ + resetPQExpBuffer(id_return); + else + id_return = createPQExpBuffer(); + + /* These checks need to match the identifier production in scan.l. + * Don't use islower() etc. */ + + if (ScanKeywordLookup(rawid)) + need_quotes = true; + /* slightly different rules for first character */ + else if (!((rawid[0] >= 'a' && rawid[0] <= 'z') || rawid[0] == '_')) + need_quotes = true; + else + { + /* otherwise check the entire string */ + for (cp = rawid; *cp; cp++) + { + if (!((*cp >= 'a' && *cp <= 'z') + || (*cp >= '0' && *cp <= '9') + || (*cp == '_'))) + { + need_quotes = true; + break; + } + } + } + + if (!need_quotes) + { + /* no quoting needed */ + appendPQExpBufferStr(id_return, rawid); + } + else + { + appendPQExpBufferChar(id_return, '\"'); + for (cp = rawid; *cp; cp++) + { + /* + * Did we find a double-quote in the string? Then make this a + * double double-quote per SQL99. Before, we put in a + * backslash/double-quote pair. - thomas 2000-08-05 + */ + if (*cp == '\"') + appendPQExpBufferChar(id_return, '\"'); + appendPQExpBufferChar(id_return, *cp); + } + appendPQExpBufferChar(id_return, '\"'); + } + + return id_return->data; +} + + + +/* + * Convert a string value to an SQL string literal and append it to + * the given buffer. + * + * Special characters are escaped. Quote mark ' goes to '' per SQL + * standard, other stuff goes to \ sequences. If escapeAll is false, + * whitespace characters are not escaped (tabs, newlines, etc.). This + * is appropriate for dump file output. + */ +void +appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll) +{ + appendPQExpBufferChar(buf, '\''); + while (*str) + { + char ch = *str++; + + if (ch == '\\' || ch == '\'') + { + appendPQExpBufferChar(buf, ch); /* double these */ + appendPQExpBufferChar(buf, ch); + } + else if ((unsigned char) ch < (unsigned char) ' ' && + (escapeAll + || (ch != '\t' && ch != '\n' && ch != '\v' && ch != '\f' && ch != '\r') + )) + { + /* + * generate octal escape for control chars other than + * whitespace + */ + appendPQExpBufferChar(buf, '\\'); + appendPQExpBufferChar(buf, ((ch >> 6) & 3) + '0'); + appendPQExpBufferChar(buf, ((ch >> 3) & 7) + '0'); + appendPQExpBufferChar(buf, (ch & 7) + '0'); + } + else + appendPQExpBufferChar(buf, ch); + } + appendPQExpBufferChar(buf, '\''); +} diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h new file mode 100644 index 0000000000..0266ee8f0c --- /dev/null +++ b/src/bin/pg_dump/dumputils.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * Utility routines for SQL dumping + * + * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * $Header: /cvsroot/pgsql/src/bin/pg_dump/dumputils.h,v 1.1 2002/08/27 18:57:26 petere Exp $ + * + *------------------------------------------------------------------------- + */ + +#ifndef DUMPUTILS_H +#define DUMPUTILS_H + +#include "postgres_fe.h" + +#include "pqexpbuffer.h" + +extern char *simple_prompt(const char *prompt, int maxlen, bool echo); + +extern const char *fmtId(const char *identifier); +extern void appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll); + +#endif DUMPUTILS_H diff --git a/src/bin/pg_dump/nls.mk b/src/bin/pg_dump/nls.mk index baf67d603c..ca39896dfc 100644 --- a/src/bin/pg_dump/nls.mk +++ b/src/bin/pg_dump/nls.mk @@ -1,8 +1,8 @@ -# $Header: /cvsroot/pgsql/src/bin/pg_dump/nls.mk,v 1.6 2001/12/21 22:30:49 petere Exp $ +# $Header: /cvsroot/pgsql/src/bin/pg_dump/nls.mk,v 1.7 2002/08/27 18:57:26 petere Exp $ CATALOG_NAME := pg_dump AVAIL_LANGUAGES := cs de ru sv zh_CN zh_TW GETTEXT_FILES := pg_dump.c common.c pg_backup_archiver.c pg_backup_custom.c \ pg_backup_db.c pg_backup_files.c pg_backup_null.c \ - pg_backup_tar.c pg_restore.c + pg_backup_tar.c pg_restore.c pg_dumpall.c GETTEXT_TRIGGERS:= write_msg:2 die_horribly:3 exit_horribly:3 simple_prompt \ - ExecuteSqlCommand:3 ahlog:3 + ExecuteSqlCommand:3 ahlog:3 _ diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index eaa46c29af..de840e1b77 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.22 2002/08/20 17:54:44 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.23 2002/08/27 18:57:26 petere Exp $ * *------------------------------------------------------------------------- */ @@ -118,11 +118,6 @@ extern void exit_horribly(Archive *AH, const char *modulename, const char *fmt,...) __attribute__((format(printf, 3, 4))); -extern char *simple_prompt(const char *prompt, int maxlen, bool echo); - -extern const char *fmtId(const char *identifier); -extern void appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll); - /* Lets the archive know we have a DB connection to shutdown if it dies */ diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 6ba15a913e..aefd094b53 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.55 2002/08/20 17:54:44 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.56 2002/08/27 18:57:26 petere Exp $ * *------------------------------------------------------------------------- */ @@ -24,14 +24,14 @@ #include "pg_dump.h" #include "pg_backup_archiver.h" #include "pg_backup_db.h" +#include "dumputils.h" #include #include -#include /* for dup */ +#include #include "pqexpbuffer.h" #include "libpq/libpq-fs.h" -#include "parser/keywords.h" typedef enum _teReqs_ @@ -2105,117 +2105,6 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName) } -/* - * Quotes input string if it's not a legitimate SQL identifier as-is. - * - * Note that the returned string must be used before calling fmtId again, - * since we re-use the same return buffer each time. Non-reentrant but - * avoids memory leakage. - */ -const char * -fmtId(const char *rawid) -{ - static PQExpBuffer id_return = NULL; - const char *cp; - bool need_quotes = false; - - if (id_return) /* first time through? */ - resetPQExpBuffer(id_return); - else - id_return = createPQExpBuffer(); - - /* These checks need to match the identifier production in scan.l. - * Don't use islower() etc. */ - - if (ScanKeywordLookup(rawid)) - need_quotes = true; - /* slightly different rules for first character */ - else if (!((rawid[0] >= 'a' && rawid[0] <= 'z') || rawid[0] == '_')) - need_quotes = true; - else - { - /* otherwise check the entire string */ - for (cp = rawid; *cp; cp++) - { - if (!((*cp >= 'a' && *cp <= 'z') - || (*cp >= '0' && *cp <= '9') - || (*cp == '_'))) - { - need_quotes = true; - break; - } - } - } - - if (!need_quotes) - { - /* no quoting needed */ - appendPQExpBufferStr(id_return, rawid); - } - else - { - appendPQExpBufferChar(id_return, '\"'); - for (cp = rawid; *cp; cp++) - { - /* - * Did we find a double-quote in the string? Then make this a - * double double-quote per SQL99. Before, we put in a - * backslash/double-quote pair. - thomas 2000-08-05 - */ - if (*cp == '\"') - appendPQExpBufferChar(id_return, '\"'); - appendPQExpBufferChar(id_return, *cp); - } - appendPQExpBufferChar(id_return, '\"'); - } - - return id_return->data; -} - - -/* - * Convert a string value to an SQL string literal and append it to - * the given buffer. - * - * Special characters are escaped. Quote mark ' goes to '' per SQL - * standard, other stuff goes to \ sequences. If escapeAll is false, - * whitespace characters are not escaped (tabs, newlines, etc.). This - * is appropriate for dump file output. - */ -void -appendStringLiteral(PQExpBuffer buf, const char *str, bool escapeAll) -{ - appendPQExpBufferChar(buf, '\''); - while (*str) - { - char ch = *str++; - - if (ch == '\\' || ch == '\'') - { - appendPQExpBufferChar(buf, ch); /* double these */ - appendPQExpBufferChar(buf, ch); - } - else if ((unsigned char) ch < (unsigned char) ' ' && - (escapeAll - || (ch != '\t' && ch != '\n' && ch != '\v' && ch != '\f' && ch != '\r') - )) - { - /* - * generate octal escape for control chars other than - * whitespace - */ - appendPQExpBufferChar(buf, '\\'); - appendPQExpBufferChar(buf, ((ch >> 6) & 3) + '0'); - appendPQExpBufferChar(buf, ((ch >> 3) & 7) + '0'); - appendPQExpBufferChar(buf, (ch & 7) + '0'); - } - else - appendPQExpBufferChar(buf, ch); - } - appendPQExpBufferChar(buf, '\''); -} - - static int _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData) diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index ed77984e17..f54153d4ae 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -5,7 +5,7 @@ * Implements the basic DB functions used by the archiver. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.38 2002/08/20 17:54:44 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.39 2002/08/27 18:57:26 petere Exp $ * *------------------------------------------------------------------------- */ @@ -13,6 +13,7 @@ #include "pg_backup.h" #include "pg_backup_archiver.h" #include "pg_backup_db.h" +#include "dumputils.h" #include #include diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 645e295aa0..c3a1ace2d0 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -22,7 +22,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.291 2002/08/22 21:35:50 tgl Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.292 2002/08/27 18:57:26 petere Exp $ * *------------------------------------------------------------------------- */ @@ -63,6 +63,7 @@ #include "pg_dump.h" #include "pg_backup.h" #include "pg_backup_archiver.h" +#include "dumputils.h" typedef struct _dumpContext @@ -269,9 +270,9 @@ main(int argc, char **argv) } #ifdef HAVE_GETOPT_LONG - while ((c = getopt_long(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:zZ:V?", long_options, &optindex)) != -1) + while ((c = getopt_long(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:Z:", long_options, &optindex)) != -1) #else - while ((c = getopt(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:zZ:V?-")) != -1) + while ((c = getopt(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:Z:-")) != -1) #endif { @@ -477,7 +478,7 @@ main(int argc, char **argv) if (dumpData == true && oids == true) { write_msg(NULL, "INSERT (-d, -D) and OID (-o) options cannot be used together.\n"); - write_msg(NULL, "(The INSERT command cannot set oids.)\n"); + write_msg(NULL, "(The INSERT command cannot set OIDs.)\n"); exit(1); } @@ -660,9 +661,7 @@ help(const char *progname) " -h, --host=HOSTNAME database server host name\n" " -i, --ignore-version proceed even when server version mismatches\n" " pg_dump version\n" - " -n, --no-quotes suppress most quotes around identifiers\n" - " -N, --quotes enable most quotes around identifiers\n" - " -o, --oids include oids in dump\n" + " -o, --oids include OIDs in dump\n" " -O, --no-owner do not output \\connect commands in plain\n" " text format\n" " -p, --port=PORT database server port number\n" @@ -696,9 +695,7 @@ help(const char *progname) " -h HOSTNAME database server host name\n" " -i proceed even when server version mismatches\n" " pg_dump version\n" - " -n suppress most quotes around identifiers\n" - " -N enable most quotes around identifiers\n" - " -o include oids in dump\n" + " -o include OIDs in dump\n" " -O do not output \\connect commands in plain\n" " text format\n" " -p PORT database server port number\n" diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c new file mode 100644 index 0000000000..5e1e66404c --- /dev/null +++ b/src/bin/pg_dump/pg_dumpall.c @@ -0,0 +1,604 @@ +/*------------------------------------------------------------------------- + * + * pg_dumpall + * + * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.1 2002/08/27 18:57:26 petere Exp $ + * + *------------------------------------------------------------------------- + */ + +#include "postgres_fe.h" + +#include +#ifdef ENABLE_NLS +#include +#endif +#ifdef HAVE_GETOPT_H +#include +#endif +#ifndef HAVE_STRDUP +#include "strdup.h" +#endif +#include + +#include "dumputils.h" +#include "libpq-fe.h" +#include "pg_backup.h" +#include "pqexpbuffer.h" + +#define _(x) gettext((x)) + + +static char *progname; + +static void help(void); +static void dumpUsers(PGconn *conn); +static void dumpGroups(PGconn *conn); +static void dumpCreateDB(PGconn *conn); +static void dumpDatabases(PGconn *conn); +static int runPgDump(const char *dbname); +static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport, + const char *pguser, bool require_password); +static PGresult *executeQuery(PGconn *conn, const char *query); +static char *findPgDump(const char *argv0); + + +char *pgdumploc; +PQExpBuffer pgdumpopts; +bool output_clean = false; +bool verbose = false; + + + +int +main(int argc, char *argv[]) +{ + char *pghost = NULL; + char *pgport = NULL; + char *pguser = NULL; + bool force_password = false; + bool globals_only = false; + PGconn *conn; + int c; + +#ifdef HAVE_GETOPT_LONG + static struct option long_options[] = { + {"clean", no_argument, NULL, 'c'}, + {"inserts", no_argument, NULL, 'd'}, + {"attribute-inserts", no_argument, NULL, 'D'}, + {"column-inserts", no_argument, NULL, 'D'}, + {"host", required_argument, NULL, 'h'}, + {"ignore-version", no_argument, NULL, 'i'}, + {"oids", no_argument, NULL, 'o'}, + {"port", required_argument, NULL, 'p'}, + {"password", no_argument, NULL, 'W'}, + {"username", required_argument, NULL, 'U'}, + {"verbose", no_argument, NULL, 'v'}, + {NULL, 0, NULL, 0} + }; + + int optindex; +#endif + +#ifdef ENABLE_NLS + setlocale(LC_ALL, ""); + bindtextdomain("pg_dump", LOCALEDIR); + textdomain("pg_dump"); +#endif + + if (!strrchr(argv[0], '/')) + progname = argv[0]; + else + progname = strrchr(argv[0], '/') + 1; + + if (argc > 1) + { + if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) + { + help(); + exit(0); + } + if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) + { + puts("pg_dumpall (PostgreSQL) " PG_VERSION); + exit(0); + } + } + + pgdumploc = findPgDump(argv[0]); + pgdumpopts = createPQExpBuffer(); + +#ifdef HAVE_GETOPT_LONG + while ((c = getopt_long(argc, argv, "cdDgh:iop:U:vW", long_options, &optindex)) != -1) +#else + while ((c = getopt(argc, argv, "cdDgh:iop:U:vW")) != -1) +#endif + { + switch (c) + { + case 'c': + output_clean = true; + appendPQExpBuffer(pgdumpopts, " -c"); + break; + + case 'd': + case 'D': + appendPQExpBuffer(pgdumpopts, " -%c", c); + break; + + case 'g': + globals_only = true; + break; + + case 'h': + pghost = optarg; + appendPQExpBuffer(pgdumpopts, " -h '%s'", pghost); + break; + + case 'i': + case 'o': + appendPQExpBuffer(pgdumpopts, " -%c", c); + break; + + case 'p': + pgport = optarg; + appendPQExpBuffer(pgdumpopts, " -p '%s'", pgport); + break; + + case 'U': + pguser = optarg; + appendPQExpBuffer(pgdumpopts, " -U '%s'", pguser); + break; + + case 'v': + verbose = true; + appendPQExpBuffer(pgdumpopts, " -v"); + break; + + case 'W': + force_password = true; + appendPQExpBuffer(pgdumpopts, " -W"); + break; + + default: + fprintf(stderr, _("Try '%s --help' for more information.\n"), progname); + exit(1); + } + } + + if (optind < argc) + { + fprintf(stderr, + _("%s: too many command line options (first is '%s')\n" + "Try '%s --help' for more information.\n"), + progname, argv[optind], progname); + exit(1); + } + + + conn = connectDatabase("template1", pghost, pgport, pguser, force_password); + + printf("--\n"); + printf("-- PostgreSQL database cluster dump\n"); + printf("--\n\n"); + printf("\\connect \"template1\"\n\n"); + + dumpUsers(conn); + dumpGroups(conn); + + if (globals_only) + goto end; + + dumpCreateDB(conn); + dumpDatabases(conn); + +end: + PQfinish(conn); + exit(0); +} + + + +static void +help(void) +{ + printf(_("%s extracts a PostgreSQL database cluster into an SQL script file.\n\n"), progname); + printf(_("Usage:\n")); + printf(_(" %s [OPTIONS]\n\n"), progname); + + printf(_("Options:\n")); +#ifdef HAVE_GETOPT_LONG + printf(_(" -c, --clean clean (drop) schema prior to create\n")); + printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n")); + printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n")); + printf(_(" -g, --globals-only only dump global objects, no databases\n")); + printf(_(" -h, --host=HOSTNAME database server host name\n")); + printf(_(" -i, --ignore-version proceed even when server version mismatches\n" + " pg_dumpall version\n")); + printf(_(" -o, --oids include OIDs in dump\n")); + printf(_(" -p, --port=PORT database server port number\n")); + printf(_(" -U, --username=NAME connect as specified database user\n")); + printf(_(" -v, --verbose verbose mode\n")); + printf(_(" -W, --password force password prompt (should happen automatically)\n")); +#else /* not HAVE_GETOPT_LONG */ + printf(_(" -c clean (drop) schema prior to create\n")); + printf(_(" -d dump data as INSERT, rather than COPY, commands\n")); + printf(_(" -D dump data as INSERT commands with column names\n")); + printf(_(" -g only dump global objects, no databases\n")); + printf(_(" -h HOSTNAME database server host name\n")); + printf(_(" -i proceed even when server version mismatches\n" + " pg_dumpall version\n")); + printf(_(" -o include oids in dump\n")); + printf(_(" -p PORT database server port number\n")); + printf(_(" -U NAME connect as specified database user\n")); + printf(_(" -v verbose mode\n")); + printf(_(" -W force password prompt (should happen automatically)\n")); +#endif /* not HAVE_GETOPT_LONG */ + + printf(_("\nThe SQL script will be written to the standard output.\n\n")); + printf(_("Report bugs to .\n")); +} + + + +/* + * Dump users (but not the user created by initdb). + */ +static void +dumpUsers(PGconn *conn) +{ + PGresult *res; + int i; + + printf("DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');\n\n"); + + res = executeQuery(conn, + "SELECT usename, usesysid, passwd, usecreatedb, usesuper, CAST(valuntil AS timestamp) " + "FROM pg_shadow " + "WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');"); + + for (i = 0; i < PQntuples(res); i++) + { + PQExpBuffer buf = createPQExpBuffer(); + + appendPQExpBuffer(buf, "CREATE USER %s WITH SYSID %s", + fmtId(PQgetvalue(res, i, 0)), + PQgetvalue(res, i, 1)); + + if (!PQgetisnull(res, i, 2)) + { + appendPQExpBuffer(buf, " PASSWORD "); + appendStringLiteral(buf, PQgetvalue(res, i, 2), true); + } + + if (strcmp(PQgetvalue(res, i, 3), "t")==0) + appendPQExpBuffer(buf, " CREATEDB"); + else + appendPQExpBuffer(buf, " NOCREATEDB"); + + if (strcmp(PQgetvalue(res, i, 4), "t")==0) + appendPQExpBuffer(buf, " CREATEUSER"); + else + appendPQExpBuffer(buf, " NOCREATEUSER"); + + if (!PQgetisnull(res, i, 5)) + appendPQExpBuffer(buf, " VALID UNTIL '%s'", PQgetvalue(res, i, 5)); + + appendPQExpBuffer(buf, ";\n"); + + printf("%s", buf->data); + destroyPQExpBuffer(buf); + } + + PQclear(res); + printf("\n\n"); +} + + + +/* + * Dump groups. + */ +static void +dumpGroups(PGconn *conn) +{ + PGresult *res; + int i; + + printf("DELETE FROM pg_group;\n\n"); + + res = executeQuery(conn, "SELECT groname, grosysid, grolist FROM pg_group;"); + + for (i = 0; i < PQntuples(res); i++) + { + PQExpBuffer buf = createPQExpBuffer(); + char *val; + char *tok; + + appendPQExpBuffer(buf, "CREATE GROUP %s WITH SYSID %s;\n", + fmtId(PQgetvalue(res, i, 0)), + PQgetvalue(res, i, 1)); + + val = strdup(PQgetvalue(res, i, 2)); + tok = strtok(val, ",{}"); + do + { + PGresult *res2; + PQExpBuffer buf2 = createPQExpBuffer(); + int j; + + appendPQExpBuffer(buf2, "SELECT usename FROM pg_shadow WHERE usesysid = %s;", tok); + res2 = executeQuery(conn, buf2->data); + destroyPQExpBuffer(buf2); + + for (j = 0; j < PQntuples(res2); j++) + { + appendPQExpBuffer(buf, "ALTER GROUP %s ", fmtId(PQgetvalue(res, i, 0))); + appendPQExpBuffer(buf, "ADD USER %s;\n", fmtId(PQgetvalue(res2, j, 0))); + } + + PQclear(res2); + + tok = strtok(NULL, "{},"); + } + while (tok); + + printf("%s", buf->data); + destroyPQExpBuffer(buf); + } + + PQclear(res); + printf("\n\n"); +} + + + +/* + * Dump commands to create each database. + * + * To minimize the number of reconnections (and possibly ensuing + * password prompts) required by the output script, we emit all CREATE + * DATABASE commands during the initial phase of the script, and then + * run pg_dump for each database to dump the contents of that + * database. We skip databases marked not datallowconn, since we'd be + * unable to connect to them anyway (and besides, we don't want to + * dump template0). + */ +static void +dumpCreateDB(PGconn *conn) +{ + PGresult *res; + int i; + + /* Basically this query returns: dbname, dbowner, encoding, istemplate, dbpath */ + res = executeQuery(conn, "SELECT datname, coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), pg_encoding_to_char(d.encoding), datistemplate, datpath FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) WHERE datallowconn ORDER BY 1;"); + + for (i = 0; i < PQntuples(res); i++) + { + PQExpBuffer buf = createPQExpBuffer(); + char *dbname = PQgetvalue(res, i, 0); + char *dbowner = PQgetvalue(res, i, 1); + char *dbencoding = PQgetvalue(res, i, 2); + char *dbistemplate = PQgetvalue(res, i, 3); + char *dbpath = PQgetvalue(res, i, 4); + + if (strcmp(dbname, "template1")==0) + continue; + + if (output_clean) + appendPQExpBuffer(buf, "DROP DATABASE %s\n;", fmtId(dbname)); + + appendPQExpBuffer(buf, "CREATE DATABASE %s", fmtId(dbname)); + appendPQExpBuffer(buf, " WITH OWNER = %s TEMPLATE = template0", fmtId(dbowner)); + + if (strcmp(dbpath, "")!=0) + { + appendPQExpBuffer(buf, " LOCATION = "); + appendStringLiteral(buf, dbpath, true); + } + + appendPQExpBuffer(buf, " ENCODING = "); + appendStringLiteral(buf, dbencoding, true); + + appendPQExpBuffer(buf, ";\n"); + + if (strcmp(dbistemplate, "t")==0) + { + appendPQExpBuffer(buf, "UPDATE pg_database SET datistemplate = 't' WHERE datname = "); + appendStringLiteral(buf, dbname, true); + appendPQExpBuffer(buf, ";\n"); + } + printf("%s", buf->data); + destroyPQExpBuffer(buf); + } + + PQclear(res); + printf("\n\n"); +} + + + +/* + * Dump contents of databases. + */ +static void +dumpDatabases(PGconn *conn) +{ + PGresult *res; + int i; + + res = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;"); + for (i = 0; i < PQntuples(res); i++) + { + int ret; + + char *dbname = PQgetvalue(res, i, 0); + if (verbose) + fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname); + + printf("\\connect %s\n", fmtId(dbname)); + ret = runPgDump(dbname); + if (ret != 0) + { + fprintf(stderr, _("%s: pg_dump failed on %s, exiting\n"), progname, dbname); + exit(1); + } + } + + PQclear(res); +} + + + +/* + * Run pg_dump on dbname. + */ +static int +runPgDump(const char *dbname) +{ + PQExpBuffer cmd = createPQExpBuffer(); + int ret; + + appendPQExpBuffer(cmd, "%s %s -X use-set-session-authorization -Fp %s", + pgdumploc, pgdumpopts->data, dbname); + if (verbose) + fprintf(stderr, _("%s: running %s\n"), progname, cmd->data); + + ret = system(cmd->data); + destroyPQExpBuffer(cmd); + + return ret; +} + + + +/* + * Make a database connection with the given parameters. An + * interactive password prompt is automatically issued if required. + */ +static PGconn * +connectDatabase(const char *dbname, const char *pghost, const char *pgport, + const char *pguser, bool require_password) +{ + PGconn *conn; + char *password = NULL; + bool need_pass = false; + + if (require_password) + password = simple_prompt("Password: ", 100, false); + + /* + * Start the connection. Loop until we have a password if requested + * by backend. + */ + do + { + need_pass = false; + conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password); + + if (!conn) + { + fprintf(stderr, _("%s: could not connection to database %s\n"), + progname, dbname); + exit(0); + } + + if (PQstatus(conn) == CONNECTION_BAD && + strcmp(PQerrorMessage(conn), "fe_sendauth: no password supplied\n") == 0 && + !feof(stdin)) + { + PQfinish(conn); + need_pass = true; + free(password); + password = NULL; + password = simple_prompt("Password: ", 100, false); + } + } while (need_pass); + + if (password) + free(password); + + /* check to see that the backend connection was successfully made */ + if (PQstatus(conn) == CONNECTION_BAD) + { + fprintf(stderr, _("%s: could not connection to database %s: %s\n"), + progname, dbname, PQerrorMessage(conn)); + exit(0); + } + + return conn; +} + + + +/* + * Run a query, return the results, exit program on failure. + */ +static PGresult * +executeQuery(PGconn *conn, const char *query) +{ + PGresult *res; + + res = PQexec(conn, query); + if (!res || + PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, _("%s: query failed: %s"), progname, PQerrorMessage(conn)); + fprintf(stderr, _("%s: query was: %s"), progname, query); + PQfinish(conn); + exit(1); + } + + return res; +} + + + +/* + * Find location of pg_dump executable. + */ +static char * +findPgDump(const char *argv0) +{ + char *last; + PQExpBuffer cmd; + static char *result = NULL; + + if (result) + return result; + + cmd = createPQExpBuffer(); + last = strrchr(argv0, '/'); + + if (!last) + appendPQExpBuffer(cmd, "pg_dump"); + else + { + char *dir = strdup(argv0); + *(dir + (last - argv0)) = '\0'; + appendPQExpBuffer(cmd, "%s/pg_dump", dir); + } + + result = strdup(cmd->data); + + appendPQExpBuffer(cmd, " -V >/dev/null 2>&1"); + if (system(cmd->data)==0) + goto end; + + result = BINDIR "/pg_dump"; + if (system(BINDIR "/pg_dump -V >/dev/null 2>&1")==0) + goto end; + + fprintf(stderr, _("%s: could not find pg_dump\n" + "Make sure it is in the path or in the same directory as %s.\n"), + progname, progname); + exit(1); + +end: + destroyPQExpBuffer(cmd); + return result; +} diff --git a/src/bin/pg_dump/pg_dumpall.sh b/src/bin/pg_dump/pg_dumpall.sh deleted file mode 100644 index 6a8ec8d3eb..0000000000 --- a/src/bin/pg_dump/pg_dumpall.sh +++ /dev/null @@ -1,289 +0,0 @@ -#! /bin/sh - -# pg_dumpall -# -# Dumps all databases to standard output. It also dumps the "pg_shadow" -# and "pg_group" tables, which belong to the whole installation rather -# than any one individual database. -# -# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_dumpall.sh,v 1.21 2002/04/12 09:37:10 momjian Exp $ - -CMDNAME="`basename $0`" - -# substituted at build -VERSION='@VERSION@' -MULTIBYTE='@MULTIBYTE@' -bindir='@bindir@' - -# These handle spaces/tabs in identifiers -_IFS="$IFS" -NL=" -" - -# -# Find out where we're located -# -PGPATH= -if echo "$0" | grep '/' > /dev/null 2>&1 ; then - # explicit dir name given - PGPATH=`echo "$0" | sed 's,/[^/]*$,,'` # (dirname command is not portable) -else - # look for it in PATH ('which' command is not portable) - echo "$PATH" | sed "s/:/$NL/g" | - while :; do - IFS="$NL" - read dir || break - IFS="$_IFS" - # empty entry in path means current dir - [ x"$dir" = x ] && dir='.' - if [ -f "$dir/$CMDNAME" ] ; then - PGPATH="$dir" - break - fi - done -fi -IFS="$_IFS" - -# As last resort use the installation directory. We don't want to use -# this as first resort because depending on how users do release upgrades -# they might temporarily move the installation tree elsewhere, so we'd -# accidentally invoke the newly installed versions of pg_dump and psql. -if [ x"$PGPATH" = x"" ]; then - PGPATH="$bindir" -fi - -# -# Look for needed programs -# -for prog in pg_dump psql ; do - if [ ! -x "$PGPATH/$prog" ] ; then - ( - echo "The program $prog needed by $CMDNAME could not be found. It was" - echo "expected at:" - echo " $PGPATH/$prog" - echo "If this is not the correct directory, please start $CMDNAME" - echo "with a full search path. Otherwise make sure that the program" - echo "was installed successfully." - ) 1>&2 - exit 1 - fi -done - -# -# to adapt to System V vs. BSD 'echo' -# -if echo '\\' | grep '\\\\' >/dev/null 2>&1 -then - BS='\' dummy='\' # BSD -else - BS='\\' # System V -fi -# The dummy assignment is necessary to prevent Emacs' font-lock -# mode from going ballistic when editing this file. - - -usage= -cleanschema= -globals_only= - - -while [ "$#" -gt 0 ] ; do - case "$1" in - --help) - usage=t - break - ;; - --version) - echo "pg_dumpall (PostgreSQL) $VERSION" - exit 0 - ;; - --host|-h) - connectopts="$connectopts -h $2" - shift;; - -h*) - connectopts="$connectopts $1" - ;; - --host=*) - connectopts="$connectopts -h `echo $1 | sed 's/^--host=//'`" - ;; - --port|-p) - connectopts="$connectopts -p $2" - shift;; - -p*) - connectopts="$connectopts $1" - ;; - --port=*) - connectopts="$connectopts -p `echo $1 | sed 's/^--port=//'`" - ;; - --user|--username|-U) - connectopts="$connectopts -U $2" - shift;; - -U*) - connectopts="$connectopts $1" - ;; - --user=*|--username=*) - connectopts="$connectopts -U `echo $1 | sed 's/^--user[^=]*=//'`" - ;; - -W|--password) - connectopts="$connectopts -W" - ;; - - -c|--clean) - cleanschema=yes - pgdumpextraopts="$pgdumpextraopts -c" - ;; - -g|--globals-only) - globals_only=yes - ;; - -F*|--format=*|-f|--file=*|-t|--table=*) - echo "pg_dump can not process option $1, exiting" 1>&2 - exit 1 - ;; - *) - pgdumpextraopts="$pgdumpextraopts $1" - ;; - esac - shift -done - - -if [ "$usage" ] ; then - echo "$CMDNAME extracts a PostgreSQL database cluster into an SQL script file." - echo - echo "Usage:" - echo " $CMDNAME [ options... ]" - echo - echo "Options:" - echo " -c, --clean Clean (drop) schema prior to create" - echo " -g, --globals-only Only dump global objects, no databases" - echo " -h, --host=HOSTNAME Server host name" - echo " -p, --port=PORT Server port number" - echo " -U, --username=NAME Connect as specified database user" - echo " -W, --password Force password prompts (should happen automatically)" - echo "Any other options will be passed to pg_dump. The dump will be written" - echo "to the standard output." - echo - echo "Report bugs to ." - exit 0 -fi - - -PSQL="${PGPATH}/psql $connectopts" -PGDUMP="${PGPATH}/pg_dump $connectopts $pgdumpextraopts -X use-set-session-authorization -Fp" - - -echo "--" -echo "-- pg_dumpall ($VERSION) $connectopts $pgdumpextraopts" -echo "--" -echo "${BS}connect \"template1\"" - -# -# Dump users (but not the user created by initdb) -# -echo "DELETE FROM pg_shadow WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');" -echo - -echo "connected to template1..." 1>&2 -$PSQL -d template1 -At -c "\ -SELECT - 'CREATE USER \"' || usename || '\" WITH SYSID ' || usesysid - || CASE WHEN passwd IS NOT NULL THEN ' PASSWORD ''' || passwd || '''' else '' end - || CASE WHEN usecreatedb THEN ' CREATEDB'::text ELSE ' NOCREATEDB' END - || CASE WHEN usesuper THEN ' CREATEUSER'::text ELSE ' NOCREATEUSER' END - || CASE WHEN valuntil IS NOT NULL THEN ' VALID UNTIL '''::text - || CAST(valuntil AS TIMESTAMP) || '''' ELSE '' END || ';' -FROM pg_shadow -WHERE usesysid <> (SELECT datdba FROM pg_database WHERE datname = 'template0');" \ -|| exit 1 -echo - -# -# Dump groups -# -echo "DELETE FROM pg_group;" -echo - - -$PSQL -d template1 -At -F "$NL" \ - -c 'SELECT groname,grosysid,grolist FROM pg_group;' | \ -while : ; do - IFS="$NL" - read GRONAME || break - read GROSYSID || break - read GROLIST || break - IFS="$_IFS" - echo "CREATE GROUP \"$GRONAME\" WITH SYSID ${GROSYSID};" - echo "$GROLIST" | sed 's/^{\(.*\)}$/\1/' | tr ',' '\n' | - while read userid; do - username="`$PSQL -d template1 -At -c \"SELECT usename FROM pg_shadow WHERE usesysid = ${userid};\"`" - echo " ALTER GROUP \"$GRONAME\" ADD USER \"$username\";" - done -done -IFS="$_IFS" - -test "$globals_only" = yes && exit 0 - - -# Save stdin for pg_dump password prompts. -exec 4<&0 - -# To minimize the number of reconnections (and possibly ensuing password -# prompts) required by the output script, we emit all CREATE DATABASE -# commands during the initial phase of the script, and then run pg_dump -# for each database to dump the contents of that database. -# We skip databases marked not datallowconn, since we'd be unable to -# connect to them anyway (and besides, we don't want to dump template0). - -$PSQL -d template1 -At -F "$NL" \ - -c "SELECT datname, coalesce(usename, (select usename from pg_shadow where usesysid=(select datdba from pg_database where datname='template0'))), pg_encoding_to_char(d.encoding), datistemplate, datpath FROM pg_database d LEFT JOIN pg_shadow u ON (datdba = usesysid) WHERE datallowconn ORDER BY 1;" | \ -while : ; do - IFS="$NL" - read DATABASE || break - read DBOWNER || break - read ENCODING || break - read ISTEMPLATE || break - read DBPATH || break - IFS="$_IFS" - if [ "$DATABASE" != template1 ] ; then - echo - - if [ "$cleanschema" = yes ] ; then - echo "DROP DATABASE \"$DATABASE\";" - fi - - createdbcmd="CREATE DATABASE \"$DATABASE\" WITH OWNER = \"$DBOWNER\" TEMPLATE = template0" - if [ x"$DBPATH" != x"" ] ; then - createdbcmd="$createdbcmd LOCATION = '$DBPATH'" - fi - if [ x"$MULTIBYTE" != x"" ] ; then - createdbcmd="$createdbcmd ENCODING = '$ENCODING'" - fi - echo "$createdbcmd;" - if [ x"$ISTEMPLATE" = xt ] ; then - echo "UPDATE pg_database SET datistemplate = 't' WHERE datname = '$DATABASE';" - fi - fi -done -IFS="$_IFS" - -$PSQL -d template1 -At -F "$NL" \ - -c "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;" | \ -while :; do - IFS="$NL" - read DATABASE || break - IFS="$_IFS" - echo "dumping database \"$DATABASE\"..." 1>&2 - echo - echo "--" - echo "-- Database $DATABASE" - echo "--" - echo "${BS}connect \"$DATABASE\"" - - $PGDUMP "$DATABASE" <&4 - if [ "$?" -ne 0 ] ; then - echo "pg_dump failed on $DATABASE, exiting" 1>&2 - exit 1 - fi -done - -exit 0 diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 319af0a987..f6602ff9e7 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -34,13 +34,14 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.38 2002/08/10 16:57:32 petere Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.39 2002/08/27 18:57:26 petere Exp $ * *------------------------------------------------------------------------- */ #include "pg_backup.h" #include "pg_backup_archiver.h" +#include "dumputils.h" #include