mirror of
https://github.com/processwire/processwire.git
synced 2025-08-18 20:41:16 +02:00
Update FieldtypeMulti::savePageField to use InnoDB transactions when possible, plus add a new shortcut method: WireDatabasePDO::allowTransaction()
This commit is contained in:
@@ -209,7 +209,9 @@ abstract class FieldtypeMulti extends Fieldtype {
|
||||
|
||||
if(!$page->id || !$field->id) return false;
|
||||
|
||||
/** @var WireDatabasePDO $database */
|
||||
$database = $this->wire('database');
|
||||
$useTransaction = $database->allowTransaction();
|
||||
$values = $page->get($field->name);
|
||||
$schema = array();
|
||||
|
||||
@@ -228,10 +230,18 @@ abstract class FieldtypeMulti extends Fieldtype {
|
||||
$table = $database->escapeTable($field->table);
|
||||
$page_id = (int) $page->id;
|
||||
|
||||
// use transaction when possible
|
||||
if($useTransaction) $database->beginTransaction();
|
||||
|
||||
try {
|
||||
// since we don't manage IDs of existing values for multi fields, we delete the existing data and insert all of it again
|
||||
$query = $database->prepare("DELETE FROM `$table` WHERE pages_id=:page_id"); // QA
|
||||
$query->bindValue(":page_id", $page_id, \PDO::PARAM_INT);
|
||||
$query->execute();
|
||||
} catch(\Exception $e) {
|
||||
if($useTransaction) $database->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if(count($values)) {
|
||||
|
||||
@@ -284,21 +294,24 @@ abstract class FieldtypeMulti extends Fieldtype {
|
||||
$sort++;
|
||||
}
|
||||
|
||||
$sql = rtrim($sql, ", ");
|
||||
$query = $database->prepare($sql);
|
||||
try {
|
||||
$query = $database->prepare(rtrim($sql, ", "));
|
||||
$result = $query->execute();
|
||||
} catch(\Exception $e) {
|
||||
if($useTransaction) $database->rollBack();
|
||||
if($this->wire('config')->allowExceptions) throw $e; // throw original
|
||||
$msg = $e->getMessage();
|
||||
if($this->wire('config')->debug && $this->wire('config')->advanced) $msg .= "\n$sql";
|
||||
throw new WireException($msg); // throw WireException
|
||||
}
|
||||
|
||||
return $result;
|
||||
} else {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
if($useTransaction) $database->commit();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -332,7 +332,7 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
||||
*
|
||||
*/
|
||||
public function inTransaction() {
|
||||
return $this->pdo()->inTransaction();
|
||||
return (bool) $this->pdo()->inTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,6 +361,22 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
||||
return strtoupper($engine) === 'INNODB';
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow a new transaction to begin right now? (i.e. supported and not already in one)
|
||||
*
|
||||
* Returns combined result of supportsTransaction() === true and inTransaction() === false.
|
||||
*
|
||||
* #pw-group-PDO
|
||||
*
|
||||
* @param string $table Optional table that transaction will be for
|
||||
* @return bool
|
||||
* @since 3.0.140
|
||||
*
|
||||
*/
|
||||
public function allowTransaction($table = '') {
|
||||
return $this->supportsTransaction($table) && !$this->inTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits a transaction
|
||||
*
|
||||
|
Reference in New Issue
Block a user