This commit is contained in:
Daniil Gentili 2024-03-26 18:32:26 +01:00
parent 4578655304
commit 53c536bf9e
24 changed files with 120 additions and 113 deletions

View File

@ -22,6 +22,7 @@ use Attribute;
use danog\AsyncOrm\KeyType; use danog\AsyncOrm\KeyType;
use danog\AsyncOrm\ValueType; use danog\AsyncOrm\ValueType;
/** @api */
#[Attribute(Attribute::TARGET_PROPERTY)] #[Attribute(Attribute::TARGET_PROPERTY)]
final class OrmMappedArray final class OrmMappedArray
{ {

View File

@ -30,9 +30,16 @@ use Traversable;
* @implements ArrayAccess<TKey, TValue> * @implements ArrayAccess<TKey, TValue>
* @implements Traversable<TKey, TValue> * @implements Traversable<TKey, TValue>
* @implements IteratorAggregate<TKey, TValue> * @implements IteratorAggregate<TKey, TValue>
*
* @api
*/ */
abstract class DbArray implements Countable, ArrayAccess, Traversable, IteratorAggregate abstract class DbArray implements Countable, ArrayAccess, Traversable, IteratorAggregate
{ {
/**
* Check if element exists.
*
* @param TKey $key
*/
final public function isset(string|int $key): bool final public function isset(string|int $key): bool
{ {
return $this->get($key) !== null; return $this->get($key) !== null;
@ -43,19 +50,19 @@ abstract class DbArray implements Countable, ArrayAccess, Traversable, IteratorA
return $this->get($offset); return $this->get($offset);
} }
final public function offsetExists(mixed $index): bool final public function offsetExists(mixed $offset): bool
{ {
return $this->isset($index); return $this->isset($offset);
} }
final public function offsetSet(mixed $index, mixed $value): void final public function offsetSet(mixed $offset, mixed $value): void
{ {
$this->set($index, $value); $this->set($offset, $value);
} }
final public function offsetUnset(mixed $index): void final public function offsetUnset(mixed $offset): void
{ {
$this->unset($index); $this->unset($offset);
} }
public function getArrayCopy(): array public function getArrayCopy(): array

View File

@ -19,7 +19,9 @@
namespace danog\AsyncOrm; namespace danog\AsyncOrm;
use danog\AsyncOrm\Annotations\OrmMappedArray; use danog\AsyncOrm\Annotations\OrmMappedArray;
use danog\AsyncOrm\Internal\Containers\ObjectContainer;
use danog\AsyncOrm\Internal\Driver\CachedArray; use danog\AsyncOrm\Internal\Driver\CachedArray;
use danog\AsyncOrm\Internal\Driver\ObjectArray;
use danog\AsyncOrm\Settings\DriverSettings; use danog\AsyncOrm\Settings\DriverSettings;
use danog\AsyncOrm\Settings\Mysql; use danog\AsyncOrm\Settings\Mysql;
use ReflectionClass; use ReflectionClass;
@ -27,11 +29,10 @@ use ReflectionClass;
use function Amp\async; use function Amp\async;
use function Amp\Future\await; use function Amp\Future\await;
/** @api */
abstract class DbObject abstract class DbObject
{ {
/** @var list<CachedArray> */ private ObjectContainer $mapper;
private array $properties;
private DbArray $mapper;
private string|int $key; private string|int $key;
/** /**
@ -39,55 +40,10 @@ abstract class DbObject
* *
* @internal * @internal
*/ */
final public function initDb(DbArray $mapper, string|int $key, FieldConfig $config): void final public function initDb(ObjectContainer $mapper, string|int $key, FieldConfig $config): void
{ {
$this->mapper = $mapper; $this->mapper = $mapper;
$this->key = $key; $this->key = $key;
$promises = [];
foreach ((new ReflectionClass(static::class))->getProperties() as $property) {
$attr = $property->getAttributes(OrmMappedArray::class);
if (!$attr) {
continue;
}
$attr = $attr[0]->newInstance();
$settings = $config->settings;
if ($settings instanceof DriverSettings) {
$ttl = $attr->cacheTtl ?? $settings->cacheTtl;
if ($ttl !== $settings->cacheTtl) {
$settings = new $settings(\array_merge(
(array) $settings,
['cacheTtl' => $ttl]
));
}
if ($settings instanceof Mysql) {
$optimize = $attr->optimizeIfWastedGtMb ?? $settings->optimizeIfWastedGtMb;
if ($optimize !== $settings->optimizeIfWastedGtMb) {
$settings = new $settings(\array_merge(
(array) $settings,
['optimizeIfWastedGtMb' => $optimize]
));
}
}
}
$config = new FieldConfig(
$config->table.'_'.($attr->tablePostfix ?? $property->getName()),
$settings,
$attr->keyType,
$attr->valueType,
);
$promises[] = async(function () use ($config, $property) {
$v = $config->build($property->getValue());
$property->setValue($v);
if ($v instanceof CachedArray) {
$this->properties []= $v;
}
});
}
await($promises);
} }
/** /**
@ -95,10 +51,21 @@ abstract class DbObject
*/ */
public function save(): void public function save(): void
{ {
$promises = [async($this->mapper->set(...), $this->key, $this)]; $this->onBeforeSave();
foreach ($this->properties as $v) { $this->mapper->inner->set($this->key, $this);
$promises []= async($v->flushCache(...)); $this->onAfterSave();
} }
await($promises);
/**
* Method invoked before saving the object.
*/
protected function onBeforeSave(): void {
}
/**
* Method invoked after saving the object.
*/
protected function onAfterSave(): void {
} }
} }

View File

@ -35,6 +35,8 @@ use function Amp\Future\await;
* @consistent-constructor * @consistent-constructor
* *
* @extends DbArray<TKey, TValue> * @extends DbArray<TKey, TValue>
*
* @api
*/ */
abstract class DriverArray extends DbArray abstract class DriverArray extends DbArray
{ {
@ -44,7 +46,8 @@ abstract class DriverArray extends DbArray
public static function getInstance(FieldConfig $config, DbArray|null $previous): DbArray public static function getInstance(FieldConfig $config, DbArray|null $previous): DbArray
{ {
if ($previous::class === static::class if ($previous !== null
&& $previous::class === static::class
&& $previous->config == $config && $previous->config == $config
) { ) {
return $previous; return $previous;

View File

@ -28,7 +28,8 @@ use danog\AsyncOrm\Settings\Database\Memory;
* *
* @template TKey as array-key * @template TKey as array-key
* @template TValue * @template TValue
* @DbArray DbArray<TKey, TValue> * @extends DbArray<TKey, TValue>
* @api
*/ */
final class MemoryArray extends DbArray final class MemoryArray extends DbArray
{ {
@ -37,7 +38,7 @@ final class MemoryArray extends DbArray
) { ) {
} }
public static function getInstance(FieldConfig $settings, DbArray|null $previous): DbArray public static function getInstance(FieldConfig $config, DbArray|null $previous): DbArray
{ {
if ($previous instanceof self) { if ($previous instanceof self) {
return $previous; return $previous;

View File

@ -29,6 +29,7 @@ use danog\AsyncOrm\Serializer;
* @template TKey as array-key * @template TKey as array-key
* @template TValue * @template TValue
* @extends DriverArray<TKey, TValue> * @extends DriverArray<TKey, TValue>
* @api
*/ */
abstract class SqlArray extends DriverArray abstract class SqlArray extends DriverArray
{ {

View File

@ -3,6 +3,7 @@
namespace danog\AsyncOrm; namespace danog\AsyncOrm;
use danog\AsyncOrm\Internal\Driver\CachedArray; use danog\AsyncOrm\Internal\Driver\CachedArray;
use danog\AsyncOrm\Internal\Driver\ObjectArray;
use danog\AsyncOrm\Settings\DriverSettings; use danog\AsyncOrm\Settings\DriverSettings;
use danog\AsyncOrm\Settings\Memory; use danog\AsyncOrm\Settings\Memory;
@ -40,9 +41,13 @@ final readonly class FieldConfig
|| ( || (
$this->settings instanceof DriverSettings $this->settings instanceof DriverSettings
&& $this->settings->cacheTtl === 0 && $this->settings->cacheTtl === 0
)) { )
) {
return $this->settings->getDriverClass()::getInstance($this, $previous); return $this->settings->getDriverClass()::getInstance($this, $previous);
} }
if ($this->valueType === ValueType::OBJECT) {
return ObjectArray::getInstance($this, $previous);
}
return CachedArray::getInstance($this, $previous); return CachedArray::getInstance($this, $previous);
} }

View File

@ -61,7 +61,7 @@ final class CacheContainer
public function startCacheCleanupLoop(int $cacheTtl): void public function startCacheCleanupLoop(int $cacheTtl): void
{ {
$this->cacheTtl = $cacheTtl; $this->cacheTtl = $cacheTtl;
if ($this->cacheCleanupId) { if ($this->cacheCleanupId !== null) {
EventLoop::cancel($this->cacheCleanupId); EventLoop::cancel($this->cacheCleanupId);
} }
$this->cacheCleanupId = EventLoop::repeat( $this->cacheCleanupId = EventLoop::repeat(
@ -71,7 +71,7 @@ final class CacheContainer
} }
public function stopCacheCleanupLoop(): void public function stopCacheCleanupLoop(): void
{ {
if ($this->cacheCleanupId) { if ($this->cacheCleanupId !== null) {
EventLoop::cancel($this->cacheCleanupId); EventLoop::cancel($this->cacheCleanupId);
$this->cacheCleanupId = null; $this->cacheCleanupId = null;
} }
@ -87,6 +87,7 @@ final class CacheContainer
} }
$result = $this->inner->offsetGet($index); $result = $this->inner->offsetGet($index);
/** @psalm-suppress ParadoxicalCondition Concurrency */
if (isset($this->ttl[$index])) { if (isset($this->ttl[$index])) {
if ($this->ttl[$index] !== true) { if ($this->ttl[$index] !== true) {
$this->ttl[$index] = \time() + $this->cacheTtl; $this->ttl[$index] = \time() + $this->cacheTtl;

View File

@ -22,6 +22,7 @@ use Amp\Sync\LocalMutex;
use danog\AsyncOrm\DbArray; use danog\AsyncOrm\DbArray;
use danog\AsyncOrm\DbObject; use danog\AsyncOrm\DbObject;
use danog\AsyncOrm\FieldConfig; use danog\AsyncOrm\FieldConfig;
use danog\AsyncOrm\Internal\Driver\ObjectArray;
use Revolt\EventLoop; use Revolt\EventLoop;
use Traversable; use Traversable;
@ -61,7 +62,7 @@ final class ObjectContainer
public function startCacheCleanupLoop(int $cacheTtl): void public function startCacheCleanupLoop(int $cacheTtl): void
{ {
$this->cacheTtl = $cacheTtl; $this->cacheTtl = $cacheTtl;
if ($this->cacheCleanupId) { if ($this->cacheCleanupId !== null) {
EventLoop::cancel($this->cacheCleanupId); EventLoop::cancel($this->cacheCleanupId);
} }
$this->cacheCleanupId = EventLoop::repeat( $this->cacheCleanupId = EventLoop::repeat(
@ -71,7 +72,7 @@ final class ObjectContainer
} }
public function stopCacheCleanupLoop(): void public function stopCacheCleanupLoop(): void
{ {
if ($this->cacheCleanupId) { if ($this->cacheCleanupId !== null) {
EventLoop::cancel($this->cacheCleanupId); EventLoop::cancel($this->cacheCleanupId);
$this->cacheCleanupId = null; $this->cacheCleanupId = null;
} }
@ -84,7 +85,7 @@ final class ObjectContainer
$ref = $obj->reference->get(); $ref = $obj->reference->get();
if ($ref !== null) { if ($ref !== null) {
$obj->ttl = \time() + $this->cacheTtl; $obj->ttl = \time() + $this->cacheTtl;
return $obj; return $ref;
} }
unset($this->cache[$index]); unset($this->cache[$index]);
} }
@ -95,7 +96,7 @@ final class ObjectContainer
} }
\assert($result instanceof DbObject); \assert($result instanceof DbObject);
$result->initDb($this->inner, $index, $this->config); $result->initDb($this, $index, $this->config);
$this->cache[$index] = new ObjectReference($result, \time() + $this->cacheTtl); $this->cache[$index] = new ObjectReference($result, \time() + $this->cacheTtl);
@ -107,9 +108,9 @@ final class ObjectContainer
if (isset($this->cache[$key]) && $this->cache[$key]->reference->get() === $value) { if (isset($this->cache[$key]) && $this->cache[$key]->reference->get() === $value) {
return; return;
} }
$value->initDb($this->inner, $key, $this->config); $value->initDb($this, $key, $this->config);
$this->cache[$key] = new ObjectReference($value, \time() + $this->cacheTtl); $this->cache[$key] = new ObjectReference($value, \time() + $this->cacheTtl);
$this->inner->set($key, $value); $value->save();
} }
public function unset(string|int $key): void public function unset(string|int $key): void
@ -122,6 +123,7 @@ final class ObjectContainer
{ {
$this->flushCache(); $this->flushCache();
foreach ($this->inner->getIterator() as $key => $value) { foreach ($this->inner->getIterator() as $key => $value) {
assert($value instanceof DbObject);
if (isset($this->cache[$key])) { if (isset($this->cache[$key])) {
$obj = $this->cache[$key]; $obj = $this->cache[$key];
$ref = $obj->reference->get(); $ref = $obj->reference->get();
@ -131,7 +133,7 @@ final class ObjectContainer
continue; continue;
} }
} }
$value->initDb($this->inner, $key, $this->config); $value->initDb($this, $key, $this->config);
$this->cache[$key] = new ObjectReference($value, \time() + $this->cacheTtl); $this->cache[$key] = new ObjectReference($value, \time() + $this->cacheTtl);
yield $value; yield $value;
} }

View File

@ -55,7 +55,7 @@ final class CachedArray extends DbArray
$previous->cache->flushCache(); $previous->cache->flushCache();
return $previous->cache->inner; return $previous->cache->inner;
} }
$previous->cache->startCacheCleanupLoop($config->cacheTtl); $previous->cache->startCacheCleanupLoop($config->settings->cacheTtl);
return $previous; return $previous;
} }
@ -84,9 +84,9 @@ final class CachedArray extends DbArray
$this->cache->clear(); $this->cache->clear();
} }
public function get(mixed $index): mixed public function get(mixed $key): mixed
{ {
return $this->cache->get($index); return $this->cache->get($key);
} }
public function set(string|int $key, mixed $value): void public function set(string|int $key, mixed $value): void

View File

@ -128,12 +128,12 @@ final class MysqlArray extends SqlArray
" "
); );
$keyType = match ($config->annotation->keyType) { $keyType = match ($config->keyType) {
KeyType::STRING_OR_INT => "VARCHAR(255)", KeyType::STRING_OR_INT => "VARCHAR(255)",
KeyType::STRING => "VARCHAR(255)", KeyType::STRING => "VARCHAR(255)",
KeyType::INT => "BIGINT", KeyType::INT => "BIGINT",
}; };
$valueType = match ($config->annotation->valueType) { $valueType = match ($config->valueType) {
ValueType::INT => "BIGINT", ValueType::INT => "BIGINT",
ValueType::STRING => "VARCHAR(255)", ValueType::STRING => "VARCHAR(255)",
default => "MEDIUMBLOB", default => "MEDIUMBLOB",
@ -143,7 +143,7 @@ final class MysqlArray extends SqlArray
CREATE TABLE IF NOT EXISTS `{$config->table}` CREATE TABLE IF NOT EXISTS `{$config->table}`
( (
`key` $keyType PRIMARY KEY NOT NULL, `key` $keyType PRIMARY KEY NOT NULL,
`value` $valueType NOT NULL, `value` $valueType NOT NULL
) )
ENGINE = InnoDB ENGINE = InnoDB
CHARACTER SET 'utf8mb4' CHARACTER SET 'utf8mb4'
@ -163,6 +163,7 @@ final class MysqlArray extends SqlArray
$expected = $valueType; $expected = $valueType;
} else { } else {
$this->db->query("ALTER TABLE `{$config->table}` DROP `$key`"); $this->db->query("ALTER TABLE `{$config->table}` DROP `$key`");
continue;
} }
if ($expected !== $type || $null !== 'NO') { if ($expected !== $type || $null !== 'NO') {
$this->db->query("ALTER TABLE `{$config->table}` MODIFY `$key` $expected NOT NULL"); $this->db->query("ALTER TABLE `{$config->table}` MODIFY `$key` $expected NOT NULL");

View File

@ -56,7 +56,7 @@ final class ObjectArray extends DbArray
$previous->cache->flushCache(); $previous->cache->flushCache();
return $previous->cache->inner; return $previous->cache->inner;
} }
$previous->cache->startCacheCleanupLoop($config->cacheTtl); $previous->cache->startCacheCleanupLoop($config->settings->cacheTtl);
return $previous; return $previous;
} }
@ -80,9 +80,9 @@ final class ObjectArray extends DbArray
$this->cache->clear(); $this->cache->clear();
} }
public function get(mixed $index): mixed public function get(mixed $key): mixed
{ {
return $this->cache->get($index); return $this->cache->get($key);
} }
public function set(string|int $key, mixed $value): void public function set(string|int $key, mixed $value): void

View File

@ -70,7 +70,7 @@ class PostgresArray extends SqlArray
} }
$connection->close(); $connection->close();
self::$connections[$dbKey] = new PostgresConnectionPool($settings->config, $settings->maxConnections, $settings->idleTimeoutgetIdleTimeout()); self::$connections[$dbKey] = new PostgresConnectionPool($settings->config, $settings->maxConnections, $settings->idleTimeout);
} }
} finally { } finally {
EventLoop::queue($lock->release(...)); EventLoop::queue($lock->release(...));
@ -78,17 +78,17 @@ class PostgresArray extends SqlArray
$connection = self::$connections[$dbKey]; $connection = self::$connections[$dbKey];
$keyType = match ($config->annotation->keyType) { $keyType = match ($config->keyType) {
KeyType::STRING_OR_INT => "VARCHAR(255)", KeyType::STRING_OR_INT => "VARCHAR(255)",
KeyType::STRING => "VARCHAR(255)", KeyType::STRING => "VARCHAR(255)",
KeyType::INT => "BIGINT", KeyType::INT => "BIGINT",
}; };
$valueType = match ($config->annotation->valueType) { $valueType = match ($config->valueType) {
ValueType::INT => "BIGINT", ValueType::INT => "BIGINT",
ValueType::STRING => "VARCHAR(255)", ValueType::STRING => "VARCHAR(255)",
default => "BYTEA", default => "BYTEA",
}; };
$serializer = match ($config->annotation->valueType) { $serializer = match ($config->valueType) {
ValueType::INT, ValueType::STRING => $serializer, ValueType::INT, ValueType::STRING => $serializer,
default => new ByteaSerializer($serializer) default => new ByteaSerializer($serializer)
}; };
@ -114,6 +114,7 @@ class PostgresArray extends SqlArray
$expected = $valueType; $expected = $valueType;
} else { } else {
$this->db->query("ALTER TABLE \"bytea_{$config->table}\" DROP \"$key\""); $this->db->query("ALTER TABLE \"bytea_{$config->table}\" DROP \"$key\"");
continue;
} }
if ($expected !== $type || $null !== 'NO') { if ($expected !== $type || $null !== 'NO') {
$this->db->query("ALTER TABLE \"bytea_{$config->table}\" MODIFY \"$key\" $expected NOT NULL"); $this->db->query("ALTER TABLE \"bytea_{$config->table}\" MODIFY \"$key\" $expected NOT NULL");

View File

@ -51,7 +51,7 @@ final class RedisArray extends DriverArray
public function __construct(FieldConfig $config, Serializer $serializer) public function __construct(FieldConfig $config, Serializer $serializer)
{ {
if ($serializer instanceof Passthrough && $config->annotation->valueType === ValueType::INT) { if ($serializer instanceof Passthrough && $config->valueType === ValueType::INT) {
$serializer = new IntString; $serializer = new IntString;
} }
parent::__construct($config, $serializer); parent::__construct($config, $serializer);
@ -60,7 +60,6 @@ final class RedisArray extends DriverArray
\assert($config->settings instanceof Redis); \assert($config->settings instanceof Redis);
$dbKey = $config->settings->getDbIdentifier(); $dbKey = $config->settings->getDbIdentifier();
$lock = self::$mutex->acquire($dbKey); $lock = self::$mutex->acquire($dbKey);
\assert($config->settings instanceof Redis);
try { try {
if (!isset(self::$connections[$dbKey])) { if (!isset(self::$connections[$dbKey])) {
@ -84,8 +83,10 @@ final class RedisArray extends DriverArray
foreach ($request as $oldKey) { foreach ($request as $oldKey) {
$newKey = $to.\substr($oldKey, $lenK); $newKey = $to.\substr($oldKey, $lenK);
$value = $this->db->get($oldKey); $value = $this->db->get($oldKey);
$this->db->set($newKey, $value); if ($value !== null) {
$this->db->delete($oldKey); $this->db->set($newKey, $value);
$this->db->delete($oldKey);
}
} }
} }
@ -110,11 +111,11 @@ final class RedisArray extends DriverArray
$this->db->set($this->rKey((string) $key), $this->serializer->serialize($value)); $this->db->set($this->rKey((string) $key), $this->serializer->serialize($value));
} }
public function get(mixed $offset): mixed public function get(mixed $key): mixed
{ {
$offset = (string) $offset; $key = (string) $key;
$value = $this->db->get($this->rKey($offset)); $value = $this->db->get($this->rKey($key));
if ($value !== null) { if ($value !== null) {
$value = $this->serializer->deserialize($value); $value = $this->serializer->deserialize($value);

View File

@ -30,6 +30,7 @@ final class ByteaSerializer implements Serializer
} }
public function serialize(mixed $value): mixed public function serialize(mixed $value): mixed
{ {
/** @psalm-suppress MixedArgument */
return new PostgresByteA($this->inner->serialize($value)); return new PostgresByteA($this->inner->serialize($value));
} }
public function deserialize(mixed $value): mixed public function deserialize(mixed $value): mixed

View File

@ -20,7 +20,11 @@ namespace danog\AsyncOrm\Serializer;
use danog\AsyncOrm\Serializer; use danog\AsyncOrm\Serializer;
/** Igbinary serializer. */ /**
* Igbinary serializer.
*
* @api
*/
final class Igbinary implements Serializer final class Igbinary implements Serializer
{ {
public function serialize(mixed $value): mixed public function serialize(mixed $value): mixed
@ -29,6 +33,7 @@ final class Igbinary implements Serializer
} }
public function deserialize(mixed $value): mixed public function deserialize(mixed $value): mixed
{ {
assert(is_string($value));
return \igbinary_unserialize($value); return \igbinary_unserialize($value);
} }
} }

View File

@ -20,7 +20,11 @@ namespace danog\AsyncOrm\Serializer;
use danog\AsyncOrm\Serializer; use danog\AsyncOrm\Serializer;
/** Integer casting serializer */ /**
* Integer casting serializer
*
* @api
*/
final class IntString implements Serializer final class IntString implements Serializer
{ {
public function serialize(mixed $value): mixed public function serialize(mixed $value): mixed

View File

@ -20,7 +20,11 @@ namespace danog\AsyncOrm\Serializer;
use danog\AsyncOrm\Serializer; use danog\AsyncOrm\Serializer;
/** JSON serializer */ /**
* JSON serializer
*
* @api
*/
final class Json implements Serializer final class Json implements Serializer
{ {
public function serialize(mixed $value): mixed public function serialize(mixed $value): mixed
@ -29,6 +33,7 @@ final class Json implements Serializer
} }
public function deserialize(mixed $value): mixed public function deserialize(mixed $value): mixed
{ {
assert(is_string($value));
return \json_decode($value, true, flags: JSON_THROW_ON_ERROR); return \json_decode($value, true, flags: JSON_THROW_ON_ERROR);
} }
} }

View File

@ -20,7 +20,11 @@ namespace danog\AsyncOrm\Serializer;
use danog\AsyncOrm\Serializer; use danog\AsyncOrm\Serializer;
/** Native serializer */ /**
* Native serializer
*
* @api
*/
final class Native implements Serializer final class Native implements Serializer
{ {
public function serialize(mixed $value): mixed public function serialize(mixed $value): mixed
@ -29,6 +33,7 @@ final class Native implements Serializer
} }
public function deserialize(mixed $value): mixed public function deserialize(mixed $value): mixed
{ {
assert(is_string($value));
return \unserialize($value); return \unserialize($value);
} }
} }

View File

@ -20,7 +20,11 @@ namespace danog\AsyncOrm\Serializer;
use danog\AsyncOrm\Serializer; use danog\AsyncOrm\Serializer;
/** Passthrough serializer */ /**
* Passthrough serializer
*
* @api
*/
final class Passthrough implements Serializer final class Passthrough implements Serializer
{ {
public function serialize(mixed $value): mixed public function serialize(mixed $value): mixed

View File

@ -30,6 +30,7 @@ use danog\AsyncOrm\Serializer;
final readonly class Mysql extends SqlSettings final readonly class Mysql extends SqlSettings
{ {
/** /**
* @api
* @param Serializer $serializer to use for object and mixed type values. * @param Serializer $serializer to use for object and mixed type values.
* @param int<0, max> $cacheTtl Cache TTL in seconds, if 0 disables caching. * @param int<0, max> $cacheTtl Cache TTL in seconds, if 0 disables caching.
* @param int<1, max> $maxConnections Maximum connection limit * @param int<1, max> $maxConnections Maximum connection limit

View File

@ -17,8 +17,8 @@
namespace danog\AsyncOrm\Settings; namespace danog\AsyncOrm\Settings;
use Amp\Postgres\PostgresConfig; use Amp\Postgres\PostgresConfig;
use Amp\Serialization\Serializer;
use danog\AsyncOrm\Internal\Driver\PostgresArray; use danog\AsyncOrm\Internal\Driver\PostgresArray;
use danog\AsyncOrm\Serializer;
/** /**
* Postgres backend settings. * Postgres backend settings.
@ -27,6 +27,7 @@ use danog\AsyncOrm\Internal\Driver\PostgresArray;
final readonly class Postgres extends SqlSettings final readonly class Postgres extends SqlSettings
{ {
/** /**
* @api
* @param Serializer $serializer to use for object and mixed type values. * @param Serializer $serializer to use for object and mixed type values.
* @param int<0, max> $cacheTtl Cache TTL in seconds * @param int<0, max> $cacheTtl Cache TTL in seconds
* @param int<1, max> $maxConnections Maximum connection limit * @param int<1, max> $maxConnections Maximum connection limit

View File

@ -26,6 +26,8 @@ use danog\AsyncOrm\Serializer;
final readonly class Redis extends DriverSettings final readonly class Redis extends DriverSettings
{ {
/** /**
* @api
*
* @param Serializer $serializer to use for object and mixed type values. * @param Serializer $serializer to use for object and mixed type values.
* @param int<0, max> $cacheTtl Cache TTL in seconds * @param int<0, max> $cacheTtl Cache TTL in seconds
*/ */
@ -34,7 +36,7 @@ final readonly class Redis extends DriverSettings
Serializer $serializer, Serializer $serializer,
int $cacheTtl = self::DEFAULT_CACHE_TTL, int $cacheTtl = self::DEFAULT_CACHE_TTL,
) { ) {
parent::__construct($cacheTtl, $serializer); parent::__construct($serializer, $cacheTtl);
} }
/** @internal */ /** @internal */
public function getDbIdentifier(): string public function getDbIdentifier(): string

View File

@ -28,18 +28,6 @@ abstract readonly class SqlSettings extends DriverSettings
{ {
final public const DEFAULT_SQL_MAX_CONNECTIONS = 100; final public const DEFAULT_SQL_MAX_CONNECTIONS = 100;
final public const DEFAULT_SQL_IDLE_TIMEOUT = 60; final public const DEFAULT_SQL_IDLE_TIMEOUT = 60;
/**
* Database password.
*/
public string $database;
/**
* Database username.
*/
public string $username;
/**
* Database password.
*/
public string $password;
/** /**
* Maximum connection limit. * Maximum connection limit.
* *
@ -76,6 +64,6 @@ abstract readonly class SqlSettings extends DriverSettings
{ {
$host = $this->config->getHost(); $host = $this->config->getHost();
$port = $this->config->getPort(); $port = $this->config->getPort();
return "$host:$port:".$this->config->getDatabase(); return "$host:$port:".(string)$this->config->getDatabase();
} }
} }