mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-05 19:09:58 +08:00
Reimplement pg_dumpall in C. Currently no change in functionality,
except that it's more robust, reconnects less often, and is NLS'ed.
This commit is contained in:
parent
6deb649cd3
commit
7af5ea736f
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.48 2002/08/18 09:36:25 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.49 2002/08/27 18:57:26 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -112,13 +112,13 @@ PostgreSQL documentation
|
|||||||
does not block other users accessing the database (readers or
|
does not block other users accessing the database (readers or
|
||||||
writers).
|
writers).
|
||||||
</para>
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
<refsect2 id="pg-dump-options">
|
<refsect1 id="pg-dump-options">
|
||||||
<title>Options</title>
|
<title>Options</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>pg_dump</command> accepts the following command
|
The following command-line options are used to control the output format.
|
||||||
line arguments. (Long option forms are only available on some platforms.)
|
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -408,7 +408,9 @@ PostgreSQL documentation
|
|||||||
<term><option>--verbose</></term>
|
<term><option>--verbose</></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies verbose mode.
|
Specifies verbose mode. This will cause
|
||||||
|
<application>pg_dump</application> to print progress messages
|
||||||
|
to standard error.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -499,13 +501,11 @@ PostgreSQL documentation
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>pg_dump</command> also accepts
|
The following command-line options control the database connection parameters.
|
||||||
the following command line arguments for connection parameters:
|
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -555,8 +555,10 @@ PostgreSQL documentation
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
</refsect2>
|
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Long option forms are only available on some platforms.
|
||||||
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.31 2002/08/27 03:55:17 momjian Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dumpall.sgml,v 1.32 2002/08/27 18:57:26 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -12,18 +12,13 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>pg_dumpall</refname>
|
<refname>pg_dumpall</refname>
|
||||||
<refpurpose>extract all <productname>PostgreSQL</productname> databases into a script file</refpurpose>
|
<refpurpose>extract a <productname>PostgreSQL</productname> database cluster into a script file</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
<command>pg_dumpall</command>
|
<command>pg_dumpall</command>
|
||||||
<group><arg>-c</arg><arg>--clean</arg></group>
|
<arg rep="repeat"><replaceable>options</replaceable></arg>
|
||||||
<group><arg>-g</arg><arg>--globals-only</arg></group>
|
|
||||||
<arg>-h <replaceable>host</replaceable></arg>
|
|
||||||
<arg>-p <replaceable>port</replaceable></arg>
|
|
||||||
<arg>-U <replaceable>username</replaceable></arg>
|
|
||||||
<arg>-W</arg>
|
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -66,97 +61,161 @@ PostgreSQL documentation
|
|||||||
The SQL script will be written to the standard output. Shell
|
The SQL script will be written to the standard output. Shell
|
||||||
operators should be used to redirect it into a file.
|
operators should be used to redirect it into a file.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<application>pg_dumpall</application> will need to connect several times to the
|
|
||||||
<productname>PostgreSQL</productname> server, asking for the password each
|
|
||||||
time. It will probably be very convenient to have a PGPASSWORDFILE in that case.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Options</title>
|
<title>Options</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
<application>pg_dumpall</application> accepts the following
|
The following command-line options are used to control the output format.
|
||||||
command line arguments:
|
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-c, --clean</term>
|
<term>-c, --clean</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Include SQL commands to clean (drop) database objects before
|
Include SQL commands to clean (drop) database objects before
|
||||||
recreating them. (This option is fairly useless, since the
|
recreating them. (This option is fairly useless, since the
|
||||||
output script expects to create the databases themselves;
|
output script expects to create the databases themselves;
|
||||||
they would always be empty upon creation.)
|
they would always be empty upon creation.)
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-g, --globals-only</term>
|
<term><option>-d</option></term>
|
||||||
<listitem>
|
<term><option>--inserts</option></term>
|
||||||
<para>
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Dump data as <command>INSERT</command> commands (rather
|
||||||
|
than <command>COPY</command>). This will make restoration very
|
||||||
|
slow, but it makes the output more portable to other RDBMS
|
||||||
|
packages.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-D</option></term>
|
||||||
|
<term><option>--column-inserts</option></term>
|
||||||
|
<term><option>--attribute-inserts</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Dump data as <command>INSERT</command> commands with explicit
|
||||||
|
column names (<literal>INSERT INTO
|
||||||
|
<replaceable>table</replaceable>
|
||||||
|
(<replaceable>column</replaceable>, ...) VALUES
|
||||||
|
...</literal>). This will make restoration very slow,
|
||||||
|
but it is necessary if you desire to rearrange column ordering.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>-g, --globals-only</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
Only dump global objects (users and groups), no databases.
|
Only dump global objects (users and groups), no databases.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-h <replaceable>host</replaceable></term>
|
<term><option>-i</></term>
|
||||||
<listitem>
|
<term><option>--ignore-version</></term>
|
||||||
<para>
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Ignore version mismatch between
|
||||||
|
<application>pg_dumpall</application> and the database server.
|
||||||
|
Since <application>pg_dumpall</application> knows a great deal
|
||||||
|
about system catalogs, any given version of
|
||||||
|
<application>pg_dumpall</application> 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
|
||||||
|
<application>pg_dumpall</application> then fails, don't say
|
||||||
|
you weren't warned).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-o</></term>
|
||||||
|
<term><option>--oids</></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Dump object identifiers (<acronym>OID</acronym>s) 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.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-v</></term>
|
||||||
|
<term><option>--verbose</></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specifies verbose mode. This will cause
|
||||||
|
<application>pg_dumpall</application> to print progress
|
||||||
|
messages to standard error.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The following command-line options control the database connection parameters.
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>-h <replaceable>host</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
Specifies the host name of the machine on which the database
|
Specifies the host name of the machine on which the database
|
||||||
server is running. If host begins with a slash, it is used as
|
server is running. If host begins with a slash, it is used as
|
||||||
the directory for the Unix domain socket. The default is
|
the directory for the Unix domain socket. The default is
|
||||||
taken from the <envar>PGHOST</envar> environment variable, if
|
taken from the <envar>PGHOST</envar> environment variable, if
|
||||||
set, else a Unix domain socket connection is attempted.
|
set, else a Unix domain socket connection is attempted.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-p <replaceable>port</replaceable></term>
|
<term>-p <replaceable>port</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The port number on which the server is listening. Defaults to
|
The port number on which the server is listening. Defaults to
|
||||||
the <envar>PGPORT</envar> environment variable, if set, or a
|
the <envar>PGPORT</envar> environment variable, if set, or a
|
||||||
compiled-in default.
|
compiled-in default.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-U <replaceable>username</replaceable></term>
|
<term>-U <replaceable>username</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Connect as the given user.
|
Connect as the given user.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-W</term>
|
<term>-W</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Force a password prompt. This should happen automatically if
|
Force a password prompt. This should happen automatically if
|
||||||
the server requires password authentication.
|
the server requires password authentication.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Any other command line parameters are passed to the underlying
|
Long options are only available on some platforms.
|
||||||
<xref linkend="app-pgdump">
|
|
||||||
calls. This is useful to control some aspects of the output
|
|
||||||
format, but some options such as <option>-f</option>,
|
|
||||||
<option>-F</option>, <option>-t</option>, and <replaceable
|
|
||||||
class="parameter">dbname</replaceable> should be avoided.
|
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
@ -180,6 +239,26 @@ PostgreSQL documentation
|
|||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Since <application>pg_dumpall</application> calls
|
||||||
|
<application>pg_dump</application> internally, some diagnostic
|
||||||
|
messages will refer to <application>pg_dump</application>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<application>pg_dumpall</application> will need to connect several
|
||||||
|
times to the <productname>PostgreSQL</productname> 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.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<comment>But where is that password file documented?</comment>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
|
||||||
<refsect1 id="app-pg-dumpall-ex">
|
<refsect1 id="app-pg-dumpall-ex">
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
<para>
|
<para>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
|
||||||
# Portions Copyright (c) 1994, Regents of the University of California
|
# 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
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
|
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
|
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
|
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
|
pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a
|
||||||
$(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@
|
$(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@
|
||||||
|
|
||||||
pg_dumpall: pg_dumpall.sh
|
pg_dumpall: pg_dumpall.o $(libpq_builddir)/libpq.a
|
||||||
sed -e 's,@VERSION@,$(VERSION),g' \
|
$(CC) $(CFLAGS) pg_dumpall.o dumputils.o sprompt.o $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@
|
||||||
-e 's,@MULTIBYTE@,$(MULTIBYTE),g' \
|
|
||||||
-e 's,@bindir@,$(bindir),g' \
|
|
||||||
$< >$@
|
|
||||||
chmod a+x $@
|
|
||||||
|
|
||||||
.PHONY: submake-backend
|
.PHONY: submake-backend
|
||||||
submake-backend:
|
submake-backend:
|
||||||
@ -44,13 +41,13 @@ submake-backend:
|
|||||||
install: all installdirs
|
install: all installdirs
|
||||||
$(INSTALL_PROGRAM) pg_dump$(X) $(DESTDIR)$(bindir)/pg_dump$(X)
|
$(INSTALL_PROGRAM) pg_dump$(X) $(DESTDIR)$(bindir)/pg_dump$(X)
|
||||||
$(INSTALL_PROGRAM) pg_restore$(X) $(DESTDIR)$(bindir)/pg_restore$(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:
|
installdirs:
|
||||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||||
|
|
||||||
uninstall:
|
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:
|
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
|
||||||
|
131
src/bin/pg_dump/dumputils.c
Normal file
131
src/bin/pg_dump/dumputils.c
Normal file
@ -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, '\'');
|
||||||
|
}
|
26
src/bin/pg_dump/dumputils.h
Normal file
26
src/bin/pg_dump/dumputils.h
Normal file
@ -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
|
@ -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
|
CATALOG_NAME := pg_dump
|
||||||
AVAIL_LANGUAGES := cs de ru sv zh_CN zh_TW
|
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 \
|
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_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 \
|
GETTEXT_TRIGGERS:= write_msg:2 die_horribly:3 exit_horribly:3 simple_prompt \
|
||||||
ExecuteSqlCommand:3 ahlog:3
|
ExecuteSqlCommand:3 ahlog:3 _
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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,...)
|
exit_horribly(Archive *AH, const char *modulename, const char *fmt,...)
|
||||||
__attribute__((format(printf, 3, 4)));
|
__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 */
|
/* Lets the archive know we have a DB connection to shutdown if it dies */
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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_dump.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "pg_backup_db.h"
|
#include "pg_backup_db.h"
|
||||||
|
#include "dumputils.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h> /* for dup */
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "pqexpbuffer.h"
|
#include "pqexpbuffer.h"
|
||||||
#include "libpq/libpq-fs.h"
|
#include "libpq/libpq-fs.h"
|
||||||
#include "parser/keywords.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum _teReqs_
|
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
|
static int
|
||||||
_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData)
|
_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Implements the basic DB functions used by the archiver.
|
* Implements the basic DB functions used by the archiver.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "pg_backup_db.h"
|
#include "pg_backup_db.h"
|
||||||
|
#include "dumputils.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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_dump.h"
|
||||||
#include "pg_backup.h"
|
#include "pg_backup.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
|
#include "dumputils.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct _dumpContext
|
typedef struct _dumpContext
|
||||||
@ -269,9 +270,9 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT_LONG
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -477,7 +478,7 @@ main(int argc, char **argv)
|
|||||||
if (dumpData == true && oids == true)
|
if (dumpData == true && oids == true)
|
||||||
{
|
{
|
||||||
write_msg(NULL, "INSERT (-d, -D) and OID (-o) options cannot be used together.\n");
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,9 +661,7 @@ help(const char *progname)
|
|||||||
" -h, --host=HOSTNAME database server host name\n"
|
" -h, --host=HOSTNAME database server host name\n"
|
||||||
" -i, --ignore-version proceed even when server version mismatches\n"
|
" -i, --ignore-version proceed even when server version mismatches\n"
|
||||||
" pg_dump version\n"
|
" pg_dump version\n"
|
||||||
" -n, --no-quotes suppress most quotes around identifiers\n"
|
" -o, --oids include OIDs in dump\n"
|
||||||
" -N, --quotes enable most quotes around identifiers\n"
|
|
||||||
" -o, --oids include oids in dump\n"
|
|
||||||
" -O, --no-owner do not output \\connect commands in plain\n"
|
" -O, --no-owner do not output \\connect commands in plain\n"
|
||||||
" text format\n"
|
" text format\n"
|
||||||
" -p, --port=PORT database server port number\n"
|
" -p, --port=PORT database server port number\n"
|
||||||
@ -696,9 +695,7 @@ help(const char *progname)
|
|||||||
" -h HOSTNAME database server host name\n"
|
" -h HOSTNAME database server host name\n"
|
||||||
" -i proceed even when server version mismatches\n"
|
" -i proceed even when server version mismatches\n"
|
||||||
" pg_dump version\n"
|
" pg_dump version\n"
|
||||||
" -n suppress most quotes around identifiers\n"
|
" -o include OIDs in dump\n"
|
||||||
" -N enable most quotes around identifiers\n"
|
|
||||||
" -o include oids in dump\n"
|
|
||||||
" -O do not output \\connect commands in plain\n"
|
" -O do not output \\connect commands in plain\n"
|
||||||
" text format\n"
|
" text format\n"
|
||||||
" -p PORT database server port number\n"
|
" -p PORT database server port number\n"
|
||||||
|
604
src/bin/pg_dump/pg_dumpall.c
Normal file
604
src/bin/pg_dump/pg_dumpall.c
Normal file
@ -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 <unistd.h>
|
||||||
|
#ifdef ENABLE_NLS
|
||||||
|
#include <locale.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GETOPT_H
|
||||||
|
#include <getopt.h>
|
||||||
|
#endif
|
||||||
|
#ifndef HAVE_STRDUP
|
||||||
|
#include "strdup.h"
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#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 <pgsql-bugs@postgresql.org>.\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;
|
||||||
|
}
|
@ -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 <pgsql-bugs@postgresql.org>."
|
|
||||||
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
|
|
@ -34,13 +34,14 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
|
#include "dumputils.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user