modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2024-07-02 08:22:49 +04:00
parent 1a395afdef
commit e605dd3876
3 changed files with 91 additions and 35 deletions

View File

@ -66,17 +66,22 @@ class Capacitor implements ITransactor {
}
function beginTransaction(?callable $func=null, bool $commit=true): void {
if ($this->subManageTransactions === null && $this->subChannels !== null) {
foreach ($this->subChannels as $channel) {
$name = $channel->getName();
$this->subManageTransactions ??= [];
if (!array_key_exists($name, $this->subManageTransactions)) {
$this->subManageTransactions[$name] = $channel->isManageTransactions();
$db = $this->db();
if ($this->subChannels !== null) {
# on gère des subchannels: ne débuter la transaction que si ce n'est déjà fait
if ($this->subManageTransactions === null) {
foreach ($this->subChannels as $channel) {
$name = $channel->getName();
$this->subManageTransactions ??= [];
if (!array_key_exists($name, $this->subManageTransactions)) {
$this->subManageTransactions[$name] = $channel->isManageTransactions();
}
$channel->setManageTransactions(false);
}
$channel->setManageTransactions(false);
if (!$db->inTransaction()) $db->beginTransaction();
}
$db = $this->db();
if (!$db->inTransaction()) $db->beginTransaction();
} elseif (!$db->inTransaction()) {
$db->beginTransaction();
}
if ($func !== null) {
$commited = false;
@ -105,13 +110,13 @@ class Capacitor implements ITransactor {
function commit(): void {
$this->beforeEndTransaction();
$db = $this->db();
if ($db->inTransaction()) $this->db()->commit();
if ($db->inTransaction()) $db->commit();
}
function rollback(): void {
$this->beforeEndTransaction();
$db = $this->db();
if ($db->inTransaction()) $this->db()->rollback();
if ($db->inTransaction()) $db->rollback();
}
function getCreateSql(): string {
@ -131,7 +136,7 @@ class Capacitor implements ITransactor {
}
function charge($item, $func=null, ?array $args=null, ?array &$values=null): int {
$this->beginTransaction();
if ($this->subChannels !== null) $this->beginTransaction();
return $this->storage->_charge($this->channel, $item, $func, $args, $values);
}
@ -152,12 +157,12 @@ class Capacitor implements ITransactor {
}
function each($filter, $func=null, ?array $args=null, ?int &$updated=null): int {
$this->beginTransaction();
if ($this->subChannels !== null) $this->beginTransaction();
return $this->storage->_each($this->channel, $filter, $func, $args, $updated);
}
function delete($filter, $func=null, ?array $args=null): int {
$this->beginTransaction();
if ($this->subChannels !== null) $this->beginTransaction();
return $this->storage->_delete($this->channel, $filter, $func, $args);
}

View File

@ -71,18 +71,6 @@ class CapacitorChannel {
return $this->tableName;
}
/**
* @var Capacitor|null instance de Capacitor par laquelle cette instance est
* utilisée. ça peut être utile pour implémenter des workflows centrés sur le
* channel
*/
protected ?Capacitor $capacitor;
function setCapacitor(Capacitor $capacitor): self {
$this->capacitor = $capacitor;
return $this;
}
/**
* @var bool indiquer si les modifications de each doivent être gérées dans
* une transaction. si false, l'utilisateur doit lui même gérer la
@ -326,4 +314,50 @@ class CapacitorChannel {
return true;
}
const onDelete = "->".[self::class, "onDelete"][1];
#############################################################################
# Méthodes déléguées pour des workflows centrés sur le channel
/**
* @var Capacitor|null instance de Capacitor par laquelle cette instance est
* utilisée
*/
protected ?Capacitor $capacitor;
function getCapacitor(): ?Capacitor {
return $this->capacitor;
}
function setCapacitor(Capacitor $capacitor): self {
$this->capacitor = $capacitor;
return $this;
}
function charge($item, $func=null, ?array $args=null, ?array &$values=null): int {
return $this->capacitor->charge($item, $func, $args, $values);
}
function discharge(bool $reset=true): iterable {
return $this->capacitor->discharge($reset);
}
function count($filter=null): int {
return $this->capacitor->count($filter);
}
function one($filter): ?array {
return $this->capacitor->one($filter);
}
function all($filter): iterable {
return $this->capacitor->all($filter);
}
function each($filter, $func=null, ?array $args=null, ?int &$updated=null): int {
return $this->capacitor->each($filter, $func, $args, $updated);
}
function delete($filter, $func=null, ?array $args=null): int {
return $this->capacitor->delete($filter, $func, $args);
}
}

View File

@ -47,7 +47,21 @@ abstract class CapacitorStorage {
}
$definitions[] = $channel->getColumnDefinitions();
$definitions[] = static::COLUMN_DEFINITIONS;
return cl::merge(...$definitions);
# forcer les définitions sans clé à la fin (sqlite requière par exemple que
# primary key (columns) soit à la fin)
$tmp = cl::merge(...$definitions);
$definitions = [];
$constraints = [];
$index = 0;
foreach ($tmp as $col => $def) {
if ($col === $index) {
$index++;
$constraints[] = $def;
} else {
$definitions[$col] = $def;
}
}
return cl::merge($definitions, $constraints);
}
/** sérialiser les valeurs qui doivent l'être dans $values */
@ -284,7 +298,8 @@ EOT;
# aucune modification
if ($insert === null) return 0;
$manageTransactions = $channel->isManageTransactions();
# si on est déjà dans une transaction, désactiver la gestion des transactions
$manageTransactions = $channel->isManageTransactions() && !$db->inTransaction();
if ($manageTransactions) {
$commited = false;
$db->beginTransaction();
@ -474,15 +489,16 @@ EOT;
func::ensure_func($func, $channel, $args);
$onEach = func::_prepare($func);
$db = $this->db();
$tableName = $channel->getTableName();
$manageTransactions = $channel->isManageTransactions();
$count = 0;
$updated = 0;
# si on est déjà dans une transaction, désactiver la gestion des transactions
$manageTransactions = $channel->isManageTransactions() && !$db->inTransaction();
if ($manageTransactions) {
$commited = false;
$db->beginTransaction();
$commitThreshold = $channel->getEachCommitThreshold();
}
$count = 0;
$updated = 0;
$tableName = $channel->getTableName();
try {
$args ??= [];
foreach ($this->_all($channel, $filter) as $values) {
@ -541,14 +557,15 @@ EOT;
func::ensure_func($func, $channel, $args);
$onEach = func::_prepare($func);
$db = $this->db();
$tableName = $channel->getTableName();
$manageTransactions = $channel->isManageTransactions();
$count = 0;
# si on est déjà dans une transaction, désactiver la gestion des transactions
$manageTransactions = $channel->isManageTransactions() && !$db->inTransaction();
if ($manageTransactions) {
$commited = false;
$db->beginTransaction();
$commitThreshold = $channel->getEachCommitThreshold();
}
$count = 0;
$tableName = $channel->getTableName();
try {
$args ??= [];
foreach ($this->_all($channel, $filter) as $values) {