diff --git a/examples/bot.php b/examples/bot.php
index fed847d9..525ce416 100755
--- a/examples/bot.php
+++ b/examples/bot.php
@@ -22,6 +22,8 @@
use danog\MadelineProto\API;
use danog\MadelineProto\EventHandler;
use danog\MadelineProto\Logger;
+use danog\MadelineProto\Settings;
+use danog\MadelineProto\Settings\Database\Redis;
/*
* Various ways to load MadelineProto
@@ -80,7 +82,6 @@ class MyEventHandler extends EventHandler
return;
}
-
$res = \json_encode($update, JSON_PRETTY_PRINT);
yield $this->messages->sendMessage(['peer' => $update, 'message' => "$res
", 'reply_to_msg_id' => isset($update['message']['id']) ? $update['message']['id'] : null, 'parse_mode' => 'HTML']);
if (isset($update['message']['media']) && $update['message']['media']['_'] !== 'messageMediaGame') {
@@ -88,14 +89,12 @@ class MyEventHandler extends EventHandler
}
}
}
-$settings = [
- 'logger' => [
- 'logger_level' => Logger::ULTRA_VERBOSE
- ],
- 'serialization' => [
- 'serialization_interval' => 30,
- ]
-];
+
+$settings = new Settings;
+$settings->getLogger()->setLevel(Logger::LEVEL_ULTRA_VERBOSE);
+
+// You can also use MySQL or PostgreSQL
+// $settings->setDb(new Redis);
$MadelineProto = new API('bot.madeline', $settings);
diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php
index 8646da8a..8834b48e 100644
--- a/src/danog/MadelineProto/API.php
+++ b/src/danog/MadelineProto/API.php
@@ -193,7 +193,7 @@ class API extends InternalDoc
}
[$unserialized, $this->unlock] = yield Tools::timeoutWithDefault(
- Serialization::unserialize($this->session, $forceFull),
+ Serialization::unserialize($this->session, $settings, $forceFull),
30000,
[0, null]
);
diff --git a/src/danog/MadelineProto/AnnotationsBuilder.php b/src/danog/MadelineProto/AnnotationsBuilder.php
index 61fc9a3e..12f7968e 100644
--- a/src/danog/MadelineProto/AnnotationsBuilder.php
+++ b/src/danog/MadelineProto/AnnotationsBuilder.php
@@ -172,9 +172,9 @@ class AnnotationsBuilder
$internalDoc[$namespace][$method]['return'] = $type;
}
$class = new \ReflectionClass($this->reflectionClasses['MTProto']);
- $methods = $class->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC);
+ $methods = $class->getMethods((\ReflectionMethod::IS_STATIC & \ReflectionMethod::IS_PUBLIC) | \ReflectionMethod::IS_PUBLIC);
$class = new \ReflectionClass(Tools::class);
- $methods = \array_merge($methods, $class->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC));
+ $methods = \array_merge($methods, $class->getMethods((\ReflectionMethod::IS_STATIC & \ReflectionMethod::IS_PUBLIC) | \ReflectionMethod::IS_PUBLIC));
foreach ($methods as $key => $method) {
$name = $method->getName();
if ($method == 'methodCallAsyncRead') {
diff --git a/src/danog/MadelineProto/Db/DbPropertiesFactory.php b/src/danog/MadelineProto/Db/DbPropertiesFactory.php
index b9bba22f..f77a76af 100644
--- a/src/danog/MadelineProto/Db/DbPropertiesFactory.php
+++ b/src/danog/MadelineProto/Db/DbPropertiesFactory.php
@@ -11,11 +11,15 @@ use danog\MadelineProto\Settings\DatabaseAbstract;
class DbPropertiesFactory
{
+ /**
+ * Indicates a simple K-V array stored in a database backend.
+ * Values can be objects or other arrays, but when lots of nesting is required, it's best to split the array into multiple arrays.
+ */
+ const TYPE_ARRAY = 'array';
/**
* @param DatabaseAbstract $dbSettings
- * @param string $namePrefix
- * @param string|array $propertyType
- * @param string $name
+ * @param string $table
+ * @param self::TYPE_*|array $propertyType
* @param $value
*
* @return Promise
@@ -25,7 +29,7 @@ class DbPropertiesFactory
* @uses \danog\MadelineProto\Db\PostgresArray
* @uses \danog\MadelineProto\Db\RedisArray
*/
- public static function get(DatabaseAbstract $dbSettings, string $namePrefix, $propertyType, string $name, $value = null): Promise
+ public static function get(DatabaseAbstract $dbSettings, string $table, $propertyType, $value = null): Promise
{
$config = $propertyType['config'] ?? [];
$propertyType = \is_array($propertyType) ? $propertyType['type'] : $propertyType;
@@ -54,13 +58,13 @@ class DbPropertiesFactory
/** @var DbType $class */
switch (\strtolower($propertyType)) {
- case 'array':
+ case self::TYPE_ARRAY:
$class .= 'Array';
break;
default:
throw new \InvalidArgumentException("Unknown $propertyType: {$propertyType}");
}
- return $class::getInstance($name, $value, $namePrefix, $dbSettings);
+ return $class::getInstance($table, $value, $dbSettings);
}
}
diff --git a/src/danog/MadelineProto/Db/DbPropertiesTrait.php b/src/danog/MadelineProto/Db/DbPropertiesTrait.php
index 809d5f4a..5cb902ec 100644
--- a/src/danog/MadelineProto/Db/DbPropertiesTrait.php
+++ b/src/danog/MadelineProto/Db/DbPropertiesTrait.php
@@ -9,6 +9,8 @@ trait DbPropertiesTrait
/**
* Initialize database instance.
*
+ * @internal
+ *
* @param MTProto $MadelineProto
* @param boolean $reset
* @return \Generator
@@ -25,7 +27,8 @@ trait DbPropertiesTrait
if ($reset) {
unset($this->{$property});
} else {
- $this->{$property} = yield DbPropertiesFactory::get($dbSettings, $prefix, $type, $property, $this->{$property});
+ $table = "{$prefix}_{$property}";
+ $this->{$property} = yield DbPropertiesFactory::get($dbSettings, $table, $type, $this->{$property});
}
}
}
diff --git a/src/danog/MadelineProto/Db/DbType.php b/src/danog/MadelineProto/Db/DbType.php
index af39e339..93d8a235 100644
--- a/src/danog/MadelineProto/Db/DbType.php
+++ b/src/danog/MadelineProto/Db/DbType.php
@@ -8,12 +8,11 @@ use danog\MadelineProto\Settings\DatabaseAbstract;
interface DbType
{
/**
- * @param string $name
- * @param null $value
- * @param string $tablePrefix
- * @param DatabaseAbstract $settings
+ * @param string $table
+ * @param null|DbType|array $value
+ * @param DatabaseAbstract $settings
*
* @return Promise
*/
- public static function getInstance(string $name, $value = null, string $tablePrefix = '', $settings): Promise;
+ public static function getInstance(string $table, $value = null, $settings): Promise;
}
diff --git a/src/danog/MadelineProto/Db/MemoryArray.php b/src/danog/MadelineProto/Db/MemoryArray.php
index 71d5cb31..4b96a90b 100644
--- a/src/danog/MadelineProto/Db/MemoryArray.php
+++ b/src/danog/MadelineProto/Db/MemoryArray.php
@@ -20,13 +20,12 @@ class MemoryArray extends \ArrayIterator implements DbArray
/**
* Get instance.
*
- * @param string $name
+ * @param string $table
* @param mixed $value
- * @param string $tablePrefix
* @param Memory $settings
* @return Promise
*/
- public static function getInstance(string $name, $value = null, string $tablePrefix = '', $settings): Promise
+ public static function getInstance(string $table, $value = null, $settings): Promise
{
return call(static function () use ($value) {
if ($value instanceof MemoryArray) {
diff --git a/src/danog/MadelineProto/Db/SqlArray.php b/src/danog/MadelineProto/Db/SqlArray.php
index d21aa02c..1e10dba8 100644
--- a/src/danog/MadelineProto/Db/SqlArray.php
+++ b/src/danog/MadelineProto/Db/SqlArray.php
@@ -24,23 +24,21 @@ abstract class SqlArray extends DriverArray
/**
- * @param string $name
+ * @param string $table
* @param DbArray|array|null $value
- * @param string $tablePrefix
* @param DatabaseAbstract $settings
*
* @return Promise
*
* @psalm-return Promise
*/
- public static function getInstance(string $name, $value = null, string $tablePrefix = '', $settings): Promise
+ public static function getInstance(string $table, $value = null, $settings): Promise
{
- $tableName = "{$tablePrefix}_{$name}";
- if ($value instanceof static && $value->table === $tableName) {
+ if ($value instanceof static && $value->table === $table) {
$instance = &$value;
} else {
$instance = new static();
- $instance->table = $tableName;
+ $instance->table = $table;
}
/** @psalm-suppress UndefinedPropertyAssignment */
diff --git a/src/danog/MadelineProto/EventHandler.php b/src/danog/MadelineProto/EventHandler.php
index 842d583c..a8c206a2 100644
--- a/src/danog/MadelineProto/EventHandler.php
+++ b/src/danog/MadelineProto/EventHandler.php
@@ -19,11 +19,16 @@
namespace danog\MadelineProto;
+use danog\MadelineProto\Db\DbPropertiesTrait;
+
/**
* Event handler.
*/
abstract class EventHandler extends InternalDoc
{
+ use DbPropertiesTrait {
+ DbPropertiesTrait::initDb as private internalInitDb;
+ }
/**
* Whether the event handler was started.
*/
@@ -57,6 +62,9 @@ abstract class EventHandler extends InternalDoc
if ($this->startedInternal) {
return;
}
+ if (isset(static::$dbProperties)) {
+ yield from $this->internalInitDb($this->API);
+ }
if (\method_exists($this, 'onStart')) {
yield $this->onStart();
}
diff --git a/src/danog/MadelineProto/InternalDoc.php b/src/danog/MadelineProto/InternalDoc.php
index a0cff163..4d408807 100644
--- a/src/danog/MadelineProto/InternalDoc.php
+++ b/src/danog/MadelineProto/InternalDoc.php
@@ -4666,16 +4666,6 @@ class InternalDoc extends APIFactory
{
return $this->__call(__FUNCTION__, [$id]);
}
- /**
- * Check state of calls.
- *
- * @psalm-return void|\Amp\Promise
- * @return mixed
- */
- public function checkCalls()
- {
- $this->__call(__FUNCTION__, []);
- }
/**
* Check for terms of service update.
*
@@ -5422,11 +5412,6 @@ class InternalDoc extends APIFactory
{
return $this->__call(__FUNCTION__, [$extra]);
}
-
- public function getSessionId(\danog\MadelineProto\MTProto $madelineProto): string
- {
- return \danog\MadelineProto\MTProto::getSessionId($madelineProto);
- }
/**
* Return current settings.
*
@@ -5551,17 +5536,6 @@ class InternalDoc extends APIFactory
{
return \danog\MadelineProto\Tools::inflateStripped($stripped);
}
- /**
- * Initialize database instance.
- *
- * @param MTProto $MadelineProto
- * @param boolean $reset
- * @return \Amp\Promise
- */
- public function initDb(\danog\MadelineProto\MTProto $MadelineProto, bool $reset = false, array $extra = [])
- {
- return $this->__call(__FUNCTION__, [$MadelineProto, $reset, $extra]);
- }
/**
* Initialize self-restart hack.
*
diff --git a/src/danog/MadelineProto/Serialization.php b/src/danog/MadelineProto/Serialization.php
index 368e5730..2cde7e45 100644
--- a/src/danog/MadelineProto/Serialization.php
+++ b/src/danog/MadelineProto/Serialization.php
@@ -23,9 +23,11 @@ use Amp\Deferred;
use Amp\Ipc\Sync\ChannelledSocket;
use Amp\Loop;
use Amp\Promise;
+use danog\MadelineProto\Db\DbPropertiesFactory;
use danog\MadelineProto\Db\DriverArray;
use danog\MadelineProto\Ipc\Server;
use danog\MadelineProto\MTProtoSession\Session;
+use danog\MadelineProto\Settings\DatabaseAbstract;
use function Amp\File\exists;
use function Amp\File\get;
@@ -97,8 +99,9 @@ abstract class Serialization
* - Start IPC server
* - Store IPC state
*
- * @param SessionPaths $session Session name
- * @param bool $forceFull Whether to force full session deserialization
+ * @param SessionPaths $session Session name
+ * @param SettingsAbstract $settings Settings
+ * @param bool $forceFull Whether to force full session deserialization
*
* @internal
*
@@ -106,7 +109,7 @@ abstract class Serialization
*
* @psalm-return \Generator
*/
- public static function unserialize(SessionPaths $session, bool $forceFull = false): \Generator
+ public static function unserialize(SessionPaths $session, SettingsAbstract $settings, bool $forceFull = false): \Generator
{
if (yield exists($session->getSessionPath())) {
// Is new session
@@ -197,7 +200,20 @@ abstract class Serialization
$unserialized = yield from $session->unserialize();
if ($unserialized instanceof DriverArray) {
Logger::log("Extracting session from database...");
- yield from $unserialized->initStartup();
+ if ($settings instanceof Settings) {
+ $settings = $settings->getDb();
+ }
+ if ($settings instanceof DatabaseAbstract) {
+ $tableName = (string) $unserialized;
+ $unserialized = yield DbPropertiesFactory::get(
+ $settings,
+ $tableName,
+ DbPropertiesFactory::TYPE_ARRAY,
+ $unserialized
+ );
+ } else {
+ yield from $unserialized->initStartup();
+ }
$unserialized = yield $unserialized['data'];
if (!$unserialized) {
throw new Exception("Could not extract session from database!");