Skip to content

Commit

Permalink
Merge pull request #5560 from morozov/parameter-type-non-nullable
Browse files Browse the repository at this point in the history
Remove the APIs deprecated in DBAL 3.x
  • Loading branch information
morozov committed Aug 3, 2022
2 parents 0cc7adc + 2beb082 commit 60f014a
Show file tree
Hide file tree
Showing 26 changed files with 193 additions and 549 deletions.
9 changes: 9 additions & 0 deletions UPGRADE.md
Expand Up @@ -8,6 +8,15 @@ awareness about deprecated code.

# Upgrade to 4.0

## BC BREAK: made parameter type in driver-level `Statement::bind*()` methods required.

The `$type` parameter of the driver-level `Statement::bindParam()` and `::bindValue()` has been made required.

## BC BREAK: removed support for using NULL as prepared statement parameter type.

The value of parameter type used in the wrapper layer (e.g. in `Connection::executeQuery()`
or `Statement::bindValue()`) can no longer be `NULL`.

## BC BREAK: converted enum-like classes to enums

The following classes have been converted to enums:
Expand Down
5 changes: 0 additions & 5 deletions phpcs.xml.dist
Expand Up @@ -124,9 +124,4 @@
<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>
</ruleset>
6 changes: 3 additions & 3 deletions src/Cache/QueryCacheProfile.php
Expand Up @@ -52,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, int|string|ParameterType|Type|null>|array<string, int|string|ParameterType|Type|null> $types
* @param array<string, mixed> $connectionParams
* @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
*
* @return string[]
*/
Expand Down
128 changes: 55 additions & 73 deletions src/Connection.php

Large diffs are not rendered by default.

43 changes: 5 additions & 38 deletions src/Driver/IBMDB2/Statement.php
Expand Up @@ -10,14 +10,12 @@
use Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use Doctrine\Deprecations\Deprecation;

use function assert;
use function db2_bind_param;
use function db2_execute;
use function error_get_last;
use function fclose;
use function func_num_args;
use function is_int;
use function is_resource;
use function stream_copy_to_stream;
Expand Down Expand Up @@ -52,39 +50,17 @@ public function __construct(private readonly mixed $stmt)
{
}

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

if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindValue() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

$this->bindParam($param, $value, $type);
}

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

if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindParam() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

switch ($type) {
case ParameterType::INTEGER:
$this->bind($param, $variable, DB2_PARAM_IN, DB2_LONG);
Expand Down Expand Up @@ -112,20 +88,11 @@ private function bind(int $position, mixed &$variable, int $parameterType, int $
}
}

public function execute(?array $params = null): Result
public function execute(): Result
{
if ($params !== null) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5556',
'Passing $params to Statement::execute() is deprecated. Bind parameters using'
. ' Statement::bindParam() or Statement::bindValue() instead.'
);
}

$handles = $this->bindLobs();

$result = @db2_execute($this->stmt, $params ?? $this->parameters);
$result = @db2_execute($this->stmt, $this->parameters);

foreach ($handles as $handle) {
fclose($handle);
Expand Down
29 changes: 4 additions & 25 deletions src/Driver/Middleware/AbstractStatementMiddleware.php
Expand Up @@ -7,50 +7,29 @@
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\ParameterType;
use Doctrine\Deprecations\Deprecation;

use function func_num_args;

abstract class AbstractStatementMiddleware implements Statement
{
public function __construct(private readonly Statement $wrappedStatement)
{
}

public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type): void
{
if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindValue() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

$this->wrappedStatement->bindValue($param, $value, $type);
}

public function bindParam(
int|string $param,
mixed &$variable,
ParameterType $type = ParameterType::STRING,
ParameterType $type,
?int $length = null
): void {
if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindParam() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

$this->wrappedStatement->bindParam($param, $variable, $type, $length);
}

public function execute(?array $params = null): Result
public function execute(): Result
{
return $this->wrappedStatement->execute($params);
return $this->wrappedStatement->execute();
}
}
57 changes: 6 additions & 51 deletions src/Driver/Mysqli/Statement.php
Expand Up @@ -10,7 +10,6 @@
use Doctrine\DBAL\Driver\Mysqli\Exception\StatementError;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use Doctrine\Deprecations\Deprecation;
use mysqli_sql_exception;
use mysqli_stmt;

