EntityModel
view release on metacpan or search on metacpan
lib/EntityModel/DB.pm view on Meta::CPAN
Call code within a transaction.
Note that this does not map exactly onto a single database transaction. Nested transactions are supported, using
savepoints, and a transaction may cover several active database handles.
=cut
sub transaction {
my $self = shift;
my $sub = shift;
$self->_fork_guard;
# Record then increment current transaction level
my $level = $self->transactionLevel;
$self->transactionLevel($level + 1);
# If we're already in a transaction, use a savepoint
if($level) {
logDebug("Savepoint %d", $level);
$self->dbh->do("savepoint tran_" . $self->transactionLevel);
}
# Run the query, if this fails $status will be false
return try {
local $ACTIVE_DB = $self;
$sub->($self, @_);
die "Fork within transaction is not recommended" unless $self->pid ~~ $$;
if($level) {
logDebug("Commit to level %d", $level);
$self->dbh->do("release tran_" . $self->transactionLevel);
} else {
logDebug("Commit");
$self->dbh->do("commit");
}
# Restore previous transaction level
$self->transactionLevel($level);
$self;
} catch {
# And for failure, do a rollback to previous level
if($level) {
logDebug("Rollback to level %d", $level);
$self->dbh->do("rollback to tran_" . $self->transactionLevel);
} else {
logDebug("Rollback");
$self->dbh->do("rollback");
}
# Restore previous transaction level
$self->transactionLevel($level);
logStack($_);
die $_;
};
}
=head2 update
Update information
=cut
sub update {
my $self = shift;
my %args = @_;
$self->_fork_guard;
my $sql = $args{sql};
my $dbh = $self->dbh;
my $sth = $dbh->prepare($sql);
$sth->execute(@{$args{param}});
$args{on_complete}->($sth) if $args{on_complete};
return $sth;
}
=head2 select
Run a select query against the database and return the results as an orderly hash.
=cut
sub select : method {
my $self = shift;
my $sql = shift;
my $param = shift;
my %args = (
sql => $sql,
param => $param
);
my ($sth, $rslt) = $self->_run_query(%args);
my @names = @{ $sth->{ NAME_lc } };
my @data;
foreach (@$rslt) {
my @row = @$_;
push @data, {
map {
$_ => shift(@row)
} @names
};
}
return \@data;
}
=head2 select_iterator
Run a select query against the database and return the results as an orderly hash.
=cut
sub select_iterator {
my $self = shift;
my %args = @_;
die "No method supplied" unless $args{method};
# Set up the statement handle so we can read data
my ($sth, $rslt) = $self->_run_query(@_);
my @names = @{ $sth->{ NAME_lc } };
my @data;
foreach (@$rslt) {
my @row = @$_;
my %data = map { $_ => shift(@row) } @names;
( run in 2.680 seconds using v1.01-cache-2.11-cpan-e1769b4cff6 )