fix(sqlite): tag per-migration database backups with version and prevent collisions

This commit is contained in:
Tyagiquamar
2026-09-18 21:31:00 +05:30
parent 803fbb2ea2
commit b74ded3a9c
5 changed files with 298 additions and 65 deletions
+16 -14
View File
@@ -5,7 +5,7 @@ import path from "path";
import semver from "semver";
import { versionMigrations } from "../db/sqlite";
import { __DIRNAME, APP_PATH, APP_VERSION } from "@server/lib/consts";
import { formatBackupTimestamp } from "@server/lib/backupFileName";
import { formatBackupFileName } from "@server/lib/backupFileName";
import { SqliteError } from "better-sqlite3";
import fs from "fs";
import { build } from "@server/build";
@@ -107,7 +107,7 @@ async function run() {
await runMigrations();
}
function backupDb() {
function backupDb(version?: string) {
// make dir config/db/backups
const appPath = APP_PATH;
const dbDir = path.join(appPath, "db");
@@ -120,11 +120,10 @@ function backupDb() {
}
// copy the db.sqlite file to backups
// add the date to the filename
const date = new Date();
const dateString = formatBackupTimestamp(date);
// add the date and migration version to the filename
const fileName = formatBackupFileName(version);
const dbPath = path.join(dbDir, "db.sqlite");
const backupPath = path.join(backupsDir, `db_${dateString}.sqlite`);
const backupPath = path.join(backupsDir, fileName);
fs.copyFileSync(dbPath, backupPath);
}
@@ -163,6 +162,12 @@ export async function runMigrations() {
}
} catch (e) {
console.error("Error running migrations:", e);
if (
process.env.NODE_ENV === "test" ||
process.env.ENVIRONMENT === "test"
) {
throw e;
}
await new Promise((resolve) =>
setTimeout(resolve, 1000 * 60 * 60 * 24 * 1)
);
@@ -191,18 +196,15 @@ async function executeScripts() {
);
// Run migrations in order
// Take a single backup before any migration runs, so one upgrade
// produces one restore point instead of one backup per migration.
if (
migrationsToRun.length > 0 &&
!process.env.DISABLE_BACKUP_ON_MIGRATION
) {
backupDb();
}
for (const migration of migrationsToRun) {
console.log(`Running migration ${migration.version}`);
try {
if (!process.env.DISABLE_BACKUP_ON_MIGRATION) {
// Backup the database before running the migration
backupDb(migration.version);
}
await migration.run();
// Update version in database