diff --git a/src/Adapter/Adapter.php b/src/Adapter/Adapter.php index e356ff9a58..ad89139360 100644 --- a/src/Adapter/Adapter.php +++ b/src/Adapter/Adapter.php @@ -313,7 +313,7 @@ protected function createDriver($parameters) $driver = new Driver\Oci8\Oci8($parameters); break; case 'pgsql': - $driver = new Driver\Pgsql\Pgsql($parameters); + $driver = new Driver\Pgsql\Pgsql($parameters, null, null, $options); break; case 'ibmdb2': $driver = new Driver\IbmDb2\IbmDb2($parameters); diff --git a/src/Adapter/Driver/DriverInterface.php b/src/Adapter/Driver/DriverInterface.php index 615dbb729f..cd76bfd830 100644 --- a/src/Adapter/Driver/DriverInterface.php +++ b/src/Adapter/Driver/DriverInterface.php @@ -9,6 +9,8 @@ namespace Zend\Db\Adapter\Driver; +use Zend\Db\Adapter\Driver\Mysqli\Statement; + interface DriverInterface { const PARAMETERIZATION_POSITIONAL = 'positional'; @@ -65,7 +67,7 @@ public function getPrepareType(); * Format parameter name * * @param string $name - * @param mixed $type + * @param mixed $type * @return string */ public function formatParameterName($name, $type = null); @@ -76,4 +78,13 @@ public function formatParameterName($name, $type = null); * @return mixed */ public function getLastGeneratedValue(); + + /** + * Check current connection to DB. + * If connection lost try reconnect. + * + * @param StatementInterface|null $statement + * @return $this + */ + public function checkConnection(StatementInterface $statement = null); } diff --git a/src/Adapter/Driver/IbmDb2/IbmDb2.php b/src/Adapter/Driver/IbmDb2/IbmDb2.php index 11a064cc91..79c27342d4 100644 --- a/src/Adapter/Driver/IbmDb2/IbmDb2.php +++ b/src/Adapter/Driver/IbmDb2/IbmDb2.php @@ -10,6 +10,7 @@ namespace Zend\Db\Adapter\Driver\IbmDb2; use Zend\Db\Adapter\Driver\DriverInterface; +use Zend\Db\Adapter\Driver\StatementInterface; use Zend\Db\Adapter\Exception; use Zend\Db\Adapter\Profiler; @@ -211,4 +212,14 @@ public function getLastGeneratedValue() { return $this->connection->getLastGeneratedValue(); } + + /** + * @inheritdoc + * @param StatementInterface|null $statement + * @return $this + */ + public function checkConnection(StatementInterface $statement = null) + { + return $this; + } } diff --git a/src/Adapter/Driver/Mysqli/Connection.php b/src/Adapter/Driver/Mysqli/Connection.php index c94e009638..c0e9d8ff74 100644 --- a/src/Adapter/Driver/Mysqli/Connection.php +++ b/src/Adapter/Driver/Mysqli/Connection.php @@ -191,6 +191,8 @@ public function disconnect() $this->resource->close(); } $this->resource = null; + + return $this; } /** diff --git a/src/Adapter/Driver/Mysqli/Mysqli.php b/src/Adapter/Driver/Mysqli/Mysqli.php index c1f3da5177..c3d56bec18 100644 --- a/src/Adapter/Driver/Mysqli/Mysqli.php +++ b/src/Adapter/Driver/Mysqli/Mysqli.php @@ -11,6 +11,7 @@ use mysqli_stmt; use Zend\Db\Adapter\Driver\DriverInterface; +use Zend\Db\Adapter\Driver\StatementInterface; use Zend\Db\Adapter\Exception; use Zend\Db\Adapter\Profiler; @@ -61,6 +62,7 @@ public function __construct( $connection = new Connection($connection); } + $this->options = array_merge($this->options, $options); $options = array_intersect_key(array_merge($this->options, $options), $this->options); $this->registerConnection($connection); @@ -259,4 +261,39 @@ public function getLastGeneratedValue() { return $this->getConnection()->getLastGeneratedValue(); } + + /** + * Check connection if not exists -> try to reconnect. + * Depends on configuration value `reconnect_tries` + * + * @param StatementInterface|null $statement + * @return $this + */ + public function checkConnection(StatementInterface $statement = null) + { + + $reconnectTries = array_key_exists('reconnect_tries', $this->options) + ? $this->options['reconnect_tries'] : 0; + + /** + * @var \mysqli $mysqli + */ + $mysqli = $this->connection->getResource(); + + for ($i = 0; $i < $reconnectTries; ++$i) { + if ($mysqli->ping()) { + if ($statement instanceof Statement) { + $statement->initialize($mysqli); + } + + return $this; + } + + $mysqli = $this->connection + ->disconnect() + ->connect() + ->getResource(); + } + return $this; + } } diff --git a/src/Adapter/Driver/Mysqli/Statement.php b/src/Adapter/Driver/Mysqli/Statement.php index 140d4aac58..765db8f1c2 100644 --- a/src/Adapter/Driver/Mysqli/Statement.php +++ b/src/Adapter/Driver/Mysqli/Statement.php @@ -202,6 +202,7 @@ public function prepare($sql = null) } $sql = ($sql) ?: $this->sql; + $this->driver->checkConnection($this); $this->resource = $this->mysqli->prepare($sql); if (! $this->resource instanceof \mysqli_stmt) { diff --git a/src/Adapter/Driver/Oci8/Oci8.php b/src/Adapter/Driver/Oci8/Oci8.php index 3f0ba5af99..93db172d2c 100644 --- a/src/Adapter/Driver/Oci8/Oci8.php +++ b/src/Adapter/Driver/Oci8/Oci8.php @@ -10,6 +10,7 @@ namespace Zend\Db\Adapter\Driver\Oci8; use Zend\Db\Adapter\Driver\DriverInterface; +use Zend\Db\Adapter\Driver\StatementInterface; use Zend\Db\Adapter\Exception; use Zend\Db\Adapter\Profiler; use Zend\Db\Adapter\Driver\Feature\AbstractFeature; @@ -299,4 +300,14 @@ public function getLastGeneratedValue() { return $this->getConnection()->getLastGeneratedValue(); } + + /** + * @inheritdoc + * @param StatementInterface|null $statement + * @return $this + */ + public function checkConnection(StatementInterface $statement = null) + { + return $this; + } } diff --git a/src/Adapter/Driver/Pdo/Pdo.php b/src/Adapter/Driver/Pdo/Pdo.php index daf4075c5e..15609cc45b 100644 --- a/src/Adapter/Driver/Pdo/Pdo.php +++ b/src/Adapter/Driver/Pdo/Pdo.php @@ -13,6 +13,7 @@ use Zend\Db\Adapter\Driver\DriverInterface; use Zend\Db\Adapter\Driver\Feature\AbstractFeature; use Zend\Db\Adapter\Driver\Feature\DriverFeatureInterface; +use Zend\Db\Adapter\Driver\StatementInterface; use Zend\Db\Adapter\Exception; use Zend\Db\Adapter\Profiler; @@ -328,4 +329,14 @@ public function getLastGeneratedValue($name = null) { return $this->connection->getLastGeneratedValue($name); } + + /** + * @inheritdoc + * @param StatementInterface|null $statement + * @return $this + */ + public function checkConnection(StatementInterface $statement = null) + { + return $this; + } } diff --git a/src/Adapter/Driver/Pgsql/Pgsql.php b/src/Adapter/Driver/Pgsql/Pgsql.php index b99b641e30..ac68af0cc0 100644 --- a/src/Adapter/Driver/Pgsql/Pgsql.php +++ b/src/Adapter/Driver/Pgsql/Pgsql.php @@ -10,6 +10,7 @@ namespace Zend\Db\Adapter\Driver\Pgsql; use Zend\Db\Adapter\Driver\DriverInterface; +use Zend\Db\Adapter\Driver\StatementInterface; use Zend\Db\Adapter\Exception; use Zend\Db\Adapter\Profiler; @@ -54,11 +55,12 @@ public function __construct( $connection, Statement $statementPrototype = null, Result $resultPrototype = null, - $options = null + $options = [] ) { if (! $connection instanceof Connection) { $connection = new Connection($connection); } + $this->options = array_merge($this->options, $options); $this->registerConnection($connection); $this->registerStatementPrototype(($statementPrototype) ?: new Statement()); @@ -234,4 +236,40 @@ public function getLastGeneratedValue($name = null) { return $this->connection->getLastGeneratedValue($name); } + + /** + * @inheritdoc + * @param StatementInterface|null $statement + * @return $this + */ + public function checkConnection(StatementInterface $statement = null) + { + + $reconnectTries = array_key_exists('reconnect_tries', $this->options) + ? $this->options['reconnect_tries'] : 0; + + $pg_sql = $this->connection->getResource(); + + for ($i = 0; $i < $reconnectTries; ++$i) { + if (pg_connection_status($pg_sql) == PGSQL_CONNECTION_OK) { + if ($statement instanceof Statement) { + $statement + ->initialize($pg_sql) + ->prepare(); + } + + return $this; + } + + try { + $pg_sql = $this->connection + ->disconnect() + ->connect() + ->getResource(); + } catch (Exception\RuntimeException $e) { + print $e->getMessage(); + } + } + return $this; + } } diff --git a/src/Adapter/Driver/Pgsql/Statement.php b/src/Adapter/Driver/Pgsql/Statement.php index c7e8450626..f54a23acf9 100644 --- a/src/Adapter/Driver/Pgsql/Statement.php +++ b/src/Adapter/Driver/Pgsql/Statement.php @@ -88,7 +88,7 @@ public function getProfiler() * Initialize * * @param resource $pgsql - * @return void + * @return $this * @throws Exception\RuntimeException for invalid or missing postgresql connection */ public function initialize($pgsql) @@ -101,6 +101,7 @@ public function initialize($pgsql) )); } $this->pgsql = $pgsql; + return $this; } /** @@ -202,6 +203,7 @@ public function execute($parameters = null) if (! $this->isPrepared()) { $this->prepare(); } + $this->driver->checkConnection($this); /** START Standard ParameterContainer Merging Block */ if (! $this->parameterContainer instanceof ParameterContainer) { diff --git a/src/Adapter/Driver/Sqlsrv/Sqlsrv.php b/src/Adapter/Driver/Sqlsrv/Sqlsrv.php index 9a712905a5..228ea8aa96 100644 --- a/src/Adapter/Driver/Sqlsrv/Sqlsrv.php +++ b/src/Adapter/Driver/Sqlsrv/Sqlsrv.php @@ -10,6 +10,7 @@ namespace Zend\Db\Adapter\Driver\Sqlsrv; use Zend\Db\Adapter\Driver\DriverInterface; +use Zend\Db\Adapter\Driver\StatementInterface; use Zend\Db\Adapter\Exception; use Zend\Db\Adapter\Profiler; @@ -212,4 +213,14 @@ public function getLastGeneratedValue() { return $this->getConnection()->getLastGeneratedValue(); } + + /** + * @inheritdoc + * @param StatementInterface|null $statement + * @return $this + */ + public function checkConnection(StatementInterface $statement = null) + { + return $this; + } }