diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index 912e5779b2e..1b7fc54198d 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -30,6 +30,7 @@ use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\DBAL\Cache\ArrayStatement; use Doctrine\DBAL\Cache\CacheException; +use Doctrine\DBAL\Driver\PingableConnection; /** * A wrapper around a Doctrine\DBAL\Driver\Connection that adds features like @@ -1488,4 +1489,31 @@ public function createQueryBuilder() { return new Query\QueryBuilder($this); } + + /** + * Ping the server! + * + * @return bool + */ + public function ping() + { + if ( ! $this->_isConnected) { + return false; // Don't connect if not done yet. It will be lazy on first use + } + + if ($this->_conn instanceof PingableConnection) { + return $this->_conn->ping(); + } + + try { + $this->query($this->_platform->getDummySelectSQL()); + + return true; + } catch (DBALException $e) { + // As the underlying connection is unset, the next query will connect again thanks to the lazyness + $this->close(); + } + + return false; + } } diff --git a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php index fde9e984921..7aefb26aa07 100644 --- a/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php +++ b/lib/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php @@ -20,11 +20,13 @@ namespace Doctrine\DBAL\Driver\Mysqli; use Doctrine\DBAL\Driver\Connection as Connection; +use \Doctrine\DBAL\Driver\PingableConnection; /** * @author Kim Hemsø Rasmussen + * @author Till Klampaeckel */ -class MysqliConnection implements Connection +class MysqliConnection implements Connection, PingableConnection { /** * @var \mysqli @@ -207,4 +209,14 @@ private function setDriverOptions(array $driverOptions = array()) ); } } + + /** + * Pings the server and re-connects when `mysqli.reconnect = 1` + * + * @return bool + */ + public function ping() + { + return $this->_conn->ping(); + } } diff --git a/lib/Doctrine/DBAL/Driver/PingableConnection.php b/lib/Doctrine/DBAL/Driver/PingableConnection.php new file mode 100644 index 00000000000..9bc893778be --- /dev/null +++ b/lib/Doctrine/DBAL/Driver/PingableConnection.php @@ -0,0 +1,39 @@ +. + */ + +namespace Doctrine\DBAL\Driver; + +/** + * An interface for connections which support a "native" ping method. + * + * @link www.doctrine-project.org + * @since 2.5 + * @author Till Klampaeckel + * @author Benjamin Eberlei + */ +interface PingableConnection +{ + /** + * Pings the database server to determine if the connection is still + * available. Return true/false based on if that was successful or not. + * + * @return bool + */ + public function ping(); +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php index 31da42f32bd..9ab7621bfde 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php @@ -193,6 +193,7 @@ public function testTransactionalWithException() { try { $this->_conn->transactional(function($conn) { + /* @var $conn \Doctrine\DBAL\Connection */ $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL()); throw new \RuntimeException("Ooops!"); }); @@ -204,7 +205,7 @@ public function testTransactionalWithException() public function testTransactional() { $this->_conn->transactional(function($conn) { - /* @var $conn Connection */ + /* @var $conn \Doctrine\DBAL\Connection */ $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL()); }); } @@ -216,4 +217,15 @@ public function testQuote() { $this->assertEquals($this->_conn->quote("foo", Type::STRING), $this->_conn->quote("foo", \PDO::PARAM_STR)); } + + public function testPingDoesNotTriggerConnect() + { + $this->assertFalse($this->_conn->ping()); + } + + public function testPingReturnsTrueWhenConnectionIsPingedOrOpen() + { + $this->_conn->connect(); + $this->assertTrue($this->_conn->ping()); + } } diff --git a/tests/Doctrine/Tests/DBAL/Functional/Mysqli/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/Mysqli/ConnectionTest.php index 662e0ea5a35..ec25e5b78cf 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Mysqli/ConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Mysqli/ConnectionTest.php @@ -39,6 +39,12 @@ public function testUnsupportedDriverOption() $this->getConnection(array('hello' => 'world')); // use local infile } + public function testPing() + { + $conn = $this->getConnection(array()); + $this->assertTrue($conn->ping()); + } + private function getConnection(array $driverOptions) { return new \Doctrine\DBAL\Driver\Mysqli\MysqliConnection(