/** * @param Config $config * @return \PDO * @throws UnknownDatabaseException * @throws RuntimeException */ public function __invoke(Config $config) { $attempt = 0; $maxAttempts = $config->getMaximumAttempts(); while (++$attempt <= $maxAttempts) { try { $connection = $this->create($config); $connection->prepare('SET NAMES ?, time_zone = ?')->execute([$config->getCharset(), $config->getTimezone()]); return $connection; } catch (\PDOException $exception) { if (UnknownDatabaseException::isUnknownDatabase($exception)) { throw UnknownDatabaseException::createFromUnknownDatabase($config->getDatabase(), $exception); } if ($maxAttempts > $attempt) { // more tries left, so we'll log this error // $template = 'Failed connection to "%s" on attempt %d with error "%s"'; // $dsn = $config->getDsn(); // error_log(sprintf($template, $dsn, $attempt, $exception->getMessage())); // $logger->error(sprintf($template, $dsn, $attempt, $exception->getMessage()), [ // 'e_message' => $exception->getMessage(), // 'e_code' => $exception->getCode(), // 'e_file' => $exception->getFile(), // 'e_line' => $exception->getLine(), // 'e_trace' => $exception->getTraceAsString() // ]); // sleep with some exponential backoff $msec = pow(2, $attempt) * 50; usleep($msec * 1000); } else { // ran out of attempts, throw the last error throw RuntimeException::createFromException($exception); } } } }
public function testCorrectlyEvaluatesPdoExceptionForNonDatabaseError() { $code = '42000'; $message = "SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRM foo' at line 1"; $pdoException = new \PDOException($message, $code); $this->assertFalse(UnknownDatabaseException::isUnknownDatabase($pdoException)); }
/** * Set database * * @param string $dbname * @return Adapter * @throws UnknownDatabaseException */ public function setDatabase($dbname) { $this->config->setDatabase($dbname); if ($this->connection) { try { $this->query('USE ' . $this->quoter->quoteIdentifier($dbname)); } catch (RuntimeException $exception) { $prevException = $exception->getPrevious(); if (UnknownDatabaseException::isUnknownDatabase($prevException)) { throw UnknownDatabaseException::createFromUnknownDatabase($dbname, $prevException); } throw $exception; } } return $this; }