1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-08 07:47:00 +02:00

Update $database API to have new reset() and close() methods. The reset() method closes and resets the DB connection, while the close() method just closes it. Also updated the execute($query) method to use the reset() method to retry a failed query due to loss of connection.

This commit is contained in:
Ryan Cramer
2024-05-24 14:47:53 -04:00
parent 3c5205721b
commit 9803df9401

View File

@@ -476,13 +476,57 @@ class WireDatabasePDO extends Wire implements WireDatabase {
} }
/** /**
* Return the actual current PDO connection instance * Reset the current PDO connection(s)
* *
* If connection is lost, this will restore it automatically. * This forces re-creation of the PDO instance(s), whether writer, reader or both.
* This may be useful to call after a "MySQL server has gone away" error to attempt
* to re-establish the connection.
* *
* #pw-group-connection * #pw-group-connection
* *
* @param string|\PDOStatement|null SQL, statement, or statement type (reader or primary) (3.0.175+) * @param string|null $type
* - Specify 'writer' to reset writer instance.
* - Specify 'reader' to reset reader instance.
* - Omit or null to reset both, or whichever one is in use.
* @return self
* @since 3.0.240
*
*/
public function reset($type = null) {
$this->close($type);
$this->pdo($type);
return $this;
}
/**
* Close the current PDO connection(s)
*
* #pw-internal
*
* @param string|null $type
* - Specify 'writer' to close writer instance.
* - Specify 'reader' to close reader instance.
* - Omit or null to close both.
* @return self
* @since 3.0.240
*
*/
public function close($type = null) {
if($type === 'reader' || $type === null) {
$this->reader['pdo'] = null;
}
if($type === 'writer' || $type === null) {
$this->writer['pdo'] = null;
}
return $this;
}
/**
* Return the actual current PDO connection instance
*
* #pw-internal
*
* @param string|\PDOStatement|null SQL, statement, or statement type (reader or writer) (3.0.175+)
* *
* @return \PDO * @return \PDO
* *
@@ -935,13 +979,16 @@ class WireDatabasePDO extends Wire implements WireDatabase {
* *
* @param \PDOStatement $query * @param \PDOStatement $query
* @param bool $throw Whether or not to throw exception on query error (default=true) * @param bool $throw Whether or not to throw exception on query error (default=true)
* @param int $maxTries Deprecated/argument does nothing (was: “Max number of times it will attempt to retry query on error”) * @param int $maxTries Max number of times it will attempt to retry query on lost connection error
* @return bool True on success, false on failure. Note if you want this, specify $throw=false in your arguments. * @return bool True on success, false on failure. Note if you want this, specify $throw=false in your arguments.
* @throws \PDOException * @throws \PDOException
* *
*/ */
public function execute(\PDOStatement $query, $throw = true, $maxTries = 3) { public function execute(\PDOStatement $query, $throw = true, $maxTries = 3) {
$tries = 0;
do {
$tryAgain = false;
try { try {
$result = $query->execute(); $result = $query->execute();
} catch(\PDOException $e) { } catch(\PDOException $e) {
@@ -952,14 +999,21 @@ class WireDatabasePDO extends Wire implements WireDatabase {
if(preg_match('/[\'"]([_a-z0-9]+\.[_a-z0-9]+)[\'"]/i', $errorInfo[2], $matches)) { if(preg_match('/[\'"]([_a-z0-9]+\.[_a-z0-9]+)[\'"]/i', $errorInfo[2], $matches)) {
$this->unknownColumnError($matches[1]); $this->unknownColumnError($matches[1]);
} }
} else if($e->getCode() === 'HY000' && $tries < $maxTries) {
// mysql server has gone away
$this->reset();
$tryAgain = true;
$tries++;
} }
if($throw) { if($tryAgain) {
// we will try again on next iteration
} else if($throw) {
throw $e; throw $e;
} else { } else {
$this->error($e->getMessage()); $this->error($e->getMessage());
} }
if($maxTries) {} // ignore, argument no longer used
} }
} while($tryAgain);
return $result; return $result;
} }