Upgrade for MysqlArray initialization

This commit is contained in:
Alexander Pankratov 2020-05-17 22:04:32 +03:00
parent 9016a7c0dd
commit fea71efc99
5 changed files with 66 additions and 43 deletions

View File

@ -2,6 +2,7 @@
namespace danog\MadelineProto\Db;
use Amp\Promise;
use danog\MadelineProto\MTProto;
class DbPropertiesFabric
@ -12,13 +13,13 @@ class DbPropertiesFabric
* @param string $name
* @param $value
*
* @return DbType
* @return Promise<DbType>
*
* @uses \danog\MadelineProto\Db\MemoryArray
* @uses \danog\MadelineProto\Db\SharedMemoryArray
* @uses \danog\MadelineProto\Db\MysqlArray
*/
public static function get(MTProto $madelineProto, string $propertyType, string $name, $value = null): DbType
public static function get(MTProto $madelineProto, string $propertyType, string $name, $value = null): Promise
{
$class = __NAMESPACE__;
$dbSettings = $madelineProto->settings['db'];

View File

@ -2,7 +2,17 @@
namespace danog\MadelineProto\Db;
use Amp\Promise;
interface DbType
{
static function getInstance(string $name, $value = null, string $tablePrefix = '', array $settings = []): self;
/**
* @param string $name
* @param null $value
* @param string $tablePrefix
* @param array $settings
*
* @return Promise<self>
*/
static function getInstance(string $name, $value = null, string $tablePrefix = '', array $settings = []): Promise;
}

View File

@ -13,12 +13,14 @@ class MemoryArray extends \ArrayIterator implements DbArray
parent::__construct((array) $array, $flags | self::STD_PROP_LIST);
}
public static function getInstance(string $name, $value = null, string $tablePrefix = '', array $settings = []): DbArray
public static function getInstance(string $name, $value = null, string $tablePrefix = '', array $settings = []): Promise
{
if ($value instanceof DbArray) {
$value = $value->getArrayCopy();
}
return new static($value);
return call(function() use ($value) {
if ($value instanceof DbArray) {
$value = $value->getArrayCopy();
}
return new static($value);
});
}
public function offsetExists($offset): Promise

View File

@ -40,7 +40,7 @@ class MysqlArray implements DbArray
}
public static function getInstance(string $name, $value = null, string $tablePrefix = '', array $settings = []): DbType
public static function getInstance(string $name, $value = null, string $tablePrefix = '', array $settings = []): Promise
{
$instance = new static();
@ -49,43 +49,51 @@ class MysqlArray implements DbArray
$instance->db = static::getDbConnection($settings);
$instance->ttl = $settings['cache_ttl'] ?? $instance->ttl;
Loop::defer(static function() use($value, $instance) {
if ($value instanceof static && $value->table) {
if (
mb_strpos($value->table, 'tmp') === 0 &&
mb_strpos($instance->table, 'tmp') !== 0
) {
yield from $instance->renameTable($value->table, $instance->table);
} elseif (mb_strpos($instance->table, 'tmp') === 0){
$instance->table = $value->table;
}
}
return call(static function() use($instance, $value) {
yield from static::renameTmpTable($instance, $value);
yield from $instance->prepareTable();
Loop::defer(fn() => static::migrateDataToDb($instance, $value));
if (!empty($value) && !$value instanceof static) {
Logger::log('Converting database.', Logger::ERROR);
if ($value instanceof DbArray) {
$value = $value->getArrayCopy();
}
$value = (array) $value;
$counter = 0;
$total = count($value);
foreach ((array) $value as $key => $item) {
$counter++;
if ($counter % 100 === 0) {
yield $instance->offsetSet($key, $item);
Logger::log("Converting database. $counter/$total", Logger::WARNING);
} else {
$instance->offsetSet($key, $item);
}
}
Logger::log('Converting database done.', Logger::ERROR);
}
return $instance;
});
}
return $instance;
private static function renameTmpTable(MysqlArray $instance, ?DbArray $value): \Generator
{
if ($value instanceof static && $value->table) {
if (
mb_strpos($value->table, 'tmp') === 0 &&
mb_strpos($instance->table, 'tmp') !== 0
) {
yield from $instance->renameTable($value->table, $instance->table);
} elseif (mb_strpos($instance->table, 'tmp') === 0) {
$instance->table = $value->table;
}
}
}
private static function migrateDataToDb(MysqlArray $instance, ?DbArray $value): \Generator
{
if (!empty($value) && !$value instanceof static) {
Logger::log('Converting database.', Logger::ERROR);
if ($value instanceof DbArray) {
$value = $value->getArrayCopy();
}
$value = (array) $value;
$counter = 0;
$total = count($value);
foreach ((array) $value as $key => $item) {
$counter++;
if ($counter % 100 === 0) {
yield $instance->offsetSet($key, $item);
Logger::log("Converting database. $counter/$total", Logger::WARNING);
} else {
$instance->offsetSet($key, $item);
}
}
Logger::log('Converting database done.', Logger::ERROR);
}
}
/**
@ -262,6 +270,7 @@ class MysqlArray implements DbArray
*/
private function prepareTable()
{
Logger::log("Creating/checking table {$this->table}", Logger::WARNING);
return yield $this->request("
CREATE TABLE IF NOT EXISTS `{$this->table}`
(
@ -278,6 +287,7 @@ class MysqlArray implements DbArray
private function renameTable(string $from, string $to)
{
Logger::log("Renaming table {$from} to {$to}", Logger::WARNING);
yield $this->request("
ALTER TABLE `{$from}` RENAME TO `{$to}`;
");

View File

@ -572,7 +572,7 @@ class MTProto extends AsyncConstruct implements TLCallback
if ($reset) {
unset($this->{$property});
} else {
$this->{$property} = DbPropertiesFabric::get($this, $type, $property, $this->{$property});
$this->{$property} = yield DbPropertiesFabric::get($this, $type, $property, $this->{$property});
}
}