Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert ParameterType to enum #5548

Merged
merged 1 commit into from Aug 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions UPGRADE.md
Expand Up @@ -14,9 +14,10 @@ The following classes have been converted to enums:

1. `Doctrine\DBAL\ColumnCase`,
2. `Doctrine\DBAL\LockMode`,
3. `Doctrine\DBAL\TransactionIsolationLevel`,
4. `Doctrine\DBAL\Platforms\DateIntervalUnit`,
5. `Doctrine\DBAL\Platforms\TrimMode`.
3. `Doctrine\DBAL\ParameterType`,
4. `Doctrine\DBAL\TransactionIsolationLevel`,
5. `Doctrine\DBAL\Platforms\DateIntervalUnit`,
6. `Doctrine\DBAL\Platforms\TrimMode`.

The corresponding class constants are now instances of their enum type.

Expand Down
4 changes: 2 additions & 2 deletions docs/en/reference/data-retrieval-and-manipulation.rst
Expand Up @@ -187,13 +187,13 @@ on the Connection, which are all described in the API section below.
Binding Types
-------------

Besides ``Doctrine\DBAL\ParameterType`` constants, you
Besides the values of ``Doctrine\DBAL\ParameterType``, you
can make use of two very powerful additional features.

Doctrine\DBAL\Types Conversion
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you don't specify an integer (through one of ``Doctrine\DBAL\ParameterType`` constants) to
If you don't specify a value of the type ``Doctrine\DBAL\ParameterType`` to
any of the parameter binding methods but a string, Doctrine DBAL will
ask the type abstraction layer to convert the passed value from
its PHP to a database representation. This way you can pass ``\DateTime``
Expand Down
10 changes: 10 additions & 0 deletions phpcs.xml.dist
Expand Up @@ -119,4 +119,14 @@
<exclude-pattern>src/Platforms/SQLitePlatform.php</exclude-pattern>
<exclude-pattern>src/Platforms/*/Comparator.php</exclude-pattern>
</rule>

<!-- This issue is likely fixed in Slevomat Coding Standard 8.0.0 -->
<rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFallbackGlobalName">
<exclude-pattern>src/ParameterType.php</exclude-pattern>
</rule>

<!-- The union types representing prepared statement parameter types are too complex -->
<rule ref="Generic.Files.LineLength.TooLong">
<exclude-pattern>src/Cache/QueryCacheProfile.php</exclude-pattern>
</rule>
Comment on lines +128 to +131
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This chunk is dedicated to all fans of union types.

</ruleset>
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Exception;
namespace Doctrine\DBAL\ArrayParameters\Exception;

use Doctrine\DBAL\Driver\AbstractException;

Expand All @@ -13,10 +13,10 @@
*
* @psalm-immutable
*/
final class UnknownParameterType extends AbstractException
final class InvalidParameterType extends AbstractException
{
public static function new(int $type): self
{
return new self(sprintf('Unknown parameter type, %d given.', $type));
return new self(sprintf('Invalid parameter type, %d given.', $type));
}
}
7 changes: 4 additions & 3 deletions src/Cache/QueryCacheProfile.php
Expand Up @@ -5,6 +5,7 @@
namespace Doctrine\DBAL\Cache;

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

Expand Down Expand Up @@ -51,9 +52,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, Type|int|string|null>|array<string, Type|int|string|null> $types
* @param array<string, mixed> $connectionParams
* @param list<mixed>|array<string, mixed> $params
* @param array<int, int|string|ParameterType|Type|null>|array<string, int|string|ParameterType|Type|null> $types
* @param array<string, mixed> $connectionParams
*
* @return string[]
*/
Expand Down
188 changes: 88 additions & 100 deletions src/Connection.php

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/Driver/IBMDB2/Statement.php
Expand Up @@ -50,7 +50,7 @@ public function __construct(private readonly mixed $stmt)
{
}

public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
assert(is_int($param));

Expand All @@ -60,7 +60,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
int|string $param,
mixed &$variable,
int $type = ParameterType::STRING,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
assert(is_int($param));
Expand Down
4 changes: 2 additions & 2 deletions src/Driver/Middleware/AbstractStatementMiddleware.php
Expand Up @@ -14,15 +14,15 @@ public function __construct(private readonly Statement $wrappedStatement)
{
}

public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->wrappedStatement->bindValue($param, $value, $type);
}

