Skip to content

Commit

Permalink
Switch to danog/async-orm
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Apr 6, 2024
1 parent ea2471f commit 6eb0954
Show file tree
Hide file tree
Showing 20 changed files with 156 additions and 77 deletions.
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"bacon/bacon-qr-code": "^2.0",
"nikic/php-parser": "^5",
"revolt/event-loop": "^1.0.5",
"danog/async-orm": "^1.0"
"danog/async-orm": "^1.0",
"symfony/thanks": "^1.3"
},
"require-dev": {
"ext-ctype": "*",
Expand Down Expand Up @@ -140,7 +141,8 @@
"allow-plugins": {
"bamarni/composer-bin-plugin": true,
"phabel/phabel": true,
"dealerdirect/phpcodesniffer-composer-installer": true
"dealerdirect/phpcodesniffer-composer-installer": true,
"symfony/thanks": true
}
}
}
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
<file name="src/TL/TLParser.php" />
<file name="src/TL/SecretTLParser.php" />
</ignoreFiles>
Expand Down
10 changes: 6 additions & 4 deletions src/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
abstract class EventHandler extends AbstractAPI
{
use DbAutoProperties {
DbAutoProperties::initDb as private internalInitDb;
DbAutoProperties::initDbProperties as private internalInitDb;
}

private static bool $includingPlugins = false;
Expand Down Expand Up @@ -128,10 +128,12 @@ final public function internalStart(APIWrapper $MadelineProto, array $pluginsPre
$this->wrapper = $MadelineProto;
$this->exportNamespaces();

\assert($this->wrapper instanceof MTProto);
if (isset(static::$dbProperties)) {
throw new AssertionError("Please switch to using OrmMappedArray annotations for mapped ORM properties!");
}
$this->internalInitDb(
$this->wrapper->getDbSettings(),
$this->wrapper->getDbPrefix(),
$this->wrapper->getAPI()->getDbSettings(),
$this->wrapper->getAPI()->getDbPrefix(),
);

if ($main) {
Expand Down
8 changes: 5 additions & 3 deletions src/MTProto.php
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ public function serializeSession(object $data)
return $data;
}
$this->session['data'] = $data;
return $this->session;
return $this->getDbPrefix().'session';
}

/**
Expand Down Expand Up @@ -563,12 +563,12 @@ public function getDbPrefix(): string
$this->tmpDbPrefix ??= 'tmp_'.hash('xxh3', $this->getSessionName());
$prefix = $this->tmpDbPrefix;
}
return (string) $prefix;
return ((string) $prefix).'_';
}
/** @internal */
public function getDbSettings(): OrmSettings
{

return $this->settings->getDb()->getOrmSettings();
}

/**
Expand Down Expand Up @@ -957,6 +957,8 @@ public function wakeup(SettingsAbstract $settings, APIWrapper $wrapper): void
$this->initPromise = $deferred->getFuture();

try {
$this->updateSettings($settings);

// Setup logger
$this->setupLogger();
if (!$this->ipcServer) {
Expand Down
4 changes: 0 additions & 4 deletions src/MTProtoTools/ReferenceDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ final class ReferenceDatabase implements TLCallback
{
use DbAutoProperties;

protected function getDbPrefix(): string
{
return $this->API->getDbPrefix();
}
// Reference from a document
public const DOCUMENT_LOCATION = 0;
// Reference from a photo
Expand Down
4 changes: 3 additions & 1 deletion src/MTProtoTools/UpdateHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
use AssertionError;
use danog\AsyncOrm\Annotations\OrmMappedArray;
use danog\AsyncOrm\DbArray;
use danog\AsyncOrm\KeyType;
use danog\AsyncOrm\ValueType;
use danog\MadelineProto\API;
use danog\MadelineProto\EventHandler\AbstractMessage;
use danog\MadelineProto\EventHandler\BotCommands;
Expand Down Expand Up @@ -142,7 +144,7 @@ trait UpdateHandler
/** @deprecated */
private CombinedUpdatesState $channels_state;
private CombinedUpdatesState $updateState;
#[OrmMappedArray(KeyType::INT, ValueType::BEST)]
#[OrmMappedArray(KeyType::INT, ValueType::SCALAR)]
private DbArray $getUpdatesQueue;
private int $getUpdatesQueueKey = 0;
private SplQueue $updateQueue;
Expand Down
22 changes: 11 additions & 11 deletions src/SecretChats/SecretChatController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
use AssertionError;
use danog\AsyncOrm\Annotations\OrmMappedArray;
use danog\AsyncOrm\DbArray;
use danog\AsyncOrm\DbPropertiesTrait;
use danog\AsyncOrm\DbAutoProperties;
use danog\AsyncOrm\KeyType;
use danog\AsyncOrm\ValueType;
use danog\MadelineProto\Logger;
use danog\MadelineProto\Loop\Secret\SecretFeedLoop;
use danog\MadelineProto\Loop\Update\UpdateLoop;
Expand All @@ -49,27 +51,22 @@
*/
final class SecretChatController implements Stringable
{
use DbPropertiesTrait;

protected function getDbPrefix(): string
{
return $this->API->getDbPrefix().'_'.$this->id;
}
use DbAutoProperties;

/**
* @var DbArray<int, array>
*/
#[OrmMappedArray(KeyType::INT, ValueType::BEST)]
#[OrmMappedArray(KeyType::INT, ValueType::SCALAR)]
private DbArray $incoming;
/**
* @var DbArray<int, array>
*/
#[OrmMappedArray(KeyType::INT, ValueType::BEST)]
#[OrmMappedArray(KeyType::INT, ValueType::SCALAR)]
private DbArray $outgoing;
/**
* @var DbArray<int, list{int, bool}> Seq, outgoing
*/
#[OrmMappedArray(KeyType::INT, ValueType::BEST)]
#[OrmMappedArray(KeyType::INT, ValueType::SCALAR)]
private DbArray $randomIdMap;
private int $in_seq_no = 0;
private int $out_seq_no = 0;
Expand Down Expand Up @@ -143,7 +140,10 @@ public function feed(array $update): void
}
public function init(): void
{
$this->initDb($this->API);
$this->initDbProperties(
$this->API->getDbSettings(),
$this->API->getDbPrefix().'_'.$this->id.'_'
);
}

public function startFeedLoop(): void
Expand Down
57 changes: 25 additions & 32 deletions src/Serialization.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
use Amp\Ipc\Sync\ChannelledSocket;
use Amp\TimeoutException;
use AssertionError;
use danog\AsyncOrm\DbArrayBuilder;
use danog\AsyncOrm\Driver\DriverArray;
use danog\AsyncOrm\KeyType;
use danog\AsyncOrm\ValueType;
use danog\MadelineProto\Ipc\Server;
use danog\MadelineProto\Settings\Database\DriverDatabaseAbstract;
use danog\MadelineProto\Settings\DatabaseAbstract;
use Revolt\EventLoop;
use Throwable;

Expand Down Expand Up @@ -218,40 +220,31 @@ public static function unserialize(SessionPaths $session, SettingsAbstract $sett
} else {
$unserialized = null;
}
if ($unserialized instanceof DriverArray || !$exists) {
\assert($unserialized instanceof DriverArray || $unserialized === null);
if ($unserialized instanceof DriverArray || \is_string($unserialized) || !$exists) {
if ($settings instanceof Settings) {
$settings = $settings->getDb();
}
if ($settings instanceof DatabaseAbstract) {
if (!$exists
&& $settings instanceof DriverDatabaseAbstract
&& $prefix = $settings->getEphemeralFilesystemPrefix()
) {
$tableName = "{$prefix}_MTProto_session";
} else {
$tableName = $unserialized
? $unserialized->__toString()
: null;
}
if ($tableName !== null) {
Logger::log('Extracting session from database...');
$unserialized = DbPropertiesFactory::get(
$settings,
$tableName,
['enableCache' => false],
$unserialized,
)['data'];
}
if (!$unserialized && $exists) {
throw new Exception('Could not extract session from database!');
}
} elseif ($unserialized !== null) {
$unserialized->initStartup();
$unserialized = $unserialized['data'];
if (!$unserialized) {
throw new Exception('Could not extract session from database!');
}
if ($settings instanceof DriverDatabaseAbstract
&& $prefix = $settings->getEphemeralFilesystemPrefix()
) {
$tableName = "{$prefix}_MTProto_session";
} elseif ($unserialized instanceof DriverArray) {
$tableName = ((array) $unserialized)["\0*\0table"];
} else {
$tableName = $unserialized;
}
$unserialized = null;
if ($tableName !== null && $settings instanceof DriverDatabaseAbstract) {
Logger::log('Extracting session from database...');
$unserialized = (new DbArrayBuilder(
$tableName,
$settings->getOrmSettings(),
KeyType::STRING,
ValueType::SCALAR,
))->build()->get('data');
}
if (!$unserialized && $exists) {
throw new Exception('Could not extract session from database!');
}
}
\assert($unserialized instanceof APIWrapper || $unserialized === null);
Expand Down
4 changes: 2 additions & 2 deletions src/SessionPaths.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public function delete(): void
/**
* Serialize object to file.
*/
public function serialize(object $object, string $path): void
public function serialize(object|string $object, string $path): void
{
Logger::log("Waiting for exclusive lock of $path.lock...");
$unlock = Tools::flock("$path.lock", LOCK_EX, 0.1);
Expand Down Expand Up @@ -173,7 +173,7 @@ public function serialize(object $object, string $path): void
*
* @param string $path Object path, defaults to session path
*/
public function unserialize(string $path = ''): ?object
public function unserialize(string $path = ''): object|string|null
{
$path = $path ?: $this->sessionPath;

Expand Down
2 changes: 2 additions & 0 deletions src/Settings/Database/DriverDatabaseAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ abstract class DriverDatabaseAbstract extends DatabaseAbstract
{
/**
* For how long to keep records in memory after last read, for cached backends.
*
* @var int<0, max>
*/
protected int $cacheTtl = 5 * 60;
/**
Expand Down
7 changes: 4 additions & 3 deletions src/Settings/Database/Memory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@

namespace danog\MadelineProto\Settings\Database;

use danog\AsyncOrm\MemoryArray;
use danog\AsyncOrm\Settings;
use danog\AsyncOrm\Settings\MemorySettings;
use danog\MadelineProto\Settings\DatabaseAbstract;

/**
* Memory backend settings.
*/
final class Memory extends DatabaseAbstract
{
public function getDriverClass(): string
public function getOrmSettings(): Settings
{
return MemoryArray::class;
return new MemorySettings;
}
}
38 changes: 35 additions & 3 deletions src/Settings/Database/Mysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@

namespace danog\MadelineProto\Settings\Database;

use Amp\Mysql\MysqlConfig;
use AssertionError;
use danog\AsyncOrm\MysqlArray;
use danog\AsyncOrm\Serializer\Igbinary;
use danog\AsyncOrm\Serializer\Native;
use danog\AsyncOrm\Settings;
use danog\AsyncOrm\Settings\MysqlSettings;

/**
* MySQL backend settings.
Expand Down Expand Up @@ -66,8 +70,36 @@ public function getOptimizeIfWastedGtMb(): ?int
{
return $this->optimizeIfWastedGtMb;
}
public function getDriverClass(): string

public function getOrmSettings(): Settings
{
return MysqlArray::class;
$host = str_replace(['tcp://', 'unix://'], '', $this->getUri());
if ($host[0] === '/') {
$port = 0;
} else {
$host = explode(':', $host, 2);
if (\count($host) === 2) {
[$host, $port] = $host;
} else {
$host = $host[0];
$port = MysqlConfig::DEFAULT_PORT;
}
}
$config = new MysqlConfig(
host: $host,
port: (int) $port,
user: $this->getUsername(),
password: $this->getPassword(),
database: $this->getDatabase()
);
return new MysqlSettings(
$config,
match ($this->serializer) {
SerializerType::IGBINARY => new Igbinary,
SerializerType::SERIALIZE => new Native,
null => null
},
$this->cacheTtl,
);
}
}
37 changes: 34 additions & 3 deletions src/Settings/Database/Postgres.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,46 @@

namespace danog\MadelineProto\Settings\Database;

use danog\AsyncOrm\PostgresArrayBytea;
use Amp\Postgres\PostgresConfig;
use danog\AsyncOrm\Serializer\Igbinary;
use danog\AsyncOrm\Serializer\Native;
use danog\AsyncOrm\Settings;
use danog\AsyncOrm\Settings\PostgresSettings;

/**
* Postgres backend settings.
*/
final class Postgres extends SqlAbstract
{
public function getDriverClass(): string
public function getOrmSettings(): Settings
{
return PostgresArrayBytea::class;
$host = str_replace(['tcp://', 'unix://'], '', $this->getUri());
if ($host[0] === '/') {
$port = 0;
} else {
$host = explode(':', $host, 2);
if (\count($host) === 2) {
[$host, $port] = $host;
} else {
$host = $host[0];
$port = PostgresConfig::DEFAULT_PORT;
}
}
$config = new PostgresConfig(
host: $host,
port: (int) $port,
user: $this->getUsername(),
password: $this->getPassword(),
database: $this->getDatabase()
);
return new PostgresSettings(
$config,
match ($this->serializer) {
SerializerType::IGBINARY => new Igbinary,
SerializerType::SERIALIZE => new Native,
null => null
},
$this->cacheTtl,
);
}
}
Loading

0 comments on commit 6eb0954

Please sign in to comment.