You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
43 lines
1.2 KiB
43 lines
1.2 KiB
/** Ejecuta migraciones dentro de una transacción que siempre se revierte. */
|
|
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import pg from 'pg';
|
|
|
|
const nombres = process.argv.slice(2);
|
|
if (nombres.length === 0)
|
|
throw new Error('Indica al menos una migración, por ejemplo 0014_artistas_y_audio.sql.');
|
|
|
|
const sentenciasDe = (texto) =>
|
|
texto
|
|
.split('--> statement-breakpoint')
|
|
.map((s) => s.trim())
|
|
.filter((s) => s && s.split('\n').some((l) => l.trim() && !l.trim().startsWith('--')));
|
|
|
|
const cliente = new pg.Client({
|
|
connectionString: process.env.DATABASE_URL,
|
|
query_timeout: 120_000
|
|
});
|
|
await cliente.connect();
|
|
await cliente.query('BEGIN');
|
|
|
|
try {
|
|
for (const nombre of nombres) {
|
|
const ruta = path.join('drizzle', nombre);
|
|
const sentencias = sentenciasDe(fs.readFileSync(ruta, 'utf8'));
|
|
for (const [indice, sentencia] of sentencias.entries()) {
|
|
try {
|
|
await cliente.query(sentencia);
|
|
} catch (error) {
|
|
throw new Error(`${nombre}, sentencia ${indice + 1}: ${error.message}`, { cause: error });
|
|
}
|
|
}
|
|
console.log(` ${nombre}: ${sentencias.length} sentencias válidas`);
|
|
}
|
|
} finally {
|
|
await cliente.query('ROLLBACK').catch(() => {});
|
|
await cliente.end();
|
|
}
|
|
|
|
console.log('Comprobadas y revertidas: la base no ha cambiado.');
|