diff --git a/psalm.xml.dist b/psalm.xml.dist index d19deca8322..35d556d2db8 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -61,6 +61,7 @@ + diff --git a/src/Statement.php b/src/Statement.php index d7a541a8de3..69a713b72f0 100644 --- a/src/Statement.php +++ b/src/Statement.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Driver\Statement as DriverStatement; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\Type; +use Doctrine\Deprecations\Deprecation; use function is_string; @@ -155,12 +156,20 @@ public function bindParam($param, &$variable, $type = ParameterType::STRING, $le /** * Executes the statement with the currently bound parameters. * + * @deprecated Statement::execute() is deprecated, use Statement::executeQuery() or executeStatement() instead + * * @param mixed[]|null $params * * @throws Exception */ public function execute($params = null): Result { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4580', + 'Statement::execute() is deprecated, use Statement::executeQuery() or Statement::executeStatement() instead' + ); + if ($params !== null) { $this->params = $params; } @@ -184,6 +193,38 @@ public function execute($params = null): Result } } + /** + * Executes the statement with the currently bound parameters and return result. + * + * @param mixed[] $params + * + * @throws Exception + */ + public function executeQuery(array $params = []): Result + { + if ($params === []) { + $params = null; // Workaround as long execute() exists and used internally. + } + + return $this->execute($params); + } + + /** + * Executes the statement with the currently bound parameters and return affected rows. + * + * @param mixed[] $params + * + * @throws Exception + */ + public function executeStatement(array $params = []): int + { + if ($params === []) { + $params = null; // Workaround as long execute() exists and used internally. + } + + return $this->execute($params)->rowCount(); + } + /** * Gets the wrapped driver statement. * diff --git a/tests/Functional/StatementTest.php b/tests/Functional/StatementTest.php index dea120981f5..2c7669118bf 100644 --- a/tests/Functional/StatementTest.php +++ b/tests/Functional/StatementTest.php @@ -300,4 +300,42 @@ public function testFetchInColumnMode(): void self::assertEquals(1, $result); } + + public function testExecuteQuery(): void + { + $platform = $this->connection->getDatabasePlatform(); + $query = $platform->getDummySelectSQL(); + $result = $this->connection->prepare($query)->executeQuery()->fetchOne(); + + 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]); + + $query = 'UPDATE stmt_test SET name = ? WHERE id = 1'; + $stmt = $this->connection->prepare($query); + + $stmt->bindValue(1, 'bar'); + + $result = $stmt->executeStatement(); + + $this->assertEquals(1, $result); + + $query = 'UPDATE stmt_test SET name = ? WHERE id = ?'; + $result = $this->connection->prepare($query)->executeStatement(['foo', 1]); + + $this->assertEquals(1, $result); + } } diff --git a/tests/Query/QueryBuilderTest.php b/tests/Query/QueryBuilderTest.php index d3574b6d079..2ee42b9d088 100644 --- a/tests/Query/QueryBuilderTest.php +++ b/tests/Query/QueryBuilderTest.php @@ -7,11 +7,13 @@ use Doctrine\DBAL\Query\Expression\ExpressionBuilder; use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Query\QueryException; +use Doctrine\DBAL\Result; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; class QueryBuilderTest extends TestCase { - /** @var Connection */ + /** @var Connection&MockObject */ protected $conn; protected function setUp(): void @@ -949,4 +951,21 @@ public function testJoinWithNonUniqueAliasThrowsException(): void $qb->getSQL(); } + + public function testExecuteSelect(): void + { + $qb = new QueryBuilder($this->conn); + + $this->conn + ->expects($this->any()) + ->method('executeQuery') + ->willReturn($this->createMock(Result::class)); + + $result = $qb + ->select('id') + ->from('foo') + ->execute(); + + self::assertInstanceOf(Result::class, $result); + } }