117 lines
3.2 KiB
PHP
117 lines
3.2 KiB
PHP
<?php
|
|
namespace nulib\db\cache;
|
|
|
|
use nulib\cl;
|
|
use nulib\db\CapacitorChannel;
|
|
use nulib\php\time\DateTime;
|
|
use nulib\php\time\Delay;
|
|
|
|
class CacheChannel extends CapacitorChannel {
|
|
/** @var int durée de vie par défaut du cache */
|
|
const DURATION = "1D"; // jusqu'au lendemain
|
|
|
|
const INCLUDES = null;
|
|
|
|
const EXCLUDES = null;
|
|
|
|
const COLUMN_DEFINITIONS = [
|
|
"group_id" => "varchar(64) not null",
|
|
"id" => "varchar(64) not null",
|
|
"date_start" => "datetime",
|
|
"duration_" => "text",
|
|
"primary key (group_id, id)",
|
|
];
|
|
|
|
static function get_cache_ids($id): array {
|
|
if (is_array($id)) {
|
|
$keys = array_keys($id);
|
|
if (array_key_exists("group_id", $id)) $groupIdKey = "group_id";
|
|
else $groupIdKey = $keys[1] ?? null;
|
|
$groupId = $id[$groupIdKey] ?? "";
|
|
if (array_key_exists("id", $id)) $idKey = "id";
|
|
else $idKey = $keys[0] ?? null;
|
|
$id = $id[$idKey] ?? "";
|
|
} else {
|
|
$groupId = "";
|
|
}
|
|
if (preg_match('/^(.*\\\\)?([^\\\\]+)$/', $groupId, $ms)) {
|
|
# si le groupe est une classe, faire un hash du package pour limiter la
|
|
# longueur du groupe
|
|
[$package, $groupId] = [$ms[1], $ms[2]];
|
|
$package = substr(md5($package), 0, 4);
|
|
$groupId = "${groupId}_$package";
|
|
}
|
|
return ["group_id" => $groupId, "id" => $id];
|
|
}
|
|
|
|
function __construct(?string $duration=null, ?string $name=null) {
|
|
parent::__construct($name);
|
|
$this->duration = $duration ?? static::DURATION;
|
|
$this->includes = static::INCLUDES;
|
|
$this->excludes = static::EXCLUDES;
|
|
}
|
|
|
|
protected string $duration;
|
|
|
|
protected ?array $includes;
|
|
|
|
protected ?array $excludes;
|
|
|
|
function getItemValues($item): ?array {
|
|
return cl::merge(self::get_cache_ids($item), [
|
|
"item" => null,
|
|
]);
|
|
}
|
|
|
|
function onCreate($item, array $values, ?array $alwaysNull, ?string $duration=null): ?array {
|
|
$now = new DateTime();
|
|
$duration ??= $this->duration;
|
|
return [
|
|
"date_start" => $now,
|
|
"duration" => new Delay($duration, $now),
|
|
];
|
|
}
|
|
|
|
function onUpdate($item, array $values, array $pvalues, ?string $duration=null): ?array {
|
|
$now = new DateTime();
|
|
$duration ??= $this->duration;
|
|
return [
|
|
"date_start" => $now,
|
|
"duration" => new Delay($duration, $now),
|
|
];
|
|
}
|
|
|
|
function shouldUpdate($id, bool $noCache=false): bool {
|
|
if ($noCache) return true;
|
|
|
|
$cacheIds = self::get_cache_ids($id);
|
|
$groupId = $cacheIds["group_id"];
|
|
if ($groupId) {
|
|
$includes = $this->includes;
|
|
$shouldInclude = $includes !== null && in_array($groupId, $includes);
|
|
$excludes = $this->excludes;
|
|
$shouldExclude = $excludes !== null && in_array($groupId, $excludes);
|
|
if (!$shouldInclude || $shouldExclude) return true;
|
|
}
|
|
|
|
$found = false;
|
|
$expired = false;
|
|
$this->each($cacheIds,
|
|
function($item, $values) use (&$found, &$expired) {
|
|
$found = true;
|
|
$expired = $values["duration"]->isElapsed();
|
|
});
|
|
return !$found || $expired;
|
|
}
|
|
|
|
function setCached($id, ?string $duration=null): void {
|
|
$cacheIds = self::get_cache_ids($id);
|
|
$this->charge($cacheIds, null, [$duration]);
|
|
}
|
|
|
|
function resetCached($id) {
|
|
$cacheIds = self::get_cache_ids($id);
|
|
$this->delete($cacheIds);
|
|
}
|
|
}
|