diff --git a/src/db/CapacitorChannel.php b/src/db/CapacitorChannel.php index 3d103f4..3d656b8 100644 --- a/src/db/CapacitorChannel.php +++ b/src/db/CapacitorChannel.php @@ -7,13 +7,16 @@ namespace nur\sery\db; class CapacitorChannel { const NAME = null; + const EACH_COMMIT_THRESHOLD = 100; + static function verifix_name(?string $name): string { if ($name === null) $name = "default"; return strtolower($name); } - function __construct(?string $name=null) { + function __construct(?string $name=null, ?int $eachCommitThreshold=null) { $this->name = self::verifix_name($name ?? static::NAME); + $this->eachCommitThreshold = $eachCommitThreshold ?? static::EACH_COMMIT_THRESHOLD; $this->created = false; } @@ -24,6 +27,17 @@ class CapacitorChannel { return $this->name; } + /** + * @var ?int nombre maximum de modifications dans une transaction avant un + * commit automatique dans {@link Capacitor::each()}. Utiliser null pour + * désactiver la fonctionnalité. + */ + protected $eachCommitThreshold; + + function getEachCommitThreshold(): ?int { + return $this->eachCommitThreshold; + } + function getTableName(): string { return $this->name."_channel"; } diff --git a/src/db/sqlite/Sqlite.php b/src/db/sqlite/Sqlite.php index 772adb1..4c3cbc5 100644 --- a/src/db/sqlite/Sqlite.php +++ b/src/db/sqlite/Sqlite.php @@ -20,6 +20,7 @@ class Sqlite { "file" => $sqlite->file, "flags" => $sqlite->flags, "encryption_key" => $sqlite->encryptionKey, + "allow_wal" => $sqlite->allowWal, "config" => $sqlite->config, "migrate" => $sqlite->migration, ], $params)); @@ -30,19 +31,30 @@ class Sqlite { } } - static function config_enableExceptions(self $sqlite) { + static function config_enableExceptions(self $sqlite): void { $sqlite->db->enableExceptions(true); } + static function config_enableWalIfAllowed(self $sqlite): void { + if ($sqlite->isWalAllowed()) { + $sqlite->db->exec("PRAGMA journal_mode=WAL"); + } + } + + const ALLOW_WAL = null; + const CONFIG = [ [self::class, "config_enableExceptions"], + [self::class, "config_enableWalIfAllowed"], ]; + const MIGRATE = null; const SCHEMA = [ "file" => ["string", ""], "flags" => ["int", SQLITE3_OPEN_READWRITE + SQLITE3_OPEN_CREATE], "encryption_key" => ["string", ""], + "allow_wal" => ["?bool"], "config" => ["?array|callable"], "migrate" => ["?array|string|callable"], "auto_open" => ["bool", true], @@ -51,21 +63,25 @@ class Sqlite { function __construct(?string $file=null, ?array $params=null) { if ($file !== null) $params["file"] = $file; ##schéma - $default_file = self::SCHEMA["file"][1]; - $this->file = strval($params["file"] ?? $default_file); + $defaultFile = self::SCHEMA["file"][1]; + $this->file = $file = strval($params["file"] ?? $defaultFile); + $inMemory = $file === ":memory:"; # - $default_flags = self::SCHEMA["flags"][1]; - $this->flags = intval($params["flags"] ?? $default_flags); + $defaultFlags = self::SCHEMA["flags"][1]; + $this->flags = intval($params["flags"] ?? $defaultFlags); # - $default_encryptionKey = self::SCHEMA["encryption_key"][1]; - $this->encryptionKey = strval($params["encryption_key"] ?? $default_encryptionKey); + $defaultEncryptionKey = self::SCHEMA["encryption_key"][1]; + $this->encryptionKey = strval($params["encryption_key"] ?? $defaultEncryptionKey); + # + $defaultAllowWal = static::ALLOW_WAL ?? !$inMemory; + $this->allowWal = $params["allow_wal"] ?? $defaultAllowWal; # configuration $this->config = $params["config"] ?? static::CONFIG; # migrations $this->migration = $params["migrate"] ?? static::MIGRATE; # - $default_autoOpen = self::SCHEMA["auto_open"][1]; - if ($params["auto_open"] ?? $default_autoOpen) { + $defaultAutoOpen = self::SCHEMA["auto_open"][1]; + if ($params["auto_open"] ?? $defaultAutoOpen) { $this->open(); } } @@ -79,6 +95,14 @@ class Sqlite { /** @var string */ protected $encryptionKey; + /** @var bool */ + protected $allowWal; + + /** vérifier s'il est autorisé de configurer le mode WAL */ + function isWalAllowed(): bool { + return $this->allowWal; + } + /** @var array|string|callable */ protected $config; diff --git a/src/db/sqlite/SqliteCapacitor.php b/src/db/sqlite/SqliteCapacitor.php index 8246397..784eb6b 100644 --- a/src/db/sqlite/SqliteCapacitor.php +++ b/src/db/sqlite/SqliteCapacitor.php @@ -196,6 +196,7 @@ class SqliteCapacitor extends CapacitorStorage { $commited = false; $count = 0; $sqlite->beginTransaction(); + $commitThreshold = $channel->getEachCommitThreshold(); try { $rows = $sqlite->all([ "select", @@ -216,6 +217,13 @@ class SqliteCapacitor extends CapacitorStorage { "values" => $updates, "where" => ["_id" => $row["_id"]], ]); + if ($commitThreshold !== null) { + $commitThreshold--; + if ($commitThreshold == 0) { + $sqlite->commit(); + $commitThreshold = $channel->getEachCommitThreshold(); + } + } } $count++; }