From 79747674351f55843f0010b51601174dc6befe7b Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sat, 30 Jul 2022 23:49:59 -0700 Subject: [PATCH] Remove support for passing parameters to Statement::execute() --- src/Driver/IBMDB2/Statement.php | 14 +------ .../AbstractStatementMiddleware.php | 4 +- src/Driver/Mysqli/Statement.php | 34 ++------------- src/Driver/OCI8/Statement.php | 22 +--------- src/Driver/PDO/Statement.php | 14 +------ src/Driver/SQLSrv/Statement.php | 20 +-------- src/Driver/Statement.php | 11 +---- src/Logging/Statement.php | 6 +-- src/Portability/Statement.php | 4 +- src/Statement.php | 41 +++---------------- .../AbstractStatementMiddlewareTest.php | 3 +- tests/Functional/DataAccessTest.php | 15 ------- .../Functional/Driver/OCI8/StatementTest.php | 30 ++++++-------- tests/Functional/StatementTest.php | 34 +++++++-------- tests/Logging/MiddlewareTest.php | 17 +------- tests/Portability/StatementTest.php | 10 +---- 16 files changed, 55 insertions(+), 224 deletions(-) diff --git a/src/Driver/IBMDB2/Statement.php b/src/Driver/IBMDB2/Statement.php index 9aed4de77ca..62191c29b0a 100644 --- a/src/Driver/IBMDB2/Statement.php +++ b/src/Driver/IBMDB2/Statement.php @@ -10,7 +10,6 @@ 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; @@ -89,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); diff --git a/src/Driver/Middleware/AbstractStatementMiddleware.php b/src/Driver/Middleware/AbstractStatementMiddleware.php index e00e45ee9f9..91c995db44a 100644 --- a/src/Driver/Middleware/AbstractStatementMiddleware.php +++ b/src/Driver/Middleware/AbstractStatementMiddleware.php @@ -28,8 +28,8 @@ public function bindParam( $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(); } } diff --git a/src/Driver/Mysqli/Statement.php b/src/Driver/Mysqli/Statement.php index c4d87dfff48..519f4e065d0 100644 --- a/src/Driver/Mysqli/Statement.php +++ b/src/Driver/Mysqli/Statement.php @@ -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; @@ -73,21 +72,10 @@ public function bindValue(int|string $param, mixed $value, ParameterType $type): $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 { @@ -106,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; @@ -165,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) { diff --git a/src/Driver/OCI8/Statement.php b/src/Driver/OCI8/Statement.php index c452e37eefa..55c2e89e6d2 100644 --- a/src/Driver/OCI8/Statement.php +++ b/src/Driver/OCI8/Statement.php @@ -8,7 +8,6 @@ use Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; -use Doctrine\Deprecations\Deprecation; use function is_int; use function oci_bind_by_name; @@ -95,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 { diff --git a/src/Driver/PDO/Statement.php b/src/Driver/PDO/Statement.php index 9b6a5ab401a..35dcf055a32 100644 --- a/src/Driver/PDO/Statement.php +++ b/src/Driver/PDO/Statement.php @@ -7,7 +7,6 @@ use Doctrine\DBAL\Driver\Exception as ExceptionInterface; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; -use Doctrine\Deprecations\Deprecation; use PDO; use PDOException; use PDOStatement; @@ -68,19 +67,10 @@ public function bindParamWithDriverOptions( } } - 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.' - ); - } - try { - $this->stmt->execute($params); + $this->stmt->execute(); } catch (PDOException $exception) { throw Exception::new($exception); } diff --git a/src/Driver/SQLSrv/Statement.php b/src/Driver/SQLSrv/Statement.php index 61617fa50c1..850b6baf9e5 100644 --- a/src/Driver/SQLSrv/Statement.php +++ b/src/Driver/SQLSrv/Statement.php @@ -8,7 +8,6 @@ use Doctrine\DBAL\Driver\SQLSrv\Exception\Error; use Doctrine\DBAL\Driver\Statement as StatementInterface; use Doctrine\DBAL\ParameterType; -use Doctrine\Deprecations\Deprecation; use function assert; use function is_int; @@ -90,25 +89,8 @@ public function bindParam( $this->stmt = null; } - 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)) { - $this->bindValue($key + 1, $val, ParameterType::STRING); - } else { - $this->bindValue($key, $val, ParameterType::STRING); - } - } - } - $this->stmt ??= $this->prepare(); if (! sqlsrv_execute($this->stmt)) { diff --git a/src/Driver/Statement.php b/src/Driver/Statement.php index f37a78bd581..cf5f8a0e2c7 100644 --- a/src/Driver/Statement.php +++ b/src/Driver/Statement.php @@ -65,16 +65,7 @@ public function bindParam( /** * Executes a prepared statement * - * If the prepared statement included parameter markers, you must either: - * call {@see bindParam()} to bind PHP variables to the parameter markers: - * bound variables pass their value as input and receive the output value, - * if any, of their associated parameter markers or pass an array of input-only - * parameter values. - * - * @param mixed[]|null $params A numeric array of values with as many elements as there are - * bound parameters in the SQL statement being executed. - * * @throws Exception */ - public function execute(?array $params = null): Result; + public function execute(): Result; } diff --git a/src/Logging/Statement.php b/src/Logging/Statement.php index d789bae7c5d..6a639b838e2 100644 --- a/src/Logging/Statement.php +++ b/src/Logging/Statement.php @@ -49,14 +49,14 @@ public function bindValue(int|string $param, mixed $value, ParameterType $type): parent::bindValue($param, $value, $type); } - public function execute(?array $params = null): ResultInterface + public function execute(): ResultInterface { $this->logger->debug('Executing statement: {sql} (parameters: {params}, types: {types})', [ 'sql' => $this->sql, - 'params' => $params ?? $this->params, + 'params' => $this->params, 'types' => $this->types, ]); - return parent::execute($params); + return parent::execute(); } } diff --git a/src/Portability/Statement.php b/src/Portability/Statement.php index 659b988c26e..3d005891df4 100644 --- a/src/Portability/Statement.php +++ b/src/Portability/Statement.php @@ -21,10 +21,10 @@ public function __construct(DriverStatement $stmt, private readonly Converter $c parent::__construct($stmt); } - public function execute(?array $params = null): ResultInterface + public function execute(): ResultInterface { return new Result( - parent::execute($params), + parent::execute(), $this->converter ); } diff --git a/src/Statement.php b/src/Statement.php index 1f0703ecd49..93b4c96cc6c 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\Type; -use Doctrine\Deprecations\Deprecation; use function func_num_args; use function is_string; @@ -135,19 +134,13 @@ public function bindParam( } /** - * @param mixed[] $params - * * @throws Exception */ - private function execute(array $params): Result + private function execute(): Result { - if ($params !== []) { - $this->params = $params; - } - try { return new Result( - $this->stmt->execute($params === [] ? null : $params), + $this->stmt->execute(), $this->conn ); } catch (Driver\Exception $ex) { @@ -158,43 +151,21 @@ private function execute(array $params): Result /** * Executes the statement with the currently bound parameters and return result. * - * @param mixed[] $params - * * @throws Exception */ - public function executeQuery(array $params = []): Result + public function executeQuery(): Result { - if (func_num_args() > 0) { - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/5556', - 'Passing $params to Statement::executeQuery() is deprecated. Bind parameters using' - . ' Statement::bindParam() or Statement::bindValue() instead.' - ); - } - - return $this->execute($params); + return $this->execute(); } /** * Executes the statement with the currently bound parameters and return affected rows. * - * @param mixed[] $params - * * @throws Exception */ - public function executeStatement(array $params = []): int + public function executeStatement(): int { - if (func_num_args() > 0) { - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/5556', - 'Passing $params to Statement::executeStatement() is deprecated. Bind parameters using' - . ' Statement::bindParam() or Statement::bindValue() instead.' - ); - } - - return $this->execute($params)->rowCount(); + return $this->execute()->rowCount(); } /** diff --git a/tests/Driver/Middleware/AbstractStatementMiddlewareTest.php b/tests/Driver/Middleware/AbstractStatementMiddlewareTest.php index 5578310b91d..c341b0e5139 100644 --- a/tests/Driver/Middleware/AbstractStatementMiddlewareTest.php +++ b/tests/Driver/Middleware/AbstractStatementMiddlewareTest.php @@ -17,10 +17,9 @@ public function testExecute(): void $statement = $this->createMock(Statement::class); $statement->expects(self::once()) ->method('execute') - ->with(['foo' => 'bar']) ->willReturn($result); - self::assertSame($result, $this->createMiddleware($statement)->execute(['foo' => 'bar'])); + self::assertSame($result, $this->createMiddleware($statement)->execute()); } private function createMiddleware(Statement $statement): AbstractStatementMiddleware diff --git a/tests/Functional/DataAccessTest.php b/tests/Functional/DataAccessTest.php index c5f27f954df..a39a0393ccd 100644 --- a/tests/Functional/DataAccessTest.php +++ b/tests/Functional/DataAccessTest.php @@ -105,21 +105,6 @@ public function testPrepareWithFetchOne(): void self::assertEquals(1, $column); } - public function testPrepareWithExecuteParams(): void - { - $paramInt = 1; - $paramStr = 'foo'; - - $sql = 'SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?'; - $stmt = $this->connection->prepare($sql); - $result = $stmt->executeQuery([$paramInt, $paramStr]); - - $row = $result->fetchAssociative(); - self::assertNotFalse($row); - $row = array_change_key_case($row, CASE_LOWER); - self::assertEquals(['test_int' => 1, 'test_string' => 'foo'], $row); - } - public function testFetchAllAssociative(): void { $sql = 'SELECT test_int, test_string FROM fetch_table WHERE test_int = ? AND test_string = ?'; diff --git a/tests/Functional/Driver/OCI8/StatementTest.php b/tests/Functional/Driver/OCI8/StatementTest.php index 94ca082f53b..6a96ed1f5f9 100644 --- a/tests/Functional/Driver/OCI8/StatementTest.php +++ b/tests/Functional/Driver/OCI8/StatementTest.php @@ -35,24 +35,6 @@ public function testQueryConversion(string $query, array $params, array $expecte ); } - /** - * Low-level approach to working with parameter binding - * - * @param mixed[] $params - * @param mixed[] $expected - * - * @dataProvider queryConversionProvider - */ - public function testStatementBindParameters(string $query, array $params, array $expected): void - { - self::assertEquals( - $expected, - $this->connection->prepare($query) - ->executeQuery($params) - ->fetchAssociative() - ); - } - /** * @return array> */ @@ -106,4 +88,16 @@ public static function queryConversionProvider(): iterable ], ]; } + + public function testBindPositionalParameter(): void + { + $statement = $this->connection->prepare('SELECT ? COL1 FROM DUAL'); + $statement->bindValue(1, 1); + + self::assertEquals( + ['COL1' => 1], + $statement->executeQuery() + ->fetchAssociative() + ); + } } diff --git a/tests/Functional/StatementTest.php b/tests/Functional/StatementTest.php index 298cc4e8443..77a326c66fb 100644 --- a/tests/Functional/StatementTest.php +++ b/tests/Functional/StatementTest.php @@ -153,9 +153,7 @@ public function testIncompletelyFetchedStatementDoesNotBlockConnection(): void // fetching only one record out of two $result->fetchAssociative(); - $stmt2 = $this->connection->prepare('SELECT id FROM stmt_test WHERE id = ?'); - $result = $stmt2->executeQuery([1]); - self::assertEquals(1, $result->fetchOne()); + self::assertEquals(1, $this->connection->fetchOne('SELECT id FROM stmt_test WHERE id = ?', [1])); } public function testReuseStatementAfterFreeingResult(): void @@ -168,15 +166,17 @@ public function testReuseStatementAfterFreeingResult(): void $this->connection->insert('stmt_test', ['id' => 2]); $stmt = $this->connection->prepare('SELECT id FROM stmt_test WHERE id = ?'); + $stmt->bindValue(1, 1); - $result = $stmt->executeQuery([1]); + $result = $stmt->executeQuery(); $id = $result->fetchOne(); self::assertEquals(1, $id); $result->free(); - $result = $stmt->executeQuery([2]); + $stmt->bindValue(1, 2); + $result = $stmt->executeQuery(); $id = $result->fetchOne(); self::assertEquals(2, $id); @@ -255,9 +255,11 @@ public function testBindInvalidNamedParameter(): void $platform = $this->connection->getDatabasePlatform(); $statement = $this->connection->prepare($platform->getDummySelectSQL(':foo')); + $this->expectException(DriverException::class); - $statement->executeQuery(['bar' => 'baz']); + $statement->bindValue('bar', 'baz'); + $statement->executeQuery(); } public function testParameterBindingOrder(): void @@ -391,7 +393,8 @@ public function testExecWithRedundantParameters(): void $this->expectException(Exception::class); } - $stmt->executeQuery([null]); + $stmt->bindValue(1, null); + $stmt->executeQuery(); } public function testExecuteQuery(): void @@ -403,16 +406,6 @@ public function testExecuteQuery(): void self::assertEquals(1, $result); } - public function testExecuteQueryWithParams(): void - { - $this->connection->insert('stmt_test', ['id' => 1]); - - $query = 'SELECT id FROM stmt_test WHERE id = ?'; - $result = $this->connection->prepare($query)->executeQuery([1])->fetchOne(); - - self::assertEquals(1, $result); - } - public function testExecuteStatement(): void { $this->connection->insert('stmt_test', ['id' => 1]); @@ -426,8 +419,11 @@ public function testExecuteStatement(): void self::assertEquals(1, $result); - $query = 'UPDATE stmt_test SET name = ? WHERE id = ?'; - $result = $this->connection->prepare($query)->executeStatement(['foo', 1]); + $query = 'UPDATE stmt_test SET name = ? WHERE id = ?'; + $stmt = $this->connection->prepare($query); + $stmt->bindValue(1, 'foo'); + $stmt->bindValue(2, 1); + $result = $stmt->executeStatement(); self::assertEquals(1, $result); } diff --git a/tests/Logging/MiddlewareTest.php b/tests/Logging/MiddlewareTest.php index d3df2444fb6..d4f3c5618aa 100644 --- a/tests/Logging/MiddlewareTest.php +++ b/tests/Logging/MiddlewareTest.php @@ -94,22 +94,7 @@ public function testBeginCommitRollback(): void $connection->rollBack(); } - public function testExecuteStatementWithUntypedParameters(): void - { - $this->logger->expects(self::once()) - ->method('debug') - ->with('Executing statement: {sql} (parameters: {params}, types: {types})', [ - 'sql' => 'SELECT ?', - 'params' => [42], - 'types' => [], - ]); - - $connection = $this->driver->connect([]); - $statement = $connection->prepare('SELECT ?'); - $statement->execute([42]); - } - - public function testExecuteStatementWithTypedParameters(): void + public function testExecuteStatementWithParameters(): void { $this->logger->expects(self::once()) ->method('debug') diff --git a/tests/Portability/StatementTest.php b/tests/Portability/StatementTest.php index 9d37b9b071b..9fd1a1e687a 100644 --- a/tests/Portability/StatementTest.php +++ b/tests/Portability/StatementTest.php @@ -54,15 +54,9 @@ public function testBindValue(): void public function testExecute(): void { - $params = [ - 'foo', - 'bar', - ]; - $this->wrappedStmt->expects(self::once()) - ->method('execute') - ->with($params); + ->method('execute'); - $this->stmt->execute($params); + $this->stmt->execute(); } }