Psalm fixes

This commit is contained in:
Daniil Gentili 2024-03-31 20:12:14 +02:00
parent ed96334674
commit ec92e9928d
11 changed files with 79 additions and 18 deletions

View File

@ -1,10 +1,9 @@
# Async ORM
[![codecov](https://codecov.io/gh/danog/AsyncOrm/branch/master/graph/badge.svg)](https://codecov.io/gh/danog/AsyncOrm)
[![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fdanog%2Floop%2Fmaster)](https://dashboard.stryker-mutator.io/r>
[![Psalm coverage](https://shepherd.dev/github/danog/AsyncOrm/coverage.svg)](https://shepherd.dev/github/danog/AsyncOrm)
[![Psalm level 1](https://shepherd.dev/github/danog/AsyncOrm/level.svg)](https://shepherd.dev/github/danog/AsyncOrm)
![License](https://img.shields.io/badge/license-MIT-blue.svg)
![License](https://img.shields.io/badge/license-Apache-2.0-blue.svg)
Async ORM based on AMPHP v3 and fibers, created by Daniil Gentili <daniil@daniil.it> and Alexander Pankratov <alexander@i-c-a.su>.

33
psalm-baseline.xml Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="dev-master@ef3b018e89c4ffc157332c13e2ebf9cf22320d17">
<file src="src/Driver/DriverArray.php">
<ImplementedParamTypeMismatch>
<code><![CDATA[$previous]]></code>
</ImplementedParamTypeMismatch>
<ImplementedReturnTypeMismatch>
<code><![CDATA[DbArray<TTKey, TTValue>]]></code>
</ImplementedReturnTypeMismatch>
</file>
<file src="src/Driver/MemoryArray.php">
<DocblockTypeContradiction>
<code><![CDATA[$previous instanceof self]]></code>
</DocblockTypeContradiction>
</file>
<file src="src/Internal/Driver/CachedArray.php">
<DocblockTypeContradiction>
<code><![CDATA[$previous instanceof self]]></code>
</DocblockTypeContradiction>
</file>
<file src="src/Internal/Driver/ObjectArray.php">
<DocblockTypeContradiction>
<code><![CDATA[$previous instanceof self]]></code>
</DocblockTypeContradiction>
<MixedArgumentTypeCoercion>
<code><![CDATA[$new::getInstance($config, $previous)]]></code>
<code><![CDATA[$new::getInstance($config, null)]]></code>
</MixedArgumentTypeCoercion>
<MixedPropertyTypeCoercion>
<code><![CDATA[$new::getInstance($config, $previous->cache->inner)]]></code>
</MixedPropertyTypeCoercion>
</file>
</files>

View File

@ -6,7 +6,9 @@
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true"
findUnusedPsalmSuppress="true"
findUnusedCode="true"
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="src" />

View File

@ -118,6 +118,12 @@ abstract class DbArray implements Countable, ArrayAccess, Traversable, IteratorA
/**
* Get instance.
*
* @template TTKey as array-key
* @template TTValue as DbObject
*
* @param DbArray<TTKey, TValue>|null $previous
* @return DbArray<TTKey, TValue>
*/
abstract public static function getInstance(DbArrayBuilder $config, self|null $previous): self;
}

View File

@ -58,6 +58,12 @@ final readonly class DbArrayBuilder
/**
* Build database array.
*
* @template TKey as array-key
* @template TValue
*
* @param DbArray<TKey, TValue>|null $previous
* @return DbArray<TKey, TValue>
*/
public function build(?DbArray $previous = null): DbArray
{
@ -68,6 +74,7 @@ final readonly class DbArrayBuilder
if ($this->settings->serializer instanceof Json) {
throw new AssertionError("The JSON backend cannot be used when serializing objects!");
}
/** @psalm-suppress MixedArgumentTypeCoercion */
return ObjectArray::getInstance($this, $previous);
}
if ($this->settings instanceof MemorySettings

View File

@ -58,9 +58,16 @@ abstract class DriverArray extends DbArray
$this->inited = true;
}
/**
* @template TTKey as array-key
* @template TTValue
* @param DbArray<TTKey, TTValue> $previous
* @return DbArray<TTKey, TTValue>
*/
public static function getInstance(DbArrayBuilder $config, DbArray|null $previous): DbArray
{
$migrate = true;
/** @psalm-suppress DocblockTypeContradiction TODO fix in psalm */
if ($previous !== null
&& $previous::class === static::class
&& $previous->config == $config
@ -72,12 +79,14 @@ abstract class DriverArray extends DbArray
}
\assert($config->settings instanceof DriverSettings);
/** @var DbArray<TTKey, TTValue> */
$instance = new static($config, $config->settings->serializer);
if ($previous === null || !$migrate) {
return $instance;
}
/** @psalm-suppress DocblockTypeContradiction TODO fix in psalm */
if ($previous instanceof SqlArray
&& $instance instanceof SqlArray
&& $previous::class === $instance::class
@ -85,7 +94,6 @@ abstract class DriverArray extends DbArray
$instance->importFromTable($previous->config->table);
} else {
$promises = [];
/** @psalm-suppress MixedAssignment */
foreach ($previous->getIterator() as $key => $value) {
$promises []= async($previous->unset(...), $key)
->map(static fn () => $instance->set($key, $value));

View File

@ -88,12 +88,14 @@ abstract class SqlArray extends DriverArray
public function set(string|int $key, mixed $value): void
{
$key = (string) $key;
/** @var scalar */
$value = $this->serializer->serialize($value);
$this->execute(
$this->set,
[
'index' => $key,
'value' => $this->serializer->serialize($value),
'value' => $value,
],
);
}
@ -124,8 +126,7 @@ abstract class SqlArray extends DriverArray
{
$row = $this->execute($this->count);
$res = $row->fetchRow();
\assert($res !== null);
/** @var int */
\assert($res !== null && isset($res['count']) && \is_int($res['count']));
return $res['count'];
}
@ -139,7 +140,7 @@ abstract class SqlArray extends DriverArray
/**
* Perform async request to db.
*
* @param array<string, scalar> $params
*/
protected function execute(string $sql, array $params = []): SqlResult
{

View File

@ -82,8 +82,10 @@ final class MysqlArray extends SqlArray
COLLATE 'utf8mb4_general_ci'
");
try {
/** @psalm-suppress PossiblyNullArrayAccess */
$max = (int) $connection->query("SHOW VARIABLES LIKE 'max_connections'")->fetchRow()['Value'];
$max = $connection->query("SHOW VARIABLES LIKE 'max_connections'")->fetchRow();
\assert(\is_array($max));
$max = $max['Value'] ?? null;
\assert(\is_int($max));
if ($max < 100000) {
$connection->query("SET GLOBAL max_connections = 100000");
}
@ -219,11 +221,9 @@ final class MysqlArray extends SqlArray
/**
* Perform async request to db.
*
*/
protected function execute(string $sql, array $params = []): SqlResult
{
/** @psalm-suppress MixedAssignment */
foreach ($params as $key => $value) {
if (\is_string($value)) {
$value = $this->pdo->quote($value);

View File

@ -50,28 +50,33 @@ final class ObjectArray extends DbArray
/**
* Get instance.
*
* @template TTKey as array-key
* @template TTValue as DbObject
*
* @param DbArray<TTKey, TValue>|null $previous
* @return DbArray<TTKey, TValue>
*/
public static function getInstance(DbArrayBuilder $config, DbArray|null $previous): DbArray
{
$new = $config->settings->getDriverClass();
\assert($config->settings instanceof DriverSettings);
if ($previous === null) {
/** @psalm-suppress MixedArgumentTypeCoercion */
$previous = new self($new::getInstance($config, null), $config, $config->settings->cacheTtl);
} elseif ($previous instanceof self) {
/** @psalm-suppress MixedPropertyTypeCoercion, InvalidArgument */
$previous->cache->inner = $new::getInstance($config, $previous->cache->inner);
$previous->cache->config = $config;
$previous->cache->cacheTtl = $config->settings->cacheTtl;
} else {
/** @psalm-suppress MixedArgumentTypeCoercion */
$previous = new self($new::getInstance($config, $previous), $config, $config->settings->cacheTtl);
}
if ($previous->cache->inner instanceof MemoryArray) {
$previous->cache->flushCache();
/** @var DbArray<TTKey, TValue> */
return $previous->cache->inner;
}
$previous->cache->startCacheCleanupLoop();
/** @var DbArray<TTKey, TValue> */
return $previous;
}

View File

@ -95,8 +95,9 @@ final class RedisArray extends DriverArray
public function set(string|int $key, mixed $value): void
{
/** @psalm-suppress MixedArgument The serializer always produces a string */
$this->db->set($this->config->table.':'.(string) $key, $this->serializer->serialize($value));
/** @var string */
$value = $this->serializer->serialize($value);
$this->db->set($this->config->table.':'.(string) $key, $value);
}
public function get(string|int $key): mixed

View File

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