File Coverage

blib/lib/DBIx/Roles/Shared.pm
Criterion Covered Total %
statement 47 51 92.1
branch 12 18 66.6
condition n/a
subroutine 4 4 100.0
pod 0 2 0.0
total 63 75 84.0


line stmt bran cond sub pod time code
1             # $Id: Shared.pm,v 1.4 2005/12/19 15:02:00 dk Exp $
2              
3             package DBIx::Roles::Shared;
4              
5 1     1   7 use strict;
  1         1  
  1         45  
6 1     1   6 use vars qw(%instances %dsns $VERSION);
  1         2  
  1         543  
7              
8             $VERSION = '1.00';
9              
10             sub connect
11             {
12 9     9 0 22 my ( $self, undef, $dsn, $user, $pass, $attr) = @_;
13              
14 9         27 my $inst_key = "$self";
15 9         28 my $dsn_key = join( ' | ', $dsn, $user, $pass);
16 9         14 my $dbh;
17              
18 9 100       26 if ( exists $instances{$inst_key}) {
19             # apparently, connect() without disconnect --
20             # 1. find if the object was connected to another handle, and clean it up
21 6         13 keys %dsns; # reset each()
22 6         32 while ( my ( $k, $v) = each %dsns) {
23 6         12 my @d = grep { $_ != $self } @$v;
  9         27  
24 6 50       20 next if @d == @$v;
25             # found a connection
26 6 50       19 last if $k eq $dsn_key; # yes, it is trying to reconnect
27             # cleanup
28 0 0       0 @d ? ( @$v = @d ) : delete $dsns{$k};
29 0         0 delete $instances{"$self"};
30 0         0 goto DEFAULT_CONNECT;
31             }
32             # 2. reconnect and apply the new handle to all the shared objects
33 6         9 eval { $dbh = $self-> super( $dsn, $user, $pass, $attr); };
  6         33  
34 6         75 my $exception = $@;
35            
36 6         9 for my $obj (@{$dsns{$dsn_key}}) {
  6         15  
37 9         24 $obj-> dbh( $dbh);
38             }
39 6         15 $instances{$inst_key} = $dbh;
40              
41 6 100       22 die $exception if $exception;
42             } else {
43             DEFAULT_CONNECT:
44 3 100       10 if ( exists $dsns{$dsn_key}) {
45             # reuse an existing connection
46 1         8 $dbh = $dsns{$dsn_key}-> [0]-> dbh;
47             } else {
48             # new connection
49 2         11 $dbh = $self-> super( $dsn, $user, $pass, $attr);
50 2 50       26 return undef unless $dbh;
51 2         8 $instances{$inst_key} = $dbh;
52             }
53 3         13 push @{$dsns{$dsn_key}}, $self;
  3         9  
54             }
55              
56 5         22 return $dbh;
57             }
58              
59             sub disconnect
60             {
61 3     3 0 4 my $self = $_[0];
62              
63 3         5 keys %dsns; # reset each()
64 3         14 while ( my ( $k, $v) = each %dsns) {
65 3         6 my @d = grep { $_ != $self } @$v;
  4         10  
66 3 50       13 if ( @d == @$v) {
    100          
67             # not found
68 0         0 next;
69             } elsif ( @d) {
70             # remove the shared connection from the list but do not disconnect
71 1         3 @$v = @d;
72 1         4 delete $instances{"$self"};
73 1         5 $self-> dbh( undef); # disconnect can be called twice
74 1         6 return;
75             } else {
76             # that was the last reference, disconnect
77 2         5 delete $dsns{$k};
78 2         5 last;
79             }
80             }
81              
82             # also disconnect if wasn't found somehow
83 2         6 delete $instances{"$self"};
84 2         6 $self-> super();
85             }
86              
87             1;
88              
89             __DATA__