DBI-Log
view release on metacpan or search on metacpan
lib/DBI/Log.pm view on Meta::CPAN
return $retval;
};
my $orig_selectall_hashref = \&DBI::db::selectall_hashref;
*DBI::db::selectall_hashref = sub {
my ($dbh, $query, $yup, @args) = @_;
my $log = pre_query("selectall_hashref", $dbh, undef, $query, \@args);
my $retval = $orig_selectall_hashref->($dbh, $query, $yup, @args);
post_query($log);
return $retval;
};
my $orig_selectrow_arrayref = \&DBI::db::selectrow_arrayref;
*DBI::db::selectrow_arrayref = sub {
my ($dbh, $query, $yup, @args) = @_;
my $log = pre_query("selectrow_arrayref", $dbh, $sth, $query, \@args);
my $retval = $orig_selectrow_arrayref->($dbh, $query, $yup, @args);
post_query($log);
return $retval;
};
my $orig_selectrow_array = \&DBI::db::selectrow_array;
*DBI::db::selectrow_array = sub {
my ($dbh, $query, $yup, @args) = @_;
my $log = pre_query("selectrow_array", $dbh, undef, $query, \@args);
my $retval = $orig_selectrow_array->($dbh, $query, $yup, @args);
post_query($log);
return $retval;
};
my $orig_selectrow_hashref = \&DBI::db::selectrow_hashref;
*DBI::db::selectrow_hashref = sub {
my ($dbh, $query, $yup, @args) = @_;
my $log = pre_query("selectrow_hashref", $dbh, undef, $query, \@args);
my $retval = $orig_selectrow_hashref->($dbh, $query, $yup, @args);
post_query($log);
return $retval;
};
my $orig_do = \&DBI::db::do;
*DBI::db::do = sub {
my ($dbh, $query, $yup, @args) = @_;
my $log = pre_query("do", $dbh, undef, $query, \@args);
my $retval = $orig_do->($dbh, $query, $yup, @args);
post_query($log);
return $retval;
};
sub import {
my ($package, %args) = @_;
for my $key (keys %args) {
$opts{$key} = $args{$key};
}
if (!$opts{file}) {
$opts{fh} = \*STDERR;
}
else {
my $file2 = $opts{file};
if ($file2 =~ m{^~/}) {
my $home = $ENV{HOME} || (getpwuid($<))[7];
$file2 =~ s{^~/}{$home/};
}
open $opts{fh}, ">>", $file2 or die "Can't open $opts{file}: $!\n";
# autoflush so that tailing to watch queries being performed works
# as you'd expect
$opts{fh}->autoflush(1);
}
}
sub pre_query {
my ($name, $dbh, $sth, $query, $args) = @_;
my $log = {};
my $mcount = 0;
# Some DBI functions are composed of other DBI functions, so make sure we
# are only logging the top level one. For example $dbh->do() will call
# $dbh->execute() internally, so we need to make sure a DBI::Log function
# logs the $dbh->do() and not the internal $dbh->execute(). If multiple
# functions were called, we return and flag this log entry to be skipped in
# the post_query() part.
for (my $i = 0; my @caller = caller($i); $i++) {
my ($package, $file, $line, $sub) = @caller;
if ($package eq "DBI::Log") {
$mcount++;
if ($mcount > 1) {
$log->{skip} = 1;
return $log;
}
}
}
my @callers;
for (my $i = 0; my @caller = caller($i); $i++) {
push @callers, \@caller;
}
# Order the call stack based on the highest level calls first, then the
# lower level calls. Once you reach a package that is excluded, do not show
# any more lines in the stack trace. By default, it will exclude anything
# past the DBI::Log package, but if user provides an exclude option, it will
# stop there.
my @filtered_callers;
CALLER: for my $caller (reverse @callers) {
my ($package, $file, $line, $long_sub) = @$caller;
if ($package eq "DBI::Log") {
last CALLER;
}
if ($opts{exclude}) {
for my $item (@{$opts{exclude}}) {
if ($package =~ /^$item(::|$)/) {
last CALLER;
}
}
}
push @filtered_callers, $caller;
}
if (!$opts{trace}) {
@filtered_callers = ($filtered_callers[-1]);
}
( run in 0.717 second using v1.01-cache-2.11-cpan-6aa56a78535 )