Skip to content

Commit

Permalink
Merge pull request #147 from rollun-lc/feature/add-network-exceptions
Browse files Browse the repository at this point in the history
Add ConnectionException, OperationTimedOutException and DataStoreServerException
  • Loading branch information
misha-rollun authored Jul 1, 2024
2 parents 7f31220 + bae9538 commit 5e58458
Show file tree
Hide file tree
Showing 21 changed files with 718 additions and 139 deletions.
32 changes: 32 additions & 0 deletions config/autoload/db.global.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,37 @@
'password' => getenv('DB_PASS'),
'hostname' => getenv('DB_HOST'),
'port' => getenv('DB_PORT') ?: 3306,
'adapters' => [
'db.pdo.wrong-connection' => [
'driver' => 'Pdo_Mysql',
'database' => getenv('DB_NAME'),
'username' => getenv('DB_USER'),
'password' => 'wrong',
'hostname' => getenv('DB_HOST'),
'port' => getenv('DB_PORT') ?: 3306,
],
'db.mysqli.wrong-connection' => [
'driver' => 'Mysqli',
'database' => getenv('DB_NAME'),
'username' => getenv('DB_USER'),
'password' => 'wrong',
'hostname' => getenv('DB_HOST'),
'port' => getenv('DB_PORT') ?: 3306,
],
'db.mysqli.timeout-1-sec' => [
'driver' => 'Mysqli',
'database' => getenv('DB_NAME'),
'username' => getenv('DB_USER'),
'password' => getenv('DB_PASS'),
'hostname' => getenv('DB_HOST'),
'port' => getenv('DB_PORT') ?: 3306,
'options' => [
'buffer_results' => true,
],
'driver_options' => [
MYSQLI_OPT_READ_TIMEOUT => 1
],
],
]
],
];
25 changes: 0 additions & 25 deletions config/autoload/test.global.php

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace rollun\datastore\DataStore\ConditionBuilder;

use rollun\datastore\DataStore\ConnectionException;
use rollun\datastore\Rql\Node\BinaryNode\BinaryOperatorNodeAbstract;
use Xiag\Rql\Parser\DataType\Glob;
use Xiag\Rql\Parser\Node\AbstractQueryNode;
Expand Down Expand Up @@ -45,6 +46,7 @@ abstract class ConditionBuilderAbstract
*
* @param AbstractQueryNode $rootQueryNode
* @return string
* @throws ConnectionException|DataStoreException
*/
public function __invoke(AbstractQueryNode $rootQueryNode = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

namespace rollun\datastore\DataStore\ConditionBuilder;

use Laminas\Db\Adapter\Exception\RuntimeException;
use rollun\datastore\DataStore\ConnectionException;
use rollun\datastore\DataStore\LaminasDbExceptionDetector;
use rollun\datastore\DataStore\OperationTimedOutException;
use rollun\datastore\Rql\Node\BinaryNode\BinaryOperatorNodeAbstract;
use Xiag\Rql\Parser\DataType\Glob;
use Xiag\Rql\Parser\Node\Query\AbstractScalarOperatorNode;
Expand Down Expand Up @@ -81,7 +85,17 @@ public function prepareFieldValue($fieldValue)
return $fieldValue;
}

return $this->db->platform->quoteValue($fieldValue);
try {
return $this->db->platform->quoteValue($fieldValue);
} catch (RuntimeException $e) {
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
if (LaminasDbExceptionDetector::isOperationTimedOutException($e)) {
throw new OperationTimedOutException($e->getMessage(), $e->getCode(), $e);
}
throw $e;
}
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/DataStore/src/DataStore/ConnectionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace rollun\datastore\DataStore;

/**
* Error establishing TCP (or any other, specific for datastore) connection
*/
class ConnectionException extends DataStoreException
{

}
11 changes: 11 additions & 0 deletions src/DataStore/src/DataStore/DataStoreServerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace rollun\datastore\DataStore;

/**
* Some server-side error, like HTTP 5xx response
* TODO: implement recognizing this exception in DbTable data store
*/
class DataStoreServerException extends DataStoreException
{
}
76 changes: 71 additions & 5 deletions src/DataStore/src/DataStore/DbTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace rollun\datastore\DataStore;

use InvalidArgumentException;
use Laminas\Db\Adapter\Exception\RuntimeException;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use rollun\datastore\DataStore\ConditionBuilder\SqlConditionBuilder;
Expand Down Expand Up @@ -86,6 +87,7 @@ protected function getSqlQueryBuilder()

/**
* {@inheritdoc}
* @throws ConnectionException|DataStoreException
*/
public function create($itemData, $rewriteIfExist = false)
{
Expand All @@ -95,7 +97,7 @@ public function create($itemData, $rewriteIfExist = false)
}

