modifs.mineures sans commentaires

This commit is contained in:
Jephté Clain 2024-06-05 14:03:42 +04:00
parent 1c57fcf041
commit 243bae60d6
5 changed files with 80 additions and 54 deletions

View File

@ -88,7 +88,7 @@ class CapacitorChannel {
*
* la clé primaire "id_" a pour définition "integer primary key autoincrement".
* elle peut être redéfinie, et dans ce cas la valeur à utiliser doit être
* retournée par {@link getKeyValues()}
* retournée par {@link getItemValues()}
*
* la colonne "item__" contient la valeur sérialisée de l'élément chargé. bien
* que ce soit possible techniquement, cette colonne n'a pas à être redéfinie
@ -112,10 +112,11 @@ class CapacitorChannel {
* calculer les valeurs des colonnes supplémentaires à insérer pour le
* chargement de $item
*
* Cette méthode est utilisée par {@link Capacitor::charge()}. Si une valeur
* "id_" est retourné, la ligne correspondate existante est mise à jour
* Cette méthode est utilisée par {@link Capacitor::charge()}. Si la clé
* primaire est retournée (il s'agit généralement de "id_"), la ligne
* correspondate est mise à jour si elle existe.
*/
function getKeyValues($item): ?array {
function getItemValues($item): ?array {
return null;
}
@ -123,30 +124,47 @@ class CapacitorChannel {
* Avant d'utiliser un id pour rechercher dans la base de donnée, corriger sa
* valeur le cas échéant.
*
* Cette fonction assume que l'unique clé primaire est id_. Elle n'est pas
* Cette fonction assume que l'unique clé primaire est "id_". Elle n'est pas
* utilisée si une clé primaire multiple est définie.
*/
function verifixId(string &$id): void {
}
/**
* méthode appelée lors du chargement d'un élément avec
* {@link Capacitor::charge()}
* méthode appelée lors du chargement avec {@link Capacitor::charge()} pour
* créer un nouvel élément
*
* @param mixed $item l'élément à charger
* @param array $updates les valeurs calculées par {@link getKeyValues()}
* @param ?array $row la ligne à mettre à jour. vaut null s'il faut insérer
* une nouvelle ligne
* @param array $updates les valeurs calculées par {@link getItemValues()}
* @return ?array le cas échéant, un tableau non null à merger dans $updates
* et utilisé pour provisionner la ligne nouvellement créée, ou mettre à jour
* la ligne existante
* et utilisé pour provisionner la ligne nouvellement créée
*
* Si $item est modifié dans cette méthode, il est possible de le retourner
* avec la clé "item" pour mettre à jour la ligne correspondante.
* La colonne "id_" ne peut pas être modifiée: si "id_" est retourné, il est
* ignoré
*/
function onCharge($item, array $updates, ?array $row): ?array {
function onCreate($item, array $updates, ?array $row): ?array {
return null;
}
/**
* méthode appelée lors du chargement avec {@link Capacitor::charge()} pour
* mettre à jour un élément existant
*
* @param mixed $item l'élément à charger
* @param array $updates les valeurs calculées par {@link getItemValues()}
* Si l'élément a été modifié par rapport au dernier chargement, ce tableau
* contient une clé "modified_" avec la date de modification.
* @param array $row la ligne à mettre à jour.
* @return ?array le cas échéant, un tableau non null à merger dans $updates
* et utilisé pour mettre à jour la ligne existante
*
* Si $item est modifié dans cette méthode, il est possible de le retourner
* avec la clé "item" pour mettre à jour la ligne correspondante.
*
* La clé primaire (il s'agit généralement de "id_") ne peut pas être
* modifiée. si elle est retournée, elle est ignorée
*/
function onUpdate($item, array $updates, ?array $row): ?array {
return null;
}

View File

@ -137,7 +137,7 @@ abstract class CapacitorStorage {
* charger une valeur dans le canal
*
* Si $func!==null, après avoir calculé les valeurs des clés supplémentaires
* avec {@link CapacitorChannel::getKeyValues()}, la fonction est appelée avec
* avec {@link CapacitorChannel::getItemValues()}, la fonction est appelée avec
* la signature ($item, $keyValues, $row, ...$args)
* Si la fonction retourne un tableau, il est utilisé pour modifier les valeurs
* insérées/mises à jour

View File

@ -67,7 +67,7 @@ class MysqlStorage extends CapacitorStorage {
$row = cl::merge([
"item__" => $item__,
"sum_" => $sum_,
], $this->unserialize($channel, $channel->getKeyValues($item)));
], $this->unserialize($channel, $channel->getItemValues($item)));
$prow = null;
$rowIds = $this->getRowIds($channel, $row, $primaryKeys);
if ($rowIds !== null) {
@ -84,6 +84,7 @@ class MysqlStorage extends CapacitorStorage {
"where" => $rowIds,
]);
}
$insert = null;
if ($prow === null) {
# création
@ -92,21 +93,26 @@ class MysqlStorage extends CapacitorStorage {
"modified_" => $now,
]);
$insert = true;
} elseif ($sum_ !== $prow["sum_"]) {
if ($func === null) $func = "->onCreate";
func::ensure_func($func, $channel, $args);
$values = $this->unserialize($channel, $row);
$args = [$item, $values, ...$args];
} else {
# modification
$row = cl::merge($row, [
"modified_" => $now,
]);
$insert = false;
}
if ($func === null) $func = [$channel, "onCharge"];
$onCharge = func::_prepare($func);
$args ??= [];
if ($sum_ !== $prow["sum_"]) $insert = false;
if ($func === null) $func = "->onUpdate";
func::ensure_func($func, $channel, $args);
$values = $this->unserialize($channel, $row);
$pvalues = $this->unserialize($channel, $prow);
$updates = func::_call($onCharge, [$item, $values, $pvalues, ...$args]);
$args = [$item, $values, $pvalues, ...$args];
}
$updates = func::call($func, ...$args);
if (is_array($updates)) {
if ($insert === null) $insert = false;
$updates = $this->serialize($channel, $updates);
if (array_key_exists("item__", $updates)) {
# si item a été mis à jour, il faut mettre à jour sum_

View File

@ -64,7 +64,7 @@ class SqliteStorage extends CapacitorStorage {
$row = cl::merge([
"item__" => $item__,
"sum_" => $sum_,
], $this->unserialize($channel, $channel->getKeyValues($item)));
], $this->unserialize($channel, $channel->getItemValues($item)));
$prow = null;
$rowIds = $this->getRowIds($channel, $row, $primaryKeys);
if ($rowIds !== null) {
@ -81,6 +81,7 @@ class SqliteStorage extends CapacitorStorage {
"where" => $rowIds,
]);
}
$insert = null;
if ($prow === null) {
# création
@ -89,21 +90,26 @@ class SqliteStorage extends CapacitorStorage {
"modified_" => $now,
]);
$insert = true;
} elseif ($sum_ !== $prow["sum_"]) {
if ($func === null) $func = "->onCreate";
func::ensure_func($func, $channel, $args);
$values = $this->unserialize($channel, $row);
$args = [$item, $values, ...$args];
} else {
# modification
$row = cl::merge($row, [
"modified_" => $now,
]);
$insert = false;
}
if ($func === null) $func = [$channel, "onCharge"];
$onCharge = func::_prepare($func);
$args ??= [];
if ($sum_ !== $prow["sum_"]) $insert = false;
if ($func === null) $func = "->onUpdate";
func::ensure_func($func, $channel, $args);
$values = $this->unserialize($channel, $row);
$pvalues = $this->unserialize($channel, $prow);
$updates = func::_call($onCharge, [$item, $values, $pvalues, ...$args]);
$args = [$item, $values, $pvalues, ...$args];
}
$updates = func::call($func, ...$args);
if (is_array($updates)) {
if ($insert === null) $insert = false;
$updates = $this->serialize($channel, $updates);
if (array_key_exists("item__", $updates)) {
# si item a été mis à jour, il faut mettre à jour sum_

View File

@ -2,6 +2,7 @@
namespace nur\sery\db\sqlite;
use nulib\tests\TestCase;
use nur\sery\cl;
use nur\sery\db\Capacitor;
use nur\sery\db\CapacitorChannel;
@ -11,7 +12,7 @@ class SqliteStorageTest extends TestCase {
$storage->charge($channel, "first");
$storage->charge($channel, "second");
$storage->charge($channel, "third");
$items = iterator_to_array($storage->discharge($channel, false));
$items = cl::all($storage->discharge($channel, false));
self::assertSame(["first", "second", "third"], $items);
}
@ -32,10 +33,9 @@ class SqliteStorageTest extends TestCase {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$storage->addChannel(new class extends CapacitorChannel {
const NAME = "arrays";
function getColumnDefinitions(): ?array {
return ["id" => "integer"];
}
function getKeyValues($item): ?array {
const COLUMN_DEFINITIONS = ["id" => "integer"];
function getItemValues($item): ?array {
return ["id" => $item["id"] ?? null];
}
});
@ -49,14 +49,12 @@ class SqliteStorageTest extends TestCase {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$capacitor = new Capacitor($storage, new class extends CapacitorChannel {
const NAME = "each";
function getColumnDefinitions(): ?array {
return [
const COLUMN_DEFINITIONS = [
"age" => "integer",
"done" => "integer default 0",
];
}
function getKeyValues($item): ?array {
function getItemValues($item): ?array {
return [
"age" => $item["age"],
];
@ -79,7 +77,7 @@ class SqliteStorageTest extends TestCase {
};
$capacitor->each(["age" => [">", 10]], $setDone, ["++"]);
$capacitor->each(["done" => 0], $setDone, null);
Txx(iterator_to_array($capacitor->discharge(null, false)));
Txx(cl::all($capacitor->discharge(null, false)));
$capacitor->close();
self::assertTrue(true);
@ -89,14 +87,12 @@ class SqliteStorageTest extends TestCase {
$storage = new SqliteStorage(__DIR__.'/capacitor.db');
$capacitor = new Capacitor($storage, new class extends CapacitorChannel {
const NAME = "pk";
function getColumnDefinitions(): ?array {
return [
const COLUMN_DEFINITIONS = [
"id_" => "varchar primary key",
"done" => "integer default 0",
];
}
function getKeyValues($item): ?array {
function getItemValues($item): ?array {
return [
"id_" => $item["numero"],
];