mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 10:19:00 +01:00
Implement serialization type migration
This commit is contained in:
parent
14f6cfcedc
commit
d17dcca02a
@ -27,7 +27,7 @@ final class Postgres
|
||||
$config = PostgresConfig::fromString('host='.\str_replace('tcp://', '', $settings->getUri()))
|
||||
->withUser($settings->getUsername())
|
||||
->withPassword($settings->getPassword())
|
||||
->withDatabase(strtolower($settings->getDatabase()));
|
||||
->withDatabase(\strtolower($settings->getDatabase()));
|
||||
|
||||
static::createDb($config);
|
||||
static::$connections[$dbKey] = new PostgresConnectionPool($config, $settings->getMaxConnections(), $settings->getIdleTimeout());
|
||||
|
@ -81,17 +81,18 @@ abstract class DriverArray implements DbArray, IteratorAggregate
|
||||
return $this->offsetGet($key) !== null;
|
||||
}
|
||||
|
||||
private function setSettings(SqlAbstract $settings): void {
|
||||
private function setSettings(SqlAbstract $settings): void
|
||||
{
|
||||
$this->dbSettings = $settings;
|
||||
$this->setCacheTtl($settings->getCacheTtl());
|
||||
$this->setSerializer($settings->getSerializer());
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
|
||||
public function __wakeup(): void
|
||||
{
|
||||
$this->setSettings($this->dbSettings);
|
||||
}
|
||||
|
||||
|
||||
/** @param SqlAbstract $settings */
|
||||
public static function getInstance(string $table, DbType|array|null $previous, DatabaseAbstract $settings): static
|
||||
{
|
||||
@ -106,7 +107,7 @@ abstract class DriverArray implements DbArray, IteratorAggregate
|
||||
$instance->initConnection($settings);
|
||||
$instance->prepareTable();
|
||||
|
||||
if (self::getClassName($previous) !== self::getClassName($instance)) {
|
||||
if (self::getMigrationName($previous) !== self::getMigrationName($instance)) {
|
||||
if ($previous instanceof DriverArray) {
|
||||
$previous->initStartup();
|
||||
}
|
||||
@ -146,11 +147,13 @@ abstract class DriverArray implements DbArray, IteratorAggregate
|
||||
}
|
||||
private static function migrateDataToDb(self $new, DbArray|array|null $old): void
|
||||
{
|
||||
if (!empty($old) && self::getClassName($old) !== self::getClassName($new)) {
|
||||
$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 '.$old::class.' to '.$new::class, Logger::ERROR);
|
||||
Logger::log("Converting $oldName to $newName", Logger::ERROR);
|
||||
|
||||
$counter = 0;
|
||||
$total = \count($old);
|
||||
@ -165,7 +168,10 @@ abstract class DriverArray implements DbArray, IteratorAggregate
|
||||
}
|
||||
$new->clearCache();
|
||||
}
|
||||
$old->clear();
|
||||
if (self::getMigrationName($new, false) !== self::getMigrationName($old, false)) {
|
||||
Logger::log("Dropping data from table {$old}", Logger::WARNING);
|
||||
$old->clear();
|
||||
}
|
||||
Logger::log('Converting database done.', Logger::ERROR);
|
||||
}
|
||||
}
|
||||
@ -214,13 +220,17 @@ abstract class DriverArray implements DbArray, IteratorAggregate
|
||||
return \iterator_to_array($this->getIterator());
|
||||
}
|
||||
|
||||
private static function getClassName($instance): ?string
|
||||
private static function getMigrationName(DbType|array|null $instance, bool $include_serialization_type = true): ?string
|
||||
{
|
||||
if ($instance === null) {
|
||||
return null;
|
||||
} elseif (\is_array($instance)) {
|
||||
return 'Array';
|
||||
}
|
||||
return \str_replace('NullCache\\', '', $instance::class);
|
||||
$base = \str_replace('NullCache\\', '', $instance::class);
|
||||
if ($include_serialization_type && $instance instanceof DriverArray) {
|
||||
$base .= ' ('.$instance->dbSettings->getSerializer()->value.')';
|
||||
}
|
||||
return $base;
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\Db;
|
||||
|
||||
use Amp\Postgres\ByteA;
|
||||
use danog\MadelineProto\Db\Driver\Postgres;
|
||||
use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\Settings\Database\Postgres as DatabasePostgres;
|
||||
use danog\MadelineProto\Settings\Database\SerializerType;
|
||||
|
||||
/**
|
||||
@ -62,16 +60,16 @@ class PostgresArray extends PostgresArrayBytea
|
||||
protected function setSerializer(SerializerType $serializer): void
|
||||
{
|
||||
$this->serializer = match ($serializer) {
|
||||
SerializerType::SERIALIZE => fn ($v) => bin2hex(\serialize($v)),
|
||||
SerializerType::IGBINARY => fn ($v) => bin2hex(\igbinary_serialize($v)),
|
||||
SerializerType::JSON => fn ($v) => bin2hex(\json_encode($v, JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES)),
|
||||
SerializerType::STRING => fn ($v) => bin2hex(\strval($v)),
|
||||
SerializerType::SERIALIZE => fn ($v) => \bin2hex(\serialize($v)),
|
||||
SerializerType::IGBINARY => fn ($v) => \bin2hex(\igbinary_serialize($v)),
|
||||
SerializerType::JSON => fn ($v) => \bin2hex(\json_encode($v, JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES)),
|
||||
SerializerType::STRING => fn ($v) => \bin2hex(\strval($v)),
|
||||
};
|
||||
$this->deserializer = match ($serializer) {
|
||||
SerializerType::SERIALIZE => fn ($v) => \unserialize(hex2bin($v)),
|
||||
SerializerType::IGBINARY => fn ($v) => \igbinary_unserialize(hex2bin($v)),
|
||||
SerializerType::JSON => fn ($value) => \json_decode(hex2bin($value), true, 256, JSON_THROW_ON_ERROR),
|
||||
SerializerType::STRING => fn ($v) => hex2bin($v),
|
||||
SerializerType::SERIALIZE => fn ($v) => \unserialize(\hex2bin($v)),
|
||||
SerializerType::IGBINARY => fn ($v) => \igbinary_unserialize(\hex2bin($v)),
|
||||
SerializerType::JSON => fn ($value) => \json_decode(\hex2bin($value), true, 256, JSON_THROW_ON_ERROR),
|
||||
SerializerType::STRING => fn ($v) => \hex2bin($v),
|
||||
};
|
||||
}
|
||||
/**
|
||||
|
@ -49,7 +49,6 @@ use danog\MadelineProto\MTProtoTools\UpdatesState;
|
||||
use danog\MadelineProto\SecretChats\MessageHandler;
|
||||
use danog\MadelineProto\SecretChats\ResponseHandler;
|
||||
use danog\MadelineProto\SecretChats\SeqNoHandler;
|
||||
use danog\MadelineProto\Settings\Database\SerializerType;
|
||||
use danog\MadelineProto\Settings\TLSchema;
|
||||
use danog\MadelineProto\TL\Conversion\BotAPI;
|
||||
use danog\MadelineProto\TL\Conversion\BotAPIFiles;
|
||||
@ -503,12 +502,12 @@ final class MTProto implements TLCallback, LoggerGetter
|
||||
* @see DbPropertiesFactory
|
||||
*/
|
||||
protected static array $dbProperties = [
|
||||
'chats' => ['serializer' => SerializerType::SERIALIZE],
|
||||
'full_chats' => ['serializer' => SerializerType::SERIALIZE],
|
||||
'sponsoredMessages' => ['serializer' => SerializerType::SERIALIZE],
|
||||
'channelParticipants' => ['serializer' => SerializerType::SERIALIZE],
|
||||
'usernames' => ['serializer' => SerializerType::SERIALIZE],
|
||||
'session' => ['serializer' => SerializerType::SERIALIZE, 'enableCache' => false],
|
||||
'chats' => [],
|
||||
'full_chats' => [],
|
||||
'sponsoredMessages' => [],
|
||||
'channelParticipants' => [],
|
||||
'usernames' => [],
|
||||
'session' => ['enableCache' => false],
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,6 @@ use danog\MadelineProto\Db\DbPropertiesTrait;
|
||||
use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use danog\MadelineProto\Settings\Database\SerializerType;
|
||||
use danog\MadelineProto\TL\TLCallback;
|
||||
use Revolt\EventLoop;
|
||||
|
||||
@ -69,7 +68,7 @@ final class MinDatabase implements TLCallback
|
||||
* @see DbPropertiesFactory
|
||||
*/
|
||||
protected static array $dbProperties = [
|
||||
'db' => ['serializer' => SerializerType::SERIALIZE],
|
||||
'db' => [],
|
||||
];
|
||||
|
||||
public function __construct(MTProto $API)
|
||||
|
@ -26,7 +26,6 @@ use danog\MadelineProto\Exception;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use danog\MadelineProto\MTProto\OutgoingMessage;
|
||||
use danog\MadelineProto\Settings\Database\SerializerType;
|
||||
use danog\MadelineProto\TL\TLCallback;
|
||||
use danog\MadelineProto\Tools;
|
||||
use Webmozart\Assert\Assert;
|
||||
@ -88,7 +87,7 @@ final class ReferenceDatabase implements TLCallback
|
||||
* @see DbPropertiesFactory
|
||||
*/
|
||||
protected static array $dbProperties = [
|
||||
'db' => ['serializer' => SerializerType::SERIALIZE],
|
||||
'db' => [],
|
||||
];
|
||||
|
||||
public function __construct(private MTProto $API)
|
||||
|
@ -30,7 +30,6 @@ use Amp\TimeoutException;
|
||||
use danog\MadelineProto\Db\DbPropertiesFactory;
|
||||
use danog\MadelineProto\Db\DriverArray;
|
||||
use danog\MadelineProto\Ipc\Server;
|
||||
use danog\MadelineProto\Settings\Database\SerializerType;
|
||||
use danog\MadelineProto\Settings\DatabaseAbstract;
|
||||
use Revolt\EventLoop;
|
||||
use Throwable;
|
||||
@ -215,7 +214,7 @@ abstract class Serialization
|
||||
$unserialized = DbPropertiesFactory::get(
|
||||
$settings,
|
||||
$tableName,
|
||||
['serializer' => SerializerType::SERIALIZE],
|
||||
[],
|
||||
$unserialized,
|
||||
);
|
||||
} else {
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto\Settings\Database;
|
||||
|
||||
use danog\MadelineProto\Magic;
|
||||
use danog\MadelineProto\Settings\DatabaseAbstract;
|
||||
|
||||
/**
|
||||
@ -21,9 +22,11 @@ abstract class DriverDatabaseAbstract extends DatabaseAbstract
|
||||
protected string $password = '';
|
||||
|
||||
/**
|
||||
* Which serializer strategy to use by default.
|
||||
* Which serializer to use by default.
|
||||
*
|
||||
* If null, the best serializater is chosen.
|
||||
*/
|
||||
protected SerializerType $serializer = SerializerType::SERIALIZE;
|
||||
protected ?SerializerType $serializer = null;
|
||||
|
||||
public function mergeArray(array $settings): void
|
||||
{
|
||||
@ -112,10 +115,15 @@ abstract class DriverDatabaseAbstract extends DatabaseAbstract
|
||||
|
||||
public function getSerializer(): SerializerType
|
||||
{
|
||||
return $this->serializer;
|
||||
return $this->serializer ?? (Magic::$can_use_igbinary ? SerializerType::IGBINARY : SerializerType::SERIALIZE);
|
||||
}
|
||||
|
||||
public function setSerializer(SerializerType $serializer): void
|
||||
/**
|
||||
* Which serializer to use by default.
|
||||
*
|
||||
* If null, the best serializer is chosen.
|
||||
*/
|
||||
public function setSerializer(?SerializerType $serializer): void
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
namespace danog\MadelineProto\Settings\Database;
|
||||
|
||||
enum SerializerType
|
||||
enum SerializerType: string
|
||||
{
|
||||
case SERIALIZE;
|
||||
case IGBINARY;
|
||||
case JSON;
|
||||
case STRING;
|
||||
case SERIALIZE = 'serialize';
|
||||
case IGBINARY = 'igbinary';
|
||||
case JSON = 'json';
|
||||
case STRING = 'string';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user