import { exec } from 'child_process' import path from 'path' import { promisify } from 'util' import fs from 'fs/promises' const execAsync = promisify(exec) export async function createDatabaseBackup(): Promise { if (!process.env.DATABASE_URL) { throw new Error('DATABASE_URL environment variable is required') } const timestamp = Date.now() const backupPath = path.join(process.cwd(), 'backups', `backup_${timestamp}.sql`) try { // Ensure backup directory exists await execAsync('mkdir -p backups') // Create PostgreSQL backup using pg_dump // Extract database name from connection string const url = new URL(process.env.DATABASE_URL) const dbName = url.pathname.substring(1) // Remove leading slash const host = url.hostname const port = url.port || '5432' const username = url.username const password = url.password // Set PGPASSWORD environment variable for pg_dump const env = { ...process.env, PGPASSWORD: password } await execAsync( `pg_dump -h ${host} -p ${port} -U ${username} -d ${dbName} --no-password > "${backupPath}"`, { env } ) return backupPath } catch (error) { console.error('Backup failed:', error) throw new Error('Database backup failed') } } export async function restoreDatabase(backupPath: string): Promise { if (!process.env.DATABASE_URL) { throw new Error('DATABASE_URL environment variable is required') } try { // Create backup of current DB first await createDatabaseBackup() // Extract database connection details const url = new URL(process.env.DATABASE_URL) const dbName = url.pathname.substring(1) const host = url.hostname const port = url.port || '5432' const username = url.username const password = url.password // Set PGPASSWORD environment variable for psql const env = { ...process.env, PGPASSWORD: password } // Restore from SQL backup await execAsync( `psql -h ${host} -p ${port} -U ${username} -d ${dbName} --no-password < "${backupPath}"`, { env } ) console.log('Database restored successfully') } catch (error) { console.error('Restore failed:', error) throw new Error('Database restore failed') } } export async function listBackups(): Promise { try { const backupDir = path.join(process.cwd(), 'backups') try { const files = await fs.readdir(backupDir) const sqlFiles = files.filter(file => file.endsWith('.sql')) // Get file stats for each backup const backupInfo = await Promise.all( sqlFiles.map(async (file) => { const filePath = path.join(backupDir, file) const stats = await fs.stat(filePath) return `${stats.mtime.toISOString()} ${file} (${Math.round(stats.size / 1024)}KB)` }) ) return backupInfo.sort().reverse() // Most recent first } catch (dirError) { return [] } } catch { return [] } }