packages/ztd-query-postgres/tests/Unit/Sql/Merge/StatementPartsTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Merge;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9
10#[CoversClass(\ZtdQuery\Platform\Postgres\Sql\Merge\StatementParts::class)]
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\RelationTarget::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeClause::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeMatchKind::class)]
18final class StatementPartsTest extends TestCase
19{
20    public function testTargetSeparatesRelationAliasAndUsingDelimiter(): void
21    {
22        $sql = 'MERGE INTO users u USING source s ON u.id = s.id WHEN MATCHED THEN DELETE';
23        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
24        $parts = new \ZtdQuery\Platform\Postgres\Sql\Merge\StatementParts();
25        $target = $parts->target($sql, $sql, $tokens);
26        self::assertSame('users', $target['name']);
27        self::assertSame('users', $target['sql']);
28        self::assertSame('u', $target['alias']);
29        self::assertSame('USING', $target['using']->text);
30    }
31
32    public function testJoinSeparatesSourceConditionAndBranches(): void
33    {
34        $sql = 'MERGE INTO users u USING source s ON u.id = s.id WHEN MATCHED THEN DELETE';
35        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
36        $parts = new \ZtdQuery\Platform\Postgres\Sql\Merge\StatementParts();
37        $target = $parts->target($sql, $sql, $tokens);
38        $join = $parts->join($sql, $sql, $tokens, $target['using']);
39        self::assertSame('source s', $join['source']);
40        self::assertSame('u.id = s.id', $join['condition']);
41        self::assertCount(1, $join['when']);
42        self::assertSame('WHEN', $join['when'][0]->text);
43    }
44
45    public function testClausesParsesEachBranchAction(): void
46    {
47        $sql = 'MERGE INTO users u USING source s ON u.id = s.id WHEN MATCHED THEN DELETE';
48        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
49        $parts = new \ZtdQuery\Platform\Postgres\Sql\Merge\StatementParts();
50        $when = (new \ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens())->mergeWhenTokens($tokens);
51        $clauses = $parts->clauses($sql, $sql, $when);
52        self::assertCount(1, $clauses);
53        self::assertSame(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::Delete, $clauses[0]->actionKind);
54    }
55}
56