Script para lanzar solo determinadas migraciones en base a la version

actual y objetivo
This commit is contained in:
2026-02-18 17:48:07 +01:00
parent d4ad5d9c61
commit 8571454835

View File

@@ -21,6 +21,13 @@ type MigrationFile = {
fullPath: string; fullPath: string;
} }
type DBVersion = {
version: string,
notes: string,
creation_date: Date,
stable: boolean
}
/** /**
* Carga de variables de entorno manual (para evitar dependencias como dotenv) * Carga de variables de entorno manual (para evitar dependencias como dotenv)
* Busca el .env en el directorio actual (CWD) * Busca el .env en el directorio actual (CWD)
@@ -33,7 +40,7 @@ async function loadEnv(envpath?: string) {
const [key, value] = line.split('='); const [key, value] = line.split('=');
if (key && value) process.env[key.trim()] = value.trim(); if (key && value) process.env[key.trim()] = value.trim();
}); });
console.log(' Archivo .env cargado desde el directorio actual.'); console.log('[i] Archivo .env cargado desde ' + envpath);
} }
} }
@@ -48,24 +55,29 @@ function getArgs() {
description: "Versión objetivo de la migracion", description: "Versión objetivo de la migracion",
requiresArg: false requiresArg: false
}) })
.parse() .option("env", {
alias: "e",
type: 'string',
description: "Path del archivo .env con los datos de la BDD"
})
.option("migrations", {
alias: "m",
type: "string",
description: "Path del directorio de migrations"
})
.parse() as {
target: string,
env: string,
migrations: string
}
console.log("args", argv) console.log("args", argv)
/* Antiguo */ /* Antiguo */
const args = process.argv.slice(2);
const targetIdx = args.indexOf('--target') !== -1 ? args.indexOf('--target') : args.indexOf('-t');
const envIdx = args.indexOf('--env') !== -1 ? args.indexOf('--env') : args.indexOf('-e');
const migrtionsIdx = args.indexOf("")
if (targetIdx === -1 || !args[targetIdx + 1]) {
console.error('❌ Error: Debes especificar una versión objetivo con --target o -t');
process.exit(1);
}
return { return {
target: args[targetIdx + 1], target: argv.target,
env: args[envIdx + 1] env: argv.env,
migrations: argv.migrations
}; };
} }
@@ -99,34 +111,55 @@ function compareVersions(va: string, vb: string) {
return 0 return 0
} }
async function getCurrentVersion() {
try {
const lastVersion = await db.query<DBVersion>(`
SELECT * form db_versions
ORDER BY creation_date DESC
LIMIT 1
`)
return lastVersion.rows[0]
} catch (e) {
console.error(e)
} finally {
}
}
/** /**
* Lógica principal de ejecución de migraciones * Lógica principal de ejecución de migraciones
* @param targetVersion Versión objetivo pasada por el usuario * @param targetVersion Versión objetivo pasada por el usuario
* @param currentVersion Versión actual obtenida de la DB * @param currentVersion Versión actual obtenida de la DB
*/ */
async function runMigrations(targetVersion: string, currentVersion: string, migrationDir: string) { async function runMigrations(args: {
targetVersion: string,
currentVersion?: string,
migrationDir: string
}) {
const dbClient = await db.connect() const dbClient = await db.connect()
try { try {
const files = await fs.readdir(migrationDir); // 1º La version explicita 2º La versión almacenada en BDD 3º 0.0.0 como version base
const currentVersion = args.currentVersion ?? (await getCurrentVersion())?.version ?? "0.0.0"
console.log("[i] Migrando desde la version " + currentVersion)
const files = await fs.readdir(args.migrationDir);
const pendingMigrations: MigrationFile[] = files const pendingMigrations: MigrationFile[] = files
.map(f => (<MigrationFile>{ .map(f => (<MigrationFile>{
version: path.parse(f).name, version: path.parse(f).name,
fileName: f, fileName: f,
fullPath: path.join(migrationDir, f) fullPath: path.join(args.migrationDir, f)
})) }))
// 1. Filtrar las migraciones > que la actual // 1. Filtrar las migraciones > que la actual
.filter(v => compareVersions(v.version, currentVersion) == -1) .filter(v => compareVersions(v.version, currentVersion) == -1)
// 2. Filtra las migraciones <= que la objetivo // 2. Filtra las migraciones <= que la objetivo
.filter(v => compareVersions(v.version, targetVersion) >= 0) .filter(v => compareVersions(v.version, args.targetVersion) >= 0)
.sort((a, b) => compareVersions(a.version, b.version)); .sort((a, b) => compareVersions(a.version, b.version));
if (pendingMigrations.length === 0) { if (pendingMigrations.length === 0) {
console.log(" La base de datos ya está actualizada."); console.log("[o] La base de datos ya está actualizada.");
return; return;
} }
console.log("Migraciones pendietes", pendingMigrations) console.log("[i] Migraciones pendietes", pendingMigrations)
console.log(`🚀 Aplicando ${pendingMigrations.length} migraciones...`); console.log(`[i] Aplicando ${pendingMigrations.length} migraciones...`);
// Iniciamos Transacción (Ejemplo conceptual con un cliente genérico) // Iniciamos Transacción (Ejemplo conceptual con un cliente genérico)
// await db.query('BEGIN'); // await db.query('BEGIN');
@@ -169,15 +202,15 @@ async function runMigrations(targetVersion: string, currentVersion: string, migr
} }
} }
/** /**
* ******************************************************************* * *******************************************************************
* ******************************************************************* * *******************************************************************
*/ */
async function main() { async function main() {
const { target: targetVersion, env: envPath } = getArgs(); const args = getArgs();
await loadEnv(envPath) await loadEnv(args.env);
runMigrations({ targetVersion: args.target, migrationDir: args.migrations })
} }
main().then(e => console.log(e)).catch(console.error) main().then(e => console.log(e)).catch(console.error)