OpenSimMirror/share/perl/lib/DBHandler.pm

120 lines
2.2 KiB
Perl

use strict;
use DBI;
use Carp;
package DBHandler;
#our $dbh = undef;
use vars qw ($DB_CONNECTION);
sub getConnection {
my ($dsn, $user, $pass) = @_;
#return $DB_CONNECTION if ($DB_CONNECTION);
$DB_CONNECTION = DBI->connect($dsn, $user, $pass);
$DB_CONNECTION->{AutoCommit} = 1;
$DB_CONNECTION->{RaiseError} = 1;
return $DB_CONNECTION;
}
# #############
# Simple statement
package Statement;
sub new {
my ( $this, $dbh, $sql, $is_trans ) = @_;
# @@@ sql should be tested OK, so here just die
my $sth = $dbh->prepare($sql) || Carp::croak( $dbh->errstr );
my %fields = (
dbh => $dbh,
sql => $sql,
sth => $sth,
is_trans => $is_trans,
);
return bless \%fields, $this;
}
sub exec {
my ( $this, @param ) = @_;
my $dbh = $this->{dbh};
my $sth = $this->{sth};
my $sql = $this->{sql};
if ( !$sth->execute(@param) ) {
if ( $this->{is_trans} ) {
$dbh->rollback();
}
Carp::croak( $dbh->errstr );
}
my @ret = ();
if ( $sql =~ /^select/i ) {
# @@@ get result object
while ( my $res = $sth->fetchrow_hashref() ) {
push @ret, $res;
}
}
# @@@ $sth->finish();
return \@ret;
}
sub last_id {
my $this = shift;
my $dbh = $this->{dbh};
return $dbh->last_insert_id(undef, undef, undef, undef);
}
sub DESTROY {
my $this = shift;
my $sth = $this->{sth};
$sth->finish();
}
# #############
# Transaction
package Transaction;
my $IS_TRANS = 1;
sub new {
my ( $this, $dbh ) = @_;
# @@@ fatal error, just die
$dbh->begin_work() || Carp::croak( $dbh->errstr );
my %fields = (
dbh => $dbh,
Active => 1,
);
return bless \%fields, $this;
}
sub createStatement {
my ( $this, $sql) = @_;
# @@@ fatal error, just die
Carp::croak("transaction not begin") if ( !$this->{Active} );
my $dbh = $this->{dbh};
return new Statement($dbh, $sql, $IS_TRANS);
}
sub commit {
my $this = shift;
my $dbh = $this->{dbh};
if ( $this->{Active} && !$dbh->{AutoCommit} ) {
$dbh->commit || Carp::croak( $dbh->errstr );
}
$this->{Active} = 0;
}
sub rollback {
my $this = shift;
my $dbh = $this->{dbh};
if ( $this->{Active} && !$dbh->{AutoCommit} ) {
$dbh->rollback || Carp::croak( $dbh->errstr );
}
$this->{Active} = 0;
}
sub DESTROY {
my $this = shift;
$this->rollback;
}
1;