#!/usr/bin/perl -w

use strict;
use Getopt::Std;
use DBI;

sub usage {
    if (my $msg = shift) { print STDERR $msg, "\n\n" }
    print STDERR <<USAGE;
usage:	$0 [options] dbname dst-dir
	-c	clean (drop) schema prior to create
	-C	output commands to create database
	-d	dump data as INSERT, rather than COPY, commands
	-D	dump data as INSERT commands with attribute names
	-h HOST	server host name
	-n	suppress most quotes around identifiers
	-N	enable most quotes around identifiers
	-o	dump object ids (oids)
	-O	do not output \\connect commands
	-p PORT	server port number
	-U USER	database user to connect as
	-v	verbose output
	-x	do not dump ACL's (grant/revoke)
USAGE
    exit 1;
}

my %opts;
my $pg_dump = '/usr/local/bin/pg_dump';

sub dump_schema {
    my ($dbname, $dstdir) = @_;
    my @opts = ();
    print STDERR "Dumping schema of $dbname..."	if $opts{v};
    foreach my $arg (qw(h p U)) {
	push @opts, "-$arg" => $opts{$arg}	if $opts{$arg};
    }
    foreach my $arg (qw(c C n N o O x)) {
	push @opts, "-$arg"	if $opts{$arg};
    }
    push @opts, '-f' => "$dstdir/$dbname-schema.sql";
    push @opts, '-s'; # --schema-only

    system($pg_dump, @opts, $dbname) == 0
	or die "pg_dump failed on schema\n";
    print STDERR " done.\n"			if $opts{v}
}

sub dump_table {
    my ($dbname, $table, $dstdir) = @_;

    print STDERR "Dumping data: $table..."	if $opts{v};
    my @opts = ();
    foreach my $arg (qw(h p U)) {
	push @opts, "-$arg" => $opts{$arg}	if $opts{$arg};
    }
    foreach my $arg (qw(d D n N o O)) {
	push @opts, "-$arg"	if $opts{$arg};
    }
    push @opts, '-f' => "$dstdir/$dbname-data-$table.sql";
    push @opts, '-a'; # --data-only
    push @opts, '-t' => $table;

    system($pg_dump, @opts, $dbname) == 0
	or die "pg_dump failed on table $table\n";
    print STDERR " done.\n"			if $opts{v}
}


getopts('cCdDh:nNoOp:U:vx', \%opts)	or usage("parameter error");
my $dbname = shift @ARGV		or usage("no database name");
my $dstdir = shift @ARGV		or usage("no destination dir");
@ARGV					and usage("extra args");

#use Data::Dumper;
#print Dumper(\%opts, $dbname, $dstdir);

dump_schema($dbname, $dstdir);

my $dbh = DBI->connect("DBI:Pg:dbname=$dbname", $opts{U})
    or die "connect: $DBI::errstr\n";
my $tables = $dbh->selectcol_arrayref(q{
	SELECT	*
	FROM	pg_class
	WHERE	relkind = 'r'
	    AND	relname !~ '^pg_'
    })
	or die "Can't list tables: $DBI::errstr\n";
$dbh->disconnect;

foreach my $table (@$tables) {
    dump_table($dbname, $table, $dstdir);
}
