Skip to content

Commit

Permalink
Merge pull request doctrine#5839 from derrabus/improvement/array-para…
Browse files Browse the repository at this point in the history
…meter-type-4.0.x

Introduce a `ArrayParameterType` enum
  • Loading branch information
derrabus committed Dec 30, 2022
2 parents 48be8ba + 06ba8a6 commit 273eff9
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 166 deletions.
4 changes: 4 additions & 0 deletions UPGRADE.md
Expand Up @@ -8,6 +8,10 @@ awareness about deprecated code.

# Upgrade to 4.0

## Removed `Connection::PARAM_*_ARRAY` constants

Use the enum `ArrayParameterType` instead.

## Disallowed partial version numbers in ``serverVersion``

The ``serverVersion`` connection parameter must consist of 3 numbers:
Expand Down
23 changes: 6 additions & 17 deletions src/ArrayParameterType.php
Expand Up @@ -4,41 +4,30 @@

namespace Doctrine\DBAL;

use Doctrine\DBAL\ArrayParameters\Exception\InvalidParameterType;

final class ArrayParameterType
enum ArrayParameterType
{
/**
* Represents an array of ints to be expanded by Doctrine SQL parsing.
*/
public const INTEGER = 101;
case INTEGER;

/**
* Represents an array of strings to be expanded by Doctrine SQL parsing.
*/
public const STRING = 102;
case STRING;

/**
* Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
*/
public const ASCII = 117;
case ASCII;

/**
* @internal
*
* @psalm-param self::INTEGER|self::STRING|self::ASCII $type
*/
public static function toElementParameterType(int $type): ParameterType
/** @internal */
public static function toElementParameterType(self $type): ParameterType
{
return match ($type) {
self::INTEGER => ParameterType::INTEGER,
self::STRING => ParameterType::STRING,
self::ASCII => ParameterType::ASCII,
default => throw InvalidParameterType::new($type),
};
}

private function __construct()
{
}
}
11 changes: 6 additions & 5 deletions src/Cache/QueryCacheProfile.php
Expand Up @@ -5,8 +5,7 @@
namespace Doctrine\DBAL\Cache;

use Doctrine\DBAL\Cache\Exception\NoCacheKey;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Connection;
use Psr\Cache\CacheItemPoolInterface;

