# -*- perl -*-
# ers_addtable
# Copyright (C) 2002 Digital Distribution GFS P/L
# Derived from code Copyright (C) 2000 PostgreSQL, Inc.

eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
    & eval 'exec perl -S $0 $argv:q'
    if 0;

use Getopt::Long;
use DBI;
use lib "@prefix@/lib";
use eRServer;

$| = 1;

$result = GetOptions("debug!", "quiet!", "help", "table=s");

$RServ::debug = $opt_debug || 0;

if (defined($opt_help)  || !defined($opt_table) ) {
    print "Usage: $0 --table=<table to replicate>\n";
    exit ((scalar(@ARGV) < 1)? 1:0);
}

my $table = $opt_table;

chdir("@prefix@/bin");

if( ! -f "@prefix@/etc/replication.cfg") {
  printf"
WARNING: @prefix@/etc/replication.cfg doesn't exist,
         which means that this server has not yet been
         configured\n\n";
  exit(1);
}

$replic = &eRServer::ReadConfig();

my $quiet	= 1 if $opt_quiet;

$masterserver = (split(/:/, (split(/\//, $replic->{'replic.master.JDBCConnectionURL'}))[2]))[0];
$masterport   = (split(/:/, (split(/\//, $replic->{'replic.master.JDBCConnectionURL'}))[2]))[1];
$masterdb     = (split(/\//, $replic->{'replic.master.JDBCConnectionURL'}))[3];
$masteruser   = $replic->{'replic.master.user'};
$masterpass   = $replic->{'replic.master.password'};
 
# Display a banner to the user
if(!$quiet) {
  print "\nPostgreSQL Enterprise Replication Server 1.20\n";
  print "   Copyright (C) 2001-2002 PostgreSQL, Inc\n";
  print "*********************************************\n";
  print "\nAdding new table...\n\n";
}

my $master = DBI->connect("dbi:Pg:dbname=$masterdb;host=$masterserver;port=$masterport", $masteruser, $masterpass)
	|| die "Connection to master database failed: ", $DBI::errstr, "\n";
$master->{AutoCommit} = 0;

#check if table exists in master
$rows = $master->prepare("SELECT relname FROM pg_class WHERE relname = ?;");
$rows->execute($table);
if($rows->rows == 0) {
  if(!$quiet) {
    print "${table} does not exist\n";
  }
  exit(1);
}

#check if table already contains the _ers_uniq field
$rows = $master->prepare("SELECT pga.attname 
                            FROM pg_class pgc, pg_attribute pga 
                           WHERE pgc.relname = ?
                             AND pgc.oid = pga.attrelid 
                             AND pga.attname = '_ers_uniq';");
$rows->execute($table);
if($rows->rows == 0) {
  $master->do("LOCK ${table} IN EXCLUSIVE MODE;") || die $master->errstr;
  $master->do("ALTER TABLE ${table} ADD COLUMN _ers_uniq BIGINT;") || die $master->errstr;
  $master->do("CREATE SEQUENCE _ers_${table}_seq;") || die $master->errstr;
  $master->do("ALTER TABLE ${table} ALTER COLUMN _ers_uniq SET DEFAULT NEXTVAL('\"_ers_${table}_seq\"');") || die $master->errstr;
  $master->do("UPDATE ${table} SET _ers_uniq = nextval('\"_ers_${table}_seq\"') WHERE _ers_uniq IS NULL;") || die $master->errstr;
  $master->do("ALTER TABLE ${table} ADD CONSTRAINT _ers_uniq_cons CHECK (_ers_uniq IS NOT NULL);") || die $master->errstr;
  $master->do("CREATE UNIQUE INDEX _ers_${table}_idx ON ${table} (_ers_uniq)") || die $master->errstr;

  $mtable = $master->prepare("SELECT pgc.oid, pga.attnum 
                                FROM pg_class pgc, pg_attribute pga 
                               WHERE pgc.relname = ?
                                 AND pgc.oid = pga.attrelid
                                 AND pga.attname = '_ers_uniq'");
  $mtable->execute($table);
  ( $m_oid, $m_attnum ) = $mtable->fetchrow_array();
  $mtable->finish();

  $master->do("CREATE TRIGGER _RSERV_TRIGGER_T_ 
                        AFTER insert or update or delete on ${table}
                          for each row execute procedure _rserv_log_('${m_attnum}')") || die $master->errstr;

  $master->do("INSERT INTO _rserv_tables_ (tname, cname, reloid, key) VALUES ('${table}', '_ers_uniq', ${m_oid}, ${m_attnum})") 
  	|| die $master->errstr;

  $master->commit();
}

$rows->finish();
$master->disconnect();

for($ii=0;$ii<$replic->{'replic.master.ConnectionPoolSize'};$ii++) {

  $slaveserver = (split(/:/, (split(/\//, (split(/,/, $replic->{'replic.slave.JDBCConnectionURL'}))[$ii]))[2]))[0];
  $slaveport   = (split(/:/, (split(/\//, (split(/,/, $replic->{'replic.slave.JDBCConnectionURL'}))[$ii]))[2]))[1];
  $slavedb     = (split(/\//, (split(/,/, $replic->{'replic.slave.JDBCConnectionURL'}))[$ii]))[3];
  $slaveuser   = (split(/,/, $replic->{'replic.slave.user'}))[$ii];
  $slavepass   = (split(/,/, $replic->{'replic.slave.password'}))[$ii];


  my $slave = DBI->connect("dbi:Pg:dbname=$slavedb;host=$slaveserver;port=$slaveport", $slaveuser, $slavepass);
  $slave->{AutoCommit} = 0;
  if(!defined($slave)) {
    if(!$quiet) {
      print "Connection to slave server failed: ", $DBI::errstr, "\n";
    }
    exit(1);
  }

  #check if table exists in master
  $rows = $slave->prepare("SELECT relname FROM pg_class WHERE relname = ?;");
  $rows->execute($table);
  if($rows->rows == 0) {
    &eRServer::CopyTbl($masteruser, $masterdb, $master, $slave, $table);
  }
  $rows->finish();

  $slave->commit();
  $slave->disconnect();
}

# Let the user know that the table was added
if(!$quiet) {
  print "Table '${table}' added\n\n";
}

exit(0);
