File Coverage

blib/lib/CGI/Application/Plugin/DBIProfile/Driver.pm
Criterion Covered Total %
statement 18 59 30.5
branch 0 16 0.0
condition 0 6 0.0
subroutine 6 14 42.8
pod 2 4 50.0
total 26 99 26.2


line stmt bran cond sub pod time code
1             package CGI::Application::Plugin::DBIProfile::Driver;
2 1     1   6 use strict;
  1         1  
  1         41  
3 1     1   945 use IO::Scalar;
  1         18921  
  1         66  
4              
5             =head1 TODO: POD
6              
7             =cut
8              
9 1     1   12 use vars qw($VERSION $DEBUG @ISA);
  1         2  
  1         123  
10             $DEBUG = 0;
11             $VERSION = "1.1";
12             @ISA = qw(DBI::ProfileDumper);
13             # TODO: requires DBI 1.49 for class method call interface.
14             # TODO: requires DBI 1.24 for DBI->{Profile} support, period.
15 1     1   7 use Carp qw(carp croak);
  1         1  
  1         69  
16 1     1   8385 use DBI;
  1         37558  
  1         86  
17 1     1   1090 use DBI::ProfileDumper;
  1         8895  
  1         705  
18              
19             # Override flush_to_disk() to use IO::Scalar rather than a real file.
20             # Also, change it to return the current formatted dataset, rather
21             # than write anything out.
22             # NOTE: the name doesn't fit. Could change that.
23             sub flush_to_disk
24             {
25 0     0 1   my $self = _get_dbiprofile_obj(shift);
26 0 0         return unless defined $self;
27              
28 0           my $output = $self->get_current_stats();
29              
30 0           $self->empty();
31              
32 0           return $output;
33             }
34              
35             # This does what flush_to_disk does, without emptying data afterwards.
36             sub get_current_stats
37             {
38 0     0 0   my $self = _get_dbiprofile_obj(shift);
39 0 0         return unless defined $self;
40              
41 0           my $data = $self->{Data};
42              
43 0           my $output;
44 0           my $fh = new IO::Scalar \$output;
45              
46 0           $self->write_header($fh);
47 0           $self->write_data($fh, $self->{Data}, 1);
48              
49 0 0         close($fh) or croak("Unable to close scalar filehandle: $!");
50              
51 0           return $output;
52             }
53              
54             # Override on_destroy() to simply clear the data, and close the IO::Scalar.
55             sub on_destroy
56             {
57 0     0 0   shift->empty();
58             }
59              
60             # Override empty to it'll behave has a class method.
61             sub empty
62             {
63 0     0 1   my $self = _get_dbiprofile_obj(shift);
64 0 0         return unless defined $self;
65 0           $self->SUPER::empty;
66             }
67              
68             # utility method to get a usable DBI::Profile object.
69             sub _get_dbiprofile_obj
70             {
71 0     0     my $self = shift;
72              
73             # if we're called by an instance var, just return it.
74 0 0 0       return $self if ref $self and UNIVERSAL::isa($self, 'DBI::Profile');
75              
76             # XXX: I couldn't find an instance where I needed to look at more
77             # than one database handle, even with multiple database handles
78             # talking to separate dbs using separate drivers.
79             # I'm not sure how this works out under mod_perl2 using the
80             # multi-threaded apache service (is there a separate perl memory/name
81             # space for each thread, or one per process?)
82             # We may need to loop over handles, fetch data && clear data && merge.
83              
84             # if we're called as a class method, we need to find at least one
85             # db handle to work with, and snag its profile.
86 0           my $dbh = (_get_all_dbh_handles())[0];
87 0 0 0       unless (ref $dbh && UNIVERSAL::isa($dbh, 'DBI::db'))
88             {
89 0 0         carp "Unable to locate active dbh." if $DEBUG;
90 0           return;
91             }
92 0           $self = $dbh->{Profile};
93 0 0         if (! ref $self) {
94 0           carp "Handle lacks Profile support";
95 0           return;
96             }
97              
98 0           return $self;
99             }
100              
101             # utility methods to enumerate all database handles
102             sub _get_all_dbh_handles
103             {
104 0     0     return grep { $_->{Type} eq 'db' } _get_all_dbi_handles();
  0            
105             }
106             sub _get_all_dbi_handles
107             {
108 0     0     my @handles;
109 0           my %drivers = DBI->installed_drivers();
110 0           push(@handles, _get_all_dbi_child_handles($_) ) for values %drivers;
111 0           return @handles;
112             }
113             sub _get_all_dbi_child_handles
114             {
115 0     0     my $h = shift;
116 0           my @h = ($h);
117 0           push(@h, _get_all_dbi_child_handles($_))
118 0           for (grep { defined } @{$h->{ChildHandles}});
  0            
119 0           return @h;
120             }
121              
122              
123             1;