Quelltext des aktuellen Standes
<?php
declare(strict_types=1);
/**
* MySQL 8 und MariaDB reservieren unterschiedliche Wörter. Ein Alias wie
* `AS system` läuft auf MariaDB durch und ist auf MySQL 8 ein Syntaxfehler –
* die Abfrage scheitert dort bei jedem Aufruf, unabhängig von den Daten. Weil
* die Suite ohne Datenbank läuft und der Migrations-Smoke-Test nur das Schema
* anlegt, fiele so etwas sonst erst beim Betrieb auf einer MySQL-Instanz auf.
*
* Geprüft wird der Quelltext: Jeder Alias hinter `AS` muss entweder unverfänglich
* oder in Backticks gesetzt sein.
*/
return static function (): void {
$wurzel = dirname(__DIR__);
/**
* In MySQL 8.0 reservierte Wörter, die sich als Alias oder Spaltenname
* anbieten (Fensterfunktionen und Verwandte, seit 8.0.3 reserviert).
*/
$reserviert = [
'system', 'rank', 'row', 'rows', 'groups', 'window', 'lead', 'lag', 'over',
'recursive', 'empty', 'except', 'lateral', 'cube', 'grouping', 'of',
'first_value', 'last_value', 'row_number', 'dense_rank', 'percent_rank',
'cume_dist', 'ntile', 'nth_value', 'json_table',
];
/** Alle PHP-Dateien unter src/. */
$dateien = static function () use ($wurzel): array {
$out = [];
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($wurzel . '/src'));
foreach ($it as $d) {
if ($d->isFile() && $d->getExtension() === 'php') {
$out[] = $d->getPathname();
}
}
sort($out);
return $out;
};
test('Kein SQL-Alias trägt ein in MySQL 8 reserviertes Wort ohne Backticks', function () use ($dateien, $reserviert, $wurzel) {
$muster = '/\bAS\s+(' . implode('|', $reserviert) . ')\b(?!\s*`)/i';
$treffer = [];
foreach ($dateien() as $datei) {
$inhalt = (string)file_get_contents($datei);
if (preg_match_all($muster, $inhalt, $m, PREG_OFFSET_CAPTURE)) {
foreach ($m[1] as $einzel) {
$zeile = substr_count(substr($inhalt, 0, (int)$einzel[1]), "\n") + 1;
$treffer[] = str_replace($wurzel . '/', '', $datei) . ':' . $zeile . ' → AS ' . $einzel[0];
}
}
}
assertSame([], $treffer, 'Alias in Backticks setzen: ' . implode(' | ', $treffer));
});
test('Die Zählung des Software-Inventars nennt ihren Alias maskiert', function () use ($wurzel) {
$quelle = (string)file_get_contents($wurzel . '/src/Software/SoftwareInventory.php');
assertTrue(str_contains($quelle, 'AS `system`'), 'Der Alias der Systembestandteile ist nicht maskiert');
});
};