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;
|
if(!$page->id || !$field->id) return false;
|
||||||
|
|
||||||
|
/** @var WireDatabasePDO $database */
|
||||||
$database = $this->wire('database');
|
$database = $this->wire('database');
|
||||||
|
$useTransaction = $database->allowTransaction();
|
||||||
$values = $page->get($field->name);
|
$values = $page->get($field->name);
|
||||||
$schema = array();
|
$schema = array();
|
||||||
|
|
||||||
@@ -228,10 +230,18 @@ abstract class FieldtypeMulti extends Fieldtype {
|
|||||||
$table = $database->escapeTable($field->table);
|
$table = $database->escapeTable($field->table);
|
||||||
$page_id = (int) $page->id;
|
$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
|
// 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 = $database->prepare("DELETE FROM `$table` WHERE pages_id=:page_id"); // QA
|
||||||
$query->bindValue(":page_id", $page_id, \PDO::PARAM_INT);
|
$query->bindValue(":page_id", $page_id, \PDO::PARAM_INT);
|
||||||
$query->execute();
|
$query->execute();
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
if($useTransaction) $database->rollBack();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
if(count($values)) {
|
if(count($values)) {
|
||||||
|
|
||||||
@@ -284,21 +294,24 @@ abstract class FieldtypeMulti extends Fieldtype {
|
|||||||
$sort++;
|
$sort++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = rtrim($sql, ", ");
|
|
||||||
$query = $database->prepare($sql);
|
|
||||||
try {
|
try {
|
||||||
|
$query = $database->prepare(rtrim($sql, ", "));
|
||||||
$result = $query->execute();
|
$result = $query->execute();
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
|
if($useTransaction) $database->rollBack();
|
||||||
if($this->wire('config')->allowExceptions) throw $e; // throw original
|
if($this->wire('config')->allowExceptions) throw $e; // throw original
|
||||||
$msg = $e->getMessage();
|
$msg = $e->getMessage();
|
||||||
if($this->wire('config')->debug && $this->wire('config')->advanced) $msg .= "\n$sql";
|
if($this->wire('config')->debug && $this->wire('config')->advanced) $msg .= "\n$sql";
|
||||||
throw new WireException($msg); // throw WireException
|
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() {
|
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';
|
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
|
* Commits a transaction
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user