Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.sai.msu.su/~megera/tips/wdb/p95_dbi-1.90.pl
Дата изменения: Tue Mar 14 17:45:35 2006
Дата индексирования: Sat Dec 22 06:57:09 2007
Кодировка:

Поисковые слова: arp 220
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.IDENTIFICATION pg95_dbi.pl
#.LANGUAGE pgperl95 script
#
#.PURPOSE Database Interface to Postgres.
#
# &dbi_connect( $host, $port, $database, $user, $pswd );
# &dbi_dosql( "... POSTQUEL commands ...");
# %row = &dbi_nextrow;
# &dbi_disconnect;
# &dbi_rowcount( $rows );
# &dbi_dateformat( $format );
#
#.AUTHOR J. Douglas Dunlop [EOL/ISTS]
#
#.VERSION 0.0 Adapted from sy_dbi.pl by Bo Frese Rasmussen
# 1.0 29/03-1995 Creation
# 1.1 15/05-1995 Converted to use postgres95
# 1.2 03/05-2005 Get it works with postgresql 8. and
# Pg.pm 1.9.0 (oleg@sai.msu.su)
#------------------------------------------------------------------------------
package WDB_DatabaseInterface;
use Pg;

$PGRES_EMPTY_QUERY = 0 ; # these are from libpq-fe.h
$PGRES_COMMAND_OK = 1 ;
$PGRES_TUPLES_OK = 2 ;
$PGRES_COPY_OUT = 3 ;
$PGRES_COPY_IN = 4 ;
$PGRES_BAD_RESPONSE = 5 ;
$PGRES_NONFATAL_ERROR = 6 ;
$PGRES_FATAL_ERROR = 7 ;

# Wrappers to work with new Pg.pm 1.9.0 ( Oleg Bartunov, oleg@sai.msu.su)
#
sub PQerrorMessage {
return $_[0]->errorMessage;
}

sub PQclear {
$_[0] = '';
}

sub PQexec {
return $conn->exec($_[1]);
}

sub PQresultStatus {
my ($res) = shift;
return $res->resultStatus;
}

sub PQntuples {
return $_[0]->ntuples;
}

sub PQnfields {
return $_[0]->nfields;
}

sub PQfname {
return $_[0]->fname($_[1]);
}

sub PQgetvalue {
return $_[0]->getvalue($_[1],$_[2]);
}

sub PQfinish {
undef $_[0];
}

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Connects to a database.
#
#.REMARKS This function must be called before any of the other functions
# in this package.
# It logs in to the given database server on the given port and
# connects to database.
#
#.RETURNS Dies on error !
#------------------------------------------------------------------------------
sub main'dbi_connect
{
local( $host, $port, $database, $user, $pswd ) = @_;

init_handler(); # Initialize a handler to tidy up aborts

$host = $ENV{'PGHOST'} if !$host;
$port = $ENV{'PGPORT'} if !$port;
##x $conn = PQsetdb ($host, $port,'','',$database);
$conn = Pg::connectdb("dbname=$database");

##x if (PQstatus($conn)) {
if ($conn->status eq PGRES_CONNECTION_BAD) {
print "Failed to connect to database '$database' on host '$host' at port '$port'\n";
die;
}
}

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Prepares and executes a POSTQUEL statement, with error check.
#
#.REMARKS Dies on error !
#
#.RETURNS Return value of dbresults
#------------------------------------------------------------------------------
sub main'dbi_dosql
{
local($query) = @_;

$curr_row = 0; # setup for dbi_nextrow

$result = PQexec($conn, $query); # the query
$r_status = PQresultStatus($result);

if ($r_status != $PGRES_COMMAND_OK && $r_status != $PGRES_TUPLES_OK) {
$errormsg = PQerrorMessage($conn) if $conn;
PQclear($result) if $result;
PQfinish($conn) if $conn;
die("$0: PQexec: the query $query produced the error $errormsg\n");
}
$num_tuples = PQntuples($result);
$num_fields = PQnfields($result);
}
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Defines the fieldnames to be returned from dbi_getnextrow
#
#.REMARKS If this function is defined the query sent to dbi_dosql
# should not use the
# 'select , , ...'
# notation but rather the simple
# 'select , , ...'
# notation and then call dbi_fieldnames with the names of the
# labels to use :
# &dbi_fieldnames( '', '', ...);
# &dbi_getnextrow will then return an associative array with the
# 's as key.
#
#.RETURNS nothing
#------------------------------------------------------------------------------
sub main'dbi_fieldnames
{
@fields = @_;
}
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Gets the next row from a previous select (dbi_dosql).
#
#.REMARKS After a dbi_dosql("select ... ") call, this function can be
# called repeatetly to retrieve all rows of the query.
#
# Example :
# &dbi_dosql("SELECT field FROM class WHERE field > 4");
# while( %row = &dbi_nextrow ) {
# print $row{'columnname'};
# ...
# }
#
#.RETURNS An associative array (keyed on the column name) of formatted
# data, based on the datatype of the corresponding columns.
#------------------------------------------------------------------------------
sub main'dbi_nextrow
{
# $num_tuples = PQntuples($result);
# $num_fields = PQnfields($result);
if ($curr_row >= $num_tuples) {
foreach $key (keys %row) {
delete $row{$key}; # prevents returning previous row
}
}
else {
for ($nfield=0 ; $nfield<$num_fields ; $nfield++) {
$fname = PQfname($result,$nfield);
$row{$fname} = PQgetvalue($result,$curr_row,$nfield);
}
}
$curr_row += 1;
return %row;
}

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Get the number of rows matched
#
#.REMARKS After doing a dbi_dosql then this is the number of rows
# that matched the selection criteria.
#
#.RETURNS number of rows matched
#------------------------------------------------------------------------------
sub main'dbi_rowsmatched
{
return $num_tuples;
}
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Disconnects the current database connection
#
#.REMARKS After this function is called there are no current database
# connection => no other function from this package can be
# called before a new dbi_connect call.
#
#.RETURNS nothing.
#------------------------------------------------------------------------------
sub main'dbi_disconnect
{
PQfinish($conn);
}

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Sets the maximim number of rows returned from a query.
#
#.REMARKS Causes Postgres server to stop processing the query ( select,
# insert update, delete) after the specified number of rows
# are affected.
#
# PORTING NOTE: This function is added for efficiency only.
# When used with WDB it can safely be ignored ( leave an
# empty function body : {} )
#
#.RETURNS nothing.
#------------------------------------------------------------------------------
sub main'dbi_rowcount
{
# not an option in postgres95
}

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Sets the default output format for dates.
#
#.REMARKS Sets the order of the date parts month/day/year for entering
# datetime data. Valid arguments are mdy, dmy, ymd, ydm, myd, dym.
#
#.RETURNS nothing.
#------------------------------------------------------------------------------
sub main'dbi_dateformat
{
# fixed as mdy in postgres95
}

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.PURPOSE Error handler code.
#
#.REMARKS Close database if HUP, INT, or QUIT signal is recieved.
#
#.RETURNS exits after doing PQfinish
#-----------------------------------------------------------------------------
sub init_handler {
$SIG{'HUP'} = 'handler';
$SIG{'INT'} = 'handler';
$SIG{'QUIT'} = 'handler';
}

sub handler { # 1st argument is signal name
local($sig) = @_;
print "Caught a SIG$sig--shutting down connection to Postgres95.\n";
PQclear($result) if $result;
PQfinish($conn) if $conn;
exit(0);
}
#------------------------------------------------------------------------------
1;