Fix migrations ordering

This commit is contained in:
Owen Schwartz 2025-01-30 23:30:33 -05:00
parent 55c0953fde
commit 57cd776c34
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD

View file

@ -3,9 +3,9 @@ import db, { exists } from "@server/db";
import path from "path"; import path from "path";
import semver from "semver"; import semver from "semver";
import { versionMigrations } from "@server/db/schema"; import { versionMigrations } from "@server/db/schema";
import { desc } from "drizzle-orm";
import { __DIRNAME } from "@server/lib/consts"; import { __DIRNAME } from "@server/lib/consts";
import { loadAppVersion } from "@server/lib/loadAppVersion"; import { loadAppVersion } from "@server/lib/loadAppVersion";
import { SqliteError } from "better-sqlite3";
import m1 from "./scripts/1.0.0-beta1"; import m1 from "./scripts/1.0.0-beta1";
import m2 from "./scripts/1.0.0-beta2"; import m2 from "./scripts/1.0.0-beta2";
import m3 from "./scripts/1.0.0-beta3"; import m3 from "./scripts/1.0.0-beta3";
@ -53,38 +53,44 @@ export async function runMigrations() {
} }
await db await db
.insert(versionMigrations) .insert(versionMigrations)
.values({ .values({
version: appVersion, version: appVersion,
executedAt: Date.now() executedAt: Date.now()
}) })
.execute(); .execute();
} }
} catch (e) { } catch (e) {
console.error("Error running migrations:", 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() { async function executeScripts() {
try { try {
// Get the last executed version from the database // Get the last executed version from the database
const lastExecuted = await db const lastExecuted = await db.select().from(versionMigrations);
.select()
.from(versionMigrations)
.orderBy(desc(versionMigrations.version))
.limit(1);
const startVersion = lastExecuted[0]?.version ?? "0.0.0";
console.log(`Starting migrations from version ${startVersion}`);
// Filter and sort migrations // Filter and sort migrations
const pendingMigrations = migrations const pendingMigrations = lastExecuted
.filter((migration) => semver.gt(migration.version, startVersion)) .map((m) => m)
.sort((a, b) => semver.compare(a.version, b.version)); .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 // Run migrations in order
for (const migration of pendingMigrations) { for (const migration of migrationsToRun) {
console.log(`Running migration ${migration.version}`); console.log(`Running migration ${migration.version}`);
try { try {
@ -102,12 +108,16 @@ async function executeScripts() {
console.log( console.log(
`Successfully completed migration ${migration.version}` `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( console.error(
`Failed to run migration ${migration.version}:`, `Failed to run migration ${migration.version}:`,
error e
); );
throw error; // Re-throw to stop migration process throw e; // Re-throw to stop migration process
} }
} }