#! /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