ap / DBIx-Connector

Fast, safe DBI connection and transaction management
https://metacpan.org/release/DBIx-Connector
40 stars 14 forks source link

Add workaround for broken ping in DBD::Pg #41

Open timbunce opened 9 years ago

timbunce commented 9 years ago

See the DBD::Pg ping bug report for details.

theory commented 8 years ago

I started to work on this, but this doesn't work:

diff --git a/lib/DBIx/Connector/Driver/Pg.pm b/lib/DBIx/Connector/Driver/Pg.pm
index c85e044..982443e 100644
--- a/lib/DBIx/Connector/Driver/Pg.pm
+++ b/lib/DBIx/Connector/Driver/Pg.pm
@@ -20,6 +20,31 @@ sub rollback_to {
     $dbh->pg_rollback_to($name);
 }

+sub ping {
+    # Work around broken ping in DBD::Pg before v3.5.
+    # https://rt.cpan.org/Ticket/Display.html?id=100648
+    my ($vn) = $DBD::Pg::VERSION =~ /\A(\d+[.]\d+)/;
+    my $ping = $vn < 3.5 ? sub {
+        Test::More::diag("old ping");
+        my ($self, $dbh) = @_;
+        local $dbh->{RaiseError} = 0;
+        local $dbh->{PrintError} = 0;
+        local $dbh->{HandleError} = undef;
+        my $sth = $dbh->prepare_cached('SELECT TRUE') or return 0;
+        $sth->execute or return 0;
+        $sth->finish;
+        return 1;
+    } : sub {
+        my ($self, $dbh) = @_;
+        return $dbh->ping;
+    };
+
+    # Replace ourself.
+    no warnings 'redefine';
+    *ping = $ping;
+    goto &ping;
+}
+
 1;
 __END__

@@ -40,6 +65,8 @@ PostgreSQL-specific implementations of the following methods:

 =item C<rollback_to>

+=item C<ping>
+
 =back

 =head1 Authors

Here's what the failure looks like when using the workaround ping:

> DBICTEST_DSN=dbi:Pg: prove -l t/svp_live.t  
t/svp_live.t .. 1/38 # old ping
DBD::Pg::db selectrow_array failed: ERROR:  current transaction is aborted, commands ignored until end of transaction block at t/svp_live.t line 127.
# Looks like you planned 38 tests but ran 32.
# Looks like your test exited with 255 just after 32.
t/svp_live.t .. Dubious, test returned 255 (wstat 65280, 0xff00)
Failed 6/38 subtests 

Test Summary Report
-------------------
t/svp_live.t (Wstat: 65280 Tests: 32 Failed: 0)
  Non-zero exit status: 255
  Parse errors: Bad plan.  You planned 38 tests but ran 32.
Files=1, Tests=32,  0 wallclock secs ( 0.03 usr  0.00 sys +  0.05 cusr  0.01 csys =  0.09 CPU)
Result: FAIL

I don't know why it does that, but don't really have time to deal with it, especially since no one has missed this, and it's easily fixed by upgrading DBD::Pg. Thinking of just recommending that and letting it go. Thoughts?