storage = $storage; $this->channel = $channel; if ($ensureExists) $this->ensureExists(); } /** @var CapacitorStorage */ protected $storage; function getStorage(): CapacitorStorage { return $this->storage; } function db(): IDatabase { return $this->getStorage()->db(); } /** @var CapacitorChannel */ protected $channel; function getChannel(): CapacitorChannel { return $this->channel; } function getTableName(): string { return $this->getChannel()->getTableName(); } /** @var CapacitorChannel[] */ protected ?array $subChannels = null; protected ?array $subManageTransactions = null; function willUpdate(...$channels): self { if ($this->subChannels === null) { # désactiver la gestion des transaction sur le channel local aussi $this->subChannels[] = $this->channel; } if ($channels) { foreach ($channels as $channel) { if ($channel instanceof Capacitor) $channel = $channel->getChannel(); if ($channel instanceof CapacitorChannel) { $this->subChannels[] = $channel; } else { throw ValueException::invalid_type($channel, CapacitorChannel::class); } } } return $this; } function inTransaction(): bool { return $this->db()->inTransaction(); } 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(); } $channel->setManageTransactions(false); } $db = $this->db(); if (!$db->inTransaction()) $db->beginTransaction(); } if ($func !== null) { $commited = false; try { func::call($func, $this); if ($commit) { $this->commit(); $commited = true; } } finally { if ($commit && !$commited) $this->rollback(); } } } protected function beforeEndTransaction(): void { if ($this->subManageTransactions !== null) { foreach ($this->subChannels as $channel) { $name = $channel->getName(); $channel->setManageTransactions($this->subManageTransactions[$name]); } $this->subManageTransactions = null; } } function commit(): void { $this->beforeEndTransaction(); $db = $this->db(); if ($db->inTransaction()) $this->db()->commit(); } function rollback(): void { $this->beforeEndTransaction(); $db = $this->db(); if ($db->inTransaction()) $this->db()->rollback(); } function getCreateSql(): string { return $this->storage->_getCreateSql($this->channel); } function exists(): bool { return $this->storage->_exists($this->channel); } function ensureExists(): void { $this->storage->_ensureExists($this->channel); } function reset(bool $recreate=false): void { $this->storage->_reset($this->channel, $recreate); } function charge($item, $func=null, ?array $args=null, ?array &$values=null): int { $this->beginTransaction(); return $this->storage->_charge($this->channel, $item, $func, $args, $values); } function discharge(bool $reset=true): iterable { return $this->storage->_discharge($this->channel, $reset); } function count($filter=null): int { return $this->storage->_count($this->channel, $filter); } function one($filter): ?array { return $this->storage->_one($this->channel, $filter); } function all($filter): iterable { return $this->storage->_all($this->channel, $filter); } function each($filter, $func=null, ?array $args=null): int { $this->beginTransaction(); return $this->storage->_each($this->channel, $filter, $func, $args); } function delete($filter, $func=null, ?array $args=null): int { $this->beginTransaction(); return $this->storage->_delete($this->channel, $filter, $func, $args); } function close(): void { $this->storage->close(); } }