packages/ztd-query-mysql/tests/Unit/Rewrite/LoadData/ColumnMappingTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Rewrite\LoadData;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Rewrite\LoadData\ColumnMapping;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
12#[CoversClass(ColumnMapping::class)]
13final class ColumnMappingTest extends TestCase
14{
15 public function testInputTargets(): void
16 {
17 $sql = "LOAD DATA INFILE 'input.csv' INTO TABLE t (id, @raw)";
18 $statement = (new \PhpMyAdmin\SqlParser\Parser($sql))->statements[0];
19 self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\LoadStatement::class, $statement);
20 $definition = new \ZtdQuery\Schema\TableDefinition(['id', 'name', 'score'], [], [], [], [], generatedExpressions: ['score' => 'id * 2']);
21 self::assertSame(['id', '@raw'], (new ColumnMapping())->inputTargets($statement, $definition, $sql));
22 $statement->col_name_or_user_var = null;
23 self::assertSame(['id', 'name'], (new ColumnMapping())->inputTargets($statement, $definition, $sql));
24 }
25
26 public function testInputTarget(): void
27 {
28 $mapping = new ColumnMapping();
29 self::assertSame('name', $mapping->inputTarget('`name`', 'LOAD DATA'));
30 self::assertSame('@raw', $mapping->inputTarget('@`raw`', 'LOAD DATA'));
31 }
32
33 public function testInputTargetRejectsExpressions(): void
34 {
35 $this->expectException(\ZtdQuery\Exception\UnsupportedSqlException::class);
36 (new ColumnMapping())->inputTarget('id + 1', 'LOAD DATA');
37 }
38
39 public function testSetOperations(): void
40 {
41 $sql = "LOAD DATA INFILE 'input.csv' INTO TABLE t SET name = UPPER(@raw)";
42 $statement = (new \PhpMyAdmin\SqlParser\Parser($sql))->statements[0];
43 self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\LoadStatement::class, $statement);
44 $definition = new \ZtdQuery\Schema\TableDefinition(['id', 'name', 'score'], [], [], [], [], generatedExpressions: ['score' => 'id * 2']);
45 self::assertSame(['name' => 'UPPER(@raw)'], (new ColumnMapping())->setOperations($statement, $definition, $sql));
46 }
47
48 public function testIgnoreRows(): void
49 {
50 $sql = "LOAD DATA INFILE 'input.csv' INTO TABLE t IGNORE 2 LINES";
51 $statement = (new \PhpMyAdmin\SqlParser\Parser($sql))->statements[0];
52 self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\LoadStatement::class, $statement);
53 self::assertSame(2, (new ColumnMapping())->ignoreRows($statement, $sql));
54 $statement->ignore_number = null;
55 self::assertSame(0, (new ColumnMapping())->ignoreRows($statement, $sql));
56 }
57
58 public function testOptionValue(): void
59 {
60 $sql = "LOAD DATA INFILE 'input.csv' INTO TABLE t FIELDS TERMINATED BY ','";
61 $statement = (new \PhpMyAdmin\SqlParser\Parser($sql))->statements[0];
62 self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\LoadStatement::class, $statement);
63 $mapping = new ColumnMapping();
64 self::assertSame(',', $mapping->optionValue($statement->fields_options, 'TERMINATED BY', "\t"));
65 self::assertSame('fallback', $mapping->optionValue($statement->fields_options, 'ENCLOSED BY', 'fallback'));
66 self::assertSame('fallback', $mapping->optionValue(null, 'TERMINATED BY', 'fallback'));
67 }
68
69}
70