use function hash;
Expand All @@ -17,6 +16,8 @@
* Query Cache Profile handles the data relevant for query caching.
*
* It is a value object, setter methods return NEW instances.
*
* @psalm-import-type WrapperParameterType from Connection
*/
class QueryCacheProfile
{
Expand Down Expand Up @@ -50,9 +51,9 @@ public function getCacheKey(): string
/**
* Generates the real cache key from query, params, types and connection parameters.
*
* @param list<mixed>|array<string, mixed> $params
* @param array<int, int|string|ParameterType|Type>|array<string, int|string|ParameterType|Type> $types
* @param array<string, mixed> $connectionParams
* @param list<mixed>|array<string, mixed> $params
* @param array<string, mixed> $connectionParams
* @psalm-param array<int, WrapperParameterType>|array<string, WrapperParameterType> $types
*
* @return array{string, string}
*/
Expand Down
122 changes: 51 additions & 71 deletions src/Connection.php

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions src/ExpandArrayParameters.php
Expand Up @@ -14,9 +14,9 @@
use function array_key_exists;
use function count;
use function implode;
use function is_int;
use function substr;

/** @psalm-import-type WrapperParameterTypeArray from Connection */
final class ExpandArrayParameters implements Visitor
{
private int $originalParameterIndex = 0;
Expand All @@ -31,11 +31,13 @@ final class ExpandArrayParameters implements Visitor
private array $convertedTypes = [];

/**
* @param array<int, mixed>|array<string, mixed> $parameters
* @param array<int,int|string|ParameterType|Type>|array<string,int|string|ParameterType|Type> $types
* @param array<int, mixed>|array<string, mixed> $parameters
* @psalm-param WrapperParameterTypeArray $types
*/
public function __construct(private readonly array $parameters, private readonly array $types)
{
public function __construct(
private readonly array $parameters,
private readonly array $types,
) {
}

public function acceptPositionalParameter(string $sql): void
Expand Down Expand Up @@ -90,7 +92,7 @@ private function acceptParameter(int|string $key, mixed $value): void

$type = $this->types[$key];

if (! is_int($type)) {
if (! $type instanceof ArrayParameterType) {
$this->appendTypedParameter([$value], $type);

return;
Expand All @@ -102,8 +104,7 @@ private function acceptParameter(int|string $key, mixed $value): void
return;
}

/** @psalm-suppress ArgumentTypeCoercion */
$this->appendTypedParameter($value, ArrayParameterType::toElementParameterType($type)); // @phpstan-ignore-line
$this->appendTypedParameter($value, ArrayParameterType::toElementParameterType($type));
}

/** @return array<int,string|ParameterType|Type> */
Expand Down
9 changes: 4 additions & 5 deletions src/Query.php
Expand Up @@ -4,18 +4,17 @@

namespace Doctrine\DBAL;

use Doctrine\DBAL\Types\Type;

/**
* An SQL query together with its bound parameters.
*
* @psalm-immutable
* @psalm-import-type WrapperParameterType from Connection
*/
final class Query
{
/**
* @param array<mixed> $params
* @param array<int|string|ParameterType|Type> $types
* @param array<mixed> $params
* @psalm-param array<WrapperParameterType> $types
*
* @psalm-suppress ImpurePropertyAssignment
*/
Expand All @@ -37,7 +36,7 @@ public function getParams(): array
return $this->params;
}

/** @return array<int|string|ParameterType|Type> */
/** @psalm-return array<WrapperParameterType> */
public function getTypes(): array
{
return $this->types;
Expand Down
28 changes: 13 additions & 15 deletions src/Query/QueryBuilder.php
Expand Up @@ -4,6 +4,7 @@

namespace Doctrine\DBAL\Query;

use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
Expand All @@ -15,7 +16,6 @@
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Statement;
use Doctrine\DBAL\Types\Type;
use Doctrine\Deprecations\Deprecation;

use function array_key_exists;
use function array_keys;
Expand All @@ -35,6 +35,8 @@
* The query builder does no validation whatsoever if certain features even work with the
* underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements
* even if some vendors such as MySQL support it.
*
* @psalm-import-type WrapperParameterTypeArray from Connection
*/
class QueryBuilder
{
Expand All @@ -48,12 +50,12 @@ class QueryBuilder
*
* @var list<mixed>|array<string, mixed>
*/
private $params = [];
private array $params = [];

/**
* The parameter type map of this query.
*
* @var array<int, int|string|ParameterType|Type>|array<string, int|string|ParameterType|Type>
* @psalm-var WrapperParameterTypeArray
*/
private array $types = [];

Expand Down Expand Up @@ -345,16 +347,14 @@ public function getSQL(): string
* ->setParameter('user_id', 1);
* </code>
*
* @param int|string $key Parameter position or name
* @param mixed $value Parameter value
* @param string|ParameterType|Type $type Parameter type
* @param int|string $key Parameter position or name
*
* @return $this This QueryBuilder instance.
*/
public function setParameter(
int|string $key,
mixed $value,
string|ParameterType|Type $type = ParameterType::STRING,
string|ParameterType|Type|ArrayParameterType $type = ParameterType::STRING,
): self {
$this->params[$key] = $value;
$this->types[$key] = $type;
Expand All @@ -376,8 +376,8 @@ public function setParameter(
* ));
* </code>
*
* @param list<mixed>|array<string, mixed> $params
* @param array<int, int|string|ParameterType|Type>|array<string, int|string|ParameterType|Type> $types
* @param list<mixed>|array<string, mixed> $params
* @psalm-param WrapperParameterTypeArray $types
*
* @return $this This QueryBuilder instance.
*/
Expand Down Expand Up @@ -414,7 +414,7 @@ public function getParameter(string|int $key): mixed
/**
* Gets all defined query parameter types for the query being constructed indexed by parameter index or name.
*
* @return array<int, int|string|ParameterType|Type>|array<string, int|string|ParameterType|Type>
* @psalm-return WrapperParameterTypeArray
*/
public function getParameterTypes(): array
{
Expand All @@ -425,10 +425,8 @@ public function getParameterTypes(): array
* Gets a (previously set) query parameter type of the query being constructed.
*
* @param int|string $key The key of the bound parameter type
*
* @return int|string|ParameterType|Type The value of the bound parameter type
*/
public function getParameterType(int|string $key): int|string|ParameterType|Type
public function getParameterType(int|string $key): string|ParameterType|Type|ArrayParameterType
{
return $this->types[$key] ?? ParameterType::STRING;
}
Expand Down Expand Up @@ -1311,7 +1309,7 @@ public function __toString(): string
*/
public function createNamedParameter(
mixed $value,
string|ParameterType|Type $type = ParameterType::STRING,
string|ParameterType|Type|ArrayParameterType $type = ParameterType::STRING,
?string $placeHolder = null,
): string {
if ($placeHolder === null) {
Expand Down Expand Up @@ -1343,7 +1341,7 @@ public function createNamedParameter(
*/
public function createPositionalParameter(
mixed $value,
string|ParameterType|Type $type = ParameterType::STRING,
string|ParameterType|Type|ArrayParameterType $type = ParameterType::STRING,
): string {
$this->setParameter($this->boundCounter, $value, $type);
$this->boundCounter++;
Expand Down
43 changes: 30 additions & 13 deletions tests/Connection/ExpandArrayParametersTest.php
Expand Up @@ -7,15 +7,26 @@
use Doctrine\DBAL\ArrayParameters\Exception\MissingNamedParameter;
use Doctrine\DBAL\ArrayParameters\Exception\MissingPositionalParameter;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ExpandArrayParameters;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\SQL\Parser;
use Doctrine\DBAL\Types\Type;
use PHPUnit\Framework\TestCase;

/** @psalm-import-type WrapperParameterTypeArray from Connection */
class ExpandArrayParametersTest extends TestCase
{
/** @return mixed[][] */
/**
* @psalm-return iterable<array{
* string,
* array<string, mixed>|array<int, mixed>,
* WrapperParameterTypeArray,
* string,
* array<string, mixed>|array<int, mixed>,
* array<string, string|Type|ParameterType>|array<int, string|Type|ParameterType>,
* }>
*/
public static function dataExpandListParameters(): iterable
{
return [
Expand Down Expand Up @@ -316,10 +327,10 @@ public static function dataExpandListParameters(): iterable
}

/**
* @param array<int, mixed>|array<string, mixed> $params
* @param array<int, int|string|Type>|array<string, int|string|Type> $types
* @param list<mixed> $expectedParams
* @param array<int,Type|int|string> $expectedTypes
* @param array<int, mixed>|array<string, mixed> $params
* @param array<int, mixed>|array<string, mixed> $expectedParams
* @param array<int, string|Type|ParameterType>|array<string, string|Type|ParameterType> $expectedTypes
* @psalm-param WrapperParameterTypeArray $types
*
* @dataProvider dataExpandListParameters
*/
Expand All @@ -338,7 +349,13 @@ public function testExpandListParameters(
self::assertEquals($expectedTypes, $types, 'Types dont match');
}

/** @return mixed[][] */
/**
* @return list<array{
* string,
* array<string, mixed>,
* array<string, ArrayParameterType>
* }>
*/
public static function missingNamedParameterProvider(): iterable
{
return [
Expand Down Expand Up @@ -366,8 +383,8 @@ public static function missingNamedParameterProvider(): iterable
}

/**
* @param array<int, mixed>|array<string, mixed> $params
* @param array<int, int|string|Type>|array<string, int|string|Type> $types
* @param array<string, mixed> $params
* @param array<string, ArrayParameterType> $types
*
* @dataProvider missingNamedParameterProvider
*/
Expand All @@ -379,7 +396,7 @@ public function testMissingNamedParameter(string $query, array $params, array $t
}

/**
* @param array<int, mixed>|array<string, mixed> $params
* @param list<mixed> $params
*
* @dataProvider missingPositionalParameterProvider
*/
Expand All @@ -390,7 +407,7 @@ public function testMissingPositionalParameter(string $query, array $params): vo
$this->expandArrayParameters($query, $params, []);
}

/** @return mixed[][] */
/** @return iterable<string, array{string, list<mixed>}> */
public static function missingPositionalParameterProvider(): iterable
{
return [
Expand All @@ -406,10 +423,10 @@ public static function missingPositionalParameterProvider(): iterable
}

/**
* @param array<int, mixed>|array<string, mixed> $params
* @param array<int, int|string|Type>|array<string, int|string|Type> $types
* @param array<int, mixed>|array<string, mixed> $params
* @psalm-param WrapperParameterTypeArray $types
*
* @return array{string, list<mixed>, array<int,string|ParameterType|Type>}
* @return array{string, list<mixed>, array<string|ParameterType|Type>}
*/
private function expandArrayParameters(string $sql, array $params, array $types): array
{
Expand Down

0 comments on commit 273eff9

Please sign in to comment.