Quelltext des aktuellen Standes
<?php
declare(strict_types=1);
use OpenNIT\Content\UpdateManager;
/**
* Deckt die Einordnung von SQL-Fehlern während eines Migrationslaufs ab.
*
* Ein als harmlos eingestufter Fehler führt dazu, dass die Migration als
* angewendet vermerkt wird und nie wieder läuft. Diese Nachsicht darf deshalb
* nur Anweisungen betreffen, deren Ziel bereits erreicht ist – niemals solche,
* deren Wirkung ausgeblieben ist.
*/
return static function (): void {
$einordnen = static function (string $meldung, string $statement = ''): bool {
$ref = new ReflectionClass(UpdateManager::class);
$m = $ref->getMethod('isIgnorableSqlError');
$m->setAccessible(true);
return (bool)$m->invokeArgs($ref->newInstanceWithoutConstructor(), [$meldung, $statement]);
};
test('Bereits vorhandene Strukturen sind harmlos', function () use ($einordnen) {
assertTrue($einordnen("Table 'assets' already exists"));
assertTrue($einordnen("Duplicate column name 'status'", 'ALTER TABLE assets ADD COLUMN status VARCHAR(20)'));
assertTrue($einordnen("Duplicate key name 'idx_status'", 'ALTER TABLE assets ADD INDEX idx_status (status)'));
assertTrue($einordnen("Can't DROP 'alt'; check that column/key exists"));
});
test('Doppelwerte beim Anlegen eines eindeutigen Schlüssels sind ein harter Fehler', function () use ($einordnen) {
// Der Schlüssel entsteht nicht – die Migration darf nicht als erledigt gelten.
assertFalse($einordnen(
"Duplicate entry '7-2' for key 'uniq_page_version'",
'ALTER TABLE page_versions ADD UNIQUE KEY uniq_page_version (page_id, version_number)'
));
assertFalse($einordnen(
"Duplicate entry '3' for key 'PRIMARY'",
'ALTER TABLE foo ADD PRIMARY KEY (id)'
));
assertFalse($einordnen(
"Duplicate entry 'x' for key 'uk_foo'",
'ALTER TABLE foo ADD CONSTRAINT uk_foo UNIQUE (name)'
));
});
test('Ein bereits vorhandener Datensatz bleibt harmlos', function () use ($einordnen) {
// Hier ist der Zielzustand erreicht, die Anweisung also wirkungslos.
assertTrue($einordnen(
"Duplicate entry 'mail_host' for key 'PRIMARY'",
"INSERT INTO system_settings (`key`, `value`) VALUES ('mail_host', '')"
));
});
test('Fehlende Rechte auf Views und Trigger bleiben harmlos', function () use ($einordnen) {
assertTrue($einordnen('SQLSTATE[HY000]: 1419 ... SUPER privilege'));
assertTrue($einordnen('log_bin_trust_function_creators'));
});
};