packages/ztd-query-mysql/tests/Unit/Rewrite/Transformer/Update/TargetProjectionTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Rewrite\Transformer\Update;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Rewrite\Transformer\Update\TargetProjection;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlIdentifierQuoter::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
13#[CoversClass(TargetProjection::class)]
14final class TargetProjectionTest extends TestCase
15{
16    public function testTargetsFromContexts(): void
17    {
18        $targets = (new TargetProjection())->targetsFromContexts(['users' => ['alias' => 'u'], 'missing' => ['alias' => 'm']], ['users' => ['columns' => ['id', 'name'], 'primaryKeys' => ['id']]]);
19        self::assertCount(1, $targets);
20        self::assertSame('users', $targets[0]->tableName());
21        self::assertSame(['id', 'name'], $targets[0]->columns());
22        self::assertSame(['id'], $targets[0]->primaryKeys());
23    }
24
25    public function testMultiTableSelectColumns(): void
26    {
27        $statement = (new \PhpMyAdmin\SqlParser\Parser('UPDATE users u SET name = 7 WHERE id = 1'))->statements[0];
28        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\UpdateStatement::class, $statement);
29        $target = new \ZtdQuery\Shadow\Mutation\Row\MultiTableMutationTarget('users', ['id', 'name'], ['id']);
30        $codec = new \ZtdQuery\Shadow\Mutation\Row\MultiTableMutationRow();
31        self::assertSame(['`u`.`id` AS `' . $codec->valueColumn(0, 0) . '`', '9 AS `' . $codec->valueColumn(0, 1) . '`', '`u`.`id` AS `' . $codec->identityColumn(0, 0) . '`'], (new TargetProjection())->multiTableSelectColumns($statement, ['users' => ['alias' => 'u']], [$target], ['9']));
32    }
33
34    public function testAssignmentsByTable(): void
35    {
36        $statement = (new \PhpMyAdmin\SqlParser\Parser('UPDATE users u, posts p SET u.name = 7, p.title = 8'))->statements[0];
37        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\UpdateStatement::class, $statement);
38        self::assertSame(['users' => ['name' => '9'], 'posts' => ['title' => '8']], (new TargetProjection())->assignmentsByTable($statement, ['users' => ['alias' => 'u'], 'posts' => ['alias' => 'p']], ['9']));
39    }
40
41    public function testUnquoteIdentifier(): void
42    {
43        self::assertSame('a`b', TargetProjection::unquoteIdentifier('`a``b`'));
44        self::assertSame('name', TargetProjection::unquoteIdentifier('name'));
45    }
46
47    public function testBuildAdditionalTables(): void
48    {
49        $statement = (new \PhpMyAdmin\SqlParser\Parser('UPDATE users u, posts p SET u.name = 7, p.title = 8'))->statements[0];
50        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\UpdateStatement::class, $statement);
51        self::assertSame(', `posts` AS p', (new TargetProjection())->buildAdditionalTables($statement));
52    }
53
54    public function testBuildJoinClause(): void
55    {
56        $statement = (new \PhpMyAdmin\SqlParser\Parser('UPDATE users u JOIN posts p ON p.uid = u.id SET u.name = 7'))->statements[0];
57        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\UpdateStatement::class, $statement);
58        self::assertSame(' JOIN `posts` AS p ON p.uid = u.id', (new TargetProjection())->buildJoinClause($statement));
59    }
60
61    public function testTargetTable(): void
62    {
63        $statement = (new \PhpMyAdmin\SqlParser\Parser('UPDATE users u SET name = 7 WHERE id = 1'))->statements[0];
64        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\UpdateStatement::class, $statement);
65        self::assertSame('users', (new TargetProjection())->targetTable($statement, $statement->build()));
66    }
67
68}
69