Skip to content

Commit 0347a87

Browse files
committed
- Throw more specific exception for "Integrity constraint violation: Duplicate entry"
1 parent 8598acd commit 0347a87

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"require-dev": {
1616
"phpunit/phpunit": "~4.0",
1717
"phake/phake": "1.0.5",
18-
"rkr/fakepdo": "0.1"
18+
"rkr/fakepdo": "0.1.*"
1919
},
2020
"autoload": {
2121
"psr-4": {

src/Builder/QueryStatement.php

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<?php
22
namespace Kir\MySQL\Builder;
33

4+
use Kir\MySQL\Databases\MySQL\MySQLExceptionInterpreter;
45
use PDO;
6+
use PDOException;
57
use PDOStatement;
68
use Kir\MySQL\Database\DatabaseStatement;
79
use Kir\MySQL\QueryLogger\QueryLoggers;
@@ -13,16 +15,20 @@ class QueryStatement implements DatabaseStatement {
1315
private $queryLoggers;
1416
/** @var string */
1517
private $query;
18+
/** @var MySQLExceptionInterpreter */
19+
private $exceptionInterpreter;
1620

1721
/**
1822
* @param PDOStatement $stmt
1923
* @param string $query
24+
* @param MySQLExceptionInterpreter $exceptionInterpreter
2025
* @param QueryLoggers $queryLoggers
2126
*/
22-
public function __construct(PDOStatement $stmt, $query, QueryLoggers $queryLoggers) {
27+
public function __construct(PDOStatement $stmt, $query, MySQLExceptionInterpreter $exceptionInterpreter, QueryLoggers $queryLoggers) {
2328
$this->statement = $stmt;
2429
$this->queryLoggers = $queryLoggers;
2530
$this->query = $query;
31+
$this->exceptionInterpreter = $exceptionInterpreter;
2632
}
2733

2834
/**
@@ -37,18 +43,22 @@ public function getStatement() {
3743
* @return bool
3844
*/
3945
public function execute(array $params = []) {
40-
$timer = microtime(true);
41-
$response = $this->statement->execute($params);
42-
$this->queryLoggers->log($this->query, microtime(true) - $timer);
43-
return $response;
46+
return $this->exceptionHandler(function () use ($params) {
47+
$timer = microtime(true);
48+
$response = $this->statement->execute($params);
49+
$this->queryLoggers->log($this->query, microtime(true) - $timer);
50+
return $response;
51+
});
4452
}
4553

4654
/**
4755
* @return array
4856
*/
4957
public function fetchAll() {
5058
$args = func_get_args();
51-
return call_user_func_array([$this->statement, 'fetchAll'], $args);
59+
return $this->exceptionHandler(function () use ($args) {
60+
return call_user_func_array([$this->statement, 'fetchAll'], $args);
61+
});
5262
}
5363

5464
/**
@@ -58,36 +68,59 @@ public function fetchAll() {
5868
* @return mixed
5969
*/
6070
public function fetch($fetchStyle = PDO::FETCH_ASSOC, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) {
61-
return $this->statement->fetch($fetchStyle, $cursorOrientation, $cursorOffset);
71+
return $this->exceptionHandler(function () use ($fetchStyle, $cursorOrientation, $cursorOffset) {
72+
return $this->statement->fetch($fetchStyle, $cursorOrientation, $cursorOffset);
73+
});
6274
}
6375

6476
/**
6577
* @param int $columnNo
6678
* @return mixed
6779
*/
6880
public function fetchColumn($columnNo = 0) {
69-
return $this->statement->fetchColumn($columnNo);
81+
return $this->exceptionHandler(function () use ($columnNo) {
82+
return $this->statement->fetchColumn($columnNo);
83+
});
7084
}
7185

7286
/**
7387
* @return bool
7488
*/
7589
public function closeCursor() {
76-
return $this->statement->closeCursor();
90+
return $this->exceptionHandler(function () {
91+
return $this->statement->closeCursor();
92+
});
7793
}
7894

7995
/**
8096
* @return int
8197
*/
8298
public function columnCount() {
83-
return $this->statement->columnCount();
99+
return $this->exceptionHandler(function () {
100+
return $this->statement->columnCount();
101+
});
84102
}
85103

86104
/**
87105
* @param int $columnNo
88106
* @return array
89107
*/
90108
public function getColumnMeta($columnNo) {
91-
return $this->statement->getColumnMeta($columnNo);
109+
return $this->exceptionHandler(function () use ($columnNo) {
110+
return $this->statement->getColumnMeta($columnNo);
111+
});
112+
}
113+
114+
/**
115+
* @param callable $fn
116+
* @return mixed
117+
*/
118+
private function exceptionHandler($fn) {
119+
try {
120+
return call_user_func($fn);
121+
} catch (PDOException $e) {
122+
$this->exceptionInterpreter->throwMoreConcreteException($e);
123+
throw $e;
124+
}
92125
}
93126
}

src/Databases/MySQL.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class MySQL implements Database {
3535
* @param PDO $pdo
3636
*/
3737
public function __construct(PDO $pdo) {
38+
if($pdo->getAttribute(PDO::ATTR_ERRMODE) === PDO::ERRMODE_SILENT) {
39+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
40+
}
3841
$this->pdo = $pdo;
3942
$this->aliasRegistry = new AliasRegistry();
4043
$this->queryLoggers = new QueryLoggers();
@@ -320,7 +323,7 @@ private function buildQueryStatement($query, $fn) {
320323
if(!$stmt) {
321324
throw new Exception("Could not execute statement:\n{$query}");
322325
}
323-
$stmtWrapper = new QueryStatement($stmt, $query, $this->queryLoggers);
326+
$stmtWrapper = new QueryStatement($stmt, $query, $this->exceptionInterpreter, $this->queryLoggers);
324327
return $stmtWrapper;
325328
}
326329
}

src/Databases/MySQL/MySQLExceptionInterpreter.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?php
22
namespace Kir\MySQL\Databases\MySQL;
33

4-
use Kir\MySQL\Exceptions\DuplicateUniqueKeyException;
5-
use Kir\MySQL\Exceptions\LockWaitTimeoutExceededException;
6-
use Kir\MySQL\Exceptions\SqlDeadLockException;
74
use PDO;
85
use PDOException;
6+
use Kir\MySQL\Exceptions\SqlDeadLockException;
7+
use Kir\MySQL\Exceptions\DuplicateUniqueKeyException;
8+
use Kir\MySQL\Exceptions\LockWaitTimeoutExceededException;
99

1010
class MySQLExceptionInterpreter {
1111
/** @var PDO */
@@ -23,9 +23,8 @@ public function __construct(PDO $pdo) {
2323
* @throw PDOException
2424
*/
2525
public function throwMoreConcreteException(PDOException $exception) {
26-
$errorInfo = $this->pdo->errorInfo();
27-
$code = $errorInfo[1];
28-
$message = $errorInfo[2];
26+
$code = $exception->errorInfo[1];
27+
$message = $exception->errorInfo[2];
2928
if($code === 1213) {
3029
throw new SqlDeadLockException($message, $code, $exception);
3130
}

0 commit comments

Comments
 (0)