public function bindParam(
int|string $param,
mixed &$variable,
int $type = ParameterType::STRING,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
$this->wrappedStatement->bindParam($param, $variable, $type, $length);
Expand Down
53 changes: 25 additions & 28 deletions src/Driver/Mysqli/Statement.php
Expand Up @@ -5,7 +5,6 @@
namespace Doctrine\DBAL\Driver\Mysqli;

use Doctrine\DBAL\Driver\Exception;
use Doctrine\DBAL\Driver\Exception\UnknownParameterType;
use Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset;
use Doctrine\DBAL\Driver\Mysqli\Exception\NonStreamResourceUsedAsLargeObject;
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
Expand All @@ -26,16 +25,9 @@

final class Statement implements StatementInterface
{
/** @var string[] */
private static array $paramTypeMap = [
ParameterType::ASCII => 's',
ParameterType::STRING => 's',
ParameterType::BINARY => 's',
ParameterType::BOOLEAN => 'i',
ParameterType::NULL => 's',
ParameterType::INTEGER => 'i',
ParameterType::LARGE_OBJECT => 'b',
];
private const PARAMETER_TYPE_STRING = 's';
private const PARAMETER_TYPE_INTEGER = 'i';
private const PARAMETER_TYPE_BINARY = 'b';

/** @var mixed[] */
private array $boundValues;
Expand All @@ -55,37 +47,29 @@ final class Statement implements StatementInterface
public function __construct(private readonly mysqli_stmt $stmt)
{
$paramCount = $this->stmt->param_count;
$this->types = str_repeat('s', $paramCount);
$this->types = str_repeat(self::PARAMETER_TYPE_STRING, $paramCount);
$this->boundValues = array_fill(1, $paramCount, null);
}

public function bindParam(
int|string $param,
mixed &$variable,
int $type = ParameterType::STRING,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
assert(is_int($param));

if (! isset(self::$paramTypeMap[$type])) {
throw UnknownParameterType::new($type);
}

$this->types[$param - 1] = $this->convertParameterType($type);
$this->boundValues[$param] =& $variable;
$this->types[$param - 1] = self::$paramTypeMap[$type];
}

public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
assert(is_int($param));

if (! isset(self::$paramTypeMap[$type])) {
throw UnknownParameterType::new($type);
}

$this->types[$param - 1] = $this->convertParameterType($type);
$this->values[$param] = $value;
$this->boundValues[$param] =& $this->values[$param];
$this->types[$param - 1] = self::$paramTypeMap[$type];
}

public function execute(?array $params = null): Result
Expand Down Expand Up @@ -120,10 +104,10 @@ private function bindTypedParameters(): void
foreach ($this->boundValues as $parameter => $value) {
assert(is_int($parameter));
if (! isset($types[$parameter - 1])) {
$types[$parameter - 1] = self::$paramTypeMap[ParameterType::STRING];
$types[$parameter - 1] = self::PARAMETER_TYPE_STRING;
}

if ($types[$parameter - 1] === self::$paramTypeMap[ParameterType::LARGE_OBJECT]) {
if ($types[$parameter - 1] === self::PARAMETER_TYPE_BINARY) {
if (is_resource($value)) {
if (get_resource_type($value) !== 'stream') {
throw NonStreamResourceUsedAsLargeObject::new($parameter);
Expand All @@ -134,7 +118,7 @@ private function bindTypedParameters(): void
continue;
}

$types[$parameter - 1] = self::$paramTypeMap[ParameterType::STRING];
$types[$parameter - 1] = self::PARAMETER_TYPE_STRING;
}

$values[$parameter] = $value;
Expand Down Expand Up @@ -180,8 +164,21 @@ private function sendLongData(array $streams): void
*/
private function bindUntypedValues(array $values): void
{
if (! $this->stmt->bind_param(str_repeat('s', count($values)), ...$values)) {
if (! $this->stmt->bind_param(str_repeat(self::PARAMETER_TYPE_STRING, count($values)), ...$values)) {
throw StatementError::new($this->stmt);
}
}

private function convertParameterType(ParameterType $type): string
{
return match ($type) {
ParameterType::NULL,
ParameterType::STRING,
ParameterType::ASCII,
ParameterType::BINARY => self::PARAMETER_TYPE_STRING,
ParameterType::INTEGER,
ParameterType::BOOLEAN => self::PARAMETER_TYPE_INTEGER,
ParameterType::LARGE_OBJECT => self::PARAMETER_TYPE_BINARY,
};
}
}
6 changes: 3 additions & 3 deletions src/Driver/OCI8/Statement.php
Expand Up @@ -39,15 +39,15 @@ public function __construct(
) {
}

public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->bindParam($param, $value, $type);
}

public function bindParam(
int|string $param,
mixed &$variable,
int $type = ParameterType::STRING,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
if (is_int($param)) {
Expand Down Expand Up @@ -85,7 +85,7 @@ public function bindParam(
/**
* Converts DBAL parameter type to oci8 parameter type
*/
private function convertParameterType(int $type): int
private function convertParameterType(ParameterType $type): int
{
return match ($type) {
ParameterType::BINARY => OCI_B_BIN,
Expand Down
4 changes: 2 additions & 2 deletions src/Driver/PDO/SQLSrv/Statement.php
Expand Up @@ -26,7 +26,7 @@ public function __construct(PDOStatement $statement)
public function bindParam(
int|string $param,
mixed &$variable,
int $type = ParameterType::STRING,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
switch ($type) {
Expand Down Expand Up @@ -56,7 +56,7 @@ public function bindParam(
}
}

public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$this->bindParam($param, $value, $type);
}
Expand Down
37 changes: 13 additions & 24 deletions src/Driver/PDO/Statement.php
Expand Up @@ -5,7 +5,6 @@
namespace Doctrine\DBAL\Driver\PDO;

use Doctrine\DBAL\Driver\Exception as ExceptionInterface;
use Doctrine\DBAL\Driver\Exception\UnknownParameterType;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use PDO;
Expand All @@ -14,24 +13,14 @@

final class Statement implements StatementInterface
{
private const PARAM_TYPE_MAP = [
ParameterType::NULL => PDO::PARAM_NULL,
ParameterType::INTEGER => PDO::PARAM_INT,
ParameterType::STRING => PDO::PARAM_STR,
ParameterType::ASCII => PDO::PARAM_STR,
ParameterType::BINARY => PDO::PARAM_LOB,
ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
ParameterType::BOOLEAN => PDO::PARAM_BOOL,
];

/**
* @internal The statement can be only instantiated by its driver connection.
*/
public function __construct(private readonly PDOStatement $stmt)
{
}

public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
$type = $this->convertParamType($type);

Expand All @@ -45,7 +34,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
string|int $param,
mixed &$variable,
int $type = ParameterType::STRING,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
try {
Expand All @@ -67,7 +56,7 @@ public function bindParam(
public function bindParamWithDriverOptions(
string|int $param,
mixed &$variable,
int $type,
ParameterType $type,
int $length,
mixed $driverOptions
): void {
Expand All @@ -91,17 +80,17 @@ public function execute(?array $params = null): Result

/**
* Converts DBAL parameter type to PDO parameter type
*
* @param int $type Parameter type
*
* @throws ExceptionInterface
*/
private function convertParamType(int $type): int
private function convertParamType(ParameterType $type): int
{
if (! isset(self::PARAM_TYPE_MAP[$type])) {
throw UnknownParameterType::new($type);
}

return self::PARAM_TYPE_MAP[$type];
return match ($type) {
ParameterType::NULL => PDO::PARAM_NULL,
ParameterType::INTEGER => PDO::PARAM_INT,
ParameterType::STRING,
ParameterType::ASCII => PDO::PARAM_STR,
ParameterType::BINARY,
ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
ParameterType::BOOLEAN => PDO::PARAM_BOOL,
};
}
}
6 changes: 3 additions & 3 deletions src/Driver/SQLSrv/Statement.php
Expand Up @@ -41,7 +41,7 @@ final class Statement implements StatementInterface
/**
* Bound parameter types.
*
* @var array<int, int>
* @var array<int, ParameterType>
*/
private array $types = [];

Expand All @@ -66,7 +66,7 @@ public function __construct(
$this->sql .= self::LAST_INSERT_ID_SQL;
}

public function bindValue(int|string $param, mixed $value, int $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
{
assert(is_int($param));

Expand All @@ -77,7 +77,7 @@ public function bindValue(int|string $param, mixed $value, int $type = Parameter
public function bindParam(
int|string $param,
mixed &$variable,
int $type = ParameterType::STRING,
ParameterType $type = ParameterType::STRING,
?int $length = null
): void {
assert(is_int($param));
Expand Down