1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-12-03 20:57:48 +01:00
MadelineProto/src/Db/RedisArray.php

163 lines
3.7 KiB
PHP
Raw Normal View History

2022-12-30 21:54:44 +01:00
<?php
declare(strict_types=1);
namespace danog\MadelineProto\Db;
2021-09-05 19:28:22 +02:00
use Amp\Iterator;
2020-09-12 19:06:42 +02:00
use Amp\Redis\Redis as RedisRedis;
2022-12-30 19:21:36 +01:00
use danog\MadelineProto\Db\Driver\Redis;
use danog\MadelineProto\Logger;
use danog\MadelineProto\Settings\Database\Redis as DatabaseRedis;
/**
* Redis database backend.
2023-01-25 16:32:48 +01:00
*
* @internal
*
* @template TKey as array-key
* @template TValue
* @extends DriverArray<TKey, TValue>
*/
class RedisArray extends DriverArray
{
2020-09-12 19:06:42 +02:00
private RedisRedis $db;
// Legacy
protected array $settings;
/**
* Initialize on startup.
*/
2023-01-08 20:33:54 +01:00
public function initStartup(): void
{
2023-01-08 20:33:54 +01:00
$this->initConnection($this->dbSettings);
}
2023-01-03 22:07:58 +01:00
protected function prepareTable(): void
{
2020-09-12 19:06:42 +02:00
}
2023-01-03 22:07:58 +01:00
protected function renameTable(string $from, string $to): void
2020-09-12 19:06:42 +02:00
{
Logger::log("Moving data from {$from} to {$to}", Logger::WARNING);
2020-09-12 20:14:58 +02:00
$from = "va:$from";
$to = "va:$to";
$request = $this->db->scan($from.'*');
2020-09-12 19:06:42 +02:00
$lenK = \strlen($from);
2023-01-11 18:47:27 +01:00
foreach ($request as $oldKey) {
$newKey = $to.\substr($oldKey, $lenK);
$value = $this->db->get($oldKey);
$this->db->set($newKey, $value);
$this->db->delete($oldKey);
2020-09-12 19:06:42 +02:00
}
}
/**
* Initialize connection.
*/
2023-01-03 22:07:58 +01:00
public function initConnection(DatabaseRedis $settings): void
{
2023-01-11 18:47:27 +01:00
$this->db ??= Redis::getConnection($settings);
}
/**
2020-09-12 19:06:42 +02:00
* Get redis key name.
*/
2020-09-12 19:06:42 +02:00
private function rKey(string $key): string
{
2020-09-12 19:06:42 +02:00
return 'va:'.$this->table.':'.$key;
}
/**
2020-09-12 19:06:42 +02:00
* Get iterator key.
*/
2020-09-12 19:06:42 +02:00
private function itKey(): string
{
2020-09-12 19:06:42 +02:00
return 'va:'.$this->table.'*';
}
2023-01-03 22:07:58 +01:00
public function set(string|int $index, mixed $value): void
{
2022-06-25 19:15:30 +02:00
if ($this->hasCache($index) && $this->getCache($index) === $value) {
2023-01-08 16:41:42 +01:00
return;
2020-09-12 19:06:42 +02:00
}
$this->setCache($index, $value);
2023-05-02 18:42:46 +02:00
$this->db->set($this->rKey($index), ($this->serializer)($value));
2023-01-03 22:07:58 +01:00
$this->setCache($index, $value);
}
2023-01-03 22:07:58 +01:00
public function offsetGet(mixed $offset): mixed
{
2022-06-25 19:15:30 +02:00
$offset = (string) $offset;
2023-01-03 22:07:58 +01:00
if ($this->hasCache($offset)) {
return $this->getCache($offset);
}
2023-01-03 22:07:58 +01:00
$value = $this->db->get($this->rKey($offset));
2023-05-02 18:42:46 +02:00
if ($value !== null && $value = ($this->deserializer)($value)) {
2023-01-03 22:07:58 +01:00
$this->setCache($offset, $value);
}
2023-01-03 22:07:58 +01:00
return $value;
}
2023-01-03 22:07:58 +01:00
public function unset(string|int $key): void
{
2021-12-06 20:20:43 +01:00
$this->unsetCache($key);
2023-01-03 22:07:58 +01:00
$this->db->delete($this->rkey($key));
}
2023-01-15 11:21:57 +01:00
/**
* Get iterator.
*
* @return \Traversable<array-key, mixed>
*/
2023-01-08 20:46:16 +01:00
public function getIterator(): \Traversable
{
2023-01-03 22:07:58 +01:00
$request = $this->db->scan($this->itKey());
2023-01-03 22:07:58 +01:00
$len = \strlen($this->rKey(''));
2023-01-08 20:46:16 +01:00
foreach ($request as $key) {
2023-05-02 18:42:46 +02:00
yield \substr($key, $len) => ($this->deserializer)($this->db->get($key));
2023-01-03 22:07:58 +01:00
}
}
/**
* Count elements.
*
* @link https://php.net/manual/en/arrayiterator.count.php
2023-01-08 20:33:54 +01:00
* @return int The number of elements or public properties in the associated
* array or object, respectively.
*/
2023-01-03 22:07:58 +01:00
public function count(): int
{
2023-01-11 18:47:27 +01:00
return \iterator_count($this->db->scan($this->itKey()));
}
2020-11-26 21:49:31 +01:00
/**
* Clear all elements.
*/
2023-01-03 22:07:58 +01:00
public function clear(): void
2020-11-26 21:49:31 +01:00
{
2022-06-25 19:15:30 +02:00
$this->clearCache();
2023-01-03 22:07:58 +01:00
$request = $this->db->scan($this->itKey());
$keys = [];
2023-01-11 18:47:27 +01:00
foreach ($request as $key) {
$keys[] = $key;
if (\count($keys) === 10) {
$this->db->delete(...$keys);
2023-01-03 22:07:58 +01:00
$keys = [];
2020-11-26 21:49:31 +01:00
}
2023-01-03 22:07:58 +01:00
}
2023-01-11 18:47:27 +01:00
if ($keys) {
2023-01-03 22:07:58 +01:00
$this->db->delete(...$keys);
}
2020-11-26 21:49:31 +01:00
}
}