File Coverage

blib/lib/DBIx/TransactionManager/Extended.pm
Criterion Covered Total %
statement 87 87 100.0
branch 30 30 100.0
condition n/a
subroutine 18 18 100.0
pod 7 9 77.7
total 142 144 98.6


line stmt bran cond sub pod time code
1             package DBIx::TransactionManager::Extended;
2 7     7   60472 use 5.008001;
  7         16  
3 7     7   22 use strict;
  7         6  
  7         101  
4 7     7   22 use warnings;
  7         8  
  7         230  
5              
6             our $VERSION = "0.01";
7              
8 7     7   403 use parent qw/DBIx::TransactionManager/;
  7         280  
  7         38  
9              
10 7     7   14534 use Carp qw/croak/;
  7         7  
  7         233  
11 7     7   2375 use DBIx::TransactionManager::Extended::Txn;
  7         9  
  7         3437  
12              
13             # override
14 16     16 1 12666 sub new { shift->SUPER::new(@_)->_initialize }
15              
16             sub _initialize {
17 17     17   118 my $self = shift;
18 17         34 $self->{_context_data} = {};
19 17         20 $self->{_hooks_before_commit} = [];
20 17         21 $self->{_hooks_after_commit} = [];
21 17         25 $self;
22             }
23              
24             sub context_data {
25 8     8 1 1316 my $self = shift;
26 8 100       22 croak 'CANNOT call context_data out of the transaction' unless $self->in_transaction;
27 7         44 return $self->{_context_data};
28             }
29              
30             # override
31 6     6 1 32 sub txn_scope { DBIx::TransactionManager::Extended::Txn->new(@_) }
32              
33             # override
34             sub txn_commit {
35 19     19 0 5129 my $self = shift;
36              
37 19         20 my $context_data = $self->{_context_data};
38 19         18 my $last = @{ $self->active_transactions } == 1;
  19         45  
39              
40 19 100       68 if ($last) {
41 17         15 my $hooks = $self->{_hooks_before_commit};
42 17 100       34 if (@$hooks) {
43 6         5 eval { $_->($context_data) for @$hooks };
  6         30  
44 6 100       1216 if ($@) {
45 1         2 $self->txn_rollback();
46 1         89 croak $@;
47             }
48 5         17 @$hooks = ();
49             }
50             }
51              
52 18         19 eval {
53 18         56 $self->SUPER::txn_commit();
54             };
55 18 100       379 if ($@) {
56 2         6 $self->_reset_all();
57 2         247 croak $@;
58             }
59              
60 16 100       27 if ($last) {
61 14         15 my $hooks = $self->{_hooks_after_commit};
62 14 100       22 if (@$hooks) {
63 5         17 eval { $_->($context_data) for @$hooks };
  5         15  
64 5 100       1084 if ($@) {
65 1         2 $self->_reset_all();
66 1         74 croak $@;
67             }
68 4         13 @$hooks = ();
69             }
70 13         31 %$context_data = ();
71             }
72             }
73              
74             # override
75             sub txn_rollback {
76 8     8 0 1108 my $self = shift;
77 8         17 $self->_reset_all();
78 8         27 $self->SUPER::txn_rollback();
79             }
80              
81             sub _reset_all {
82 11         21 %{$_[0]->{_context_data}}
83 11         18 = @{$_[0]->{_hooks_before_commit}}
84 11     11   14 = @{$_[0]->{_hooks_after_commit}}
  11         25  
85             = ();
86             }
87              
88             sub add_hook_before_commit {
89 12     12 1 713 my ($self, $hook) = @_;
90 12 100       20 croak 'CANNOT call add_hook_before_commit out of the transaction' unless $self->in_transaction;
91 11         45 push @{ $self->{_hooks_before_commit} } => $hook;
  11         16  
92 11         14 return $hook;
93             }
94              
95             sub add_hook_after_commit {
96 12     12 1 817 my ($self, $hook) = @_;
97 12 100       22 croak 'CANNOT call add_hook_after_commit out of the transaction' unless $self->in_transaction;
98 11         46 push @{ $self->{_hooks_after_commit} } => $hook;
  11         13  
99 11         12 return $hook;
100             }
101              
102             sub remove_hook_before_commit {
103 3     3 1 379 my ($self, $hook) = @_;
104 3 100       8 croak 'CANNOT call remove_hook_before_commit out of the transaction' unless $self->in_transaction;
105 2         9 _remove_hook($self->{_hooks_before_commit}, $hook);
106             }
107              
108             sub remove_hook_after_commit {
109 3     3 1 394 my ($self, $hook) = @_;
110 3 100       5 croak 'CANNOT call remove_hook_after_commit out of the transaction' unless $self->in_transaction;
111 2         10 _remove_hook($self->{_hooks_after_commit}, $hook);
112             }
113              
114             sub _remove_hook {
115 4     4   5 my ($hooks, $hook) = @_;
116              
117 4         4 my $found;
118 4         3 for my $i (0..$#{$hooks}) {
  4         10  
119 8 100       16 if ($hook == $hooks->[$i]) {
120 2         2 $found = $i;
121 2         3 last;
122             }
123             }
124 4 100       7 splice @$hooks, $found, 1 if $found;
125 4 100       14 return $found ? $hook : undef;
126             }
127              
128             1;
129             __END__