$adapter = $this->dbTable->getAdapter();
$adapter->getDriver()->getConnection()->beginTransaction();
$this->beginTransaction();

try {
$insertedItem = $this->insertItem($itemData, $rewriteIfExist);
Expand Down Expand Up @@ -154,6 +156,7 @@ protected function insertItem($itemData, $rewriteIfExist = false)

/**
* {@inheritdoc}
* @throws ConnectionException|DataStoreException
*/
public function update($itemData, $createIfAbsent = false)
{
Expand All @@ -166,7 +169,7 @@ public function update($itemData, $createIfAbsent = false)
}

$adapter = $this->dbTable->getAdapter();
$adapter->getDriver()->getConnection()->beginTransaction();
$this->beginTransaction();

try {
$result = $this->updateItem($itemData, $createIfAbsent);
Expand Down Expand Up @@ -428,6 +431,12 @@ public function query(Query $query)
} catch (\Throwable $e) {
$logContext['exception'] = $e;
$this->writeLogsIfNeeded($logContext, "Request to db table '{$this->dbTable->getTable()}' failed");
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
if (LaminasDbExceptionDetector::isOperationTimedOutException($e)) {
throw new OperationTimedOutException($e->getMessage(), $e->getCode(), $e);
}
throw $e;
}

Expand Down Expand Up @@ -474,6 +483,12 @@ public function delete($id)
} catch (\Throwable $e) {
$logContext['exception'] = $e;
$this->writeLogsIfNeeded($logContext, "Request to db table '{$this->dbTable->getTable()}' failed");
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
if (LaminasDbExceptionDetector::isOperationTimedOutException($e)) {
throw new OperationTimedOutException($e->getMessage(), $e->getCode(), $e);
}
throw $e;
}

Expand Down Expand Up @@ -508,6 +523,12 @@ public function read($id)
} catch (\Throwable $e) {
$logContext['exception'] = $e;
$this->writeLogsIfNeeded($logContext, "Request to db table '{$this->dbTable->getTable()}' failed");
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
if (LaminasDbExceptionDetector::isOperationTimedOutException($e)) {
throw new OperationTimedOutException($e->getMessage(), $e->getCode(), $e);
}
throw $e;
}

Expand All @@ -532,7 +553,17 @@ public function read($id)
public function deleteAll()
{
$where = '1=1';
return $this->dbTable->delete($where);
try {
return $this->dbTable->delete($where);
} catch (RuntimeException $e) {
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
if (LaminasDbExceptionDetector::isOperationTimedOutException($e)) {
throw new OperationTimedOutException($e->getMessage(), $e->getCode(), $e);
}
throw new DataStoreException($e->getMessage(), $e->getCode(), $e);
}
}

/**
Expand All @@ -544,7 +575,17 @@ public function count()

$sql = 'SELECT COUNT(*) AS count FROM ' . $adapter->getPlatform()->quoteIdentifier($this->dbTable->getTable());

$statement = $adapter->getDriver()->createStatement($sql);
try {
$statement = $adapter->getDriver()->createStatement($sql);
} catch (RuntimeException $e) {
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
if (LaminasDbExceptionDetector::isOperationTimedOutException($e)) {
throw new OperationTimedOutException($e->getMessage(), $e->getCode(), $e);
}
throw new DataStoreException($e->getMessage(), $e->getCode(), $e);
}
$result = $statement->execute();

return $result->current()['count'];
Expand All @@ -558,7 +599,14 @@ public function count()
public function multiCreate($itemsData)
{
$multiInsertTableGw = $this->createMultiInsertTableGw();
$multiInsertTableGw->getAdapter()->getDriver()->getConnection()->beginTransaction();
try {
$multiInsertTableGw->getAdapter()->getDriver()->getConnection()->beginTransaction();
} catch (RuntimeException $e) {
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
throw $e;
}
$getIdCallable = function ($item) {
return $item[$this->getIdentifier()];
};
Expand Down Expand Up @@ -646,4 +694,22 @@ private function getRequestTime(float $start, float $end): float
{
return round($end - $start, 3);
}

/**
* @throws ConnectionException
*/
private function beginTransaction(): void
{
try {
$this->dbTable->getAdapter()->getDriver()->getConnection()->beginTransaction();
} catch (RuntimeException $e) {
if (LaminasDbExceptionDetector::isConnectionException($e)) {
throw new ConnectionException($e->getMessage(), $e->getCode(), $e);
}
if (LaminasDbExceptionDetector::isOperationTimedOutException($e)) {
throw new OperationTimedOutException($e->getMessage(), $e->getCode(), $e);
}
throw $e;
}
}
}
Loading

0 comments on commit 5e58458

Please sign in to comment.