diff --git a/nuxt4/server/api/debug/export-database.post.ts b/nuxt4/server/api/debug/export-database.post.ts index eb4d29b..0f3df7b 100644 --- a/nuxt4/server/api/debug/export-database.post.ts +++ b/nuxt4/server/api/debug/export-database.post.ts @@ -55,9 +55,15 @@ export default defineEventHandler(async (event) => { const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5) const filename = `backup-seguidordelotes-${timestamp}.sql` - // Ejecutar pg_dump - // Usar PGPASSWORD en la variable de entorno para evitar prompt de contraseña - const command = `PGPASSWORD="${password}" pg_dump -h ${host} -p ${port} -U ${user} -d ${database} --clean --if-exists --no-owner --no-acl` + // Ejecutar pg_dump con opciones para máxima compatibilidad + // --clean: incluir DROP antes de CREATE + // --if-exists: usar IF EXISTS en los DROP + // --no-owner: no incluir comandos de ownership + // --no-acl: no incluir permisos + // --no-tablespaces: no incluir tablespaces + // --no-security-labels: no incluir security labels + // --no-synchronized-snapshots: no usar snapshots sincronizados + const command = `PGPASSWORD="${password}" pg_dump -h ${host} -p ${port} -U ${user} -d ${database} --clean --if-exists --no-owner --no-acl --no-tablespaces --no-security-labels --no-synchronized-snapshots` console.log(' - Ejecutando pg_dump...') const { stdout, stderr } = await execAsync(command, { diff --git a/nuxt4/server/api/debug/import-database.post.ts b/nuxt4/server/api/debug/import-database.post.ts index 160586d..aad6d29 100644 --- a/nuxt4/server/api/debug/import-database.post.ts +++ b/nuxt4/server/api/debug/import-database.post.ts @@ -45,13 +45,13 @@ export default defineEventHandler(async (event) => { }) } - const sqlContent = fileData.data.toString('utf-8') - const fileSize = (sqlContent.length / 1024).toFixed(2) + const originalSqlContent = fileData.data.toString('utf-8') + const originalFileSize = (originalSqlContent.length / 1024).toFixed(2) console.log(` - Archivo recibido: ${fileData.filename || 'sin nombre'}`) - console.log(` - Tamaño: ${fileSize} KB`) + console.log(` - Tamaño original: ${originalFileSize} KB`) - if (!sqlContent.trim()) { + if (!originalSqlContent.trim()) { throw createError({ statusCode: 400, statusMessage: 'Archivo vacío', @@ -59,6 +59,23 @@ export default defineEventHandler(async (event) => { }) } + // Limpiar el SQL de comandos problemáticos o incompatibles + console.log(' - Limpiando SQL de comandos incompatibles...') + const sqlLines = originalSqlContent.split('\n') + const cleanedLines = sqlLines.filter(line => { + const trimmed = line.trim() + // Remover líneas problemáticas conocidas + if (trimmed.startsWith('SET transaction_timeout')) return false + if (trimmed.startsWith('SET idle_in_transaction_session_timeout')) return false + if (trimmed.startsWith('SET lock_timeout')) return false + if (trimmed.startsWith('\\unrestrict')) return false + return true + }) + + const sqlContent = cleanedLines.join('\n') + const cleanedFileSize = (sqlContent.length / 1024).toFixed(2) + console.log(` - Tamaño después de limpieza: ${cleanedFileSize} KB`) + // Guardar el archivo temporalmente const timestamp = Date.now() tempFilePath = join('/tmp', `import-${timestamp}.sql`) @@ -101,20 +118,27 @@ export default defineEventHandler(async (event) => { console.log(' - Ejecutando psql para importar el backup...') console.log(' - ADVERTENCIA: Esto eliminará y recreará todas las tablas') - const command = `PGPASSWORD="${password}" psql -h ${host} -p ${port} -U ${user} -d ${database} -f ${tempFilePath}` + // Opciones de psql: + // -q: quiet mode (menos mensajes) + // -v ON_ERROR_STOP=1: detener en el primer error crítico + const command = `PGPASSWORD="${password}" psql -h ${host} -p ${port} -U ${user} -d ${database} -q -v ON_ERROR_STOP=1 -f ${tempFilePath}` const { stdout, stderr } = await execAsync(command, { maxBuffer: 50 * 1024 * 1024, // 50MB buffer }) - // psql envía mensajes normales a stderr, solo preocuparse si hay errores reales - if (stderr && stderr.includes('ERROR')) { - console.error('⚠️ Errores durante la importación:', stderr) - throw new Error(`Error ejecutando psql: ${stderr}`) - } + // psql envía algunos mensajes normales a stderr + // Solo fallar si hay errores críticos (ERROR en mayúsculas o 'error:' en minúsculas) + if (stderr) { + const hasError = stderr.includes('ERROR:') || stderr.includes('error:') || stderr.includes('FATAL:') - if (stderr && !stderr.includes('ERROR')) { - console.log(' - Mensajes de psql:', stderr) + if (hasError) { + console.error('⚠️ Errores durante la importación:', stderr) + throw new Error(`Error ejecutando psql: ${stderr}`) + } else { + // Son solo warnings o notices, no son críticos + console.log(' - Mensajes de psql (no críticos):', stderr) + } } console.log('✅ Backup importado exitosamente') @@ -122,7 +146,8 @@ export default defineEventHandler(async (event) => { return { success: true, message: 'Backup importado exitosamente. La base de datos ha sido restaurada.', - file_size: fileSize, + original_size: originalFileSize, + cleaned_size: cleanedFileSize, filename: fileData.filename || 'sin nombre', } } catch (error: any) {