#!/usr/bin/perl -w
# $Id: oradebug 8 2014-09-19 13:51:01Z abalama $
use strict;

=head1 NAME

oradebug - Tiny Oracle Debugger of App::MonM

=head1 VERSION

Version 1.01

=head1 SYNOPSIS

    oradebug [ -s SID | -n DSN ] [ -u USER ] [ -p PASSWORD ] [ -q SQL ]
    oradebug [ --sid=SID | --dsn=DSN ] [ --user=DBUSER ] 
        [ --password=DBPASSWORD ] [ -sql=SQL ]
    
    Example:
    
    oradebug -s SID -u USER -p PASSWORD

    Type oradebug -h or oradebug -? for more details

=head1 DEPENDENCES

L<DBI>, L<DBD::Oracle>

=head1 AUTHOR

Serz Minus (Lepenkov Sergey) L<http://www.serzik.com> E<lt>minus@mail333.comE<gt>.

=head1 COPYRIGHT

Copyright (C) 1998-2014 D&D Corporation. All Rights Reserved

=head1 LICENSE

This program is distributed under the GNU GPL v3.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

See C<LICENSE> file

=cut

use DBI;
use Data::Dumper;
use Time::HiRes qw(gettimeofday);
use Getopt::Long;
use Pod::Usage;
use constant {
    DSN      => "", # 'DBI:Oracle:SID'
    SID      => "",
    LOGIN    => "",
    PASSWORD => "",
    SQL      => q/SELECT 'OK' STATUS, SYSDATE FROM DUAL/,
};

use vars qw/$VERSION/;
$VERSION = '1.01';

$SIG{INT} = sub { die "ABORTED\n"; };

$| = 1;  # autoflush

Getopt::Long::Configure("bundling");
my %OPT;
GetOptions(\%OPT,
    "help|usage|h",
    "longhelp|man|m|?",
    "user|login|oralogin|orauser|u=s",                   # Oracle Login
    "password|passwd|orapassword|orapass|orapasswd|p=s", # Oracle Password
    "dsn|n=s",                                           # DSN
    "sid|tns|orasid|oraname|oratns|tnsname|s=s",         # SID
    "sql|orarequest|orasql|q=s",                         # SQL
) || pod2usage(-exitval => 1, -verbose => 0);
pod2usage(-exitval => 0, -verbose => 1) if $OPT{help};
pod2usage(-exitval => 0, -verbose => 2) if $OPT{longhelp};
my $sid         = $OPT{sid} || SID || '';
my $dsn         = $OPT{dsn} || DSN || "DBI:Oracle:$sid";
my $login       = $OPT{user} || LOGIN || '';
my $password    = $OPT{password} || PASSWORD || '';
my $sql         = $OPT{sql} || SQL || 'SELECT SYSDATE FROM DUAL';

my $TM = gettimeofday();
BEGIN {
    sub say { print STDOUT @_ ? @_ : '',"\n"}
    sub err { print STDERR @_ ? @_ : '',"\n"}
    sub tms { "[$$] {TimeStamp: ".sprintf("%+.*f",4, gettimeofday()-$TM)." sec}" }
    sub _ {my $s=shift||'';my $l=length $s;$s.($l<70?('.'x(70-$l)):'').' '}
    sub exception { say "FAILED"; err @_ }
}

say "App::MonM oradebug/$VERSION";
say;
START: say "START TRANSACTION ", tms;

print _"  1/6 Connecting to \"$dsn\"";
my $ora = DBI->connect($dsn,$login,$password,{PrintError => 0}) or exception($DBI::errstr) && goto(FINISH);
say "PASSED";

print _"  2/6 SQL preparing \"$sql\"";
my $sth = $ora->prepare($sql) or exception($ora->errstr) && goto(FINISH);
say "PASSED";

print _"  3/6 SQL executing";
my $rv = $sth->execute() or exception($ora->errstr) && goto(FINISH);
say "PASSED";

print _"  4/6 Result fetching";
my $result = $sth->fetchrow_hashref or exception($ora->errstr || 'No fetch data') && goto(FINISH);
exception($sth->errstr) if $sth->err && goto(FINISH);
say "PASSED";

print _"  5/6 Finishing";
$sth->finish or exception($ora->errstr || 'Finishing error') && goto(FINISH);
say "PASSED";

print _"  6/6 Disconnecting";
$ora->disconnect or exception($ora->errstr) && goto(FINISH);
say "PASSED";

FINISH: say "FINISH TRANSACTION ", tms;
say;
if ($result) {
    say "RESULT:";
    print "  ", Dumper($result);
    say "OK";
} else {
    say "FAILED";
}
exit 0;
__END__
