From 4a654821a1a0b33e8c10c9f012d60a664120973d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=91=E6=9E=97?= Date: Tue, 20 Sep 2022 18:53:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Command.php | 53 ++++++++++++++++++++++++++++++++++++++++++++++++-- Connection.php | 2 +- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Command.php b/Command.php index ca5a8b8..9794981 100644 --- a/Command.php +++ b/Command.php @@ -26,6 +26,8 @@ class Command extends Component const EXECUTE = 'execute'; const FETCH_COLUMN = 'fetchColumn'; + const DB_ERROR_MESSAGE = 'The system is busy, please try again later.'; + /** @var Connection */ public Connection $db; @@ -139,7 +141,17 @@ class Command extends Component { $pdo = $this->db->getPdo(); try { - $result = $pdo->execute($this->sql, $this->params); + if (!(($prepare = $pdo->prepare($this->sql)) instanceof PDOStatement)) { + throw new Exception($prepare->errorInfo()[2] ?? static::DB_ERROR_MESSAGE); + } + if ($prepare->execute($this->params) === false) { + throw new Exception($prepare->errorInfo()[2] ?? static::DB_ERROR_MESSAGE); + } + + $result = (int)$pdo->lastInsertId(); + $prepare->closeCursor(); + + $result = $result == 0 ? true : $result; } catch (\Throwable $exception) { $result = $this->logger->addError($this->sql . '. error: ' . $exception->getMessage(), 'mysql'); } finally { @@ -149,6 +161,33 @@ class Command extends Component } + /** + * @param \PDO $pdo + * @param string $sql + * @param array $params + * @return PDOStatement + * @throws Exception + */ + private function queryPrev(\PDO $pdo): PDOStatement + { + try { + if (($statement = $pdo->query($this->sql)) === false) { + throw new Exception($pdo->errorInfo()[1]); + } + foreach ($this->params as $key => $param) { + $statement->bindValue($key, $param); + } + return $statement; + } catch (\PDOException|\Throwable $throwable) { + if (str_contains($throwable->getMessage(), 'MySQL server has gone away')) { + unset($pdo); + return $this->queryPrev($this->db->getSlaveClient()); + } + throw new Exception($throwable->getMessage()); + } + } + + /** * @param string $type * @return array|int|bool|null @@ -158,7 +197,17 @@ class Command extends Component { $pdo = $this->db->getSlaveClient(); try { - $data = $pdo->{$type}($this->sql, $this->params); + if ($type == self::FETCH_ALL) { + $data = $this->queryPrev($pdo)->fetchAll(\PDO::FETCH_ASSOC); + } else if ($type == self::FETCH) { + $data = $this->queryPrev($pdo)->fetch(\PDO::FETCH_ASSOC); + } else if ($type == self::FETCH_COLUMN) { + $data = $this->queryPrev($pdo)->fetchColumn(\PDO::FETCH_ASSOC); + } else if ($type == self::ROW_COUNT) { + $data = $this->queryPrev($pdo)->rowCount(); + } else { + $data = null; + } } catch (\Throwable $throwable) { $data = $this->logger->addError($this->sql . '. error: ' . $throwable->getMessage(), 'mysql'); } finally { diff --git a/Connection.php b/Connection.php index ebe4851..971bb4f 100644 --- a/Connection.php +++ b/Connection.php @@ -14,7 +14,7 @@ namespace Database; use Database\Affair\BeginTransaction; use Database\Affair\Commit; use Database\Affair\Rollback; -use Database\Mysql\PDO; +use PDO; use Database\Mysql\Schema; use Exception; use Kiri;