diff --git a/nuxt4/server/api/debug/import-database.post.ts b/nuxt4/server/api/debug/import-database.post.ts index fc35c86..160586d 100644 --- a/nuxt4/server/api/debug/import-database.post.ts +++ b/nuxt4/server/api/debug/import-database.post.ts @@ -11,9 +11,16 @@ * Antes de eliminarlo, preguntar si todavía es necesario. */ -import { getClient } from '../../utils/db' +import { exec } from 'child_process' +import { promisify } from 'util' +import { writeFile, unlink } from 'fs/promises' +import { join } from 'path' + +const execAsync = promisify(exec) export default defineEventHandler(async (event) => { + let tempFilePath: string | null = null + try { console.log('📥 IMPORT DATABASE - Importando backup SQL...') @@ -52,37 +59,86 @@ export default defineEventHandler(async (event) => { }) } - const client = await getClient() + // Guardar el archivo temporalmente + const timestamp = Date.now() + tempFilePath = join('/tmp', `import-${timestamp}.sql`) + await writeFile(tempFilePath, sqlContent, 'utf-8') - try { - await client.query('BEGIN') + console.log(` - Archivo guardado temporalmente en: ${tempFilePath}`) - console.log(' - Ejecutando SQL del backup...') - console.log(' - ADVERTENCIA: Esto eliminará y recreará todas las tablas') + // Obtener credenciales de la base de datos + const config = useRuntimeConfig() + let host: string + let port: string + let database: string + let user: string + let password: string - // Ejecutar el SQL del backup - // Los backups de pg_dump con --clean --if-exists ya incluyen los DROP necesarios - await client.query(sqlContent) + if (config.postgresUrl) { + // Parsear la URL de conexión + const url = new URL(config.postgresUrl) + host = url.hostname + port = url.port || '5432' + database = url.pathname.slice(1) + user = url.username + password = url.password + } else { + // Fallback a variables de entorno + const defaultHost = process.env.APP_NAME ? `${process.env.APP_NAME}-postgres` : 'postgres' + host = process.env.POSTGRES_HOST || defaultHost + port = process.env.POSTGRES_PORT || '5432' + database = process.env.POSTGRES_DB || 'seguidor_lotes' + user = process.env.POSTGRES_USER || 'seguidor' + password = process.env.POSTGRES_PASSWORD || 'seguidor_password' + } - await client.query('COMMIT') + console.log(` - Host: ${host}`) + console.log(` - Puerto: ${port}`) + console.log(` - Base de datos: ${database}`) + console.log(` - Usuario: ${user}`) - console.log('✅ Backup importado exitosamente') + // Ejecutar psql para importar el backup + console.log(' - Ejecutando psql para importar el backup...') + console.log(' - ADVERTENCIA: Esto eliminará y recreará todas las tablas') - return { - success: true, - message: 'Backup importado exitosamente. La base de datos ha sido restaurada.', - file_size: fileSize, - filename: fileData.filename || 'sin nombre', - } - } catch (error) { - await client.query('ROLLBACK') - throw error - } finally { - client.release() + const command = `PGPASSWORD="${password}" psql -h ${host} -p ${port} -U ${user} -d ${database} -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}`) + } + + if (stderr && !stderr.includes('ERROR')) { + console.log(' - Mensajes de psql:', stderr) + } + + console.log('✅ Backup importado exitosamente') + + return { + success: true, + message: 'Backup importado exitosamente. La base de datos ha sido restaurada.', + file_size: fileSize, + filename: fileData.filename || 'sin nombre', } } catch (error: any) { console.error('❌ Error importando backup:', error) + // Si el error es porque psql no está disponible + if (error.message?.includes('psql') && error.message?.includes('not found')) { + throw createError({ + statusCode: 500, + statusMessage: 'psql no está disponible', + data: { + message: 'El comando psql no está disponible en el servidor. Asegúrate de que PostgreSQL client tools estén instalados.', + }, + }) + } + // Si el error ya es un createError, reusarlo if (error.statusCode) { throw error @@ -93,5 +149,15 @@ export default defineEventHandler(async (event) => { statusMessage: 'Error importando backup', data: { message: error.message }, }) + } finally { + // Limpiar el archivo temporal + if (tempFilePath) { + try { + await unlink(tempFilePath) + console.log(` - Archivo temporal eliminado: ${tempFilePath}`) + } catch (unlinkError) { + console.warn('⚠️ No se pudo eliminar el archivo temporal:', unlinkError) + } + } } })