‪TYPO3CMS  ‪main
IndexDefinitionTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
28 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
29 
33 final class ‪IndexDefinitionTest extends UnitTestCase
34 {
47  public static function ‪canParseIndexDefinitionDataProvider(): array
48  {
49  return [
50  'PRIMARY KEY (single column)' => [
51  'PRIMARY KEY (`aField`)',
52  '',
53  [['aField', 0, null]],
54  true,
55  false,
56  false,
57  false,
58  '',
59  [],
60  ],
61  'PRIMARY KEY (multiple columns)' => [
62  'PRIMARY KEY (`aField`, `bField`(199), cField)',
63  '',
64  [['aField', 0, null], ['bField', 199, null], ['cField', 0, null]],
65  true,
66  false,
67  false,
68  false,
69  '',
70  [],
71  ],
72  'PRIMARY KEY (index type)' => [
73  'PRIMARY KEY USING HASH (`aField`)',
74  '',
75  [['aField', 0, null]],
76  true,
77  false,
78  false,
79  false,
80  'HASH',
81  [],
82  ],
83  'PRIMARY KEY (index options)' => [
84  "PRIMARY KEY (`aField`, bField(199)) KEY_BLOCK_SIZE 4 WITH PARSER `something` COMMENT 'aTest'",
85  '',
86  [['aField', 0, null], ['bField', 199, null]],
87  true,
88  false,
89  false,
90  false,
91  '',
92  [
93  'key_block_size' => 4,
94  'parser' => new ‪Identifier('something'),
95  'comment' => 'aTest',
96  ],
97  ],
98  'PRIMARY KEY (all parts)' => [
99  "PRIMARY KEY USING BTREE (`aField`, bField(199)) KEY_BLOCK_SIZE 4 COMMENT 'aTest'",
100  '',
101  [['aField', 0, null], ['bField', 199, null]],
102  true,
103  false,
104  false,
105  false,
106  'BTREE',
107  [
108  'key_block_size' => 4,
109  'comment' => 'aTest',
110  ],
111  ],
112  'INDEX (single column)' => [
113  'INDEX (`aField`(24))',
114  '',
115  [['aField', 24, null]],
116  false,
117  false,
118  false,
119  false,
120  '',
121  [],
122  ],
123  'INDEX (multiple columns)' => [
124  'INDEX (`aField`(24), bField)',
125  '',
126  [['aField', 24, null], ['bField', 0, null]],
127  false,
128  false,
129  false,
130  false,
131  '',
132  [],
133  ],
134  'INDEX (index name)' => [
135  'INDEX aIndex (`aField`)',
136  'aIndex',
137  [['aField', 0, null]],
138  false,
139  false,
140  false,
141  false,
142  '',
143  [],
144  ],
145  'INDEX (index type)' => [
146  'INDEX USING HASH (`aField`)',
147  '',
148  [['aField', 0, null]],
149  false,
150  false,
151  false,
152  false,
153  'HASH',
154  [],
155  ],
156  'INDEX (index name & type)' => [
157  'INDEX `aIndex` USING BTREE (`aField`)',
158  'aIndex',
159  [['aField', 0, null]],
160  false,
161  false,
162  false,
163  false,
164  'BTREE',
165  [],
166  ],
167  'INDEX (all parts)' => [
168  "INDEX `aIndex` USING BTREE (`aField`) COMMENT 'aComment'",
169  'aIndex',
170  [['aField', 0, null]],
171  false,
172  false,
173  false,
174  false,
175  'BTREE',
176  [
177  'comment' => 'aComment',
178  ],
179  ],
180  'KEY (single column)' => [
181  'KEY (`aField`(24))',
182  '',
183  [['aField', 24, null]],
184  false,
185  false,
186  false,
187  false,
188  '',
189  [],
190  ],
191  'KEY (multiple columns)' => [
192  'KEY (`aField`(24), bField)',
193  '',
194  [['aField', 24, null], ['bField', 0, null]],
195  false,
196  false,
197  false,
198  false,
199  '',
200  [],
201  ],
202  'KEY (index name)' => [
203  'KEY aIndex (`aField`)',
204  'aIndex',
205  [['aField', 0, null]],
206  false,
207  false,
208  false,
209  false,
210  '',
211  [],
212  ],
213  'KEY (index type)' => [
214  'KEY USING BTREE (aField(96))',
215  '',
216  [['aField', 96, null]],
217  false,
218  false,
219  false,
220  false,
221  'BTREE',
222  [],
223  ],
224  'KEY (index name & type)' => [
225  'KEY `aIndex` USING HASH (`aField`)',
226  'aIndex',
227  [['aField', 0, null]],
228  false,
229  false,
230  false,
231  false,
232  'HASH',
233  [],
234  ],
235  'KEY (all parts)' => [
236  'KEY `aIndex` USING HASH (`aField`) WITH PARSER aParser',
237  'aIndex',
238  [['aField', 0, null]],
239  false,
240  false,
241  false,
242  false,
243  'HASH',
244  [
245  'parser' => new ‪Identifier('aParser'),
246  ],
247  ],
248  'UNIQUE (single column)' => [
249  'UNIQUE (`aField`)',
250  '',
251  [['aField', 0, null]],
252  false,
253  true,
254  false,
255  false,
256  '',
257  [],
258  ],
259  'UNIQUE (multiple columns)' => [
260  'UNIQUE (`aField`, bField, cField(40))',
261  '',
262  [['aField', 0, null], ['bField', 0, null], ['cField', 40, null]],
263  false,
264  true,
265  false,
266  false,
267  '',
268  [],
269  ],
270  'UNIQUE INDEX (single column)' => [
271  'UNIQUE INDEX (`aField`)',
272  '',
273  [['aField', 0, null]],
274  false,
275  true,
276  false,
277  false,
278  '',
279  [],
280  ],
281  'UNIQUE KEY (multiple columns)' => [
282  'UNIQUE KEY (`aField`, bField, cField(40))',
283  '',
284  [['aField', 0, null], ['bField', 0, null], ['cField', 40, null]],
285  false,
286  true,
287  false,
288  false,
289  '',
290  [],
291  ],
292  'UNIQUE (index name)' => [
293  'UNIQUE aIndex (`aField`)',
294  'aIndex',
295  [['aField', 0, null]],
296  false,
297  true,
298  false,
299  false,
300  '',
301  [],
302  ],
303  'UNIQUE (index type)' => [
304  'UNIQUE USING BTREE (`aField`)',
305  '',
306  [['aField', 0, null]],
307  false,
308  true,
309  false,
310  false,
311  'BTREE',
312  [],
313  ],
314  'UNIQUE (index name & type)' => [
315  'UNIQUE `aIndex` USING BTREE (`aField`)',
316  'aIndex',
317  [['aField', 0, null]],
318  false,
319  true,
320  false,
321  false,
322  'BTREE',
323  [],
324  ],
325  'UNIQUE (all parts)' => [
326  'UNIQUE `aIndex` USING BTREE (`aField`) KEY_BLOCK_SIZE = 24',
327  'aIndex',
328  [['aField', 0, null]],
329  false,
330  true,
331  false,
332  false,
333  'BTREE',
334  [
335  'key_block_size' => 24,
336  ],
337  ],
338  'FULLTEXT (single column)' => [
339  'FULLTEXT (`aField`)',
340  '',
341  [['aField', 0, null]],
342  false,
343  false,
344  true,
345  false,
346  '',
347  [],
348  ],
349  'FULLTEXT (multiple columns)' => [
350  'FULLTEXT (`aField`, `bField`)',
351  '',
352  [['aField', 0, null], ['bField', 0, null]],
353  false,
354  false,
355  true,
356  false,
357  '',
358  [],
359  ],
360  'FULLTEXT (index name)' => [
361  'FULLTEXT aIndex (`aField`, `bField`)',
362  'aIndex',
363  [['aField', 0, null], ['bField', 0, null]],
364  false,
365  false,
366  true,
367  false,
368  '',
369  [],
370  ],
371  'FULLTEXT (all parts)' => [
372  "FULLTEXT `aIndex` (`aField`, `bField`) COMMENT 'aComment'",
373  'aIndex',
374  [['aField', 0, null], ['bField', 0, null]],
375  false,
376  false,
377  true,
378  false,
379  '',
380  [
381  'comment' => 'aComment',
382  ],
383  ],
384  'FULLTEXT INDEX (single column)' => [
385  'FULLTEXT INDEX (`aField`)',
386  '',
387  [['aField', 0, null]],
388  false,
389  false,
390  true,
391  false,
392  '',
393  [],
394  ],
395  'FULLTEXT INDEX (multiple columns)' => [
396  'FULLTEXT INDEX (`aField`, bField(19))',
397  '',
398  [['aField', 0, null], ['bField', 19, null]],
399  false,
400  false,
401  true,
402  false,
403  '',
404  [],
405  ],
406  'FULLTEXT KEY (single column)' => [
407  'FULLTEXT KEY (aField(20))',
408  '',
409  [['aField', 20, null]],
410  false,
411  false,
412  true,
413  false,
414  '',
415  [],
416  ],
417  'FULLTEXT KEY (multiple columns)' => [
418  'FULLTEXT KEY (aField(20), `bField`)',
419  '',
420  [['aField', 20, null], ['bField', 0, null]],
421  false,
422  false,
423  true,
424  false,
425  '',
426  [],
427  ],
428  'SPATIAL (single column)' => [
429  'SPATIAL (`aField`)',
430  '',
431  [['aField', 0, null]],
432  false,
433  false,
434  false,
435  true,
436  '',
437  [],
438  ],
439  'SPATIAL (multiple columns)' => [
440  'SPATIAL (`aField`, `bField`)',
441  '',
442  [['aField', 0, null], ['bField', 0, null]],
443  false,
444  false,
445  false,
446  true,
447  '',
448  [],
449  ],
450  'SPATIAL (index name)' => [
451  'SPATIAL `aIndex` (`aField`, `bField`)',
452  'aIndex',
453  [['aField', 0, null], ['bField', 0, null]],
454  false,
455  false,
456  false,
457  true,
458  '',
459  [],
460  ],
461  'SPATIAL (all parts)' => [
462  "SPATIAL `aIndex` (`aField`, `bField`) WITH PARSER aParser COMMENT 'aComment'",
463  'aIndex',
464  [['aField', 0, null], ['bField', 0, null]],
465  false,
466  false,
467  false,
468  true,
469  '',
470  [
471  'parser' => new ‪Identifier('aParser'),
472  'comment' => 'aComment',
473  ],
474  ],
475  'SPATIAL INDEX (single column)' => [
476  'SPATIAL INDEX (`aField`)',
477  '',
478  [['aField', 0, null]],
479  false,
480  false,
481  false,
482  true,
483  '',
484  [],
485  ],
486  'SPATIAL INDEX (multiple columns)' => [
487  'SPATIAL INDEX (aField, bField)',
488  '',
489  [['aField', 0, null], ['bField', 0, null]],
490  false,
491  false,
492  false,
493  true,
494  '',
495  [],
496  ],
497  'SPATIAL KEY (single column)' => [
498  'SPATIAL KEY (aField)',
499  '',
500  [['aField', 0, null]],
501  false,
502  false,
503  false,
504  true,
505  '',
506  [],
507  ],
508  'SPATIAL KEY (multiple columns)' => [
509  'SPATIAL KEY (aField, bField(240))',
510  '',
511  [['aField', 0, null], ['bField', 240, null]],
512  false,
513  false,
514  false,
515  true,
516  '',
517  [],
518  ],
519  ];
520  }
521 
522  #[DataProvider('canParseIndexDefinitionDataProvider')]
523  #[Test]
524  public function ‪canParseIndexDefinition(
525  string $indexDefinition,
526  string $indexName,
527  array $indexColumns,
528  bool $isPrimary,
529  bool $isUnique,
530  bool $isFulltext,
531  bool $isSpatial,
532  string $indexType,
533  array $indexOptions
534  ): void {
535  $statement = sprintf('CREATE TABLE `aTable`(`aField` INT(11), %s);', $indexDefinition);
536  $subject = $this->‪createSubject($statement);
537 
538  self::assertInstanceOf(CreateIndexDefinitionItem::class, $subject);
539  self::assertSame($indexName, $subject->indexName->schemaObjectName);
540  self::assertSame($isPrimary, $subject->isPrimary);
541  self::assertSame($isUnique, $subject->isUnique);
542  self::assertSame($isFulltext, $subject->isFulltext);
543  self::assertSame($isSpatial, $subject->isSpatial);
544  self::assertSame($indexType, $subject->indexType);
545  self::assertEquals($indexOptions, $subject->options);
546 
547  foreach ($indexColumns as $index => $column) {
548  self::assertSame($column[0], $subject->columnNames[$index]->columnName->schemaObjectName);
549  self::assertSame($column[1], $subject->columnNames[$index]->length);
550  self::assertSame($column[2], $subject->columnNames[$index]->direction);
551  }
552  }
553 
557  private function ‪createSubject(string $statement): ‪AbstractCreateDefinitionItem
558  {
559  ‪$parser = new ‪Parser(new ‪Lexer());
561  $createTableStatement = ‪$parser->getAST($statement);
562  return $createTableStatement->createDefinition->items[1];
563  }
564 }
‪TYPO3\CMS\Core\Database\Schema\Parser\AST\Identifier
Definition: Identifier.php:27
‪TYPO3\CMS\Core\Tests\Unit\Database\Schema\Parser\IndexDefinitionTest
Definition: IndexDefinitionTest.php:34
‪TYPO3\CMS\Core\Database\Schema\Parser\AST\CreateTableStatement
Definition: CreateTableStatement.php:26
‪TYPO3\CMS\Core\Database\Schema\Parser\AST\CreateIndexDefinitionItem
Definition: CreateIndexDefinitionItem.php:26
‪TYPO3\CMS\Core\Tests\Unit\Database\Schema\Parser\IndexDefinitionTest\canParseIndexDefinitionDataProvider
‪static canParseIndexDefinitionDataProvider()
Definition: IndexDefinitionTest.php:47
‪$parser
‪$parser
Definition: annotationChecker.php:103
‪TYPO3\CMS\Core\Tests\Unit\Database\Schema\Parser\IndexDefinitionTest\createSubject
‪createSubject(string $statement)
Definition: IndexDefinitionTest.php:557
‪TYPO3\CMS\Core\Database\Schema\Parser\Parser
Definition: Parser.php:75
‪TYPO3\CMS\Core\Tests\Unit\Database\Schema\Parser\IndexDefinitionTest\canParseIndexDefinition
‪canParseIndexDefinition(string $indexDefinition, string $indexName, array $indexColumns, bool $isPrimary, bool $isUnique, bool $isFulltext, bool $isSpatial, string $indexType, array $indexOptions)
Definition: IndexDefinitionTest.php:524
‪TYPO3\CMS\Core\Database\Schema\Parser\AST\AbstractCreateDefinitionItem
Definition: AbstractCreateDefinitionItem.php:24
‪TYPO3\CMS\Core\Tests\Unit\Database\Schema\Parser
Definition: AbstractDataTypeBaseTestCase.php:18
‪TYPO3\CMS\Core\Database\Schema\Parser\Lexer
Definition: Lexer.php:26