Skip to content
Snippets Groups Projects
Commit b11de370 authored by Marek Szuba's avatar Marek Szuba
Browse files

dbConnection.t: do not use $dbh->ping() to check if disconnected from DB

A bugfix implemented in DBD::mysql between 4.049 and 4.050 means that
pinging a MySQL server now implicitly reestablishes the connection if
down for whatever reason. Moreover, it is not clear from DBI
documentation whether ping() is supposed to check if the connection to
the database was open before calling it or not (it says "if the database
server is still running and the connection to it is still working",
which may well mean the _network_ connection between the client and the
server rather than an open _database_ connection) and the behaviour of
specific implementations varies. For instance:
 - DBD::Oracle: according to documentation it returns "either 0,
   indicating that the connection is no longer valid, or 1 indicating
   the connection is valid", under the bonnet it calls either OCIPing()
   (if available) or OCIServerVersion(). In light of the facts both of
   these methods take a service-context handle as an argument and that
   disconnect() calls OCIServerDetach(), which quite thoroughly releases
   resources allocated to the database client, it is likely ping() will
   return 0 if disconnected;
 - DBD::Pg: according to documentation it checks "if there is a
   working connection to an active database server", the code under
   the bonnet is non-trivial but the module's test suite indicates
   ping() is supposed to return 0 after disconnect();
 - DBD::SQLite: according to documentation it checks "if the
   database connection is active", under the bonnet seems to rely on
   the "Active" flag (see below);
 - finally, DBD::mysql - documentation simply says "this can be used to
   ping the server" and under the bonnet the module explicitly attempts
   to reconnect to the database, which only did not happen due to the
   aforementioned bug.

In light of the above, we now check the "Active" attribute of the
database handle to check if we are still connected. According to DBI
documentation, "the exact meaning of active is somewhat vague at the
moment. For a database handle it typically means that the handle is
connected to a database ($dbh->disconnect sets Active off)"; the latter
is indeed the case for all four DBD modules mentioned above.

This fixes dbConnection.t test failures when running with
DBD::mysql-4.050.

Note that there are still some occurrences of ping() in the test file,
however in the remaining cases it is called as a method of
$dbc->db_handle rather than of $dbh. These should in theory be one and
the same but just to be extra careful, we will take care of those
separately.
parent dbd5c058
No related branches found
No related tags found
2 merge requests!359dbConnection.t: do not use $dbh->ping() to check if disconnected from DB [master],!359dbConnection.t: do not use $dbh->ping() to check if disconnected from DB [master]
......@@ -120,9 +120,11 @@ is_deeply($dbc->to_hash(), \%dbc_args, 'Checking to_hash() can roundtrip a DBCon
#
my $dbh = $dbc->db_handle();
ok( $dbh->{Active}, 'DB handle is active before enabling disconnect_when_inactive()' );
$dbc->disconnect_when_inactive(1);
ok(!$dbh->ping());
ok( !$dbh->{Active}, 'DB handle has deactivated after enabling disconnect_when_inactive()' );
{
# reconnect should happen now
......@@ -135,7 +137,7 @@ ok(!$dbh->ping());
# disconnect should occur now
}
ok(!$dbh->ping());
ok( !$dbh->{Active}, 'DB handle has deactivated after previous test' );
$dbh = $dbc->db_handle();
......@@ -161,7 +163,7 @@ $dbh = $dbc->db_handle();
}
ok(!$dbh->ping());
ok( !$dbh->{Active}, 'DB handle has deactivated after previous tests' );
$dbc->disconnect_when_inactive(0);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment