packages/ztd-query-postgres/tests/Unit/Sql/Merge/ActionClauseTest.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\ActionClause::class)]
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\BranchTokens::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\RelationTarget::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeClause::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeMatchKind::class)]
17final class ActionClauseTest extends TestCase
18{
19    public function testParseClause(): void
20    {
21        self::assertEquals(new \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeClause(matchKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeMatchKind::Matched, conditionSql: null, actionKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::Delete, assignments: [], insertColumns: [], insertValues: []), (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parseClause('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', 'WHEN MATCHED THEN DELETE'));
22
23        self::assertEquals(new \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeClause(matchKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeMatchKind::NotMatched, conditionSql: null, actionKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::DoNothing, assignments: [], insertColumns: [], insertValues: []), (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parseClause('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', 'WHEN NOT MATCHED THEN DO NOTHING'));
24
25        self::assertEquals(new \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeClause(matchKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeMatchKind::Matched, conditionSql: 's.active', actionKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::Update, assignments: ['name' => 's.name'], insertColumns: [], insertValues: []), (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parseClause('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', 'WHEN MATCHED AND s.active THEN UPDATE SET name = s.name'));
26
27        self::assertEquals(new \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeClause(matchKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeMatchKind::NotMatched, conditionSql: null, actionKind: \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::Insert, assignments: [], insertColumns: ['id', 'name'], insertValues: ['s.id', 's.name']), (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parseClause('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', 'WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)'));
28    }
29
30    public function testParseAssignments(): void
31    {
32        $sql = 'UPDATE SET id = source.id, name = source.name';
33        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
34
35        self::assertSame(['id' => 'source.id', 'name' => 'source.name'], (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parseAssignments('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', $sql, $tokens));
36    }
37
38    public function testParseInsert(): void
39    {
40        $sql = 'INSERT (id, name) VALUES (s.id, s.name)';
41        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
42
43        self::assertSame(['columns' => ['id', 'name'], 'values' => ['s.id', 's.name']], (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parseInsert('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', $sql, $tokens));
44
45        $sql = 'INSERT DEFAULT VALUES';
46        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
47
48        self::assertSame(['columns' => [], 'values' => []], (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parseInsert('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', $sql, $tokens));
49    }
50
51    public function testParenthesizedList(): void
52    {
53        $sql = '(id, coalesce(name, \'x\'))';
54        $tokens = \ZtdQuery\Sql\SqlTokenStream::tokenize($sql, \ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::create())->significantTokens();
55
56        self::assertSame(['items' => ['id', 'coalesce(name, \'x\')'], 'next' => 10], (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->parenthesizedList('MERGE INTO users u USING incoming s ON u.id = s.id WHEN MATCHED AND s.active THEN UPDATE SET name = s.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name)', $sql, $tokens, 0));
57    }
58    public function testActionMatchesTheBranchKind(): void
59    {
60        $clause = (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->action('MERGE test', ' DELETE', \ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeMatchKind::Matched, 'active');
61        self::assertSame(\ZtdQuery\Platform\Postgres\Sql\Merge\PgSqlMergeActionKind::Delete, $clause->actionKind);
62        self::assertSame('active', $clause->conditionSql);
63    }
64
65    public function testInsertColumnsUnquotesOrderedIdentifiers(): void
66    {
67        self::assertSame(['id', 'Display Name'], (new \ZtdQuery\Platform\Postgres\Sql\Merge\ActionClause())->insertColumns('MERGE test', ['id', '"Display Name"']));
68    }
69}
70