# -*- cperl -*-
#
# async cancel test script
#

#*  uses
#
use DBI;
use DBD::PgAsync	':async';
use Encode;

#*  constants
#
use constant CSPEC_PRF =>	'dbi:PgAsync:';
use constant SECS =>		qw(1 4 7);

use constant R_CMD =>		0;
use constant R_WHATIS =>	1;

#*  subs
#
sub msg
{
    my $msg;

    $msg = sprintf($_[0], @_[1 .. $#_]);
    print STDERR ($msg, "\n");
}

sub wait_for
{
    my ($fd, $what) = @_;
    my ($rin, $win, $vec, $nf);
    
    vec($vec, $fd, 1) = 1;
    if ($what == 1) {
        $rin = $vec;
    } else {
        $win = $vec;
    }

    $nf = select($rin, $win, undef, undef);
    msg('select returned %d', $nf);
}

sub wait_for_query
{
    my $dbh = $_[0];
    my ($fd, $rc);

    $fd = $$dbh{pg_socket};
    do {
        wait_for($fd, 1);
        $rc = $dbh->pg_ready();
    } until $rc;

    $dbh->pg_result();
}

sub make_cspec
{
    my $acct = $_[0];
    my ($fh, $rc);

    $rc = open($fh, '<', $acct);
    die("open $acct: $!") unless $rc;

    return CSPEC_PRF.join(' ', map { chomp; join('=', split) } <$fh>);
}

sub dbh_connect
{
    my $acct = $_[0];
    my ($cs, $dbh, $rc);
    
    msg('connecting');

    $cs = make_cspec($acct);
    $dbh = DBI->connect($cs, '', '',
                               {
                                AutoCommit => 0,
                                RaiseError => 1,
                                pg_server_prepare => 1,
                                pg_async_connect => 1});
    $dbh->{ReadOnly} = 1;

    do {
        $rc = $dbh->pg_continue_connect();
        msg('continue async connect %d', $rc);
        wait_for($$dbh{pg_socket}, $rc) if $rc;
    } while $rc;

    msg('connected');

    return $dbh;
}

#*  main
#
{
    my ($dbh, $sth, $row);
    
    DBI->trace(15);
    $dbh = dbh_connect('../../pg-conn');
    
#    $sth = $dbh->prepare('select cmd, whatis from whatis where section = ? order by cmd', { pg_async => 1, pg_prepare_now => 1 });
    $sth = $dbh->prepare('select pg_sleep(?)', { pg_async => 1, pg_prepare_now => 1 });
    $sth->execute(10);
    $dbh->pg_cancel();
    wait_for_query($dbh);
}
