a closed STDERR...
Revision history for DBIx::Class
+ - refactor Statistics to create debugging filehandle to fix bug with
+ closed STDERR, update docs and modify Versioned to use Statistics
+ (original fix from diz)
+
0.08004 2007-08-06 19:00:00
- fix storage connect code to not trigger bug via auto-viv
(test from aherzog)
my $sql = shift();
my $params = @_;
- print "Executing $sql: ".join(', ', @params)."\n";
+ $self->print("Executing $sql: ".join(', ', @params)."\n");
$start = time();
}
my $sql = shift();
my @params = @_;
- printf("Execution took %0.4f seconds.\n", time() - $start);
+ my $elapsed = sprintf("%0.4f", time() - $start);
+ $self->print("Execution took $elapsed seconds.\n");
$start = undef;
}
You can then install that class as the debugging object:
- __PACKAGE__->storage()->debugobj(new My::Profiler());
- __PACKAGE__->storage()->debug(1);
+ __PACKAGE__->storage->debugobj(new My::Profiler());
+ __PACKAGE__->storage->debug(1);
A more complicated example might involve storing each execution of SQL in an
array:
You could then create average, high and low execution times for an SQL
statement and dig down to see if certain parameters cause aberrant behavior.
+You might want to check out L<DBIx::Class::QueryLog> as well.
=head2 Getting the value of the primary key for the last database insert
for (@statements)
{
- $self->storage->debugfh->print("$_\n") if $self->storage->debug;
-# print "Running \n>>$_<<\n";
+ $self->storage->debugobj->query_start($_) if $self->storage->debug;
$self->storage->dbh->do($_) or warn "SQL was:\n $_";
+ $self->storage->debugobj->query_end($_) if $self->storage->debug;
}
return 1;
$new->set_schema($schema);
$new->debugobj(new DBIx::Class::Storage::Statistics());
- my $fh;
+ #my $fh;
my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
|| $ENV{DBIC_TRACE};
- if (defined($debug_env) && ($debug_env =~ /=(.+)$/)) {
- $fh = IO::File->new($1, 'w')
- or $new->throw_exception("Cannot open trace file $1");
- } else {
- $fh = IO::File->new('>&STDERR');
- }
-
- $fh->autoflush(1);
- $new->debugfh($fh);
$new->debug(1) if $debug_env;
$new;
should be set to STDERR - although see information on the
L<DBIC_TRACE> environment variable.
+=head2 print
+
+Prints the specified string to our debugging filehandle, which we will attempt
+to open if we haven't yet. Provided to save our methods the worry of how
+to display the message.
+
+=cut
+sub print {
+ my ($self, $msg) = @_;
+
+ if(!defined($self->debugfh())) {
+ my $fh;
+ my $debug_env = $ENV{DBIX_CLASS_STORAGE_DBI_DEBUG}
+ || $ENV{DBIC_TRACE};
+ if (defined($debug_env) && ($debug_env =~ /=(.+)$/)) {
+ $fh = IO::File->new($1, 'w')
+ or die("Cannot open trace file $1");
+ } else {
+ $fh = IO::File->new('>&STDERR')
+ or die('Duplication of STDERR for debug output failed (perhaps your STDERR is closed?)');
+ }
+
+ $fh->autoflush();
+ $self->debugfh($fh);
+ }
+
+ $self->debugfh->print($msg);
+}
+
=head2 txn_begin
Called when a transaction begins.
sub txn_begin {
my $self = shift;
- $self->debugfh->print("BEGIN WORK\n");
+ $self->print("BEGIN WORK\n");
}
=head2 txn_rollback
sub txn_rollback {
my $self = shift;
- $self->debugfh->print("ROLLBACK\n");
+ $self->print("ROLLBACK\n");
}
=head2 txn_commit
sub txn_commit {
my $self = shift;
- $self->debugfh->print("COMMIT\n");
+ $self->print("COMMIT\n");
}
=head2 query_start
return;
}
- $self->debugfh->print($message);
+ $self->print($message);
}
=head2 query_end
my $schema = DBICTest->init_schema();
-plan tests => 2;
+plan tests => 5;
ok ( $schema->storage->debug(1), 'debug' );
ok ( defined(
'debugfh'
);
+my $rs = $schema->resultset('CD')->search({});
+$rs->count();
+
+my $log = new IO::File('t/var/sql.log', 'r') or die($!);
+my $line = <$log>;
+$log->close();
+ok($line =~ /^SELECT COUNT/, 'Log success');
+
+$schema->storage->debugfh(undef);
+$ENV{'DBIC_TRACE'} = '=t/var/foo.log';
+$rs = $schema->resultset('CD')->search({});
+$rs->count();
+$log = new IO::File('t/var/foo.log', 'r') or die($!);
+$line = <$log>;
+$log->close();
+ok($line =~ /^SELECT COUNT/, 'Log success');
+
+$schema->storage->debugobj->debugfh(undef);
+delete($ENV{'DBIC_TRACE'});
+open(STDERRCOPY, '>&STDERR');
+stat(STDERRCOPY); # nop to get warnings quiet
+close(STDERR);
+eval {
+ $rs = $schema->resultset('CD')->search({});
+ $rs->count();
+};
+ok($@, 'Died on closed FH');
+open(STDERR, '>&STDERRCOPY');
+
1;