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 )