Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
Blocking bug fix. Code clearity enhancements
  • Loading branch information
adamturcsan committed Dec 26, 2016
2 parents 02b98f6 + b43a4be commit 46ffe1a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 32 deletions.
36 changes: 19 additions & 17 deletions src/ReconnectingPDO.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use PDO;
use LegoW\ReconnectingPDO\ReconnectingPDOStatement;
use LegoW\ReconnectingPDO\ReconnectingPDOException;

/**
* It covers the PDO database handler to prevent connection loss caused by non-critical
Expand Down Expand Up @@ -40,7 +41,7 @@ class ReconnectingPDO
/**
* @var PDO
*/
protected $db;
protected $connection;

/**
* @var string DSN
Expand Down Expand Up @@ -110,42 +111,45 @@ public function __call($method, $arguments)
*/
protected function call($method, $arguments)
{
if (!($this->db instanceof PDO)) {
if (!($this->connection instanceof PDO)) {
throw new ReconnectingPDOException('No PDO connection is set');
}
try {
$returnValue = call_user_func_array([$this->db, $method], $arguments);
$this->connection->query('SELECT 1');
$returnValue = call_user_func_array([$this->connection, $method],
$arguments);
} catch (\PDOException $ex) {
if (!stristr($ex->getMessage(), "server has gone away") || $ex->getCode() != 'HY000') {
throw $ex;
}
if ($this->reconnectCounter < $this->maxReconnection) {
$this->reconnectDb();
$returnValue = $this->call($method, $arguments); // Retry
$this->resetCounter();
} else {
if ($this->reconnectCounter >= $this->maxReconnection) {
throw new ExceededMaxReconnectionException('ReconnectingPDO has exceeded max reconnection limit',
$ex->getCode(), $ex);
}
$this->reconnectDb();
$returnValue = $this->call($method, $arguments); // Retry
$this->resetCounter();
}
if ($returnValue instanceof \PDOStatement) {
return new ReconnectingPDOStatement($returnValue, $this, $method === 'query');
return new ReconnectingPDOStatement($returnValue, $this,
$method === 'query');
}
return $returnValue;
}

protected function reconnectDb()
{
unset($this->db);
unset($this->connection);
$this->connectDb();
$this->reconnectCounter++;
}

protected function connectDb()
{
$this->db = new PDO($this->dsn, $this->username, $this->passwd,
$this->connection = new PDO($this->dsn, $this->username, $this->passwd,
$this->options);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);
}

/**
Expand Down Expand Up @@ -173,24 +177,21 @@ public function setMaxReconnection($max)
* @param array $parameters
* @param bool $autoconnect
*/
public function setConnectionParameters($parameters, $autoconnect = false)
public function setConnectionParameters($parameters)
{
foreach ($parameters as $key => $param) {
if (property_exists($this, $key)) {
$this->$key = $param;
}
}
if ($autoconnect) {
$this->connectDb();
}
}

public function setPDO(PDO $pdoObject)
{
if (!$this->connectionParametersAreSet()) {
throw new ConnectionParametersMissingException();
}
$this->db = $pdoObject;
$this->connection = $pdoObject;
}

protected function connectionParametersAreSet()
Expand All @@ -200,4 +201,5 @@ protected function connectionParametersAreSet()
}
return false;
}

}
5 changes: 4 additions & 1 deletion src/ReconnectingPDOStatement.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ protected function call($method, &$arguments)
switch ($method) {
//Differenct method handlers
case 'bindParam':
return $this->statement->bindParam(...$arguments);
for($i=0; $i<5; $i++) {
${'a'.$i} = &$arguments[$i];
}
return $this->statement->bindParam($a0, $a1, $a2, $a3, $a4);
//Pre-call
case 'fetch':
case 'fetchAll':
Expand Down
18 changes: 4 additions & 14 deletions test/ReconnectingPDOTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
use PHPUnit\Framework\TestCase;
use LegoW\ReconnectingPDO\ReconnectingPDO;
use LegoW\ReconnectingPDO\ReconnectingPDOStatement;
use LegoW\ReconnectingPDO\ReconnectingPDOException;
use LegoW\ReconnectingPDO\ConnectionParametersMissingException;
use LegoW\ReconnectingPDO\ExceededMaxReconnectionException;

Expand All @@ -37,9 +36,9 @@ public function testConstruct()
$this->assertAttributeEquals('test', 'passwd', $rpdo);
$this->assertAttributeEquals([], 'options', $rpdo);
$this->assertAttributeEquals(3, 'maxReconnection', $rpdo);
$this->assertAttributeInstanceOf(\PDO::class, 'db', $rpdo);
$this->assertAttributeInstanceOf(\PDO::class, 'connection', $rpdo);
}

public function testSetters()
{
$dsn = 'sqlite::memory:';
Expand Down Expand Up @@ -73,15 +72,6 @@ public function testSetters()
}
$this->assertNull($exception);

unset($rpdo);
$rpdo = new ReconnectingPDO();
$rpdo->setConnectionParameters([
'dsn' => $dsn,
'passwd' => $passwd,
'username' => $username
], true);

$this->assertAttributeInstanceOf(\PDO::class, 'db', $rpdo);
}

public function testReconnection()
Expand All @@ -100,7 +90,7 @@ public function testReconnection()
$rpdo = new ReconnectingPDO($dsn, $username, $passwd);
$rpdo->setPDO($mockPDO);

$this->assertAttributeEquals($mockPDO, 'db', $rpdo);
$this->assertAttributeEquals($mockPDO, 'connection', $rpdo);

$exception = null;
try {
Expand Down Expand Up @@ -151,7 +141,7 @@ public function testCallProtection()
$rpdo = new ReconnectingPDO();

//Should throw exception
$rpdo->prepare('SELECT 1');
$rpdo->query('SELECT 1');
}

public function testQuery()
Expand Down

0 comments on commit 46ffe1a

Please sign in to comment.