/usr/local/CPAN/RDBAL/RDBAL/Layer/DBI.pm
package RDBAL::Layer::DBI;
require 5.000;
$VERSION = "1.00";
sub Version { $VERSION; }
use strict;
use vars qw(@ISA @EXPORT $VERSION $DefaultClass $AutoloadClass);
use Exporter;
@ISA = qw();
@EXPORT = ();
sub import {
my $pkg = shift;
my $callpkg = caller;
Exporter::export 'RDBAL::Layer::DBI', $callpkg, @_;
}
# Default class for the SQL object to use when all else fails.
$DefaultClass = 'RDBAL::Layer::DBI' unless defined $RDBAL::Layer::DBI::DefaultClass;
# This is where to look for autoloaded routines.
$AutoloadClass = $DefaultClass unless defined $RDBAL::Layer::DBI::AutoloadClass;
sub new {
my($class) = shift;
my($username) = shift;
my($password) = shift;
my($server) = shift;
my($driver) = shift;
my($database) = shift;
my($self) = {};
my($data_source);
bless $self,ref $class || $class || $DefaultClass;
if ($driver eq 'Sybase') {
$data_source = "dbi:$driver" . ':server=' . $server;
} else {
if (defined($database)) {
$data_source = "dbi:$driver:$database";
} else {
$data_source = "dbi:$driver:";
}
}
$self->{'connection'} =
DBI->connect($data_source, $username, $password, { PrintError => 0 });
$self->{'driver'} = $driver;
return $self;
}
#
# Execute SQL command
#
sub Sql {
my($self) = shift;
my($connection) = $self->{'connection'};
my($command) = shift;
my($sth);
if (defined($self->{'sth'})) {
$self->{'sth'}->finish;
}
$sth = $connection->prepare($command) or return undef;
$self->{'sth'} = $sth;
$self->{'sth'}->execute or return undef;
$self->{'empty_fetch'} = 0;
return 1;
}
sub RowCount {
my($self) = shift;
return $self->{'sth'}->rows;
}
sub UseDatabase {
my($self) = shift;
my($connection) = $self->{'connection'};
my($database) = shift;
my($retval);
if ($self->{'driver'} eq 'Sybase' ) {
$self->Sql("use $database") or return undef;
while($self->More_Results) {};
}
return 1;
}
#
# @row = NextRow($connection);
#
sub NextRow {
my($self) = shift;
my(@row) = $self->{'sth'}->fetchrow_array;
$self->{'empty_fetch'} = 0;
return @row;
}
#
# $bool_regular_row = Regular_Row($connection);
#
sub Regular_Row {
my($self) = shift;
if ($self->{'sth'}->{NAME}->[0] ne 'COL(1)') {
return 1;
} else {
return 0;
}
}
#
# $bool_no_more_result_sets = More_Results($connection);
#
sub More_Results {
my($self) = shift;
my($retval) = 0;
my(@row);
if ($self->{'empty_fetch'}) {
while($self->{'sth'}->fetchrow_array) {}
}
$self->{'empty_fetch'} = 1;
if (defined($self->{'sth'}->{syb_more_results}) &&
$self->{'sth'}->{syb_more_results}) {
$retval = 1;
}
return $retval;
}
#
# Get column names
#
sub ColumnNames {
my($self) = shift;
return @{$self->{'sth'}->{NAME}};
}
#
# Get column types
#
sub ColumnTypes {
my($self) = shift;
return undef;
}
#
# Get column field lengths
#
sub ColumnLengths {
my($self) = shift;
return undef;
}
#
# Output one result table as text
#
sub PrintTable {
my($self) = shift;
my(@columnname);
my(@row);
@columnname = $self->ColumnNames();
print join("\t", @columnname)."\n";
while(@row = $self->NextRow()) {
print join("\t", @row)."\n";
}
return 1;
}
#
# Output one or more result tables as text
#
sub PrintTables {
my($self) = shift;
my($connection) = $self->{'connection'};
my(@columnname);
my(@row);
do {
PrintTable($self);
} while ($self->More_Results());
return 1;
}
#
# Execute an SQL query and return the results in an array
#
# If the query produces a single value per row, just return
# an array of the data.
#
# If the query produces multiple values per row, return an
# array of references to arrays.
#
sub Query {
my($self) = shift;
my($command) = shift;
my(@out,@row,$ptr,$ret);
$ret = $self->Sql($command);
if (!$ret) {
print "Error on query $command\n";
return undef;
}
do {
while(@row = $self->NextRow()) {
if (@row<=1) {
push(@out,$row[0]);
} else {
$ptr = [];
push(@{$ptr},@row);
push(@out,$ptr);
}
}
} while ($self->More_Results());
return(@out);
}
1;
__END__