diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index e0a840850..25b8f1810 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -45,10 +45,6 @@
$eventHandler
-
- loop
- loop
-
getMessage
isInited
@@ -64,33 +60,6 @@
-
- self::call($a)
- self::call($b)
- self::call($callable)
- self::call($promise)
- self::call($promise)
- self::timeout($promise, $timeout)
-
-
- $callable instanceof Generator
-
-
- $callable
-
-
- ]]>
-
-
- $v instanceof Generator ? self::consumeGenerator($v) : $v]]>
-
-
- all
- any
- first
- some
- wait
-
\is_callable($callable)
@@ -227,18 +196,13 @@
permAuthKey =& $this->API->datacenter->getDataCenterConnection($dc)->permAuthKey]]>
-
-
- $value
-
-
- getCache
-
-
-
-
- ]]>
-
+
+
+ ttl[$index])]]>
+
+
+ $cacheTtl
+
@@ -268,9 +232,6 @@
$settings
$settings
-
- $instance
-
$v
$value
@@ -285,14 +246,6 @@
$dbSettings
$dbSettings
$dbSettings
- $dbSettings
- $dbSettings
- $dbSettings
- $dbSettings
- $deserializer
- $deserializer
- $deserializer
- $deserializer
$deserializer
$deserializer
$deserializer
@@ -301,25 +254,14 @@
$serializer
$serializer
$serializer
- $serializer
- $serializer
- $serializer
- $serializer
- $table
- $table
- $table
- $table
$table
$table
$table
$table
-
- static
-
-
+
$old
-
+
setSettings
@@ -349,14 +291,8 @@
$pdo
- $pdo
-
-
- $value
-
-
$v
@@ -411,9 +347,6 @@
$db
$db
$db
- $db
- $db
- $db
fetchRow()['count']]]>
@@ -434,10 +367,6 @@
$class
-
- getReportPeers())]]>
- getReportPeers())]]>
-
wrapper->getAPI()]]>
@@ -720,19 +649,6 @@
-
- \danog\MadelineProto\AsyncTools::after($a, $b)
- \danog\MadelineProto\AsyncTools::all($promises)
- \danog\MadelineProto\AsyncTools::any($promises)
- \danog\MadelineProto\AsyncTools::call($promise)
- \danog\MadelineProto\AsyncTools::first($promises)
- \danog\MadelineProto\AsyncTools::some($promises)
- \danog\MadelineProto\AsyncTools::timeout($promise, $timeout)
- \danog\MadelineProto\AsyncTools::timeoutWithDefault($promise, $timeout, $default)
- \danog\MadelineProto\AsyncTools::wait($promise)
- loop
- loop
-
wrapper->getAPI()->getEventHandler($class)]]>
@@ -745,19 +661,14 @@
MTProtoToTd
MTProtoToTdcli
- all
- any
completePhoneLogin
downloadToCallable
downloadToDir
downloadToStream
end
- first
- loop
phoneLogin
requestCall
requestSecretChat
- some
start
tdToTdcli
upload
@@ -766,7 +677,6 @@
uploadFromStream
uploadFromTgfile
uploadFromUrl
- wait
account ??= new \danog\MadelineProto\Namespace\AbstractAPI('account')]]>
@@ -789,9 +699,6 @@
upload ??= new \danog\MadelineProto\Namespace\AbstractAPI('upload')]]>
users ??= new \danog\MadelineProto\Namespace\AbstractAPI('users')]]>
-
- $callback
-
setWrapper
setWrapper
@@ -822,7 +729,6 @@
downloadToCallable
downloadToDir
downloadToFile
- loop
methodCallAsyncRead
uploadFromCallable
uploadFromTgfile
@@ -1295,7 +1201,6 @@
chats]]>
- minDatabase?->sync()]]>
wrapper) && $this->isInited()]]>
wrapper) && isset(self::$references[$this->getSessionName()])]]>
@@ -1305,9 +1210,6 @@
\is_int($dc_id)
datacenter)]]>
-
- minDatabase]]>
-
settings->getAppInfo()->getLangCode()]]]>
@@ -1561,7 +1463,7 @@
$db
- API->chats]]>
+ db]]>
db]]>
@@ -1717,15 +1619,11 @@
-
- Tools::wait($callable())
-
completeLogin
createApp
getApp
hasApp
- loop
settings]]>
@@ -1832,9 +1730,6 @@
$ipcSocket
$ipcSocket
-
- $unserialized
-
@@ -2454,13 +2349,4 @@
$result
-
-
- function ($_) use ($callback) {
-
-
- $callback()
- $callback()
-
-
diff --git a/src/Db/ArrayCacheTrait.php b/src/Db/ArrayCacheTrait.php
deleted file mode 100644
index 875239a06..000000000
--- a/src/Db/ArrayCacheTrait.php
+++ /dev/null
@@ -1,129 +0,0 @@
-.
- *
- * @author Daniil Gentili
- * @copyright 2016-2023 Daniil Gentili
- * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
- * @link https://docs.madelineproto.xyz MadelineProto documentation
- */
-
-namespace danog\MadelineProto\Db;
-
-use danog\MadelineProto\Logger;
-use Revolt\EventLoop;
-
-/**
- * Array caching trait.
- *
- * @internal
- */
-trait ArrayCacheTrait
-{
- /**
- * @var array
- */
- private array $cache = [];
- /**
- * @var array
- */
- private array $ttl = [];
-
- private int $cacheTtl = 5 * 60;
-
- /**
- * Cache cleanup watcher ID.
- */
- private ?string $cacheCleanupId = null;
-
- protected function setCacheTtl(int $ttl): void
- {
- $this->cacheTtl = $ttl;
- }
-
- protected function getCache(string $key)
- {
- $this->ttl[$key] = \time() + $this->cacheTtl;
- return $this->cache[$key];
- }
-
- protected function hasCache(string $key): bool
- {
- return isset($this->ttl[$key]);
- }
-
- /**
- * Save item in cache.
- */
- protected function setCache(string $key, $value): void
- {
- $this->cache[$key] = $value;
- $this->ttl[$key] = \time() + $this->cacheTtl;
- }
-
- /**
- * Remove key from cache.
- */
- protected function unsetCache(string $key): void
- {
- unset($this->cache[$key], $this->ttl[$key]);
- }
-
- protected function startCacheCleanupLoop(): void
- {
- $this->cacheCleanupId = EventLoop::repeat(
- \max(1, $this->cacheTtl / 5),
- fn () => $this->cleanupCache(),
- );
- }
- protected function stopCacheCleanupLoop(): void
- {
- if ($this->cacheCleanupId) {
- EventLoop::cancel($this->cacheCleanupId);
- $this->cacheCleanupId = null;
- }
- }
-
- protected function clearCache(): void
- {
- $this->cache = [];
- $this->ttl = [];
- }
-
- /**
- * Remove all keys from cache.
- */
- private function cleanupCache(): void
- {
- $newValues = [];
- $newTtl = [];
- $now = \time();
- $oldCount = 0;
- foreach ($this->ttl as $key => $ttl) {
- if ($ttl < $now) {
- $oldCount++;
- } else {
- $newTtl[$key] = $this->ttl[$key];
- $newValues[$key] = $this->cache[$key];
- }
- }
- $this->ttl = $newTtl;
- $this->cache = $newValues;
-
- Logger::log(
- \sprintf(
- 'cache for table: %s; keys left: %s; keys removed: %s',
- (string) $this,
- \count($this->cache),
- $oldCount,
- ),
- Logger::VERBOSE,
- );
- }
-}
diff --git a/src/Db/CacheContainer.php b/src/Db/CacheContainer.php
new file mode 100644
index 000000000..47dd8baa1
--- /dev/null
+++ b/src/Db/CacheContainer.php
@@ -0,0 +1,148 @@
+.
+ *
+ * @author Daniil Gentili
+ * @copyright 2016-2023 Daniil Gentili
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
+ * @link https://docs.madelineproto.xyz MadelineProto documentation
+ */
+
+namespace danog\MadelineProto\Db;
+
+use Amp\Sync\LocalMutex;
+use Revolt\EventLoop;
+use Traversable;
+
+/** @internal */
+final class CacheContainer
+{
+ /**
+ * @var array
+ */
+ private array $cache = [];
+ /**
+ * @var array
+ */
+ private array $ttl = [];
+
+ private int $cacheTtl;
+
+ /**
+ * Cache cleanup watcher ID.
+ */
+ private ?string $cacheCleanupId = null;
+
+ private LocalMutex $mutex;
+
+ public function __construct(
+ public DbType $inner
+ ) {
+ $this->mutex = new LocalMutex;
+ }
+ public function __sleep()
+ {
+ $this->flushCache();
+ return ['cache', 'ttl', 'inner'];
+ }
+
+ public function startCacheCleanupLoop(int $cacheTtl): void
+ {
+ $this->cacheTtl = $cacheTtl;
+ if ($this->cacheCleanupId) {
+ EventLoop::cancel($this->cacheCleanupId);
+ }
+ $this->cacheCleanupId = EventLoop::repeat(
+ \max(1, $this->cacheTtl / 5),
+ fn () => $this->flushCache(),
+ );
+ }
+ public function stopCacheCleanupLoop(): void
+ {
+ if ($this->cacheCleanupId) {
+ EventLoop::cancel($this->cacheCleanupId);
+ $this->cacheCleanupId = null;
+ }
+ }
+
+ public function get(string|int $index): mixed
+ {
+ if (isset($this->ttl[$index])) {
+ return $this->cache[$index];
+ }
+
+ $result = $this->inner->offsetGet($index);
+ if (isset($this->ttl[$index])) {
+ return $this->cache[$index];
+ }
+
+ $this->ttl[$index] = \time() + $this->cacheTtl;
+ $this->cache[$index] = $result;
+
+ return $result;
+ }
+
+ public function set(string|int $key, mixed $value): void
+ {
+ $this->cache[$key] = $value;
+ $this->ttl[$key] = true;
+ }
+
+ public function getIterator(): Traversable
+ {
+ $this->flushCache();
+ return $this->inner->getIterator();
+ }
+
+ public function count(): int
+ {
+ $this->flushCache();
+ return $this->inner->count();
+ }
+
+ public function clear(): void
+ {
+ $lock = $this->mutex->acquire();
+ $this->cache = [];
+ $this->ttl = [];
+ $lock->release();
+
+ $this->inner->clear();
+ }
+
+ /**
+ * Flush all flushable keys.
+ */
+ public function flushCache(): void
+ {
+ $lock = $this->mutex->acquire();
+ try {
+ $newValues = [];
+ $newTtl = [];
+ $now = \time();
+ foreach ($this->ttl as $key => &$ttl) {
+ if ($ttl === true) {
+ if ($this->cache[$key] === null) {
+ $this->inner->unset($key);
+ } else {
+ $this->inner->set($key, $this->cache[$key]);
+ }
+ $ttl = \time() + $this->cacheTtl;
+ } elseif ($ttl > $now) {
+ $newTtl[$key] = $this->ttl[$key];
+ $newValues[$key] = $this->cache[$key];
+ }
+ }
+ $this->ttl = $newTtl;
+ $this->cache = $newValues;
+ } finally {
+ $lock->release();
+ }
+ }
+}
diff --git a/src/Db/CachedArray.php b/src/Db/CachedArray.php
new file mode 100644
index 000000000..9c6778512
--- /dev/null
+++ b/src/Db/CachedArray.php
@@ -0,0 +1,100 @@
+.
+ *
+ * @author Daniil Gentili
+ * @copyright 2016-2023 Daniil Gentili
+ * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
+ * @link https://docs.madelineproto.xyz MadelineProto documentation
+ */
+
+namespace danog\MadelineProto\Db;
+
+use danog\MadelineProto\Settings\Database\DriverDatabaseAbstract;
+use danog\MadelineProto\Settings\DatabaseAbstract;
+use Traversable;
+
+/**
+ * Array caching proxy.
+ *
+ * @internal
+ *
+ * @template TKey as array-key
+ * @template TValue
+ *
+ * @implements DbArray
+ */
+final class CachedArray implements DbArray
+{
+ use DbArrayTrait;
+
+ private CacheContainer $cache;
+
+ /**
+ * Get instance.
+ */
+ public static function getInstance(string $table, DbType|null $previous, DatabaseAbstract $settings): DbType
+ {
+ $new = $settings->getDriverClass();
+ if ($previous === null) {
+ $previous = new self($new::getInstance($table, null, $settings));
+ } elseif ($previous instanceof self) {
+ $previous->cache->inner = $new::getInstance($table, $previous->cache->inner, $settings);
+ } else {
+ $previous = new self($new::getInstance($table, $previous, $settings));
+ }
+ if ($previous->cache->inner instanceof MemoryArray) {
+ $previous->cache->flushCache();
+ return $previous->cache->inner;
+ }
+ \assert($settings instanceof DriverDatabaseAbstract);
+ $previous->cache->startCacheCleanupLoop($settings->getCacheTtl());
+ return $previous;
+ }
+
+ public function __construct(DbType $inner)
+ {
+ $this->cache = new CacheContainer($inner);
+ }
+
+ public function __destruct()
+ {
+ $this->cache->stopCacheCleanupLoop();
+ }
+
+ public function count(): int
+ {
+ return $this->cache->count();
+ }
+
+ public function clear(): void
+ {
+ $this->cache->clear();
+ }
+
+ public function offsetGet(mixed $index): mixed
+ {
+ return $this->cache->get($index);
+ }
+
+ public function set(string|int $key, mixed $value): void
+ {
+ $this->cache->set($key, $value);
+ }
+
+ public function unset(string|int $key): void
+ {
+ $this->cache->set($key, null);
+ }
+
+ public function getIterator(): Traversable
+ {
+ return $this->cache->getIterator();
+ }
+}
diff --git a/src/Db/DbArray.php b/src/Db/DbArray.php
index da98c6301..9c5c379d6 100644
--- a/src/Db/DbArray.php
+++ b/src/Db/DbArray.php
@@ -17,7 +17,6 @@
namespace danog\MadelineProto\Db;
use ArrayAccess;
-use Countable;
/**
* DB array interface.
@@ -26,40 +25,10 @@ use Countable;
* @template TValue
*
* @extends ArrayAccess
+ * @extends DbType
*/
-interface DbArray extends DbType, ArrayAccess, Countable
+interface DbArray extends DbType, ArrayAccess
{
- /**
- * Get Array copy.
- *
- * @psalm-return array
- */
- public function getArrayCopy(): array;
- /**
- * Check if element is set.
- *
- * @param TKey $key
- */
- public function isset(string|int $key): bool;
- /**
- * Unset element.
- *
- * @param TKey $key
- */
- public function unset(string|int $key): void;
- /**
- * Set element.
- *
- * @param TKey $key
- * @param TValue $value
- */
- public function set(string|int $key, mixed $value): void;
- /**
- * Get element.
- *
- * @param TKey $index
- */
- public function offsetGet(mixed $index): mixed;
/**
* Set element.
*
@@ -79,13 +48,9 @@ interface DbArray extends DbType, ArrayAccess, Countable
*/
public function offsetExists(mixed $index): bool;
/**
- * Clear all elements.
- */
- public function clear(): void;
- /**
- * Get iterator.
+ * Get Array copy.
*
- * @return \Traversable
+ * @psalm-return array
*/
- public function getIterator(): \Traversable;
+ public function getArrayCopy(): array;
}
diff --git a/src/Db/NullCache/NullCacheTrait.php b/src/Db/DbArrayTrait.php
similarity index 58%
rename from src/Db/NullCache/NullCacheTrait.php
rename to src/Db/DbArrayTrait.php
index 1f2587abd..522465c11 100644
--- a/src/Db/NullCache/NullCacheTrait.php
+++ b/src/Db/DbArrayTrait.php
@@ -14,52 +14,45 @@
* @link https://docs.madelineproto.xyz MadelineProto documentation
*/
-namespace danog\MadelineProto\Db\NullCache;
-
-use RuntimeException;
+namespace danog\MadelineProto\Db;
/**
- * Trait that disables database caching.
- *
- * @internal
+ * DB array trait.
*/
-trait NullCacheTrait
+trait DbArrayTrait
{
- protected function setCacheTtl(int $ttl): void
+ /**
+ * Check if key isset.
+ *
+ * @param mixed $key
+ * @return bool true if the offset exists, otherwise false
+ */
+ final public function isset(string|int $key): bool
{
- }
- protected function hasCache(string $key): bool
- {
- return false;
+ return $this->offsetGet($key) !== null;
}
- protected function getCache(string $key): void
+ /** @param string|int $index */
+ final public function offsetExists(mixed $index): bool
{
- throw new RuntimeException('Not implemented!');
+ return $this->isset($index);
+ }
+
+ final public function offsetSet(mixed $index, mixed $value): void
+ {
+ $this->set($index, $value);
+ }
+
+ final public function offsetUnset(mixed $index): void
+ {
+ $this->unset($index);
}
/**
- * Save item in cache.
+ * Get array copy.
*/
- protected function setCache(string $key, $value): void
- {
- }
-
- /**
- * Remove key from cache.
- */
- protected function unsetCache(string $key): void
- {
- }
-
- protected function clearCache(): void
- {
- }
-
- protected function startCacheCleanupLoop(): void
- {
- }
- protected function stopCacheCleanupLoop(): void
+ final public function getArrayCopy(): array
{
+ return \iterator_to_array($this->getIterator());
}
}
diff --git a/src/Db/DbPropertiesFactory.php b/src/Db/DbPropertiesFactory.php
index f15ddad9c..078aee6d1 100644
--- a/src/Db/DbPropertiesFactory.php
+++ b/src/Db/DbPropertiesFactory.php
@@ -18,13 +18,8 @@ namespace danog\MadelineProto\Db;
use danog\MadelineProto\Magic;
use danog\MadelineProto\Settings\Database\DriverDatabaseAbstract;
-use danog\MadelineProto\Settings\Database\Memory;
-use danog\MadelineProto\Settings\Database\Mysql;
-use danog\MadelineProto\Settings\Database\Postgres;
-use danog\MadelineProto\Settings\Database\Redis;
use danog\MadelineProto\Settings\Database\SerializerType;
use danog\MadelineProto\Settings\DatabaseAbstract;
-use InvalidArgumentException;
/**
* This factory class initializes the correct database backend for MadelineProto.
@@ -35,30 +30,27 @@ final class DbPropertiesFactory
{
/**
* @param array{serializer?: SerializerType, enableCache?: bool, cacheTtl?: int, innerMadelineProto?: bool, innerMadelineProtoSerializer?: SerializerType}|'array' $config
- * @return DbType
* @internal
* @uses \danog\MadelineProto\Db\MemoryArray
* @uses \danog\MadelineProto\Db\MysqlArray
* @uses \danog\MadelineProto\Db\PostgresArray
* @uses \danog\MadelineProto\Db\RedisArray
*/
- public static function get(DatabaseAbstract $dbSettings, string $table, string|array $config, ?DbType $value = null)
+ public static function get(DatabaseAbstract $dbSettings, string $table, string|array $config, ?DbType $value = null): DbArray
{
// Legacy
if ($config === 'array') {
$config = [];
}
- $dbSettingsCopy = clone $dbSettings;
- $class = __NAMESPACE__;
+ $dbSettings = clone $dbSettings;
- if ($dbSettingsCopy instanceof DriverDatabaseAbstract) {
+ if ($dbSettings instanceof DriverDatabaseAbstract) {
$config = \array_merge([
- 'serializer' => $dbSettingsCopy->getSerializer() ?? (
+ 'serializer' => $dbSettings->getSerializer() ?? (
Magic::$can_use_igbinary ? SerializerType::IGBINARY : SerializerType::SERIALIZE
),
'innerMadelineProto' => false,
- 'enableCache' => true,
- 'cacheTtl' => $dbSettingsCopy->getCacheTtl(),
+ 'cacheTtl' => $dbSettings->getCacheTtl(),
], $config);
if ($config['innerMadelineProto']
@@ -73,31 +65,12 @@ final class DbPropertiesFactory
);
}
- $class = $dbSettings instanceof DriverDatabaseAbstract && (!($config['enableCache'] ?? true) || !$config['cacheTtl'])
- ? __NAMESPACE__ . '\\NullCache'
- : __NAMESPACE__;
-
- $dbSettingsCopy->setSerializer($config['serializer']);
- $dbSettingsCopy->setCacheTtl($config['cacheTtl']);
+ $dbSettings->setSerializer($config['serializer']);
+ $dbSettings->setCacheTtl($config['cacheTtl']);
}
- switch (true) {
- case $dbSettings instanceof Memory:
- $class .= '\\MemoryArray';
- break;
- case $dbSettings instanceof Mysql:
- $class .= '\\MysqlArray';
- break;
- case $dbSettings instanceof Postgres:
- $class .= '\\PostgresArrayBytea';
- break;
- case $dbSettings instanceof Redis:
- $class .= '\\RedisArray';
- break;
- default:
- throw new InvalidArgumentException('Unknown dbType: ' . $dbSettings::class);
- }
- /** @var DbType $class */
- return $class::getInstance($table, $value, $dbSettingsCopy);
+ $result = CachedArray::getInstance($table, $value, $dbSettings);
+ \assert($result instanceof DbArray);
+ return $result;
}
}
diff --git a/src/Db/DbType.php b/src/Db/DbType.php
index 53adb3b81..f550bf6c1 100644
--- a/src/Db/DbType.php
+++ b/src/Db/DbType.php
@@ -16,9 +16,55 @@
namespace danog\MadelineProto\Db;
+use Countable;
use danog\MadelineProto\Settings\DatabaseAbstract;
-interface DbType
+/**
+ * DB type interface.
+ *
+ * @template TKey as array-key
+ * @template TValue
+ */
+interface DbType extends Countable
{
- public static function getInstance(string $table, DbType|array|null $previous, DatabaseAbstract $settings): static;
+ /**
+ * Check if element is set.
+ *
+ * @param TKey $key
+ */
+ public function isset(string|int $key): bool;
+ /**
+ * Unset element.
+ *
+ * @param TKey $key
+ */
+ public function unset(string|int $key): void;
+ /**
+ * Set element.
+ *
+ * @param TKey $key
+ * @param TValue $value
+ */
+ public function set(string|int $key, mixed $value): void;
+ /**
+ * Get element.
+ *
+ * @param TKey $index
+ */
+ public function offsetGet(mixed $index): mixed;
+ /**
+ * Clear all elements.
+ */
+ public function clear(): void;
+ /**
+ * Get iterator.
+ *
+ * @return \Traversable
+ */
+ public function getIterator(): \Traversable;
+
+ /**
+ * Get instance.
+ */
+ public static function getInstance(string $table, DbType|null $previous, DatabaseAbstract $settings): self;
}
diff --git a/src/Db/DriverArray.php b/src/Db/DriverArray.php
index b6bdeee4d..51145ebb5 100644
--- a/src/Db/DriverArray.php
+++ b/src/Db/DriverArray.php
@@ -19,10 +19,8 @@ namespace danog\MadelineProto\Db;
use danog\MadelineProto\Logger;
use danog\MadelineProto\Magic;
use danog\MadelineProto\Settings\Database\DriverDatabaseAbstract;
-use danog\MadelineProto\Settings\Database\Memory;
use danog\MadelineProto\Settings\Database\SerializerType;
use danog\MadelineProto\Settings\DatabaseAbstract;
-use IteratorAggregate;
use function Amp\async;
use function Amp\Future\await;
@@ -35,10 +33,9 @@ use function Amp\Future\await;
* @template TKey as array-key
* @template TValue
*
- * @implements IteratorAggregate
- * @implements DbArray
+ * @implements DbType
*/
-abstract class DriverArray implements DbArray, IteratorAggregate
+abstract class DriverArray implements DbType
{
protected string $table;
/** @var callable(mixed): mixed */
@@ -47,8 +44,6 @@ abstract class DriverArray implements DbArray, IteratorAggregate
protected $deserializer;
protected DriverDatabaseAbstract $dbSettings;
- use ArrayCacheTrait;
-
/**
* Initialize on startup.
*/
@@ -82,13 +77,7 @@ abstract class DriverArray implements DbArray, IteratorAggregate
return $this;
}
- /**
- * Check if key isset.
- *
- * @param mixed $key
- * @return bool true if the offset exists, otherwise false
- */
- public function isset(string|int $key): bool
+ final public function isset(string|int $key): bool
{
return $this->offsetGet($key) !== null;
}
@@ -96,7 +85,6 @@ abstract class DriverArray implements DbArray, IteratorAggregate
private function setSettings(DriverDatabaseAbstract $settings): void
{
$this->dbSettings = $settings;
- $this->setCacheTtl($settings->getCacheTtl());
$this->setSerializer($settings->getSerializer() ?? (
Magic::$can_use_igbinary ? SerializerType::IGBINARY : SerializerType::SERIALIZE
));
@@ -112,7 +100,7 @@ abstract class DriverArray implements DbArray, IteratorAggregate
}
}
- public static function getInstance(string $table, DbType|array|null $previous, DatabaseAbstract $settings): static
+ public static function getInstance(string $table, DbType|null $previous, DatabaseAbstract $settings): DbType
{
/** @var MysqlArray|PostgresArray|RedisArray */
$instance = new static();
@@ -122,8 +110,6 @@ abstract class DriverArray implements DbArray, IteratorAggregate
$instance->setSettings($settings);
- $instance->startCacheCleanupLoop();
-
$instance->initConnection($settings);
$instance->prepareTable();
@@ -165,14 +151,11 @@ abstract class DriverArray implements DbArray, IteratorAggregate
SerializerType::STRING => fn ($v) => $v,
};
}
- private static function migrateDataToDb(self $new, DbArray|array|null $old): void
+ private static function migrateDataToDb(self $new, DbArray|null $old): void
{
$oldName = self::getMigrationName($old);
$newName = self::getMigrationName($new);
if (!empty($old) && $oldName !== $newName) {
- if (!$old instanceof DbArray) {
- $old = MemoryArray::getInstance('', $old, new Memory);
- }
Logger::log("Converting $oldName to $newName", Logger::ERROR);
$counter = 0;
@@ -186,7 +169,6 @@ abstract class DriverArray implements DbArray, IteratorAggregate
$promises = [];
Logger::log("Loading data to table {$newName}: $counter/$total", Logger::WARNING);
}
- $new->clearCache();
}
if (self::getMigrationName($new, false) !== self::getMigrationName($old, false)) {
Logger::log("Dropping data from table {$oldName}", Logger::WARNING);
@@ -196,11 +178,6 @@ abstract class DriverArray implements DbArray, IteratorAggregate
}
}
- public function __destruct()
- {
- $this->stopCacheCleanupLoop();
- }
-
/**
* Get the value of table.
*/
@@ -216,30 +193,6 @@ abstract class DriverArray implements DbArray, IteratorAggregate
{
return ['table', 'dbSettings'];
}
-
- final public function offsetExists($index): bool
- {
- return $this->isset($index);
- }
-
- final public function offsetSet(mixed $index, mixed $value): void
- {
- $this->set($index, $value);
- }
-
- final public function offsetUnset(mixed $index): void
- {
- $this->unset($index);
- }
-
- /**
- * Get array copy.
- */
- public function getArrayCopy(): array
- {
- return \iterator_to_array($this->getIterator());
- }
-
private static function getMigrationName(DbType|array|null $instance, bool $include_serialization_type = true): ?string
{
if ($instance === null) {
diff --git a/src/Db/MemoryArray.php b/src/Db/MemoryArray.php
index e89b09e35..cfb8471d1 100644
--- a/src/Db/MemoryArray.php
+++ b/src/Db/MemoryArray.php
@@ -40,7 +40,7 @@ final class MemoryArray extends ArrayIterator implements DbArray
/**
* @param Memory $settings
*/
- public static function getInstance(string $table, DbType|array|null $previous, $settings): static
+ public static function getInstance(string $table, DbType|null $previous, $settings): DbType
{
if ($previous instanceof MemoryArray) {
return $previous;
diff --git a/src/Db/MysqlArray.php b/src/Db/MysqlArray.php
index e4099aaa6..892217aec 100644
--- a/src/Db/MysqlArray.php
+++ b/src/Db/MysqlArray.php
@@ -33,7 +33,7 @@ use PDO;
* @template TValue
* @extends SqlArray
*/
-class MysqlArray extends SqlArray
+final class MysqlArray extends SqlArray
{
// We're forced to use quoting (just like PDO does internally when using prepares) because native MySQL prepares are extremely slow.
protected PDO $pdo;
diff --git a/src/Db/NullCache/MysqlArray.php b/src/Db/NullCache/MysqlArray.php
deleted file mode 100644
index d0addd853..000000000
--- a/src/Db/NullCache/MysqlArray.php
+++ /dev/null
@@ -1,34 +0,0 @@
-.
- *
- * @author Daniil Gentili
- * @copyright 2016-2023 Daniil Gentili
- * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
- * @link https://docs.madelineproto.xyz MadelineProto documentation
- */
-
-namespace danog\MadelineProto\Db\NullCache;
-
-use danog\MadelineProto\Db\MysqlArray as DbMysqlArray;
-
-/**
- * MySQL database backend, no caching.
- *
- * @internal
- *
- * @template TKey as array-key
- * @template TValue
- *
- * @extends DbMysqlArray
- */
-final class MysqlArray extends DbMysqlArray
-{
- use NullCacheTrait;
-}
diff --git a/src/Db/NullCache/PostgresArray.php b/src/Db/NullCache/PostgresArray.php
deleted file mode 100644
index c309c2c79..000000000
--- a/src/Db/NullCache/PostgresArray.php
+++ /dev/null
@@ -1,33 +0,0 @@
-.
- *
- * @author Daniil Gentili
- * @copyright 2016-2023 Daniil Gentili
- * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
- * @link https://docs.madelineproto.xyz MadelineProto documentation
- */
-
-namespace danog\MadelineProto\Db\NullCache;
-
-use danog\MadelineProto\Db\PostgresArray as DbPostgresArray;
-
-/**
- * Postgres database backend, no caching.
- *
- * @template TKey as array-key
- * @template TValue
- *
- * @extends DbPostgresArray
- * @internal
- */
-final class PostgresArray extends DbPostgresArray
-{
- use NullCacheTrait;
-}
diff --git a/src/Db/NullCache/PostgresArrayBytea.php b/src/Db/NullCache/PostgresArrayBytea.php
deleted file mode 100644
index bdf42e50b..000000000
--- a/src/Db/NullCache/PostgresArrayBytea.php
+++ /dev/null
@@ -1,33 +0,0 @@
-.
- *
- * @author Daniil Gentili
- * @copyright 2016-2023 Daniil Gentili
- * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
- * @link https://docs.madelineproto.xyz MadelineProto documentation
- */
-
-namespace danog\MadelineProto\Db\NullCache;
-
-use danog\MadelineProto\Db\PostgresArrayBytea as DbPostgresArrayBytea;
-
-/**
- * Postgres database backend, no caching.
- *
- * @template TKey as array-key
- * @template TValue
- *
- * @extends DbPostgresArrayBytea
- * @internal
- */
-final class PostgresArrayBytea extends DbPostgresArrayBytea
-{
- use NullCacheTrait;
-}
diff --git a/src/Db/NullCache/RedisArray.php b/src/Db/NullCache/RedisArray.php
deleted file mode 100644
index 01d389040..000000000
--- a/src/Db/NullCache/RedisArray.php
+++ /dev/null
@@ -1,34 +0,0 @@
-.
- *
- * @author Daniil Gentili
- * @copyright 2016-2023 Daniil Gentili
- * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3
- * @link https://docs.madelineproto.xyz MadelineProto documentation
- */
-
-namespace danog\MadelineProto\Db\NullCache;
-
-use danog\MadelineProto\Db\RedisArray as DbRedisArray;
-
-/**
- * Redis database backend, no caching.
- *
- * @internal
- *
- * @template TKey as array-key
- * @template TValue
- *
- * @extends DbRedisArray
- */
-final class RedisArray extends DbRedisArray
-{
- use NullCacheTrait;
-}
diff --git a/src/Db/PostgresArray.php b/src/Db/PostgresArray.php
index cde219e46..b4862b6fb 100644
--- a/src/Db/PostgresArray.php
+++ b/src/Db/PostgresArray.php
@@ -29,7 +29,7 @@ use danog\MadelineProto\Settings\Database\SerializerType;
* @template TValue
* @extends PostgresArrayBytea
*/
-class PostgresArray extends PostgresArrayBytea
+final class PostgresArray extends PostgresArrayBytea
{
/**
* Prepare statements.
diff --git a/src/Db/RedisArray.php b/src/Db/RedisArray.php
index 81a45c71b..e9890d566 100644
--- a/src/Db/RedisArray.php
+++ b/src/Db/RedisArray.php
@@ -30,7 +30,7 @@ use danog\MadelineProto\Settings\Database\Redis as DatabaseRedis;
* @template TValue
* @extends DriverArray
*/
-class RedisArray extends DriverArray
+final class RedisArray extends DriverArray
{
private RedisRedis $db;
@@ -87,27 +87,17 @@ class RedisArray extends DriverArray
}
public function set(string|int $key, mixed $value): void
{
- if ($this->hasCache($key) && $this->getCache($key) === $value) {
- return;
- }
-
- $this->setCache($key, $value);
-
$this->db->set($this->rKey($key), ($this->serializer)($value));
- $this->setCache($key, $value);
}
public function offsetGet(mixed $offset): mixed
{
$offset = (string) $offset;
- if ($this->hasCache($offset)) {
- return $this->getCache($offset);
- }
$value = $this->db->get($this->rKey($offset));
- if ($value !== null && $value = ($this->deserializer)($value)) {
- $this->setCache($offset, $value);
+ if ($value !== null) {
+ $value = ($this->deserializer)($value);
}
return $value;
@@ -115,8 +105,6 @@ class RedisArray extends DriverArray
public function unset(string|int $key): void
{
- $this->unsetCache($key);
-
$this->db->delete($this->rkey($key));
}
@@ -152,7 +140,6 @@ class RedisArray extends DriverArray
*/
public function clear(): void
{
- $this->clearCache();
$request = $this->db->scan($this->itKey());
$keys = [];
diff --git a/src/Db/SqlArray.php b/src/Db/SqlArray.php
index a2d2a78d9..737c763c8 100644
--- a/src/Db/SqlArray.php
+++ b/src/Db/SqlArray.php
@@ -82,9 +82,6 @@ abstract class SqlArray extends DriverArray
public function offsetGet(mixed $key): mixed
{
$key = (string) $key;
- if ($this->hasCache($key)) {
- return $this->getCache($key);
- }
$row = $this->execute($this->queries[self::SQL_GET], ['index' => $key])->fetchRow();
if ($row === null) {
@@ -92,7 +89,6 @@ abstract class SqlArray extends DriverArray
}
$value = ($this->deserializer)($row['value']);
- $this->setCache($key, $value);
return $value;
}
@@ -100,11 +96,6 @@ abstract class SqlArray extends DriverArray
public function set(string|int $key, mixed $value): void
{
$key = (string) $key;
- if ($this->hasCache($key) && $this->getCache($key) === $value) {
- return;
- }
-
- $this->setCache($key, $value);
$this->execute(
$this->queries[self::SQL_SET],
@@ -113,7 +104,6 @@ abstract class SqlArray extends DriverArray
'value' => ($this->serializer)($value),
],
);
- $this->setCache($key, $value);
}
/**
@@ -124,7 +114,6 @@ abstract class SqlArray extends DriverArray
public function unset(string|int $key): void
{
$key = (string) $key;
- $this->unsetCache($key);
$this->execute(
$this->queries[self::SQL_UNSET],
@@ -151,7 +140,6 @@ abstract class SqlArray extends DriverArray
*/
public function clear(): void
{
- $this->clearCache();
$this->execute($this->queries[self::SQL_CLEAR]);
}
diff --git a/src/Settings/Database/Memory.php b/src/Settings/Database/Memory.php
index ac3afa866..b8e1fdd46 100644
--- a/src/Settings/Database/Memory.php
+++ b/src/Settings/Database/Memory.php
@@ -16,6 +16,7 @@
namespace danog\MadelineProto\Settings\Database;
+use danog\MadelineProto\Db\MemoryArray;
use danog\MadelineProto\Settings\DatabaseAbstract;
/**
@@ -23,4 +24,8 @@ use danog\MadelineProto\Settings\DatabaseAbstract;
*/
final class Memory extends DatabaseAbstract
{
+ public function getDriverClass(): string
+ {
+ return MemoryArray::class;
+ }
}
diff --git a/src/Settings/Database/Mysql.php b/src/Settings/Database/Mysql.php
index d4f3c06e7..16f15c3f4 100644
--- a/src/Settings/Database/Mysql.php
+++ b/src/Settings/Database/Mysql.php
@@ -16,6 +16,8 @@
namespace danog\MadelineProto\Settings\Database;
+use danog\MadelineProto\Db\MysqlArray;
+
/**
* MySQL backend settings.
*
@@ -23,6 +25,10 @@ namespace danog\MadelineProto\Settings\Database;
*/
final class Mysql extends SqlAbstract
{
+ public function getDriverClass(): string
+ {
+ return MysqlArray::class;
+ }
public function mergeArray(array $settings): void
{
$settings = $settings['db']['mysql'] ?? [];
diff --git a/src/Settings/Database/Postgres.php b/src/Settings/Database/Postgres.php
index 83b7c2453..17493863f 100644
--- a/src/Settings/Database/Postgres.php
+++ b/src/Settings/Database/Postgres.php
@@ -16,11 +16,17 @@
namespace danog\MadelineProto\Settings\Database;
+use danog\MadelineProto\Db\PostgresArrayBytea;
+
/**
* Postgres backend settings.
*/
final class Postgres extends SqlAbstract
{
+ public function getDriverClass(): string
+ {
+ return PostgresArrayBytea::class;
+ }
public function mergeArray(array $settings): void
{
$settings = $settings['db']['postgres'] ?? [];
diff --git a/src/Settings/Database/Redis.php b/src/Settings/Database/Redis.php
index 3e269627d..593d9c9cf 100644
--- a/src/Settings/Database/Redis.php
+++ b/src/Settings/Database/Redis.php
@@ -16,11 +16,17 @@
namespace danog\MadelineProto\Settings\Database;
+use danog\MadelineProto\Db\RedisArray;
+
/**
* Redis backend settings.
*/
final class Redis extends DriverDatabaseAbstract
{
+ public function getDriverClass(): string
+ {
+ return RedisArray::class;
+ }
/**
* Database number.
*/
diff --git a/src/Settings/DatabaseAbstract.php b/src/Settings/DatabaseAbstract.php
index 1380bf6d9..a94ccb5ce 100644
--- a/src/Settings/DatabaseAbstract.php
+++ b/src/Settings/DatabaseAbstract.php
@@ -16,6 +16,7 @@
namespace danog\MadelineProto\Settings;
+use danog\MadelineProto\Db\DbType;
use danog\MadelineProto\SettingsAbstract;
/**
@@ -143,4 +144,7 @@ abstract class DatabaseAbstract extends SettingsAbstract
return $this;
}
+
+ /** @return class-string */
+ abstract public function getDriverClass(): string;
}
diff --git a/tests/testing.php b/tests/testing.php
index 990381dea..c2bc34ba1 100755
--- a/tests/testing.php
+++ b/tests/testing.php
@@ -344,4 +344,3 @@ foreach (json_decode(getenv('TEST_DESTINATION_GROUPS'), true) as $peer) {
$sentMessage = $MadelineProto->messages->sendMessage(['peer' => $peer, 'message' => $message, 'entities' => [['_' => 'inputMessageEntityMentionName', 'offset' => 0, 'length' => mb_strlen($message), 'user_id' => $mention]]]);
$MadelineProto->logger($sentMessage, Logger::NOTICE);
}
-});
diff --git a/tools/build_docs/layerUpgrade.php b/tools/build_docs/layerUpgrade.php
index f24739c45..32b7cf7de 100644
--- a/tools/build_docs/layerUpgrade.php
+++ b/tools/build_docs/layerUpgrade.php
@@ -4,7 +4,7 @@
* Upgrade layer number.
*
* @param integer $layer Layer number
- *
+ * @internal
*/
function layerUpgrade(int $layer): void
{
diff --git a/tools/build_docs/merge.php b/tools/build_docs/merge.php
index 6a7843a0e..6f1b645ff 100644
--- a/tools/build_docs/merge.php
+++ b/tools/build_docs/merge.php
@@ -4,7 +4,7 @@ use danog\MadelineProto\Lang;
/**
* Merge extracted docs.
- *
+ * @internal
*/
function mergeExtracted(): void
{
diff --git a/tools/build_docs/schemas.php b/tools/build_docs/schemas.php
index bea1c6da1..d35af1643 100644
--- a/tools/build_docs/schemas.php
+++ b/tools/build_docs/schemas.php
@@ -2,7 +2,7 @@
/**
* Load schema file names.
- *
+ * @internal
*/
function loadSchemas(): array
{
@@ -19,6 +19,7 @@ function loadSchemas(): array
* Return max available layer number.
*
* @param array $schemas Scheme array
+ * @internal
*
* @return integer
*/
@@ -32,6 +33,7 @@ function maxLayer(array $schemas): int
* Init docs.
*
* @param array $layers Scheme array
+ * @internal
*
* @return array Documentation information for old docs
*/
diff --git a/tools/layerdiff.php b/tools/layerdiff.php
index 757acdb79..d30319587 100644
--- a/tools/layerdiff.php
+++ b/tools/layerdiff.php
@@ -30,6 +30,8 @@ if ($argc !== 3) {
*
* @param int $layer Layer number
*
+ * @internal
+ *
* @return void
*/
function getTL($layer)
@@ -40,6 +42,7 @@ function getTL($layer)
return ['methods' => $layer->getMethods(), 'constructors' => $layer->getConstructors()];
}
+/** @internal */
function getUrl($constructor, $type)
{
$orig = $constructor;
diff --git a/tools/static.php b/tools/static.php
index 89317d4ce..f080c94dd 100644
--- a/tools/static.php
+++ b/tools/static.php
@@ -9,6 +9,7 @@ require 'vendor/autoload.php';
$class = new \ReflectionClass(Tools::class);
$methods = $class->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PUBLIC);
+/** @internal */
function ssort($a, $b)
{
return strlen($b->getName())-strlen($a->getName());
diff --git a/tools/std.php b/tools/std.php
index f0128381a..d089e8615 100644
--- a/tools/std.php
+++ b/tools/std.php
@@ -15,12 +15,7 @@ foreach ($classes as $class) {
}
$methods = array_unique($methods);
-function ssort($a, $b)
-{
- return strlen($b->getName())-strlen($a->getName());
-}
-
-usort($methods, 'ssort');
+usort($methods, fn ($a, $b) => strlen($b->getName())-strlen($a->getName()));
$find = [];
$replace = [];