1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-12-03 20:57:48 +01:00
MadelineProto/src/Db/PostgresArray.php

133 lines
4.0 KiB
PHP
Raw Normal View History

2022-12-30 21:54:44 +01:00
<?php
declare(strict_types=1);
2020-07-30 19:51:16 +02:00
namespace danog\MadelineProto\Db;
2023-05-02 18:42:46 +02:00
use Amp\Postgres\ByteA;
2023-01-11 21:06:10 +01:00
use Amp\Postgres\PostgresConfig;
use danog\MadelineProto\Db\Driver\Postgres;
2020-11-26 21:49:31 +01:00
use danog\MadelineProto\Exception;
2020-07-30 19:51:16 +02:00
use danog\MadelineProto\Logger;
use danog\MadelineProto\Settings\Database\Postgres as DatabasePostgres;
2023-05-02 18:42:46 +02:00
use danog\MadelineProto\Settings\Database\SerializerType;
2022-12-30 19:21:36 +01:00
use PDO;
/**
* Postgres database backend.
2023-01-25 16:32:48 +01:00
*
* @internal
* @template TKey as array-key
* @template TValue
2023-01-25 16:37:15 +01:00
* @extends SqlArray<TKey, TValue>
*/
class PostgresArray extends SqlArray
2020-07-30 19:51:16 +02:00
{
// Legacy
protected array $settings;
/**
* Prepare statements.
*
2023-01-14 19:18:23 +01:00
* @param SqlArray::SQL_* $type
*/
2021-02-27 20:58:01 +01:00
protected function getSqlQuery(int $type): string
{
2020-11-26 21:49:31 +01:00
switch ($type) {
2022-12-08 20:16:40 +01:00
case SqlArray::SQL_GET:
return "SELECT value FROM \"{$this->table}\" WHERE key = :index";
case SqlArray::SQL_SET:
return "
2020-11-26 21:49:31 +01:00
INSERT INTO \"{$this->table}\"
(key,value)
VALUES (:index, :value)
ON CONFLICT (key) DO UPDATE SET value = :value
2021-02-27 20:58:01 +01:00
";
2022-12-08 20:16:40 +01:00
case SqlArray::SQL_UNSET:
return "
2020-11-26 21:49:31 +01:00
DELETE FROM \"{$this->table}\"
WHERE key = :index
2021-02-27 20:58:01 +01:00
";
2022-12-08 20:16:40 +01:00
case SqlArray::SQL_COUNT:
return "
2020-11-26 21:49:31 +01:00
SELECT count(key) as count FROM \"{$this->table}\"
2021-02-27 20:58:01 +01:00
";
2022-12-08 20:16:40 +01:00
case SqlArray::SQL_ITERATE:
return "
2020-11-26 21:49:31 +01:00
SELECT key, value FROM \"{$this->table}\"
2021-02-27 20:58:01 +01:00
";
2022-12-08 20:16:40 +01:00
case SqlArray::SQL_CLEAR:
return "
2020-11-26 21:49:31 +01:00
DELETE FROM \"{$this->table}\"
2021-02-27 20:58:01 +01:00
";
2020-11-26 21:49:31 +01:00
}
throw new Exception("An invalid statement type $type was provided!");
}
/**
* Initialize on startup.
*/
2023-01-03 22:07:58 +01:00
public function initStartup(): void
{
2022-06-25 19:15:30 +02:00
$this->setTable($this->table);
$this->initConnection($this->dbSettings);
}
/**
* Initialize connection.
*/
2023-01-03 22:07:58 +01:00
public function initConnection(DatabasePostgres $settings): void
2020-09-12 19:06:42 +02:00
{
2023-01-11 21:06:10 +01:00
$config = PostgresConfig::fromString('host='.\str_replace('tcp://', '', $settings->getUri()));
2021-04-07 00:13:59 +02:00
$host = $config->getHost();
$port = $config->getPort();
2022-12-30 19:21:36 +01:00
$this->pdo = new PDO(
2021-04-25 16:50:19 +02:00
"pgsql:host={$host};port={$port}",
2021-02-27 22:24:55 +01:00
$settings->getUsername(),
2022-12-30 19:21:36 +01:00
$settings->getPassword(),
2021-02-27 22:24:55 +01:00
);
2020-09-12 19:06:42 +02:00
if (!isset($this->db)) {
$this->db = Postgres::getConnection($settings);
2020-09-12 19:06:42 +02:00
}
}
2023-05-02 18:42:46 +02:00
protected function setSerializer(SerializerType $serializer): void
{
2023-05-02 18:42:46 +02:00
$this->serializer = match ($serializer) {
SerializerType::SERIALIZE => fn ($v) => new ByteA(\serialize($v)),
SerializerType::IGBINARY => fn ($v) => new ByteA(\igbinary_serialize($v)),
SerializerType::JSON => fn ($value) => \json_encode($value, JSON_THROW_ON_ERROR|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES),
SerializerType::STRING => strval(...),
};
$this->deserializer = match ($serializer) {
SerializerType::SERIALIZE => \unserialize(...),
SerializerType::IGBINARY => \igbinary_unserialize(...),
SerializerType::JSON => fn ($value) => \json_decode($value, true, 256, JSON_THROW_ON_ERROR),
SerializerType::STRING => fn ($v) => $v,
};
}
2020-07-30 19:51:16 +02:00
/**
* Create table for property.
*/
2023-01-03 22:07:58 +01:00
protected function prepareTable(): void
2020-07-30 19:51:16 +02:00
{
Logger::log("Creating/checking table {$this->table}", Logger::WARNING);
$this->db->query("
2020-07-30 19:51:16 +02:00
CREATE TABLE IF NOT EXISTS \"{$this->table}\"
(
2022-06-25 19:15:30 +02:00
\"key\" VARCHAR(255) PRIMARY KEY NOT NULL,
2023-05-02 18:42:46 +02:00
\"value\" BYTEA NOT NULL
);
2020-07-30 19:51:16 +02:00
");
}
2023-01-03 22:07:58 +01:00
protected function renameTable(string $from, string $to): void
2020-07-30 19:51:16 +02:00
{
Logger::log("Moving data from {$from} to {$to}", Logger::WARNING);
2020-10-23 18:19:20 +02:00
$this->db->query(/** @lang PostgreSQL */ "
2022-06-25 19:29:01 +02:00
ALTER TABLE \"$from\" RENAME TO \"$to\";
2020-07-30 19:51:16 +02:00
");
}
}