File Coverage

blib/lib/Test/Database.pm
Criterion Covered Total %
statement 104 108 96.3
branch 29 40 72.5
condition 4 8 50.0
subroutine 18 18 100.0
pod 7 7 100.0
total 162 181 89.5


line stmt bran cond sub pod time code
1             package Test::Database;
2             $Test::Database::VERSION = '1.113';
3 4     4   109266 use 5.006;
  4         24  
  4         185  
4 4     4   24 use warnings;
  4         8  
  4         148  
5 4     4   26 use strict;
  4         10  
  4         202  
6              
7 4     4   4744 use File::HomeDir;
  4         27986  
  4         301  
8 4     4   35 use File::Spec;
  4         10  
  4         76  
9 4     4   9881 use DBI;
  4         79777  
  4         318  
10 4     4   50 use Carp;
  4         207  
  4         354  
11              
12 4     4   2704 use Test::Database::Util;
  4         9  
  4         25  
13 4     4   2406 use Test::Database::Driver;
  4         14  
  4         148  
14 4     4   27 use Test::Database::Handle;
  4         7  
  4         4552  
15              
16             #
17             # global configuration
18             #
19              
20             # internal data structures
21             my @HANDLES;
22             my @DRIVERS;
23              
24             # driver information
25             my @DRIVERS_OUR;
26             my @DRIVERS_OK;
27              
28             # find the list of all drivers we support
29             sub load_drivers {
30 5     5 1 12 my %seen;
31 5         15 for my $dir (@INC) {
32 55 100       2161 opendir my $dh, File::Spec->catdir( $dir, qw( Test Database Driver ) )
33             or next;
34 15         260 $seen{$_}++ for map { s/\.pm$//; $_ } grep {/\.pm$/} readdir $dh;
  90         223  
  90         3067  
  120         1583  
35 15         198 closedir $dh;
36             }
37              
38             # drivers we support
39 5         47 @DRIVERS_OUR = sort keys %seen;
40              
41             # available DBI drivers
42 5         1378 my %DRIVERS_DBI = map { $_ => 1 } DBI->available_drivers();
  35         2449  
43              
44             # supported
45 5         19 @DRIVERS_OK = grep { exists $DRIVERS_DBI{$_} } @DRIVERS_OUR;
  30         56  
46              
47             # automatically load all drivers in @DRIVERS_OK
48             # (but ignore compilation errors)
49 5         410 eval "require Test::Database::Driver::$_" for @DRIVERS_OK;
50              
51             # actual driver objects
52 10         22 @DRIVERS = map {
53 10         77 my $driver;
54 10 50       17 eval { $driver = Test::Database::Driver->new( dbd => $_ ); 1; }
  10         50  
  10         43  
55             or warn "$@\n";
56 10 50       77 $driver || ();
57             }
58 5         16 grep { "Test::Database::Driver::$_"->is_filebased() } @DRIVERS_OK;
59             }
60              
61             # startup configuration
62             __PACKAGE__->load_drivers();
63             __PACKAGE__->load_config();
64              
65             #
66             # private functions
67             #
68             # location of our resource file
69             sub _rcfile {
70 4     4   8 my $basename = '.test-database';
71 4         34 my $rc = File::Spec->catfile( File::HomeDir->my_home(), $basename );
72 4 50       243 return $rc if -e $rc;
73              
74             # while transitioning to the new scheme, give the old name if it exists
75 4         42 my $old = File::Spec->catfile( File::HomeDir->my_data(), $basename );
76 4 50       247 return -e $old ? $old : $rc;
77             }
78              
79             #
80             # methods
81             #
82             sub clean_config {
83 3     3 1 1713 @HANDLES = ();
84 3         59 @DRIVERS = ();
85             }
86              
87             sub load_config {
88 5     5 1 27 my ( $class, @files ) = @_;
89 5 100       26 @files = grep -e, _rcfile() if !@files;
90              
91             # fetch the items (dsn, driver_dsn) from the config files
92 5         53 my @items = map { _read_file($_) } @files;
  1         7  
93              
94             # load the key
95 3         13 Test::Database::Driver->_set_key( $_->{key} )
96 5         18 for grep { exists $_->{key} } @items;
97              
98             # create the handles
99             push @HANDLES,
100 3 50       5 map { eval { Test::Database::Handle->new(%$_) } || () }
  3         27  
  3         9  
101 5         14 grep { exists $_->{dsn} } @items;
102              
103             # create the drivers
104             push @DRIVERS,
105 0 0       0 map { eval { Test::Database::Driver->new(%$_) } || () }
  0         0  
  3         17  
106 5         12 grep { exists $_->{driver_dsn} } @items;
107             }
108              
109             sub list_drivers {
110 5     5 1 775 my ( $class, $type ) = @_;
111 5   100     25 $type ||= '';
112             return
113 4         18 $type eq 'all' ? @DRIVERS_OUR
114             : $type eq 'available' ? @DRIVERS_OK
115 5 100       31 : map { $_->name() } @DRIVERS;
    100          
116             }
117              
118 2     2 1 27 sub drivers { @DRIVERS }
119              
120             # requests for handles
121             sub handles {
122 62     62 1 17771567 my ( $class, @requests ) = @_;
123 62         89 my @handles;
124              
125             # empty request means "everything"
126 62 100       250 return @handles = ( @HANDLES, map { $_->make_handle() } @DRIVERS )
  0         0  
127             if !@requests;
128              
129             # turn strings (driver name) into actual requests
130 56 100       93 @requests = map { (ref) ? $_ : { dbd => $_ } } @requests;
  86         354  
131              
132             # process parameter aliases
133 56   66     407 $_->{dbd} ||= delete $_->{driver} for @requests;
134              
135             # get the matching handles
136 56         118 for my $handle (@HANDLES) {
137 162         151 my $ok;
138 162         218 my $driver = $handle->{driver};
139 162         290 for my $request (@requests) {
140 192 100       572 next if $request->{dbd} ne $handle->dbd();
141 96 50       666 if ( grep /version/, keys %$request ) {
142 0 0 0     0 next if !$driver || !$driver->version_matches($request);
143             }
144 96         126 $ok = 1;
145 96         251 last;
146             }
147 162 100       490 push @handles, $handle if $ok;
148             }
149              
150             # get the matching drivers
151 56         73 my @drivers;
152 56         96 for my $driver (@DRIVERS) {
153 4         8 my $ok;
154 4         7 for my $request (@requests) {
155 4 100       27 next if $request->{dbd} ne $driver->dbd();
156 2 50       15 next if !$driver->version_matches($request);
157 2         4 $ok = 1;
158 2         4 last;
159             }
160 4 100       19 push @drivers, $driver if $ok;
161             }
162              
163             # get a new database handle from the drivers
164 56         83 push @handles, map { $_->make_handle() } @drivers;
  2         15  
165              
166             # then on the handles
167 56         1088 return @handles;
168             }
169              
170             sub handle {
171 20     20 1 22380 my @h = shift->handles(@_);
172 20 100       654 return @h ? $h[0] : ();
173             }
174              
175             'TRUE';
176              
177             __END__