diff --git a/server/setup/migrations.ts b/server/setup/migrations.ts index 2f1aae21..b06f176c 100644 --- a/server/setup/migrations.ts +++ b/server/setup/migrations.ts @@ -3,9 +3,9 @@ import db, { exists } from "@server/db"; import path from "path"; import semver from "semver"; import { versionMigrations } from "@server/db/schema"; -import { desc } from "drizzle-orm"; import { __DIRNAME } from "@server/lib/consts"; import { loadAppVersion } from "@server/lib/loadAppVersion"; +import { SqliteError } from "better-sqlite3"; import m1 from "./scripts/1.0.0-beta1"; import m2 from "./scripts/1.0.0-beta2"; import m3 from "./scripts/1.0.0-beta3"; @@ -53,38 +53,44 @@ export async function runMigrations() { } await db - .insert(versionMigrations) - .values({ - version: appVersion, - executedAt: Date.now() - }) - .execute(); + .insert(versionMigrations) + .values({ + version: appVersion, + executedAt: Date.now() + }) + .execute(); } } catch (e) { console.error("Error running migrations:", e); - await new Promise((resolve) => setTimeout(resolve, 1000 * 60 * 60 * 24 * 1)); + await new Promise((resolve) => + setTimeout(resolve, 1000 * 60 * 60 * 24 * 1) + ); } } async function executeScripts() { try { // Get the last executed version from the database - const lastExecuted = await db - .select() - .from(versionMigrations) - .orderBy(desc(versionMigrations.version)) - .limit(1); - - const startVersion = lastExecuted[0]?.version ?? "0.0.0"; - console.log(`Starting migrations from version ${startVersion}`); + const lastExecuted = await db.select().from(versionMigrations); // Filter and sort migrations - const pendingMigrations = migrations - .filter((migration) => semver.gt(migration.version, startVersion)) - .sort((a, b) => semver.compare(a.version, b.version)); + const pendingMigrations = lastExecuted + .map((m) => m) + .sort((a, b) => semver.compare(b.version, a.version)); + const startVersion = pendingMigrations[0]?.version ?? "0.0.0"; + console.log(`Starting migrations from version ${startVersion}`); + + const migrationsToRun = migrations.filter((migration) => + semver.gt(migration.version, startVersion) + ); + + console.log( + "Migrations to run:", + migrationsToRun.map((m) => m.version).join(", ") + ); // Run migrations in order - for (const migration of pendingMigrations) { + for (const migration of migrationsToRun) { console.log(`Running migration ${migration.version}`); try { @@ -102,12 +108,16 @@ async function executeScripts() { console.log( `Successfully completed migration ${migration.version}` ); - } catch (error) { + } catch (e) { + if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") { + console.error("Migration has already run! Skipping..."); + continue; + } console.error( `Failed to run migration ${migration.version}:`, - error + e ); - throw error; // Re-throw to stop migration process + throw e; // Re-throw to stop migration process } }