mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-26 17:24:40 +01:00
New ORM API
This commit is contained in:
parent
2b76934531
commit
d7a2ef38c3
@ -45,10 +45,6 @@
|
||||
<ArgumentTypeCoercion>
|
||||
<code>$eventHandler</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod>
|
||||
<code>loop</code>
|
||||
<code>loop</code>
|
||||
</DeprecatedMethod>
|
||||
<PossiblyNullReference>
|
||||
<code>getMessage</code>
|
||||
<code>isInited</code>
|
||||
@ -64,33 +60,6 @@
|
||||
</RiskyCast>
|
||||
</file>
|
||||
<file src="src/AsyncTools.php">
|
||||
<DeprecatedMethod>
|
||||
<code>self::call($a)</code>
|
||||
<code>self::call($b)</code>
|
||||
<code>self::call($callable)</code>
|
||||
<code>self::call($promise)</code>
|
||||
<code>self::call($promise)</code>
|
||||
<code>self::timeout($promise, $timeout)</code>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction>
|
||||
<code>$callable instanceof Generator</code>
|
||||
</DocblockTypeContradiction>
|
||||
<InvalidReturnStatement>
|
||||
<code>$callable</code>
|
||||
</InvalidReturnStatement>
|
||||
<InvalidReturnType>
|
||||
<code><![CDATA[Future<T>]]></code>
|
||||
</InvalidReturnType>
|
||||
<MissingClosureReturnType>
|
||||
<code><![CDATA[fn ($v) => $v instanceof Generator ? self::consumeGenerator($v) : $v]]></code>
|
||||
</MissingClosureReturnType>
|
||||
<MissingReturnType>
|
||||
<code>all</code>
|
||||
<code>any</code>
|
||||
<code>first</code>
|
||||
<code>some</code>
|
||||
<code>wait</code>
|
||||
</MissingReturnType>
|
||||
<RedundantConditionGivenDocblockType>
|
||||
<code>\is_callable($callable)</code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
@ -227,18 +196,13 @@
|
||||
<code><![CDATA[$this->permAuthKey =& $this->API->datacenter->getDataCenterConnection($dc)->permAuthKey]]></code>
|
||||
</UnsupportedReferenceUsage>
|
||||
</file>
|
||||
<file src="src/Db/ArrayCacheTrait.php">
|
||||
<MissingParamType>
|
||||
<code>$value</code>
|
||||
</MissingParamType>
|
||||
<MissingReturnType>
|
||||
<code>getCache</code>
|
||||
</MissingReturnType>
|
||||
</file>
|
||||
<file src="src/Db/DbArray.php">
|
||||
<ImplementedReturnTypeMismatch>
|
||||
<code><![CDATA[\Traversable<TKey, TValue>]]></code>
|
||||
</ImplementedReturnTypeMismatch>
|
||||
<file src="src/Db/CacheContainer.php">
|
||||
<ParadoxicalCondition>
|
||||
<code><![CDATA[isset($this->ttl[$index])]]></code>
|
||||
</ParadoxicalCondition>
|
||||
<PropertyNotSetInConstructor>
|
||||
<code>$cacheTtl</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
</file>
|
||||
<file src="src/Db/Driver/Mysql.php">
|
||||
<ArgumentTypeCoercion>
|
||||
@ -268,9 +232,6 @@
|
||||
<code>$settings</code>
|
||||
<code>$settings</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<LessSpecificReturnStatement>
|
||||
<code>$instance</code>
|
||||
</LessSpecificReturnStatement>
|
||||
<MissingClosureParamType>
|
||||
<code>$v</code>
|
||||
<code>$value</code>
|
||||
@ -285,14 +246,6 @@
|
||||
<code>$dbSettings</code>
|
||||
<code>$dbSettings</code>
|
||||
<code>$dbSettings</code>
|
||||
<code>$dbSettings</code>
|
||||
<code>$dbSettings</code>
|
||||
<code>$dbSettings</code>
|
||||
<code>$dbSettings</code>
|
||||
<code>$deserializer</code>
|
||||
<code>$deserializer</code>
|
||||
<code>$deserializer</code>
|
||||
<code>$deserializer</code>
|
||||
<code>$deserializer</code>
|
||||
<code>$deserializer</code>
|
||||
<code>$deserializer</code>
|
||||
@ -301,25 +254,14 @@
|
||||
<code>$serializer</code>
|
||||
<code>$serializer</code>
|
||||
<code>$serializer</code>
|
||||
<code>$serializer</code>
|
||||
<code>$serializer</code>
|
||||
<code>$serializer</code>
|
||||
<code>$serializer</code>
|
||||
<code>$table</code>
|
||||
<code>$table</code>
|
||||
<code>$table</code>
|
||||
<code>$table</code>
|
||||
<code>$table</code>
|
||||
<code>$table</code>
|
||||
<code>$table</code>
|
||||
<code>$table</code>
|
||||
</MissingConstructor>
|
||||
<MoreSpecificReturnType>
|
||||
<code>static</code>
|
||||
</MoreSpecificReturnType>
|
||||
<PossibleRawObjectIteration>
|
||||
<RawObjectIteration>
|
||||
<code>$old</code>
|
||||
</PossibleRawObjectIteration>
|
||||
</RawObjectIteration>
|
||||
<UndefinedMethod>
|
||||
<code>setSettings</code>
|
||||
</UndefinedMethod>
|
||||
@ -349,14 +291,8 @@
|
||||
</InvalidDocblockParamName>
|
||||
<MissingConstructor>
|
||||
<code>$pdo</code>
|
||||
<code>$pdo</code>
|
||||
</MissingConstructor>
|
||||
</file>
|
||||
<file src="src/Db/NullCache/NullCacheTrait.php">
|
||||
<MissingParamType>
|
||||
<code>$value</code>
|
||||
</MissingParamType>
|
||||
</file>
|
||||
<file src="src/Db/PostgresArray.php">
|
||||
<MissingClosureParamType>
|
||||
<code>$v</code>
|
||||
@ -411,9 +347,6 @@
|
||||
<code>$db</code>
|
||||
<code>$db</code>
|
||||
<code>$db</code>
|
||||
<code>$db</code>
|
||||
<code>$db</code>
|
||||
<code>$db</code>
|
||||
</MissingConstructor>
|
||||
<PossiblyNullArrayAccess>
|
||||
<code><![CDATA[$row->fetchRow()['count']]]></code>
|
||||
@ -434,10 +367,6 @@
|
||||
<ArgumentTypeCoercion>
|
||||
<code>$class</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[Tools::call($this->getReportPeers())]]></code>
|
||||
<code><![CDATA[Tools::call($this->getReportPeers())]]></code>
|
||||
</DeprecatedMethod>
|
||||
<PossiblyInvalidArgument>
|
||||
<code><![CDATA[$this->wrapper->getAPI()]]></code>
|
||||
</PossiblyInvalidArgument>
|
||||
@ -720,19 +649,6 @@
|
||||
</PropertyTypeCoercion>
|
||||
</file>
|
||||
<file src="src/InternalDoc.php">
|
||||
<DeprecatedMethod>
|
||||
<code>\danog\MadelineProto\AsyncTools::after($a, $b)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::all($promises)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::any($promises)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::call($promise)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::first($promises)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::some($promises)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::timeout($promise, $timeout)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::timeoutWithDefault($promise, $timeout, $default)</code>
|
||||
<code>\danog\MadelineProto\AsyncTools::wait($promise)</code>
|
||||
<code>loop</code>
|
||||
<code>loop</code>
|
||||
</DeprecatedMethod>
|
||||
<InvalidReturnStatement>
|
||||
<code><![CDATA[$this->wrapper->getAPI()->getEventHandler($class)]]></code>
|
||||
</InvalidReturnStatement>
|
||||
@ -745,19 +661,14 @@
|
||||
<MissingReturnType>
|
||||
<code>MTProtoToTd</code>
|
||||
<code>MTProtoToTdcli</code>
|
||||
<code>all</code>
|
||||
<code>any</code>
|
||||
<code>completePhoneLogin</code>
|
||||
<code>downloadToCallable</code>
|
||||
<code>downloadToDir</code>
|
||||
<code>downloadToStream</code>
|
||||
<code>end</code>
|
||||
<code>first</code>
|
||||
<code>loop</code>
|
||||
<code>phoneLogin</code>
|
||||
<code>requestCall</code>
|
||||
<code>requestSecretChat</code>
|
||||
<code>some</code>
|
||||
<code>start</code>
|
||||
<code>tdToTdcli</code>
|
||||
<code>upload</code>
|
||||
@ -766,7 +677,6 @@
|
||||
<code>uploadFromStream</code>
|
||||
<code>uploadFromTgfile</code>
|
||||
<code>uploadFromUrl</code>
|
||||
<code>wait</code>
|
||||
</MissingReturnType>
|
||||
<PossiblyInvalidPropertyAssignmentValue>
|
||||
<code><![CDATA[$this->account ??= new \danog\MadelineProto\Namespace\AbstractAPI('account')]]></code>
|
||||
@ -789,9 +699,6 @@
|
||||
<code><![CDATA[$this->upload ??= new \danog\MadelineProto\Namespace\AbstractAPI('upload')]]></code>
|
||||
<code><![CDATA[$this->users ??= new \danog\MadelineProto\Namespace\AbstractAPI('users')]]></code>
|
||||
</PossiblyInvalidPropertyAssignmentValue>
|
||||
<PossiblyNullArgument>
|
||||
<code>$callback</code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyUndefinedMethod>
|
||||
<code>setWrapper</code>
|
||||
<code>setWrapper</code>
|
||||
@ -822,7 +729,6 @@
|
||||
<code>downloadToCallable</code>
|
||||
<code>downloadToDir</code>
|
||||
<code>downloadToFile</code>
|
||||
<code>loop</code>
|
||||
<code>methodCallAsyncRead</code>
|
||||
<code>uploadFromCallable</code>
|
||||
<code>uploadFromTgfile</code>
|
||||
@ -1295,7 +1201,6 @@
|
||||
<code><![CDATA[$this->chats]]></code>
|
||||
</RawObjectIteration>
|
||||
<RedundantCondition>
|
||||
<code><![CDATA[$this->minDatabase?->sync()]]></code>
|
||||
<code><![CDATA[isset($this->wrapper) && $this->isInited()]]></code>
|
||||
<code><![CDATA[isset($this->wrapper) && isset(self::$references[$this->getSessionName()])]]></code>
|
||||
</RedundantCondition>
|
||||
@ -1305,9 +1210,6 @@
|
||||
<code>\is_int($dc_id)</code>
|
||||
<code><![CDATA[isset($this->datacenter)]]></code>
|
||||
</RedundantConditionGivenDocblockType>
|
||||
<TypeDoesNotContainNull>
|
||||
<code><![CDATA[$this->minDatabase]]></code>
|
||||
</TypeDoesNotContainNull>
|
||||
<UnsupportedReferenceUsage>
|
||||
<code><![CDATA[Lang::$current_lang =& Lang::$lang[$this->settings->getAppInfo()->getLangCode()]]]></code>
|
||||
</UnsupportedReferenceUsage>
|
||||
@ -1561,7 +1463,7 @@
|
||||
<code>$db</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<RawObjectIteration>
|
||||
<code><![CDATA[$this->API->chats]]></code>
|
||||
<code><![CDATA[$this->db]]></code>
|
||||
<code><![CDATA[$this->db]]></code>
|
||||
</RawObjectIteration>
|
||||
</file>
|
||||
@ -1717,15 +1619,11 @@
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
</file>
|
||||
<file src="src/MyTelegramOrgWrapper.php">
|
||||
<DeprecatedMethod>
|
||||
<code>Tools::wait($callable())</code>
|
||||
</DeprecatedMethod>
|
||||
<MissingReturnType>
|
||||
<code>completeLogin</code>
|
||||
<code>createApp</code>
|
||||
<code>getApp</code>
|
||||
<code>hasApp</code>
|
||||
<code>loop</code>
|
||||
</MissingReturnType>
|
||||
<PossiblyNullArgument>
|
||||
<code><![CDATA[$this->settings]]></code>
|
||||
@ -1832,9 +1730,6 @@
|
||||
<code>$ipcSocket</code>
|
||||
<code>$ipcSocket</code>
|
||||
</NullableReturnStatement>
|
||||
<PossiblyUndefinedMethod>
|
||||
<code>$unserialized</code>
|
||||
</PossiblyUndefinedMethod>
|
||||
</file>
|
||||
<file src="src/SessionPaths.php">
|
||||
<LessSpecificReturnStatement>
|
||||
@ -2454,13 +2349,4 @@
|
||||
<code>$result</code>
|
||||
</PossiblyUndefinedVariable>
|
||||
</file>
|
||||
<file src="src/loop.php">
|
||||
<MissingClosureReturnType>
|
||||
<code>function ($_) use ($callback) {</code>
|
||||
</MissingClosureReturnType>
|
||||
<PossiblyNullFunctionCall>
|
||||
<code>$callback()</code>
|
||||
<code>$callback()</code>
|
||||
</PossiblyNullFunctionCall>
|
||||
</file>
|
||||
</files>
|
||||
|
@ -1,129 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @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<mixed>
|
||||
*/
|
||||
private array $cache = [];
|
||||
/**
|
||||
* @var array<int>
|
||||
*/
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
148
src/Db/CacheContainer.php
Normal file
148
src/Db/CacheContainer.php
Normal file
@ -0,0 +1,148 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General private License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General private License for more details.
|
||||
* You should have received a copy of the GNU General private License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @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<mixed>
|
||||
*/
|
||||
private array $cache = [];
|
||||
/**
|
||||
* @var array<int|true>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
100
src/Db/CachedArray.php
Normal file
100
src/Db/CachedArray.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @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<TKey, TValue>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
@ -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<TKey, TValue>
|
||||
* @extends DbType<TKey, TValue>
|
||||
*/
|
||||
interface DbArray extends DbType, ArrayAccess, Countable
|
||||
interface DbArray extends DbType, ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Get Array copy.
|
||||
*
|
||||
* @psalm-return array<TKey, TValue>
|
||||
*/
|
||||
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<TKey, TValue>
|
||||
* @psalm-return array<TKey, TValue>
|
||||
*/
|
||||
public function getIterator(): \Traversable;
|
||||
public function getArrayCopy(): array;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<TKey, TValue>
|
||||
*/
|
||||
public function getIterator(): \Traversable;
|
||||
|
||||
/**
|
||||
* Get instance.
|
||||
*/
|
||||
public static function getInstance(string $table, DbType|null $previous, DatabaseAbstract $settings): self;
|
||||
}
|
||||
|
@ -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<TKey, TValue>
|
||||
* @implements DbArray<TKey, TValue>
|
||||
* @implements DbType<TKey, TValue>
|
||||
*/
|
||||
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) {
|
||||
|
@ -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;
|
||||
|
@ -33,7 +33,7 @@ use PDO;
|
||||
* @template TValue
|
||||
* @extends SqlArray<TKey, TValue>
|
||||
*/
|
||||
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;
|
||||
|
@ -1,34 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @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<TKey, TValue>
|
||||
*/
|
||||
final class MysqlArray extends DbMysqlArray
|
||||
{
|
||||
use NullCacheTrait;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @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<TKey, TValue>
|
||||
* @internal
|
||||
*/
|
||||
final class PostgresArray extends DbPostgresArray
|
||||
{
|
||||
use NullCacheTrait;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @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<TKey, TValue>
|
||||
* @internal
|
||||
*/
|
||||
final class PostgresArrayBytea extends DbPostgresArrayBytea
|
||||
{
|
||||
use NullCacheTrait;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of MadelineProto.
|
||||
* MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
* MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Affero General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License along with MadelineProto.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @author Daniil Gentili <daniil@daniil.it>
|
||||
* @copyright 2016-2023 Daniil Gentili <daniil@daniil.it>
|
||||
* @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<TKey, TValue>
|
||||
*/
|
||||
final class RedisArray extends DbRedisArray
|
||||
{
|
||||
use NullCacheTrait;
|
||||
}
|
@ -29,7 +29,7 @@ use danog\MadelineProto\Settings\Database\SerializerType;
|
||||
* @template TValue
|
||||
* @extends PostgresArrayBytea<TKey, TValue>
|
||||
*/
|
||||
class PostgresArray extends PostgresArrayBytea
|
||||
final class PostgresArray extends PostgresArrayBytea
|
||||
{
|
||||
/**
|
||||
* Prepare statements.
|
||||
|
@ -30,7 +30,7 @@ use danog\MadelineProto\Settings\Database\Redis as DatabaseRedis;
|
||||
* @template TValue
|
||||
* @extends DriverArray<TKey, TValue>
|
||||
*/
|
||||
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 = [];
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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'] ?? [];
|
||||
|
@ -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'] ?? [];
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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<DbType> */
|
||||
abstract public function getDriverClass(): string;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Upgrade layer number.
|
||||
*
|
||||
* @param integer $layer Layer number
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function layerUpgrade(int $layer): void
|
||||
{
|
||||
|
@ -4,7 +4,7 @@ use danog\MadelineProto\Lang;
|
||||
|
||||
/**
|
||||
* Merge extracted docs.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function mergeExtracted(): void
|
||||
{
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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 = [];
|
||||
|
Loading…
Reference in New Issue
Block a user