diff --git a/composer.json b/composer.json index 0016c08..6a69587 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ ], "require": { "php": "^8.1", - "doctrine/orm": "^3.0.0" + "doctrine/orm": "^3.3.0" }, "require-dev": { "doctrine/dbal": "^4.0", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4a129f6..cb5f743 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,16 +1,32 @@ + + + + tests + + diff --git a/src/HintDrivenSqlWalker.php b/src/HintDrivenSqlWalker.php index 23a69f0..b532276 100644 --- a/src/HintDrivenSqlWalker.php +++ b/src/HintDrivenSqlWalker.php @@ -53,6 +53,10 @@ use Doctrine\ORM\Query\AST\UpdateItem; use Doctrine\ORM\Query\AST\UpdateStatement; use Doctrine\ORM\Query\AST\WhereClause; +use Doctrine\ORM\Query\Exec\PreparedExecutorFinalizer; +use Doctrine\ORM\Query\Exec\SingleSelectSqlFinalizer; +use Doctrine\ORM\Query\Exec\SqlFinalizer; +use Doctrine\ORM\Query\OutputWalker; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; use LogicException; @@ -61,7 +65,7 @@ /** * @psalm-import-type QueryComponent from Parser */ -class HintDrivenSqlWalker extends SqlWalker +class HintDrivenSqlWalker extends SqlWalker implements OutputWalker { /** @@ -91,6 +95,22 @@ public function __construct( } } + public function getFinalizer(DeleteStatement|UpdateStatement|SelectStatement $AST): SqlFinalizer + { + switch (true) { + case $AST instanceof SelectStatement: + return new SingleSelectSqlFinalizer($this->walkSelectStatement($AST)); + + case $AST instanceof UpdateStatement: + return new PreparedExecutorFinalizer($this->createUpdateStatementExecutor($AST)); + + case $AST instanceof DeleteStatement: // @phpstan-ignore instanceof.alwaysTrue (keep it readable) + return new PreparedExecutorFinalizer($this->createDeleteStatementExecutor($AST)); + } + + throw new LogicException('Unexpected AST node type'); + } + public function walkSelectStatement(SelectStatement $AST): string { return $this->callWalkers(SqlNode::SelectStatement, parent::walkSelectStatement($AST)); diff --git a/tests/Handlers/CommentWholeSqlHintHandler.php b/tests/Handlers/CommentWholeSqlHintHandler.php index 05e80e3..9e34ac4 100644 --- a/tests/Handlers/CommentWholeSqlHintHandler.php +++ b/tests/Handlers/CommentWholeSqlHintHandler.php @@ -13,7 +13,7 @@ class CommentWholeSqlHintHandler extends HintHandler public function getNodes(): array { - return [SqlNode::SelectStatement]; + return [SqlNode::SelectStatement, SqlNode::UpdateStatement, SqlNode::DeleteStatement]; } public function processNode(SqlNode $sqlNode, string $sql): string diff --git a/tests/HintDrivenSqlWalkerTest.php b/tests/HintDrivenSqlWalkerTest.php index 4851e12..a307f00 100644 --- a/tests/HintDrivenSqlWalkerTest.php +++ b/tests/HintDrivenSqlWalkerTest.php @@ -20,13 +20,12 @@ class HintDrivenSqlWalkerTest extends TestCase { /** - * @param mixed $hintValue * @dataProvider walksProvider */ public function testWalker( string $dql, string $handlerClass, - $hintValue, + mixed $hintValue, string $expectedSql, ): void { @@ -56,12 +55,26 @@ public static function walksProvider(): iterable 'select d0_.id AS id_0 FROM dummy_entity d0_', ]; - yield 'Comment whole sql' => [ + yield 'Comment whole sql - select' => [ $selectDql, CommentWholeSqlHintHandler::class, 'custom comment', 'SELECT d0_.id AS id_0 FROM dummy_entity d0_ -- custom comment', ]; + + yield 'Comment whole sql - update' => [ + sprintf('UPDATE %s w SET w.id = 1', DummyEntity::class), + CommentWholeSqlHintHandler::class, + 'custom comment', + 'UPDATE dummy_entity SET id = 1 -- custom comment', + ]; + + yield 'Comment whole sql - delete' => [ + sprintf('DELETE FROM %s w', DummyEntity::class), + CommentWholeSqlHintHandler::class, + 'custom comment', + 'DELETE FROM dummy_entity -- custom comment', + ]; } private function createEntityManagerMock(): EntityManager