changement majeur dans Capacitor
This commit is contained in:
parent
9cf7ac908f
commit
8b7b318acd
@ -138,9 +138,9 @@ class Capacitor implements ITransactor {
|
|||||||
$this->storage->_reset($this->channel, $recreate);
|
$this->storage->_reset($this->channel, $recreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
function charge($item, $func=null, ?array $args=null, ?array &$values=null): int {
|
function charge($item, $func=null, ?array $args=null, ?array &$row=null): int {
|
||||||
if ($this->subChannels !== null) $this->beginTransaction();
|
if ($this->subChannels !== null) $this->beginTransaction();
|
||||||
return $this->storage->_charge($this->channel, $item, $func, $args, $values);
|
return $this->storage->_charge($this->channel, $item, $func, $args, $row);
|
||||||
}
|
}
|
||||||
|
|
||||||
function discharge(bool $reset=true): Traversable {
|
function discharge(bool $reset=true): Traversable {
|
||||||
|
@ -25,8 +25,6 @@ class CapacitorChannel implements ITransactor {
|
|||||||
|
|
||||||
const EACH_COMMIT_THRESHOLD = 100;
|
const EACH_COMMIT_THRESHOLD = 100;
|
||||||
|
|
||||||
const USE_CACHE = false;
|
|
||||||
|
|
||||||
static function verifix_name(?string &$name, ?string &$tableName=null): void {
|
static function verifix_name(?string &$name, ?string &$tableName=null): void {
|
||||||
if ($name !== null) {
|
if ($name !== null) {
|
||||||
$name = strtolower($name);
|
$name = strtolower($name);
|
||||||
@ -60,7 +58,6 @@ class CapacitorChannel implements ITransactor {
|
|||||||
$this->tableName = $tableName;
|
$this->tableName = $tableName;
|
||||||
$this->manageTransactions = $manageTransactions ?? static::MANAGE_TRANSACTIONS;
|
$this->manageTransactions = $manageTransactions ?? static::MANAGE_TRANSACTIONS;
|
||||||
$this->eachCommitThreshold = self::verifix_eachCommitThreshold($eachCommitThreshold);
|
$this->eachCommitThreshold = self::verifix_eachCommitThreshold($eachCommitThreshold);
|
||||||
$this->useCache = static::USE_CACHE;
|
|
||||||
$this->setup = false;
|
$this->setup = false;
|
||||||
$this->created = false;
|
$this->created = false;
|
||||||
$columnDefinitions = $this->COLUMN_DEFINITIONS();
|
$columnDefinitions = $this->COLUMN_DEFINITIONS();
|
||||||
@ -168,23 +165,6 @@ class CapacitorChannel implements ITransactor {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool faut-il passer par le cache pour les requêtes de all(), each()
|
|
||||||
* et delete()?
|
|
||||||
* ça peut être nécessaire avec MySQL/MariaDB si on utilise les requêtes non
|
|
||||||
* bufférisées, et que la fonction manipule la base de données
|
|
||||||
*/
|
|
||||||
protected bool $useCache;
|
|
||||||
|
|
||||||
function isUseCache(): bool {
|
|
||||||
return $this->useCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setUseCache(bool $useCache=true): self {
|
|
||||||
$this->useCache = $useCache;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initialiser ce channel avant sa première utilisation.
|
* initialiser ce channel avant sa première utilisation.
|
||||||
*/
|
*/
|
||||||
@ -283,8 +263,8 @@ class CapacitorChannel implements ITransactor {
|
|||||||
*
|
*
|
||||||
* cette méthode doit être utilisée dans {@link self::onUpdate()}
|
* cette méthode doit être utilisée dans {@link self::onUpdate()}
|
||||||
*/
|
*/
|
||||||
function wasRowModified(array $values, array $pvalues): bool {
|
function wasRowModified(array $row, array $prow): bool {
|
||||||
return $values["item__sum_"] !== $pvalues["item__sum_"];
|
return $row["item__sum_"] !== $prow["item__sum_"];
|
||||||
}
|
}
|
||||||
|
|
||||||
final function serialize($item): ?string {
|
final function serialize($item): ?string {
|
||||||
@ -315,17 +295,17 @@ class CapacitorChannel implements ITransactor {
|
|||||||
return array_combine($sumCols, [$serial, $sum]);
|
return array_combine($sumCols, [$serial, $sum]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasSumModified(string $key, $value, array $pvalues): bool {
|
function wasSumModified(string $key, $value, array $prow): bool {
|
||||||
$sumCol = $this->getSumCols($key)[1];
|
$sumCol = $this->getSumCols($key)[1];
|
||||||
$sum = $this->sum(null, $value);
|
$sum = $this->sum(null, $value);
|
||||||
$psum = $pvalues[$sumCol] ?? $this->sum(null, $pvalues[$key] ?? null);
|
$psum = $prow[$sumCol] ?? $this->sum(null, $prow[$key] ?? null);
|
||||||
return $sum !== $psum;
|
return $sum !== $psum;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _wasSumModified(string $key, array $row, array $prow): bool {
|
function _wasSumModified(string $key, array $raw, array $praw): bool {
|
||||||
$sumCol = $this->getSumCols($key)[1];
|
$sumCol = $this->getSumCols($key)[1];
|
||||||
$sum = $row[$sumCol] ?? null;
|
$sum = $raw[$sumCol] ?? null;
|
||||||
$psum = $prow[$sumCol] ?? null;
|
$psum = $praw[$sumCol] ?? null;
|
||||||
return $sum !== $psum;
|
return $sum !== $psum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,9 +314,9 @@ class CapacitorChannel implements ITransactor {
|
|||||||
* créer un nouvel élément
|
* créer un nouvel élément
|
||||||
*
|
*
|
||||||
* @param mixed $item l'élément à charger
|
* @param mixed $item l'élément à charger
|
||||||
* @param array $values la ligne à créer, calculée à partir de $item et des
|
* @param array $row la ligne à créer, calculée à partir de $item et des
|
||||||
* valeurs retournées par {@link getItemValues()}
|
* valeurs retournées par {@link getItemValues()}
|
||||||
* @return ?array le cas échéant, un tableau non null à merger dans $values et
|
* @return ?array le cas échéant, un tableau non null à merger dans $row et
|
||||||
* utilisé pour provisionner la ligne nouvellement créée.
|
* utilisé pour provisionner la ligne nouvellement créée.
|
||||||
* Retourner [false] pour annuler le chargement (la ligne n'est pas créée)
|
* Retourner [false] pour annuler le chargement (la ligne n'est pas créée)
|
||||||
*
|
*
|
||||||
@ -348,7 +328,7 @@ class CapacitorChannel implements ITransactor {
|
|||||||
* peut techniquement retourner de nouvelles valeurs pour la clé primaire, ça
|
* peut techniquement retourner de nouvelles valeurs pour la clé primaire, ça
|
||||||
* risque de créer des doublons
|
* risque de créer des doublons
|
||||||
*/
|
*/
|
||||||
function onCreate($item, array $values, ?array $alwaysNull): ?array {
|
function onCreate($item, array $row, ?array $alwaysNull): ?array {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,12 +337,12 @@ class CapacitorChannel implements ITransactor {
|
|||||||
* mettre à jour un élément existant
|
* mettre à jour un élément existant
|
||||||
*
|
*
|
||||||
* @param mixed $item l'élément à charger
|
* @param mixed $item l'élément à charger
|
||||||
* @param array $values la nouvelle ligne, calculée à partir de $item et
|
* @param array $row la nouvelle ligne, calculée à partir de $item et
|
||||||
* des valeurs retournées par {@link getItemValues()}
|
* des valeurs retournées par {@link getItemValues()}
|
||||||
* @param array $pvalues la précédente ligne, chargée depuis la base de
|
* @param array $prow la précédente ligne, chargée depuis la base de
|
||||||
* données
|
* données
|
||||||
* @return ?array null s'il ne faut pas mettre à jour la ligne. sinon, ce
|
* @return ?array null s'il ne faut pas mettre à jour la ligne. sinon, ce
|
||||||
* tableau est mergé dans $values puis utilisé pour mettre à jour la ligne
|
* tableau est mergé dans $row puis utilisé pour mettre à jour la ligne
|
||||||
* existante
|
* existante
|
||||||
* Retourner [false] pour annuler le chargement (la ligne n'est pas mise à
|
* Retourner [false] pour annuler le chargement (la ligne n'est pas mise à
|
||||||
* jour)
|
* jour)
|
||||||
@ -371,7 +351,7 @@ class CapacitorChannel implements ITransactor {
|
|||||||
* - La clé primaire (il s'agit généralement de "id_") ne peut pas être
|
* - 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
|
* modifiée. si elle est retournée, elle est ignorée
|
||||||
*/
|
*/
|
||||||
function onUpdate($item, array $values, array $pvalues): ?array {
|
function onUpdate($item, array $row, array $prow): ?array {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,8 +359,8 @@ class CapacitorChannel implements ITransactor {
|
|||||||
* méthode appelée lors du parcours des éléments avec
|
* méthode appelée lors du parcours des éléments avec
|
||||||
* {@link Capacitor::each()}
|
* {@link Capacitor::each()}
|
||||||
*
|
*
|
||||||
* @param mixed $item l'élément courant
|
* @param ?array $row la ligne courante. l'élément courant est accessible via
|
||||||
* @param ?array $values la ligne courante
|
* $row["item"]
|
||||||
* @return ?array le cas échéant, un tableau non null utilisé pour mettre à
|
* @return ?array le cas échéant, un tableau non null utilisé pour mettre à
|
||||||
* jour la ligne courante
|
* jour la ligne courante
|
||||||
*
|
*
|
||||||
@ -388,7 +368,7 @@ class CapacitorChannel implements ITransactor {
|
|||||||
* - La clé primaire (il s'agit généralement de "id_") ne peut pas être
|
* - 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
|
* modifiée. si elle est retournée, elle est ignorée
|
||||||
*/
|
*/
|
||||||
function onEach($item, array $values): ?array {
|
function onEach(array $row): ?array {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const onEach = "->".[self::class, "onEach"][1];
|
const onEach = "->".[self::class, "onEach"][1];
|
||||||
@ -397,11 +377,11 @@ class CapacitorChannel implements ITransactor {
|
|||||||
* méthode appelée lors du parcours des éléments avec
|
* méthode appelée lors du parcours des éléments avec
|
||||||
* {@link Capacitor::delete()}
|
* {@link Capacitor::delete()}
|
||||||
*
|
*
|
||||||
* @param mixed $item l'élément courant
|
* @param ?array $row la ligne courante. l'élément courant est accessible via
|
||||||
* @param ?array $values la ligne courante
|
* $row["item"]
|
||||||
* @return bool true s'il faut supprimer la ligne, false sinon
|
* @return bool true s'il faut supprimer la ligne, false sinon
|
||||||
*/
|
*/
|
||||||
function onDelete($item, array $values): bool {
|
function onDelete(array $row): bool {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const onDelete = "->".[self::class, "onDelete"][1];
|
const onDelete = "->".[self::class, "onDelete"][1];
|
||||||
@ -460,8 +440,8 @@ class CapacitorChannel implements ITransactor {
|
|||||||
$this->capacitor->reset($recreate);
|
$this->capacitor->reset($recreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
function charge($item, $func=null, ?array $args=null, ?array &$values=null): int {
|
function charge($item, $func=null, ?array $args=null, ?array &$row=null): int {
|
||||||
return $this->capacitor->charge($item, $func, $args, $values);
|
return $this->capacitor->charge($item, $func, $args, $row);
|
||||||
}
|
}
|
||||||
|
|
||||||
function discharge(bool $reset=true): Traversable {
|
function discharge(bool $reset=true): Traversable {
|
||||||
|
@ -125,9 +125,35 @@ abstract class CapacitorStorage {
|
|||||||
return $channel->getMigration();
|
return $channel->getMigration();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** sérialiser les valeurs qui doivent l'être dans $values */
|
/** sérialiser les valeurs qui doivent l'être dans $row */
|
||||||
protected function serialize(CapacitorChannel $channel, ?array $values): ?array {
|
protected function serialize(CapacitorChannel $channel, ?array $row): ?array {
|
||||||
if ($values === null) return null;
|
if ($row === null) return null;
|
||||||
|
$cols = $this->ColumnDefinitions($channel);
|
||||||
|
$index = 0;
|
||||||
|
$raw = [];
|
||||||
|
foreach (array_keys($cols) as $col) {
|
||||||
|
$key = $col;
|
||||||
|
if ($key === $index) {
|
||||||
|
$index++;
|
||||||
|
} elseif ($channel->isSerialCol($key)) {
|
||||||
|
[$serialCol, $sumCol] = $channel->getSumCols($key);
|
||||||
|
if (array_key_exists($key, $row)) {
|
||||||
|
$sum = $channel->getSum($key, $row[$key]);
|
||||||
|
$raw[$serialCol] = $sum[$serialCol];
|
||||||
|
if (array_key_exists($sumCol, $cols)) {
|
||||||
|
$raw[$sumCol] = $sum[$sumCol];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (array_key_exists($key, $row)) {
|
||||||
|
$raw[$col] = $row[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** désérialiser les valeurs qui doivent l'être dans $values */
|
||||||
|
protected function unserialize(CapacitorChannel $channel, ?array $raw): ?array {
|
||||||
|
if ($raw === null) return null;
|
||||||
$cols = $this->ColumnDefinitions($channel);
|
$cols = $this->ColumnDefinitions($channel);
|
||||||
$index = 0;
|
$index = 0;
|
||||||
$row = [];
|
$row = [];
|
||||||
@ -135,44 +161,18 @@ abstract class CapacitorStorage {
|
|||||||
$key = $col;
|
$key = $col;
|
||||||
if ($key === $index) {
|
if ($key === $index) {
|
||||||
$index++;
|
$index++;
|
||||||
|
} elseif (!array_key_exists($col, $raw)) {
|
||||||
} elseif ($channel->isSerialCol($key)) {
|
} elseif ($channel->isSerialCol($key)) {
|
||||||
[$serialCol, $sumCol] = $channel->getSumCols($key);
|
$value = $raw[$col];
|
||||||
if (array_key_exists($key, $values)) {
|
if ($value !== null) $value = $channel->unserialize($value);
|
||||||
$sum = $channel->getSum($key, $values[$key]);
|
$row[$key] = $value;
|
||||||
$row[$serialCol] = $sum[$serialCol];
|
} else {
|
||||||
if (array_key_exists($sumCol, $cols)) {
|
$row[$key] = $raw[$col];
|
||||||
$row[$sumCol] = $sum[$sumCol];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} elseif (array_key_exists($key, $values)) {
|
|
||||||
$row[$col] = $values[$key];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $row;
|
return $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** désérialiser les valeurs qui doivent l'être dans $values */
|
|
||||||
protected function unserialize(CapacitorChannel $channel, ?array $row): ?array {
|
|
||||||
if ($row === null) return null;
|
|
||||||
$cols = $this->ColumnDefinitions($channel);
|
|
||||||
$index = 0;
|
|
||||||
$values = [];
|
|
||||||
foreach (array_keys($cols) as $col) {
|
|
||||||
$key = $col;
|
|
||||||
if ($key === $index) {
|
|
||||||
$index++;
|
|
||||||
} elseif (!array_key_exists($col, $row)) {
|
|
||||||
} elseif ($channel->isSerialCol($key)) {
|
|
||||||
$value = $row[$col];
|
|
||||||
if ($value !== null) $value = $channel->unserialize($value);
|
|
||||||
$values[$key] = $value;
|
|
||||||
} else {
|
|
||||||
$values[$key] = $row[$col];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $values;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPrimaryKeys(CapacitorChannel $channel): array {
|
function getPrimaryKeys(CapacitorChannel $channel): array {
|
||||||
$primaryKeys = $channel->getPrimaryKeys();
|
$primaryKeys = $channel->getPrimaryKeys();
|
||||||
if ($primaryKeys === null) $primaryKeys = ["id_"];
|
if ($primaryKeys === null) $primaryKeys = ["id_"];
|
||||||
@ -238,13 +238,13 @@ abstract class CapacitorStorage {
|
|||||||
"class_name" => "varchar",
|
"class_name" => "varchar",
|
||||||
];
|
];
|
||||||
|
|
||||||
function channelExists(string $name, ?array &$row=null): bool {
|
function channelExists(string $name, ?array &$raw=null): bool {
|
||||||
$row = $this->db()->one([
|
$raw = $this->db()->one([
|
||||||
"select",
|
"select",
|
||||||
"from" => static::CHANNELS_TABLE,
|
"from" => static::CHANNELS_TABLE,
|
||||||
"where" => ["name" => $name],
|
"where" => ["name" => $name],
|
||||||
]);
|
]);
|
||||||
return $row !== null;
|
return $raw !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannels(): iterable {
|
function getChannels(): iterable {
|
||||||
@ -355,7 +355,7 @@ abstract class CapacitorStorage {
|
|||||||
* en fonction du type d'opération: création ou mise à jour
|
* en fonction du type d'opération: création ou mise à jour
|
||||||
*
|
*
|
||||||
* Dans les deux cas, si la fonction retourne un tableau, il est utilisé pour
|
* Dans les deux cas, si la fonction retourne un tableau, il est utilisé pour
|
||||||
* modifier les valeurs insérées/mises à jour. De plus, $values obtient la
|
* modifier les valeurs insérées/mises à jour. De plus, $row obtient la
|
||||||
* valeur finale des données insérées/mises à jour
|
* valeur finale des données insérées/mises à jour
|
||||||
*
|
*
|
||||||
* Si $args est renseigné, il est ajouté aux arguments utilisés pour appeler
|
* Si $args est renseigné, il est ajouté aux arguments utilisés pour appeler
|
||||||
@ -366,27 +366,27 @@ abstract class CapacitorStorage {
|
|||||||
* @return int 1 si l'objet a été chargé ou mis à jour, 0 s'il existait
|
* @return int 1 si l'objet a été chargé ou mis à jour, 0 s'il existait
|
||||||
* déjà à l'identique dans le canal
|
* déjà à l'identique dans le canal
|
||||||
*/
|
*/
|
||||||
function _charge(CapacitorChannel $channel, $item, $func, ?array $args, ?array &$values=null): int {
|
function _charge(CapacitorChannel $channel, $item, $func, ?array $args, ?array &$row=null): int {
|
||||||
$this->_create($channel);
|
$this->_create($channel);
|
||||||
$tableName = $channel->getTableName();
|
$tableName = $channel->getTableName();
|
||||||
$db = $this->db();
|
$db = $this->db();
|
||||||
$args ??= [];
|
$args ??= [];
|
||||||
|
|
||||||
$values = func::call([$channel, "getItemValues"], $item, ...$args);
|
$row = func::call([$channel, "getItemValues"], $item, ...$args);
|
||||||
if ($values === [false]) return 0;
|
if ($row === [false]) return 0;
|
||||||
|
|
||||||
if (array_key_exists("item", $values)) {
|
if ($row !== null && array_key_exists("item", $row)) {
|
||||||
$item = A::pop($values, "item");
|
$item = A::pop($row, "item");
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = cl::merge(
|
$raw = cl::merge(
|
||||||
$channel->getSum("item", $item),
|
$channel->getSum("item", $item),
|
||||||
$this->serialize($channel, $values));
|
$this->serialize($channel, $row));
|
||||||
$prow = null;
|
$praw = null;
|
||||||
$rowIds = $this->getRowIds($channel, $row, $primaryKeys);
|
$rowIds = $this->getRowIds($channel, $raw, $primaryKeys);
|
||||||
if ($rowIds !== null) {
|
if ($rowIds !== null) {
|
||||||
# modification
|
# modification
|
||||||
$prow = $db->one([
|
$praw = $db->one([
|
||||||
"select",
|
"select",
|
||||||
"from" => $tableName,
|
"from" => $tableName,
|
||||||
"where" => $rowIds,
|
"where" => $rowIds,
|
||||||
@ -395,47 +395,47 @@ abstract class CapacitorStorage {
|
|||||||
|
|
||||||
$now = date("Y-m-d H:i:s");
|
$now = date("Y-m-d H:i:s");
|
||||||
$insert = null;
|
$insert = null;
|
||||||
if ($prow === null) {
|
if ($praw === null) {
|
||||||
# création
|
# création
|
||||||
$row = cl::merge($row, [
|
$raw = cl::merge($raw, [
|
||||||
"created_" => $now,
|
"created_" => $now,
|
||||||
"modified_" => $now,
|
"modified_" => $now,
|
||||||
]);
|
]);
|
||||||
$insert = true;
|
$insert = true;
|
||||||
$initFunc = func::with([$channel, "onCreate"], $args);
|
$initFunc = func::with([$channel, "onCreate"], $args);
|
||||||
$values = $this->unserialize($channel, $row);
|
$row = $this->unserialize($channel, $raw);
|
||||||
$pvalues = null;
|
$prow = null;
|
||||||
} else {
|
} else {
|
||||||
# modification
|
# modification
|
||||||
# intégrer autant que possible les valeurs de prow dans row, de façon que
|
# intégrer autant que possible les valeurs de praw dans raw, de façon que
|
||||||
# l'utilisateur puisse voir clairement ce qui a été modifié
|
# l'utilisateur puisse voir clairement ce qui a été modifié
|
||||||
if ($channel->_wasSumModified("item", $row, $prow)) {
|
if ($channel->_wasSumModified("item", $raw, $praw)) {
|
||||||
$insert = false;
|
$insert = false;
|
||||||
$row = cl::merge($prow, $row, [
|
$raw = cl::merge($praw, $raw, [
|
||||||
"modified_" => $now,
|
"modified_" => $now,
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$row = cl::merge($prow, $row);
|
$raw = cl::merge($praw, $raw);
|
||||||
}
|
}
|
||||||
$initFunc = func::with([$channel, "onUpdate"], $args);
|
$initFunc = func::with([$channel, "onUpdate"], $args);
|
||||||
$values = $this->unserialize($channel, $row);
|
$row = $this->unserialize($channel, $raw);
|
||||||
$pvalues = $this->unserialize($channel, $prow);
|
$prow = $this->unserialize($channel, $praw);
|
||||||
}
|
}
|
||||||
|
|
||||||
$updates = $initFunc->prependArgs([$item, $values, $pvalues])->invoke();
|
$updates = $initFunc->prependArgs([$item, $row, $prow])->invoke();
|
||||||
if ($updates === [false]) return 0;
|
if ($updates === [false]) return 0;
|
||||||
if (is_array($updates) && $updates) {
|
if (is_array($updates) && $updates) {
|
||||||
if ($insert === null) $insert = false;
|
if ($insert === null) $insert = false;
|
||||||
if (!array_key_exists("modified_", $updates)) {
|
if (!array_key_exists("modified_", $updates)) {
|
||||||
$updates["modified_"] = $now;
|
$updates["modified_"] = $now;
|
||||||
}
|
}
|
||||||
$values = cl::merge($values, $updates);
|
$row = cl::merge($row, $updates);
|
||||||
$row = cl::merge($row, $this->serialize($channel, $updates));
|
$raw = cl::merge($raw, $this->serialize($channel, $updates));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($func !== null) {
|
if ($func !== null) {
|
||||||
$updates = func::with($func)
|
$updates = func::with($func)
|
||||||
->prependArgs([$item, $values, $pvalues])
|
->prependArgs([$item, $row, $prow])
|
||||||
->bind($channel)
|
->bind($channel)
|
||||||
->invoke();
|
->invoke();
|
||||||
if ($updates === [false]) return 0;
|
if ($updates === [false]) return 0;
|
||||||
@ -444,8 +444,8 @@ abstract class CapacitorStorage {
|
|||||||
if (!array_key_exists("modified_", $updates)) {
|
if (!array_key_exists("modified_", $updates)) {
|
||||||
$updates["modified_"] = $now;
|
$updates["modified_"] = $now;
|
||||||
}
|
}
|
||||||
$values = cl::merge($values, $updates);
|
$row = cl::merge($row, $updates);
|
||||||
$row = cl::merge($row, $this->serialize($channel, $updates));
|
$raw = cl::merge($raw, $this->serialize($channel, $updates));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,25 +464,23 @@ abstract class CapacitorStorage {
|
|||||||
$id = $db->exec([
|
$id = $db->exec([
|
||||||
"insert",
|
"insert",
|
||||||
"into" => $tableName,
|
"into" => $tableName,
|
||||||
"values" => $row,
|
"values" => $raw,
|
||||||
]);
|
]);
|
||||||
if (count($primaryKeys) == 1 && $rowIds === null) {
|
if (count($primaryKeys) == 1 && $rowIds === null) {
|
||||||
# mettre à jour avec l'id généré
|
# mettre à jour avec l'id généré
|
||||||
$values[$primaryKeys[0]] = $id;
|
$row[$primaryKeys[0]] = $id;
|
||||||
}
|
}
|
||||||
$nbModified = 1;
|
$nbModified = 1;
|
||||||
} else {
|
} else {
|
||||||
# calculer ce qui a changé pour ne mettre à jour que le nécessaire
|
# calculer ce qui a changé pour ne mettre à jour que le nécessaire
|
||||||
$updates = [];
|
$updates = [];
|
||||||
foreach ($row as $col => $value) {
|
foreach ($raw as $col => $value) {
|
||||||
if (array_key_exists($col, $rowIds)) {
|
if (array_key_exists($col, $rowIds)) {
|
||||||
# ne jamais mettre à jour la clé primaire
|
# ne jamais mettre à jour la clé primaire
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$pvalue = $prow[$col] ?? null;
|
$pvalue = $praw[$col] ?? null;
|
||||||
if ($value !== ($pvalue)) {
|
if ($value !== $pvalue) $updates[$col] = $value;
|
||||||
$updates[$col] = $value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (count($updates) == 1 && array_key_first($updates) == "modified_") {
|
if (count($updates) == 1 && array_key_first($updates) == "modified_") {
|
||||||
# si l'unique modification porte sur la date de modification, alors
|
# si l'unique modification porte sur la date de modification, alors
|
||||||
@ -510,19 +508,22 @@ abstract class CapacitorStorage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function charge(?string $channel, $item, $func=null, ?array $args=null, ?array &$values=null): int {
|
function charge(?string $channel, $item, $func=null, ?array $args=null, ?array &$row=null): int {
|
||||||
return $this->_charge($this->getChannel($channel), $item, $func, $args, $values);
|
return $this->_charge($this->getChannel($channel), $item, $func, $args, $row);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** décharger les données du canal spécifié */
|
/**
|
||||||
|
* décharger les données du canal spécifié. seul la valeur de $item est
|
||||||
|
* fournie
|
||||||
|
*/
|
||||||
function _discharge(CapacitorChannel $channel, bool $reset=true): Traversable {
|
function _discharge(CapacitorChannel $channel, bool $reset=true): Traversable {
|
||||||
$this->_create($channel);
|
$this->_create($channel);
|
||||||
$rows = $this->db()->all([
|
$raws = $this->db()->all([
|
||||||
"select item__",
|
"select item__",
|
||||||
"from" => $channel->getTableName(),
|
"from" => $channel->getTableName(),
|
||||||
]);
|
]);
|
||||||
foreach ($rows as $row) {
|
foreach ($raws as $raw) {
|
||||||
yield unserialize($row['item__']);
|
yield unserialize($raw['item__']);
|
||||||
}
|
}
|
||||||
if ($reset) $this->_reset($channel);
|
if ($reset) $this->_reset($channel);
|
||||||
}
|
}
|
||||||
@ -591,45 +592,34 @@ abstract class CapacitorStorage {
|
|||||||
if ($filter === null) throw ValueException::null("filter");
|
if ($filter === null) throw ValueException::null("filter");
|
||||||
$this->_create($channel);
|
$this->_create($channel);
|
||||||
$this->verifixFilter($channel, $filter);
|
$this->verifixFilter($channel, $filter);
|
||||||
$row = $this->db()->one(cl::merge([
|
$raw = $this->db()->one(cl::merge([
|
||||||
"select",
|
"select",
|
||||||
"from" => $channel->getTableName(),
|
"from" => $channel->getTableName(),
|
||||||
"where" => $filter,
|
"where" => $filter,
|
||||||
], $mergeQuery));
|
], $mergeQuery));
|
||||||
return $this->unserialize($channel, $row);
|
return $this->unserialize($channel, $raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
function one(?string $channel, $filter, ?array $mergeQuery=null): ?array {
|
function one(?string $channel, $filter, ?array $mergeQuery=null): ?array {
|
||||||
return $this->_one($this->getChannel($channel), $filter, $mergeQuery);
|
return $this->_one($this->getChannel($channel), $filter, $mergeQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function _allCached(string $id, CapacitorChannel $channel, $filter, ?array $mergeQuery=null): Traversable {
|
|
||||||
$this->_create($channel);
|
|
||||||
$this->verifixFilter($channel, $filter);
|
|
||||||
$rows = $this->db()->all(cl::merge([
|
|
||||||
"select",
|
|
||||||
"from" => $channel->getTableName(),
|
|
||||||
"where" => $filter,
|
|
||||||
], $mergeQuery), null, $this->getPrimaryKeys($channel));
|
|
||||||
if ($channel->isUseCache()) {
|
|
||||||
$cacheIds = [$id, get_class($channel)];
|
|
||||||
cache::get()->resetCached($cacheIds);
|
|
||||||
$rows = cache::new(null, $cacheIds, function() use ($rows) {
|
|
||||||
yield from $rows;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
foreach ($rows as $key => $row) {
|
|
||||||
yield $key => $this->unserialize($channel, $row);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* obtenir les lignes correspondant au filtre sur le canal spécifié
|
* obtenir les lignes correspondant au filtre sur le canal spécifié
|
||||||
*
|
*
|
||||||
* si $filter n'est pas un tableau, il est transformé en ["id_" => $filter]
|
* si $filter n'est pas un tableau, il est transformé en ["id_" => $filter]
|
||||||
*/
|
*/
|
||||||
function _all(CapacitorChannel $channel, $filter, ?array $mergeQuery=null): Traversable {
|
function _all(CapacitorChannel $channel, $filter, ?array $mergeQuery=null): Traversable {
|
||||||
return $this->_allCached("all", $channel, $filter, $mergeQuery);
|
$this->_create($channel);
|
||||||
|
$this->verifixFilter($channel, $filter);
|
||||||
|
$raws = $this->db()->all(cl::merge([
|
||||||
|
"select",
|
||||||
|
"from" => $channel->getTableName(),
|
||||||
|
"where" => $filter,
|
||||||
|
], $mergeQuery), null, $this->getPrimaryKeys($channel));
|
||||||
|
foreach ($raws as $key => $raw) {
|
||||||
|
yield $key => $this->unserialize($channel, $raw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function all(?string $channel, $filter, $mergeQuery=null): Traversable {
|
function all(?string $channel, $filter, $mergeQuery=null): Traversable {
|
||||||
@ -665,10 +655,10 @@ abstract class CapacitorStorage {
|
|||||||
$tableName = $channel->getTableName();
|
$tableName = $channel->getTableName();
|
||||||
try {
|
try {
|
||||||
$args ??= [];
|
$args ??= [];
|
||||||
$all = $this->_allCached("each", $channel, $filter, $mergeQuery);
|
$rows = $this->_all($channel, $filter, $mergeQuery);
|
||||||
foreach ($all as $values) {
|
foreach ($rows as $row) {
|
||||||
$rowIds = $this->getRowIds($channel, $values);
|
$rowIds = $this->getRowIds($channel, $row);
|
||||||
$updates = $onEach->invoke([$values["item"], $values, ...$args]);
|
$updates = $onEach->invoke([$row, ...$args]);
|
||||||
if (is_array($updates) && $updates) {
|
if (is_array($updates) && $updates) {
|
||||||
if (!array_key_exists("modified_", $updates)) {
|
if (!array_key_exists("modified_", $updates)) {
|
||||||
$updates["modified_"] = date("Y-m-d H:i:s");
|
$updates["modified_"] = date("Y-m-d H:i:s");
|
||||||
@ -732,10 +722,10 @@ abstract class CapacitorStorage {
|
|||||||
$tableName = $channel->getTableName();
|
$tableName = $channel->getTableName();
|
||||||
try {
|
try {
|
||||||
$args ??= [];
|
$args ??= [];
|
||||||
$all = $this->_allCached("delete", $channel, $filter);
|
$rows = $this->_all($channel, $filter);
|
||||||
foreach ($all as $values) {
|
foreach ($rows as $row) {
|
||||||
$rowIds = $this->getRowIds($channel, $values);
|
$rowIds = $this->getRowIds($channel, $row);
|
||||||
$shouldDelete = boolval($onDelete->invoke([$values["item"], $values, ...$args]));
|
$shouldDelete = boolval($onDelete->invoke([$row, ...$args]));
|
||||||
if ($shouldDelete) {
|
if ($shouldDelete) {
|
||||||
$db->exec([
|
$db->exec([
|
||||||
"delete",
|
"delete",
|
||||||
|
@ -73,7 +73,8 @@ class SqliteStorageTest extends TestCase {
|
|||||||
$capacitor->charge(["name" => "third", "age" => 15]);
|
$capacitor->charge(["name" => "third", "age" => 15]);
|
||||||
$capacitor->charge(["name" => "fourth", "age" => 20]);
|
$capacitor->charge(["name" => "fourth", "age" => 20]);
|
||||||
|
|
||||||
$setDone = function ($item, $row, $suffix=null) {
|
$setDone = function ($row, $suffix=null) {
|
||||||
|
$item = $row["item"];
|
||||||
$updates = ["done" => 1];
|
$updates = ["done" => 1];
|
||||||
if ($suffix !== null) {
|
if ($suffix !== null) {
|
||||||
$item["name"] .= $suffix;
|
$item["name"] .= $suffix;
|
||||||
@ -82,7 +83,7 @@ class SqliteStorageTest extends TestCase {
|
|||||||
return $updates;
|
return $updates;
|
||||||
};
|
};
|
||||||
$capacitor->each(["age" => [">", 10]], $setDone, ["++"]);
|
$capacitor->each(["age" => [">", 10]], $setDone, ["++"]);
|
||||||
$capacitor->each(["done" => 0], $setDone, null);
|
$capacitor->each(["done" => 0], $setDone);
|
||||||
|
|
||||||
self::Txx(cl::all($capacitor->discharge(false)));
|
self::Txx(cl::all($capacitor->discharge(false)));
|
||||||
$capacitor->close();
|
$capacitor->close();
|
||||||
@ -147,8 +148,8 @@ class SqliteStorageTest extends TestCase {
|
|||||||
"from" => $capacitor->getChannel()->getTableName(),
|
"from" => $capacitor->getChannel()->getTableName(),
|
||||||
])));
|
])));
|
||||||
self::Txx("=== each");
|
self::Txx("=== each");
|
||||||
$capacitor->each(null, function ($item, $values) {
|
$capacitor->each(null, function ($row) {
|
||||||
self::Txx($values);
|
self::Txx($row);
|
||||||
});
|
});
|
||||||
|
|
||||||
$capacitor->close();
|
$capacitor->close();
|
||||||
@ -176,99 +177,100 @@ class SqliteStorageTest extends TestCase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$capacitor->reset();
|
$capacitor->reset();
|
||||||
$capacitor->charge(["name" => "first", "age" => 5], function($item, ?array $values, ?array $pvalues) {
|
$capacitor->charge(["name" => "first", "age" => 5], function($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame("first", $item["name"]);
|
self::assertSame("first", $item["name"]);
|
||||||
self::assertSame(5, $item["age"]);
|
self::assertSame(5, $item["age"]);
|
||||||
self::assertnotnull($values);
|
self::assertnotnull($row);
|
||||||
self::assertSame(["name", "age", "item", "item__sum_", "created_", "modified_"], array_keys($values));
|
self::assertSame(["name", "age", "item", "item__sum_", "created_", "modified_"], array_keys($row));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 5,
|
"age" => 5,
|
||||||
"item" => $item,
|
"item" => $item,
|
||||||
], cl::select($values, ["name", "age", "item"]));
|
], cl::select($row, ["name", "age", "item"]));
|
||||||
self::assertNull($pvalues);
|
self::assertNull($prow);
|
||||||
});
|
});
|
||||||
$capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $values, ?array $pvalues) {
|
$capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame("first", $item["name"]);
|
self::assertSame("first", $item["name"]);
|
||||||
self::assertSame(10, $item["age"]);
|
self::assertSame(10, $item["age"]);
|
||||||
self::assertnotnull($values);
|
self::assertnotnull($row);
|
||||||
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
|
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 10,
|
"age" => 10,
|
||||||
"done" => 0,
|
"done" => 0,
|
||||||
"notes" => null,
|
"notes" => null,
|
||||||
"item" => $item,
|
"item" => $item,
|
||||||
], cl::select($values, ["name", "age", "done", "notes", "item"]));
|
], cl::select($row, ["name", "age", "done", "notes", "item"]));
|
||||||
self::assertNotNull($pvalues);
|
self::assertNotNull($prow);
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 5,
|
"age" => 5,
|
||||||
"done" => 0,
|
"done" => 0,
|
||||||
"notes" => null,
|
"notes" => null,
|
||||||
"item" => ["name" => "first", "age" => 5],
|
"item" => ["name" => "first", "age" => 5],
|
||||||
], cl::select($pvalues, ["name", "age", "done", "notes", "item"]));
|
], cl::select($prow, ["name", "age", "done", "notes", "item"]));
|
||||||
});
|
});
|
||||||
|
|
||||||
$capacitor->each(null, function($item, ?array $values) {
|
$capacitor->each(null, function(array $row) {
|
||||||
|
$item = $row["item"];
|
||||||
self::assertSame("first", $item["name"]);
|
self::assertSame("first", $item["name"]);
|
||||||
self::assertSame(10, $item["age"]);
|
self::assertSame(10, $item["age"]);
|
||||||
self::assertnotnull($values);
|
self::assertnotnull($row);
|
||||||
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
|
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 10,
|
"age" => 10,
|
||||||
"done" => 0,
|
"done" => 0,
|
||||||
"notes" => null,
|
"notes" => null,
|
||||||
"item" => $item,
|
"item" => $item,
|
||||||
], cl::select($values, ["name", "age", "done", "notes", "item"]));
|
], cl::select($row, ["name", "age", "done", "notes", "item"]));
|
||||||
return [
|
return [
|
||||||
"done" => 1,
|
"done" => 1,
|
||||||
"notes" => "modified",
|
"notes" => "modified",
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
$capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $values, ?array $pvalues) {
|
$capacitor->charge(["name" => "first", "age" => 10], function($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame("first", $item["name"]);
|
self::assertSame("first", $item["name"]);
|
||||||
self::assertSame(10, $item["age"]);
|
self::assertSame(10, $item["age"]);
|
||||||
self::assertnotnull($values);
|
self::assertnotnull($row);
|
||||||
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
|
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 10,
|
"age" => 10,
|
||||||
"done" => 1,
|
"done" => 1,
|
||||||
"notes" => "modified",
|
"notes" => "modified",
|
||||||
"item" => $item,
|
"item" => $item,
|
||||||
], cl::select($values, ["name", "age", "done", "notes", "item"]));
|
], cl::select($row, ["name", "age", "done", "notes", "item"]));
|
||||||
self::assertNotNull($pvalues);
|
self::assertNotNull($prow);
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 10,
|
"age" => 10,
|
||||||
"done" => 1,
|
"done" => 1,
|
||||||
"notes" => "modified",
|
"notes" => "modified",
|
||||||
"item" => $item,
|
"item" => $item,
|
||||||
], cl::select($pvalues, ["name", "age", "done", "notes", "item"]));
|
], cl::select($prow, ["name", "age", "done", "notes", "item"]));
|
||||||
});
|
});
|
||||||
|
|
||||||
$capacitor->charge(["name" => "first", "age" => 20], function($item, ?array $values, ?array $pvalues) {
|
$capacitor->charge(["name" => "first", "age" => 20], function($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame("first", $item["name"]);
|
self::assertSame("first", $item["name"]);
|
||||||
self::assertSame(20, $item["age"]);
|
self::assertSame(20, $item["age"]);
|
||||||
self::assertnotnull($values);
|
self::assertnotnull($row);
|
||||||
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($values));
|
self::assertSame(["name", "age", "done", "notes", "item", "item__sum_", "created_", "modified_"], array_keys($row));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 20,
|
"age" => 20,
|
||||||
"done" => 1,
|
"done" => 1,
|
||||||
"notes" => "modified",
|
"notes" => "modified",
|
||||||
"item" => $item,
|
"item" => $item,
|
||||||
], cl::select($values, ["name", "age", "done", "notes", "item"]));
|
], cl::select($row, ["name", "age", "done", "notes", "item"]));
|
||||||
self::assertNotNull($pvalues);
|
self::assertNotNull($prow);
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first",
|
"name" => "first",
|
||||||
"age" => 10,
|
"age" => 10,
|
||||||
"done" => 1,
|
"done" => 1,
|
||||||
"notes" => "modified",
|
"notes" => "modified",
|
||||||
"item" => ["name" => "first", "age" => 10],
|
"item" => ["name" => "first", "age" => 10],
|
||||||
], cl::select($pvalues, ["name", "age", "done", "notes", "item"]));
|
], cl::select($prow, ["name", "age", "done", "notes", "item"]));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,55 +295,55 @@ class SqliteStorageTest extends TestCase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$capacitor->reset();
|
$capacitor->reset();
|
||||||
$nbModified = $capacitor->charge(["name" => "first", "age" => 5], function ($item, ?array $values, ?array $pvalues) {
|
$nbModified = $capacitor->charge(["name" => "first", "age" => 5], function ($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first", "age" => 5,
|
"name" => "first", "age" => 5,
|
||||||
"item" => $item,
|
"item" => $item,
|
||||||
], cl::select($values, ["name", "age", "item"]));
|
], cl::select($row, ["name", "age", "item"]));
|
||||||
return ["item" => null];
|
return ["item" => null];
|
||||||
});
|
});
|
||||||
self::assertSame(1, $nbModified);
|
self::assertSame(1, $nbModified);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
# nb: on met des sleep() pour que la date de modification soit systématiquement différente
|
# nb: on met des sleep() pour que la date de modification soit systématiquement différente
|
||||||
|
|
||||||
$nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $values, ?array $pvalues) {
|
$nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first", "age" => 10,
|
"name" => "first", "age" => 10,
|
||||||
"item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
|
"item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
|
||||||
], cl::select($values, ["name", "age", "item", "item__sum_"]));
|
], cl::select($row, ["name", "age", "item", "item__sum_"]));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first", "age" => 5,
|
"name" => "first", "age" => 5,
|
||||||
"item" => null, "item__sum_" => null,
|
"item" => null, "item__sum_" => null,
|
||||||
], cl::select($pvalues, ["name", "age", "item", "item__sum_"]));
|
], cl::select($prow, ["name", "age", "item", "item__sum_"]));
|
||||||
return ["item" => null];
|
return ["item" => null];
|
||||||
});
|
});
|
||||||
self::assertSame(1, $nbModified);
|
self::assertSame(1, $nbModified);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
# pas de modification ici
|
# pas de modification ici
|
||||||
$nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $values, ?array $pvalues) {
|
$nbModified = $capacitor->charge(["name" => "first", "age" => 10], function ($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first", "age" => 10,
|
"name" => "first", "age" => 10,
|
||||||
"item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
|
"item" => $item, "item__sum_" => "9181336dfca20c86313d6065d89aa2ad5070b0fc",
|
||||||
], cl::select($values, ["name", "age", "item", "item__sum_"]));
|
], cl::select($row, ["name", "age", "item", "item__sum_"]));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first", "age" => 10,
|
"name" => "first", "age" => 10,
|
||||||
"item" => null, "item__sum_" => null,
|
"item" => null, "item__sum_" => null,
|
||||||
], cl::select($pvalues, ["name", "age", "item", "item__sum_"]));
|
], cl::select($prow, ["name", "age", "item", "item__sum_"]));
|
||||||
return ["item" => null];
|
return ["item" => null];
|
||||||
});
|
});
|
||||||
self::assertSame(0, $nbModified);
|
self::assertSame(0, $nbModified);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
$nbModified = $capacitor->charge(["name" => "first", "age" => 20], function ($item, ?array $values, ?array $pvalues) {
|
$nbModified = $capacitor->charge(["name" => "first", "age" => 20], function ($item, ?array $row, ?array $prow) {
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first", "age" => 20,
|
"name" => "first", "age" => 20,
|
||||||
"item" => $item, "item__sum_" => "001b91982b4e0883b75428c0eb28573a5dc5f7a5",
|
"item" => $item, "item__sum_" => "001b91982b4e0883b75428c0eb28573a5dc5f7a5",
|
||||||
], cl::select($values, ["name", "age", "item", "item__sum_"]));
|
], cl::select($row, ["name", "age", "item", "item__sum_"]));
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
"name" => "first", "age" => 10,
|
"name" => "first", "age" => 10,
|
||||||
"item" => null, "item__sum_" => null,
|
"item" => null, "item__sum_" => null,
|
||||||
], cl::select($pvalues, ["name", "age", "item", "item__sum_"]));
|
], cl::select($prow, ["name", "age", "item", "item__sum_"]));
|
||||||
return ["item" => null];
|
return ["item" => null];
|
||||||
});
|
});
|
||||||
self::assertSame(1, $nbModified);
|
self::assertSame(1, $nbModified);
|
||||||
|
@ -3,6 +3,7 @@ namespace nulib\db\sqlite;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use nulib\tests\TestCase;
|
use nulib\tests\TestCase;
|
||||||
|
use nulib\ValueException;
|
||||||
|
|
||||||
class SqliteTest extends TestCase {
|
class SqliteTest extends TestCase {
|
||||||
const CREATE_PERSON = "create table person(nom varchar, prenom varchar, age integer)";
|
const CREATE_PERSON = "create table person(nom varchar, prenom varchar, age integer)";
|
||||||
@ -12,8 +13,8 @@ class SqliteTest extends TestCase {
|
|||||||
function testMigration() {
|
function testMigration() {
|
||||||
$sqlite = new Sqlite(":memory:", [
|
$sqlite = new Sqlite(":memory:", [
|
||||||
"migration" => [
|
"migration" => [
|
||||||
self::CREATE_PERSON,
|
"create" => self::CREATE_PERSON,
|
||||||
self::INSERT_JEPHTE,
|
"insert" => self::INSERT_JEPHTE,
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
self::assertSame("clain", $sqlite->get("select nom, age from person"));
|
self::assertSame("clain", $sqlite->get("select nom, age from person"));
|
||||||
@ -30,15 +31,15 @@ class SqliteTest extends TestCase {
|
|||||||
], $sqlite->get("select nom, age from person where nom = 'payet'", null, true));
|
], $sqlite->get("select nom, age from person where nom = 'payet'", null, true));
|
||||||
|
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
["key" => "0", "value" => self::CREATE_PERSON, "done" => 1],
|
["channel" => "", "name" => "create", "done" => 1],
|
||||||
["key" => "1", "value" => self::INSERT_JEPHTE, "done" => 1],
|
["channel" => "", "name" => "insert", "done" => 1],
|
||||||
], iterator_to_array($sqlite->all("select key, value, done from _migration")));
|
], iterator_to_array($sqlite->all("select channel, name, done from _migration")));
|
||||||
}
|
}
|
||||||
|
|
||||||
function testException() {
|
function testException() {
|
||||||
$sqlite = new Sqlite(":memory:");
|
$sqlite = new Sqlite(":memory:");
|
||||||
self::assertException(Exception::class, [$sqlite, "exec"], "prout");
|
self::assertException(Exception::class, [$sqlite, "exec"], "prout");
|
||||||
self::assertException(SqliteException::class, [$sqlite, "exec"], ["prout"]);
|
self::assertException(ValueException::class, [$sqlite, "exec"], ["prout"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function assertInserted(Sqlite $sqlite, array $row, array $query): void {
|
protected function assertInserted(Sqlite $sqlite, array $row, array $query): void {
|
||||||
@ -141,6 +142,10 @@ class SqliteTest extends TestCase {
|
|||||||
|
|
||||||
self::assertSame([
|
self::assertSame([
|
||||||
["count" => 2],
|
["count" => 2],
|
||||||
], iterator_to_array($sqlite->all(["select count(name) as count from user", "group by" => ["amount"], "having" => ["count(name) = 2"]])));
|
], iterator_to_array($sqlite->all([
|
||||||
|
"select count(name) as count from user",
|
||||||
|
"group by" => ["amount"],
|
||||||
|
"having" => ["count(name) = 2"],
|
||||||
|
])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user