packages/ztd-query-mysql/tests/Unit/Shadow/Mutation/Row/RowMutationResolverTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation\Row;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Shadow\Mutation\Row\RowMutationResolver;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\DmlWhereClauseExtractor::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\TargetName::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\MySqlCastRenderer::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Cte\MySqlCteShadowComposer::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\FullText\MySqlFullTextSearchRewriter::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\GeneratedColumn\MySqlGeneratedColumnProjector::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlIdentifierQuoter::class)]
18#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
19#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlParser::class)]
20#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Partition\MySqlPartitionSelectionRewriter::class)]
21#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Relation\MySqlSelectRelationParser::class)]
22#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Type\MySqlTypeSemantics::class)]
23#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Upsert\MySqlUpsertAssignmentExtractor::class)]
24#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\MySqlUpsertExpressionParser::class)]
25#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\MySqlValueRenderer::class)]
26#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\AssignmentExpression::class)]
27#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Cte\HeaderParser::class)]
28#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Cte\IdentifierReferences::class)]
29#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\OptionalInsertIntoNormalizer::class)]
30#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Relation\ExpressionNames::class)]
31#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Relation\ReferenceReader::class)]
32#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Upsert\AssignmentReader::class)]
33#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\ExpressionReader::class)]
34#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\LiteralReader::class)]
35#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\StringLiteral::class)]
36#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\FullText\ExpressionEditor::class)]
37#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Partition\SelectionReader::class)]
38#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Partition\SourceProjection::class)]
39#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer::class)]
40#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Delete\ResultSelect::class)]
41#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Delete\TargetProjection::class)]
42#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer::class)]
43#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Set\OrderRewriter::class)]
44#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Set\ValueNormalizer::class)]
45#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Shadow\CteRows::class)]
46#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer::class)]
47#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Update\ResultSelect::class)]
48#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Update\TargetProjection::class)]
49#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\CastTypeResolver::class)]
50#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Type\RankEdits::class)]
51#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\ScalarExpression::class)]
52#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\StringCoercion::class)]
53#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\UpdateAssignmentExtractor::class)]
54#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\UpdateSourceExtractor::class)]
55#[CoversClass(RowMutationResolver::class)]
56final class RowMutationResolverTest extends TestCase
57{
58    public function testResolveInsert(): void
59    {
60        $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
61        $select = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer();
62        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
63        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id', 'name'], [], ['id'], [], []));
64        $store = new \ZtdQuery\Shadow\ShadowStore();
65        $store->set('users', [['id' => 1, 'name' => 'old']]);
66        $resolver = new RowMutationResolver(new \ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer($parser, $select), $registry, $store, new \ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer($parser, $select));
67        $statement = (new \PhpMyAdmin\SqlParser\Parser('INSERT INTO users (id) VALUES (2)'))->statements[0];
68        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\InsertStatement::class, $statement);
69        $mutation = $resolver->resolveInsert($statement, $statement->build());
70        self::assertInstanceOf(\ZtdQuery\Shadow\Mutation\Row\InsertMutation::class, $mutation);
71        self::assertSame('users', $mutation->tableName());
72    }
73
74    public function testResolveUpdate(): void
75    {
76        $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
77        $select = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer();
78        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
79        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id', 'name'], [], ['id'], [], []));
80        $store = new \ZtdQuery\Shadow\ShadowStore();
81        $store->set('users', [['id' => 1, 'name' => 'old']]);
82        $resolver = new RowMutationResolver(new \ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer($parser, $select), $registry, $store, new \ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer($parser, $select));
83        $statement = (new \PhpMyAdmin\SqlParser\Parser('UPDATE users SET name = 7'))->statements[0];
84        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\UpdateStatement::class, $statement);
85        $mutation = $resolver->resolveUpdate($statement, $statement->build());
86        self::assertInstanceOf(\ZtdQuery\Shadow\Mutation\Row\UpdateMutation::class, $mutation);
87        self::assertSame('users', $mutation->tableName());
88    }
89
90    public function testResolveDelete(): void
91    {
92        $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
93        $select = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer();
94        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
95        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id', 'name'], [], ['id'], [], []));
96        $store = new \ZtdQuery\Shadow\ShadowStore();
97        $store->set('users', [['id' => 1, 'name' => 'old']]);
98        $resolver = new RowMutationResolver(new \ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer($parser, $select), $registry, $store, new \ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer($parser, $select));
99        $statement = (new \PhpMyAdmin\SqlParser\Parser('DELETE FROM users'))->statements[0];
100        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\DeleteStatement::class, $statement);
101        $mutation = $resolver->resolveDelete($statement, $statement->build());
102        self::assertInstanceOf(\ZtdQuery\Shadow\Mutation\Row\DeleteMutation::class, $mutation);
103        self::assertSame('users', $mutation->tableName());
104    }
105
106    public function testResolveReplace(): void
107    {
108        $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
109        $select = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer();
110        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
111        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id', 'name'], [], ['id'], [], []));
112        $store = new \ZtdQuery\Shadow\ShadowStore();
113        $store->set('users', [['id' => 1, 'name' => 'old']]);
114        $resolver = new RowMutationResolver(new \ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer($parser, $select), $registry, $store, new \ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer($parser, $select));
115        $statement = (new \PhpMyAdmin\SqlParser\Parser('REPLACE INTO users (id) VALUES (2)'))->statements[0];
116        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\ReplaceStatement::class, $statement);
117        $mutation = $resolver->resolveReplace($statement, $statement->build());
118        self::assertInstanceOf(\ZtdQuery\Shadow\Mutation\Row\ReplaceMutation::class, $mutation);
119        self::assertSame('users', $mutation->tableName());
120    }
121
122
123    public function testMultiTableTargets(): void
124    {
125        $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
126        $select = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer();
127        $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
128        $registry->register('users', new \ZtdQuery\Schema\TableDefinition(['id', 'name'], [], ['id'], [], []));
129        $store = new \ZtdQuery\Shadow\ShadowStore();
130        $store->set('users', [['id' => 1, 'name' => 'old']]);
131        $resolver = new RowMutationResolver(new \ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer($parser, $select), $registry, $store, new \ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer($parser, $select));
132        $targets = $resolver->multiTableTargets(['users'], 'UPDATE users SET name = 7');
133        self::assertCount(1, $targets);
134        self::assertSame('users', $targets[0]->tableName());
135        self::assertSame(['id', 'name'], $targets[0]->columns());
136        self::assertSame(['id'], $targets[0]->primaryKeys());
137    }
138
139}
140