_execute(); } /** * @return int|bool * @throws Exception */ public function save(): int|bool { return $this->_execute(); } /** * @return array|null * @throws Exception */ public function all(): ?array { try { [$pdo, $statement] = $this->search(); $statement->execute($this->params); return $statement->fetchAll(PDO::FETCH_ASSOC); } catch (\Throwable $throwable) { if (!str_contains($throwable->getMessage(), 'MySQL server has gone away')) { return $this->all(); } else { return $this->printErrorMessage($throwable); } } finally { if (isset($pdo)) { $this->db->release($pdo); } } } /** * @return array|null * @throws Exception */ public function one(): ?array { try { [$pdo, $statement] = $this->search(); $statement->execute($this->params); return $statement->fetch(PDO::FETCH_ASSOC); } catch (\Throwable $throwable) { if (!str_contains($throwable->getMessage(), 'MySQL server has gone away')) { return $this->printErrorMessage($throwable); } else { return $this->one(); } } finally { if (isset($pdo)) { $this->db->release($pdo); } } } /** * @return mixed * @throws Exception */ public function fetchColumn(): mixed { try { [$pdo, $statement] = $this->search(); $statement->execute($this->params); return $statement->fetchColumn(PDO::FETCH_ASSOC); } catch (\Throwable $throwable) { if (!str_contains($throwable->getMessage(), 'MySQL server has gone away')) { return $this->printErrorMessage($throwable); } else { return $this->fetchColumn(); } } finally { if (isset($pdo)) { $this->db->release($pdo); } } } /** * @return int|null * @throws Exception */ public function rowCount(): ?int { try { [$pdo, $statement] = $this->search(); $statement->execute($this->params); return $statement->rowCount(); } catch (\Throwable $throwable) { if (!str_contains($throwable->getMessage(), 'MySQL server has gone away')) { return $this->printErrorMessage($throwable); } else { return $this->rowCount(); } } finally { if (isset($pdo)) { $this->db->release($pdo); } } } private function printErrorMessage(\Throwable $throwable): mixed { $this->logger->addError($this->sql . '. error: ' . $throwable->getMessage(), 'mysql'); return null; } /** * @return int|bool * @throws Exception */ public function flush(): int|bool { return $this->_execute(); } /** * @param bool $restore * @return bool|int * @throws Exception */ private function _execute(bool $restore = false): bool|int { try { $pdo = $this->db->getPdo($restore); 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(); return $result == 0 ? true : $result; } catch (\PDOException|\Throwable $throwable) { if (str_contains($throwable->getMessage(), 'MySQL server has gone away')) { return $this->_execute(true); } else { return $this->printErrorMessage($throwable); } } finally { isset($pdo) && $this->db->release($pdo); } } /** * @return array|bool * @throws Exception */ private function search(): bool|array { $pdo = $this->db->getSlaveClient(); if (($statement = $pdo->prepare($this->sql)) === false) { throw new Exception($pdo->errorInfo()[1]); } return [$pdo, $statement]; } /** * @return int|bool * @throws Exception */ public function delete(): int|bool { return $this->_execute(); } /** * @return int|bool * @throws Exception */ public function exec(): int|bool { return $this->_execute(); } /** * @param array $data * @return $this */ public function bindValues(array $data = []): static { if (count($data) > 0) { $this->params = array_merge($this->params, $data); } return $this; } /** * @param $sql * @return $this * @throws Exception */ public function setSql($sql): static { $this->sql = $sql; return $this; } }