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 # Async ORM
[![codecov](https://codecov.io/gh/danog/AsyncOrm/branch/master/graph/badge.svg)](https://codecov.io/gh/danog/AsyncOrm) [![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 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) [![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>. 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" xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true" findUnusedBaselineEntry="true"
findUnusedPsalmSuppress="true"
findUnusedCode="true" findUnusedCode="true"
errorBaseline="psalm-baseline.xml"
> >
<projectFiles> <projectFiles>
<directory name="src" /> <directory name="src" />

View File

@ -118,6 +118,12 @@ abstract class DbArray implements Countable, ArrayAccess, Traversable, IteratorA
/** /**
* Get instance. * 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; abstract public static function getInstance(DbArrayBuilder $config, self|null $previous): self;
} }

View File

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

View File

@ -58,9 +58,16 @@ abstract class DriverArray extends DbArray
$this->inited = true; $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 public static function getInstance(DbArrayBuilder $config, DbArray|null $previous): DbArray
{ {
$migrate = true; $migrate = true;
/** @psalm-suppress DocblockTypeContradiction TODO fix in psalm */
if ($previous !== null if ($previous !== null
&& $previous::class === static::class && $previous::class === static::class
&& $previous->config == $config && $previous->config == $config
@ -72,12 +79,14 @@ abstract class DriverArray extends DbArray
} }
\assert($config->settings instanceof DriverSettings); \assert($config->settings instanceof DriverSettings);
/** @var DbArray<TTKey, TTValue> */
$instance = new static($config, $config->settings->serializer); $instance = new static($config, $config->settings->serializer);
if ($previous === null || !$migrate) { if ($previous === null || !$migrate) {
return $instance; return $instance;
} }
/** @psalm-suppress DocblockTypeContradiction TODO fix in psalm */
if ($previous instanceof SqlArray if ($previous instanceof SqlArray
&& $instance instanceof SqlArray && $instance instanceof SqlArray
&& $previous::class === $instance::class && $previous::class === $instance::class
@ -85,7 +94,6 @@ abstract class DriverArray extends DbArray
$instance->importFromTable($previous->config->table); $instance->importFromTable($previous->config->table);
} else { } else {
$promises = []; $promises = [];
/** @psalm-suppress MixedAssignment */
foreach ($previous->getIterator() as $key => $value) { foreach ($previous->getIterator() as $key => $value) {
$promises []= async($previous->unset(...), $key) $promises []= async($previous->unset(...), $key)
->map(static fn () => $instance->set($key, $value)); ->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 public function set(string|int $key, mixed $value): void
{ {
$key = (string) $key; $key = (string) $key;
/** @var scalar */
$value = $this->serializer->serialize($value);
$this->execute( $this->execute(
$this->set, $this->set,
[ [
'index' => $key, 'index' => $key,
'value' => $this->serializer->serialize($value), 'value' => $value,
], ],
); );
} }
@ -124,8 +126,7 @@ abstract class SqlArray extends DriverArray
{ {
$row = $this->execute($this->count); $row = $this->execute($this->count);
$res = $row->fetchRow(); $res = $row->fetchRow();
\assert($res !== null); \assert($res !== null && isset($res['count']) && \is_int($res['count']));
/** @var int */
return $res['count']; return $res['count'];
} }
@ -139,7 +140,7 @@ abstract class SqlArray extends DriverArray
/** /**
* Perform async request to db. * Perform async request to db.
* * @param array<string, scalar> $params
*/ */
protected function execute(string $sql, array $params = []): SqlResult protected function execute(string $sql, array $params = []): SqlResult
{ {

View File

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

View File

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

View File

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

View File

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