Checkpoint: mysqldump n'est pas disponible dans le container Node.js. Remplacement par un dump SQL généré directement via mysql2 : SHOW CREATE TABLE + SELECT * pour chaque table, avec échappement correct des valeurs.

This commit is contained in:
Manus
2026-08-08 10:52:58 +00:00
parent d3426c1663
commit 6b83361056

View File

@@ -256,13 +256,48 @@ async function startServer() {
const fileName = `backup-${database}-${timestamp}.sql`;
const filePath = path.join(backupDir, fileName);
// Construire la commande mysqldump
const sslFlag = dbUrl.searchParams.get("ssl-mode") === "DISABLED" ? "" : "--ssl-mode=REQUIRED";
const cmd = `mysqldump ${sslFlag} -h "${host}" -P ${port} -u "${username}" --password="${password}" "${database}" > "${filePath}"`;
// Dump SQL via mysql2 (pas besoin de mysqldump)
console.log(`[Backup] Generating SQL dump for database ${database}...`);
const mysql = await import("mysql2/promise");
const sslRequired = !dbUrl.searchParams.get("ssl-mode")?.includes("DISABLED");
const conn = await mysql.createConnection({
host, port: parseInt(port), user: username, password: decodeURIComponent(password),
database, ssl: sslRequired ? { rejectUnauthorized: false } : undefined,
});
console.log(`[Backup] Generating dump for database ${database}...`);
await execAsync(cmd);
console.log(`[Backup] Dump saved to ${filePath}`);
let sql = `-- Backup généré le ${new Date().toISOString()}\n-- Base : ${database}\nSET FOREIGN_KEY_CHECKS=0;\n\n`;
// Lister les tables
const [tables] = await conn.query<any[]>(`SHOW TABLES`);
const tableNames: string[] = tables.map((r: any) => Object.values(r)[0] as string);
for (const table of tableNames) {
// CREATE TABLE
const [createRows] = await conn.query<any[]>(`SHOW CREATE TABLE \`${table}\``);
const createSql: string = createRows[0]['Create Table'] || createRows[0][`Create Table`];
sql += `\n-- Table: ${table}\nDROP TABLE IF EXISTS \`${table}\`;\n${createSql};\n\n`;
// INSERT DATA
const [rows] = await conn.query<any[]>(`SELECT * FROM \`${table}\``);
if (rows.length > 0) {
const cols = Object.keys(rows[0]).map(c => `\`${c}\``).join(", ");
const values = rows.map(row =>
"(" + Object.values(row).map(v =>
v === null ? "NULL" :
v instanceof Date ? `'${v.toISOString().replace('T', ' ').replace('Z', '')}'` :
typeof v === "number" ? v :
`'${String(v).replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`
).join(", ") + ")"
).join(",\n");
sql += `INSERT INTO \`${table}\` (${cols}) VALUES\n${values};\n\n`;
}
}
sql += `\nSET FOREIGN_KEY_CHECKS=1;\n-- Fin du dump\n`;
await conn.end();
fs.writeFileSync(filePath, sql, "utf8");
console.log(`[Backup] Dump saved to ${filePath} (${(sql.length / 1024).toFixed(1)} Ko)`);
// Retourner le fichier en téléchargement
const encodedName = encodeURIComponent(fileName);