fix(database): emit valid shell env vars in dump-all MySQL imports

This commit is contained in:
Andras Bacsai
2026-09-09 13:06:04 +02:00
parent 5a3d0002f8
commit 903b5d3a0d
2 changed files with 25 additions and 1 deletions
@@ -62,6 +62,9 @@ class DatabaseImportCommandBuilder
private function mysqlDumpAll(string $binary, string $prefix, string $path): string
{
return "for pid in \$({$binary} -u root -p\${{$prefix}_ROOT_PASSWORD} -N -e \"SELECT id FROM information_schema.processlist WHERE user != 'root';\"); do {$binary} -u root -p\${{$prefix}_ROOT_PASSWORD} -e \"KILL \$pid\" 2>/dev/null || true; done && {$binary} -u root -p\${{$prefix}_ROOT_PASSWORD} -N -e \"SELECT CONCAT('DROP DATABASE IF EXISTS \\`',schema_name,'\\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');\" | {$binary} -u root -p\${{$prefix}_ROOT_PASSWORD} && {$binary} -u root -p\${{$prefix}_ROOT_PASSWORD} -e \"CREATE DATABASE IF NOT EXISTS \\`\${{{$prefix}_DATABASE:-default}}\\`;\" && (gunzip -cf {$path} 2>/dev/null || cat {$path}) | {$binary} -u root -p\${{{$prefix}_ROOT_PASSWORD}} \${{{$prefix}_DATABASE:-default}}";
$rootPassword = '${'.$prefix.'_ROOT_PASSWORD}';
$database = '${'.$prefix.'_DATABASE:-default}';
return "for pid in \$({$binary} -u root -p{$rootPassword} -N -e \"SELECT id FROM information_schema.processlist WHERE user != 'root';\"); do {$binary} -u root -p{$rootPassword} -e \"KILL \$pid\" 2>/dev/null || true; done && {$binary} -u root -p{$rootPassword} -N -e \"SELECT CONCAT('DROP DATABASE IF EXISTS \\`',schema_name,'\\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');\" | {$binary} -u root -p{$rootPassword} && {$binary} -u root -p{$rootPassword} -e \"CREATE DATABASE IF NOT EXISTS \\`{$database}\\`;\" && (gunzip -cf {$path} 2>/dev/null || cat {$path}) | {$binary} -u root -p{$rootPassword} {$database}";
}
}
@@ -48,6 +48,27 @@ test('builds dump-all commands and postgres safety scan', function () {
->toContain('docker exec postgres-safe');
});
test('dump-all mysql and mariadb commands use valid shell parameter expansions', function (string $class, string $binary, string $prefix) {
$builder = new DatabaseImportCommandBuilder;
$command = $builder->buildRestoreCommand(importResource($class), '/tmp/dump.sql.gz', true);
$rootPassword = '${'.$prefix.'_ROOT_PASSWORD}';
$database = '${'.$prefix.'_DATABASE:-default}';
expect($command)
->toContain($binary)
->toContain("gunzip -cf '/tmp/dump.sql.gz'")
->toContain('-p'.$rootPassword)
->toContain('CREATE DATABASE IF NOT EXISTS \`'.$database.'\`')
->and(substr_count($command, $rootPassword))->toBe(6)
->and(substr_count($command, $database))->toBe(2)
->and($command)->not->toContain('${{');
})->with([
'mysql' => [StandaloneMysql::class, 'mysql', 'MYSQL'],
'mariadb' => [StandaloneMariadb::class, 'mariadb', 'MARIADB'],
]);
test('stops PostgreSQL restores on the first error without replacing existing objects by default', function () {
$builder = new DatabaseImportCommandBuilder;
$postgres = importResource(StandalonePostgresql::class);