DBIx-QuickORM

 view release on metacpan or  search on metacpan

lib/DBIx/QuickORM/Connection/Transaction.pm  view on Meta::CPAN

package DBIx::QuickORM::Connection::Transaction;
use strict;
use warnings;

our $VERSION = '0.000028';

use Carp qw/croak confess/;
use Scalar::Util qw/weaken/;

use Object::HashBase qw{
    <id
    +connection
    +savepoint

    +on_success
    +on_fail
    +on_completion

    verbose

    <result
    <errors
    <trace

    exception
    +aborted

    <in_destroy
    +finalize

    no_last
};

=pod

=encoding UTF-8

=head1 NAME

DBIx::QuickORM::Connection::Transaction - One transaction or savepoint on a
DBIx::QuickORM connection.

=head1 DESCRIPTION

Represents a single transaction (or savepoint) and the callbacks queued
against it. C<commit> and C<rollback> record the outcome and break out of the
enclosing C<QORM_TRANSACTION> loop; C<terminate> records the final result and
fires the queued success / fail / completion callbacks. An optional finalize
callback runs when the transaction completes or, as a safety net, when the
object is destroyed while still pending.

=head1 SYNOPSIS

    QORM_TRANSACTION: {
        my $txn = DBIx::QuickORM::Connection::Transaction->new(id => $id);
        $txn->add_success_callback(sub { ... });
        ...
        $txn->commit;
    }

=head1 ATTRIBUTES

=over 4

=item id

The transaction identifier (required).

lib/DBIx/QuickORM/Connection/Transaction.pm  view on Meta::CPAN


=item result

Undef while open; 1 on success, 0 on failure once terminated.

=item errors

The error(s) captured on failure.

=item trace

Arrayref describing where the transaction was started, used in C<throw>.

=item exception

The exception that forced the transaction to roll back, if any. Set when the
transaction's body threw (or the transaction fell out of scope); undef for a
normal commit or an explicit C<rollback>.

=item in_destroy

True while finalize runs from C<DESTROY>.

=item finalize

The finalize callback, if set.

=item no_last

When true, C<commit> / C<rollback> skip the C<last QORM_TRANSACTION> jump.

=back

=head1 PUBLIC METHODS

=over 4

=item $bool = $txn->is_savepoint

True when this is a savepoint.

=cut

sub is_savepoint { $_[0]->{+SAVEPOINT} ? 1 : 0 }

=pod

=item $txn->init

Object construction hook invoked by L<Object::HashBase>. Validates the id and
normalizes the callback queues. Not called directly.

=cut

sub init {
    my $self = shift;

    croak "A transaction ID is required" unless $self->{+ID};

    # Hold the connection weakly. The connection holds its transactions weakly in
    # turn, so this back-reference does not create a strong cycle; weakening it
    # keeps a transaction from pinning its connection alive and from dragging the
    # whole connection into a dump or deep comparison of the txn.
    weaken($self->{+CONNECTION}) if $self->{+CONNECTION};

    $self->{+RESULT} = undef;

    $self->{+ON_SUCCESS}    = [$self->{+ON_SUCCESS}]    if 'CODE' eq ref($self->{+ON_SUCCESS});
    $self->{+ON_FAIL}       = [$self->{+ON_FAIL}]       if 'CODE' eq ref($self->{+ON_FAIL});
    $self->{+ON_COMPLETION} = [$self->{+ON_COMPLETION}] if 'CODE' eq ref($self->{+ON_COMPLETION});
}

=pod

=item $bool = $txn->complete

True once a result has been recorded.

=cut

sub complete { defined $_[0]->{+RESULT} }

=pod

=item $str = $txn->state

Returns C<active> while the transaction is open, then C<committed> or
C<rolled_back> once it finishes. Derived from C<result>.

=item $bool = $txn->committed

True if the transaction committed, false if it rolled back, undef while still
open. Derived from C<result>.

=item $bool = $txn->rolled_back

The inverse of C<committed>: true if it rolled back, false if it committed,
undef while still open.

=item $bool = $txn->aborted

True if an explicit C<rollback> was requested on this transaction.

=cut

sub committed {
    my $r = $_[0]->{+RESULT};
    return undef unless defined $r;
    return $r ? 1 : 0;
}

sub rolled_back {
    my $r = $_[0]->{+RESULT};
    return undef unless defined $r;
    return $r ? 0 : 1;
}

# True if an explicit rollback was requested (drives the commit/rollback
# decision in Connection::txn before the result is recorded).
sub aborted { $_[0]->{+ABORTED} ? 1 : 0 }

sub _assert_innermost {
    my $self = shift;
    my ($op) = @_;



( run in 1.154 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )