diff --git a/composer.json b/composer.json index 126f127..bdefceb 100644 --- a/composer.json +++ b/composer.json @@ -42,9 +42,9 @@ "nyholm/psr7": "^1.2", "php-http/message-factory": "^1.1", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.0.0", - "phpstan/phpstan-strict-rules": "^1.0.0", + "phpstan/phpstan": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0.0", + "phpstan/phpstan-strict-rules": "^2.0.0", "phpunit/phpunit": "^11.0", "symfony/http-client": "^7.0" }, diff --git a/src/Client/Http/RequestFactory.php b/src/Client/Http/RequestFactory.php index 863ce5f..4c74502 100644 --- a/src/Client/Http/RequestFactory.php +++ b/src/Client/Http/RequestFactory.php @@ -82,7 +82,8 @@ public function prepareRequest(RequestOptions $requestOptions): RequestInterface } } - $typeToParam = array_reduce( + /** @var array $paramToType */ + $paramToType = array_reduce( array_keys($matches[1]), static function (array $acc, string|int $k) use ($matches) { $acc[$matches[1][$k]] = Type::fromString($matches[2][$k]); @@ -94,7 +95,7 @@ static function (array $acc, string|int $k) use ($matches) { $streamElements = [['name' => 'query', 'contents' => $requestOptions->sql]]; foreach ($requestOptions->params as $name => $value) { - $type = $typeToParam[$name] ?? null; + $type = $paramToType[$name] ?? null; if ($type === null) { continue; } diff --git a/src/Format/Json.php b/src/Format/Json.php index 9f68bec..ebc42ae 100644 --- a/src/Format/Json.php +++ b/src/Format/Json.php @@ -16,7 +16,10 @@ final class Json implements Format /** @throws JsonException */ public static function output(string $contents): Output { - return new \SimPod\ClickHouseClient\Output\Json($contents); + /** @var \SimPod\ClickHouseClient\Output\Json $output */ + $output = new \SimPod\ClickHouseClient\Output\Json($contents); + + return $output; } public static function toSql(): string diff --git a/src/Format/JsonCompact.php b/src/Format/JsonCompact.php index c901cc0..9f986ea 100644 --- a/src/Format/JsonCompact.php +++ b/src/Format/JsonCompact.php @@ -16,7 +16,10 @@ final class JsonCompact implements Format /** @throws JsonException */ public static function output(string $contents): Output { - return new \SimPod\ClickHouseClient\Output\JsonCompact($contents); + /** @var \SimPod\ClickHouseClient\Output\JsonCompact $output */ + $output = new \SimPod\ClickHouseClient\Output\JsonCompact($contents); + + return $output; } public static function toSql(): string diff --git a/src/Format/JsonEachRow.php b/src/Format/JsonEachRow.php index 9f2aa8d..819d35a 100644 --- a/src/Format/JsonEachRow.php +++ b/src/Format/JsonEachRow.php @@ -16,7 +16,10 @@ final class JsonEachRow implements Format /** @throws JsonException */ public static function output(string $contents): Output { - return new \SimPod\ClickHouseClient\Output\JsonEachRow($contents); + /** @var \SimPod\ClickHouseClient\Output\JsonEachRow $output */ + $output = new \SimPod\ClickHouseClient\Output\JsonEachRow($contents); + + return $output; } public static function toSql(): string diff --git a/src/Format/Null_.php b/src/Format/Null_.php index edbcfbe..5766ccb 100644 --- a/src/Format/Null_.php +++ b/src/Format/Null_.php @@ -16,7 +16,10 @@ final class Null_ implements Format { public static function output(string $contents): Output { - return new \SimPod\ClickHouseClient\Output\Null_($contents); + /** @var \SimPod\ClickHouseClient\Output\Null_ $output */ + $output = new \SimPod\ClickHouseClient\Output\Null_($contents); + + return $output; } public static function toSql(): string diff --git a/src/Format/Pretty.php b/src/Format/Pretty.php index c744539..3978bb0 100644 --- a/src/Format/Pretty.php +++ b/src/Format/Pretty.php @@ -15,7 +15,10 @@ final class Pretty implements Format { public static function output(string $contents): Output { - return new Basic($contents); + /** @var Basic $output */ + $output = new Basic($contents); + + return $output; } public static function toSql(): string diff --git a/src/Format/PrettySpace.php b/src/Format/PrettySpace.php index 09c7c76..c0da02d 100644 --- a/src/Format/PrettySpace.php +++ b/src/Format/PrettySpace.php @@ -15,7 +15,10 @@ final class PrettySpace implements Format { public static function output(string $contents): Output { - return new Basic($contents); + /** @var Basic $output */ + $output = new Basic($contents); + + return $output; } public static function toSql(): string diff --git a/src/Format/TabSeparated.php b/src/Format/TabSeparated.php index a0f14e2..5944855 100644 --- a/src/Format/TabSeparated.php +++ b/src/Format/TabSeparated.php @@ -15,7 +15,10 @@ final class TabSeparated implements Format { public static function output(string $contents): Output { - return new Basic($contents); + /** @var Basic $output */ + $output = new Basic($contents); + + return $output; } public static function toSql(): string diff --git a/src/Output/Json.php b/src/Output/Json.php index 6ae8e89..4a96cab 100644 --- a/src/Output/Json.php +++ b/src/Output/Json.php @@ -25,7 +25,7 @@ final class Json implements Output public int $rows; - public int|null $rowsBeforeLimitAtLeast = null; + public int|null $rowsBeforeLimitAtLeast; /** @var array{elapsed: float, rows_read: int, bytes_read: int} */ public array $statistics; diff --git a/src/Output/JsonCompact.php b/src/Output/JsonCompact.php index 959b83e..782f3fe 100644 --- a/src/Output/JsonCompact.php +++ b/src/Output/JsonCompact.php @@ -25,7 +25,7 @@ final class JsonCompact implements Output public int $rows; - public int|null $rowsBeforeLimitAtLeast = null; + public int|null $rowsBeforeLimitAtLeast; /** @var array{elapsed: float, rows_read: int, bytes_read: int} */ public array $statistics; diff --git a/src/Param/ParamValueConverterRegistry.php b/src/Param/ParamValueConverterRegistry.php index fa102bf..0dd7859 100644 --- a/src/Param/ParamValueConverterRegistry.php +++ b/src/Param/ParamValueConverterRegistry.php @@ -51,14 +51,22 @@ final class ParamValueConverterRegistry public function __construct() { $formatPoint = static fn (array $point) => sprintf('(%s)', implode(',', $point)); - $formatRing = static fn (array $v) => sprintf('[%s]', implode( - ',', - array_map($formatPoint, $v), - )); - $formatPolygon = static fn (array $v) => sprintf('[%s]', implode( - ',', - array_map($formatRing, $v), - )); + // phpcs:ignore SlevomatCodingStandard.Functions.RequireArrowFunction.RequiredArrowFunction + $formatRing = static function (array $v) use ($formatPoint) { + /** @phpstan-var array> $v */ + return sprintf('[%s]', implode( + ',', + array_map($formatPoint, $v), + )); + }; + // phpcs:ignore SlevomatCodingStandard.Functions.RequireArrowFunction.RequiredArrowFunction + $formatPolygon = static function (array $v) use ($formatRing) { + /** @phpstan-var array> $v */ + return sprintf('[%s]', implode( + ',', + array_map($formatRing, $v), + )); + }; /** @phpstan-var array $registry */ $registry = [ @@ -105,6 +113,7 @@ public function __construct() $types = array_map(static fn ($type) => explode(' ', trim($type))[1], $this->splitTypes($type->params)); + /** @phpstan-var array> $v */ return sprintf('[%s]', implode(',', array_map( fn (array $row) => sprintf('(%s)', implode(',', array_map( fn (int|string $i) => $this->get($types[$i])($row[$i], $types[$i], true), @@ -154,10 +163,14 @@ public function __construct() : $formatPolygon($v), 'MultiPolygon' => static fn (string|array $v) => is_string($v) ? $v - : (static fn (array $vv) => sprintf('[%s]', implode( - ',', - array_map($formatPolygon, $vv), - )))($v), + // phpcs:ignore SlevomatCodingStandard.Functions.RequireArrowFunction.RequiredArrowFunction + : (static function (array $vv) use ($formatPolygon) { + /** @phpstan-var array> $vv */ + return sprintf('[%s]', implode( + ',', + array_map($formatPolygon, $vv), + )); + })($v), 'Array' => fn (array|string $v, Type $type) => is_string($v) ? $v @@ -194,7 +207,7 @@ public function __construct() /** * @phpstan-return Converter * - * @throws UnsupportedParamType; + * @throws UnsupportedParamType */ public function get(Type|string $type): Closure { diff --git a/src/Sql/ValueFormatter.php b/src/Sql/ValueFormatter.php index f2559e2..b68caaf 100644 --- a/src/Sql/ValueFormatter.php +++ b/src/Sql/ValueFormatter.php @@ -11,6 +11,7 @@ use function array_key_first; use function array_map; +use function assert; use function implode; use function is_array; use function is_bool; @@ -92,13 +93,17 @@ public function format(mixed $value, string|null $paramName = null, string|null $firstValue = $value[array_key_first($value)]; $mapper = is_array($firstValue) - ? fn ($value): string => sprintf( - '(%s)', - implode( - ',', - array_map(fn ($val) => $this->format($val), $value), - ), - ) + ? function ($value): string { + assert(is_array($value)); + + return sprintf( + '(%s)', + implode( + ',', + array_map(fn ($val) => $this->format($val), $value), + ), + ); + } : fn ($value): string => $value === null ? 'NULL' : $this->format($value); return implode( diff --git a/tests/Client/SelectAsyncTest.php b/tests/Client/SelectAsyncTest.php index 309eff9..a5dd78b 100644 --- a/tests/Client/SelectAsyncTest.php +++ b/tests/Client/SelectAsyncTest.php @@ -39,6 +39,12 @@ public function testAsyncSelect(): void $client->select($sql, $format), ]; + /** + * @var array{ + * \SimPod\ClickHouseClient\Output\JsonEachRow, + * \SimPod\ClickHouseClient\Output\JsonEachRow + * } $jsonEachRowOutputs + */ $jsonEachRowOutputs = Utils::all($promises)->wait(); $expectedData = [ @@ -46,8 +52,6 @@ public function testAsyncSelect(): void ['number' => '1'], ]; - self::assertIsArray($jsonEachRowOutputs); - self::assertCount(2, $jsonEachRowOutputs); self::assertSame($expectedData, $jsonEachRowOutputs[0]->data); self::assertSame($expectedData, $jsonEachRowOutputs[1]->data); } diff --git a/tests/Exception/UnsupportedParamValueTest.php b/tests/Exception/UnsupportedParamValueTest.php index c343aeb..27ba415 100644 --- a/tests/Exception/UnsupportedParamValueTest.php +++ b/tests/Exception/UnsupportedParamValueTest.php @@ -12,9 +12,6 @@ use stdClass; use function opendir; -use function sprintf; - -use const PHP_VERSION_ID; #[CoversClass(UnsupportedParamValue::class)] final class UnsupportedParamValueTest extends TestCaseBase @@ -68,17 +65,12 @@ public static function providerValue(): iterable new stdClass(), ]; - $prefix = PHP_VERSION_ID >= 80200 ? '\\' : ''; - yield [ - sprintf( - "Value \"%sDateTime::__set_state(array( + "Value \"\DateTime::__set_state(array( 'date' => '2022-02-02 13:31:37.593289', 'timezone_type' => 3, 'timezone' => 'UTC', ))\" is not supported as a parameter", - $prefix, - ), new DateTime('2022-02-02 13:31:37.593289'), ]; }