Expand All @@ -19,7 +18,6 @@
use function count;
use function feof;
use function fread;
use function func_num_args;
use function get_resource_type;
use function is_int;
use function is_resource;
Expand Down Expand Up @@ -56,57 +54,28 @@ public function __construct(private readonly mysqli_stmt $stmt)
public function bindParam(
int|string $param,
mixed &$variable,
ParameterType $type = ParameterType::STRING,
ParameterType $type,
?int $length = null
): void {
assert(is_int($param));

if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindParam() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

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

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

if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindValue() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

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

public function execute(?array $params = null): Result
public function execute(): Result
{
if ($params !== null) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5556',
'Passing $params to Statement::execute() is deprecated. Bind parameters using'
. ' Statement::bindParam() or Statement::bindValue() instead.'
);
}

if ($params !== null && count($params) > 0) {
$this->bindUntypedValues($params);
} elseif (count($this->boundValues) > 0) {
$this->bindTypedParameters();
if (count($this->boundValues) > 0) {
$this->bindParameters();
}

try {
Expand All @@ -125,7 +94,7 @@ public function execute(?array $params = null): Result
*
* @throws Exception
*/
private function bindTypedParameters(): void
private function bindParameters(): void
{
$streams = $values = [];
$types = $this->types;
Expand Down Expand Up @@ -184,20 +153,6 @@ private function sendLongData(array $streams): void
}
}

/**
* Binds a array of values to bound parameters.
*
* @param mixed[] $values
*
* @throws Exception
*/
private function bindUntypedValues(array $values): void
{
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) {
Expand Down
45 changes: 3 additions & 42 deletions src/Driver/OCI8/Statement.php
Expand Up @@ -8,9 +8,7 @@
use Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Doctrine\DBAL\ParameterType;
use Doctrine\Deprecations\Deprecation;

use function func_num_args;
use function is_int;
use function oci_bind_by_name;
use function oci_execute;
Expand Down Expand Up @@ -41,35 +39,17 @@ public function __construct(
) {
}

public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
public function bindValue(int|string $param, mixed $value, ParameterType $type): void
{
if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindValue() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

$this->bindParam($param, $value, $type);
}

public function bindParam(
int|string $param,
mixed &$variable,
ParameterType $type = ParameterType::STRING,
ParameterType $type,
?int $length = null
): void {
if (func_num_args() < 3) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5558',
'Not passing $type to Statement::bindParam() is deprecated.'
. ' Pass the type corresponding to the parameter being bound.'
);
}

if (is_int($param)) {
if (! isset($this->parameterMap[$param])) {
throw UnknownParameterIndex::new($param);
Expand Down Expand Up @@ -114,27 +94,8 @@ private function convertParameterType(ParameterType $type): int
};
}

public function execute(?array $params = null): Result
public function execute(): Result
{
if ($params !== null) {
Deprecation::trigger(
'doctrine/dbal',
'https://github.com/doctrine/dbal/pull/5556',
'Passing $params to Statement::execute() is deprecated. Bind parameters using'
. ' Statement::bindParam() or Statement::bindValue() instead.'
);

foreach ($params as $key => $val) {
if (is_int($key)) {
$param = $key + 1;
} else {
$param = $key;
}

$this->bindValue($param, $val, ParameterType::STRING);
}
}

if ($this->executionMode->isAutoCommitEnabled()) {
$mode = OCI_COMMIT_ON_SUCCESS;
} else {
Expand Down

0 comments on commit 60f014a

Please sign in to comment.