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