1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-07 15:26:54 +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
*
* @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
*
@@ -935,13 +979,16 @@ class WireDatabasePDO extends Wire implements WireDatabase {
*
* @param \PDOStatement $query
* @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.
* @throws \PDOException
*
*/
public function execute(\PDOStatement $query, $throw = true, $maxTries = 3) {
$tries = 0;
do {
$tryAgain = false;
try {
$result = $query->execute();
} 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)) {
$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;
} else {
$this->error($e->getMessage());
}
if($maxTries) {} // ignore, argument no longer used
}
} while($tryAgain);
return $result;
}