#!/usr/bin/perl

# split PostgreSQL dump into individual files for backup with git
#
# 09/11/08 20:10:39 CEST Dobrica Pavlinusic <dpavlin@rot13.org>

use warnings;
use strict;

use Getopt::Long;
use Fatal qw/:void open close mkdir chdir/;
my $git = '/tmp/pgsql-git-backup/';
my $verbose = 0;
my $database = '';
my $repack = 0;

my $usage = "Usage: $0 --database name < name-dump.sql\n";

GetOptions(
	'git=s'		=> \$git,
	'database=s'	=> \$database,
	'verbose+'	=> \$verbose,
	'repack'	=> \$repack,
) or die $usage;

die $usage unless $database;

my $nr = 0;
my $name = $database;

sub git {
	my $cmd = shift or die "no cmd?";
	system($cmd) == 0 or die "$cmd FAILED $?";
}

sub dump_path {
	return sprintf("%s/%04d%s.sql", $database, $nr, $name);
}

mkdir $git if ! -e $git;

chdir $git;
warn "## using $git\n" if $verbose;

git 'git-init-db' if ! -e "$git/.git";

if ( ! -e $database ) {
	mkdir $database;
#	git "git-add '$database'";
#	git "git-commit -m 'added $database directory' $database";
}

my $sort_fh;
my $fh;

open($fh, '>', dump_path);

while(<STDIN>) {
	if ( $sort_fh ) {
		print $sort_fh $_;
		if ( /^\\\.$/ ) {
			close($sort_fh);
			undef $sort_fh;
			open($fh, '>>', dump_path);
			print $fh $_;
		}
		next;
	}

	if (/-- (.*)Name: (\w+);.*Schema: (\w+)/) {
		close($fh);
		my $path = dump_path;
		warn "> $path ", -s $path, "\n" if $verbose;
		git "git-add '$path'";

		$nr++;
		$name = ' ' . $3 . '.' . $2;
#		$name .= '-data' if $1;
		open($fh, '>', dump_path);
	}
	if (/^COPY/) {
		print $fh $_;
		close($fh);

		my $cmd = '| sort -n >> \'' . $git . '/' . dump_path . '\'';
		warn "## sorting using $cmd\n" if $verbose;
		open( $sort_fh, $cmd );
		next;
	} else {
		print $fh $_;
	}
}

close($fh);

git "git-commit -m '$database' '$database'";

git "git-repack" if $repack;

