fix(db): make document revision migration replay-safe
This commit is contained in:
parent
761dce559d
commit
90889c12d8
2 changed files with 79 additions and 5 deletions
|
|
@ -169,4 +169,76 @@ describeEmbeddedPostgres("applyPendingMigrations", () => {
|
|||
},
|
||||
20_000,
|
||||
);
|
||||
|
||||
it(
|
||||
"replays migration 0046 safely when document revision columns already exist",
|
||||
async () => {
|
||||
const connectionString = await createTempDatabase();
|
||||
|
||||
await applyPendingMigrations(connectionString);
|
||||
|
||||
const sql = postgres(connectionString, { max: 1, onnotice: () => {} });
|
||||
try {
|
||||
const smoothSentinelsHash = await migrationHash("0046_smooth_sentinels.sql");
|
||||
|
||||
await sql.unsafe(
|
||||
`DELETE FROM "drizzle"."__drizzle_migrations" WHERE hash = '${smoothSentinelsHash}'`,
|
||||
);
|
||||
|
||||
const columns = await sql.unsafe<{ column_name: string; is_nullable: string; column_default: string | null }[]>(
|
||||
`
|
||||
SELECT column_name, is_nullable, column_default
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'document_revisions'
|
||||
AND column_name IN ('title', 'format')
|
||||
ORDER BY column_name
|
||||
`,
|
||||
);
|
||||
expect(columns).toHaveLength(2);
|
||||
} finally {
|
||||
await sql.end();
|
||||
}
|
||||
|
||||
const pendingState = await inspectMigrations(connectionString);
|
||||
expect(pendingState).toMatchObject({
|
||||
status: "needsMigrations",
|
||||
pendingMigrations: ["0046_smooth_sentinels.sql"],
|
||||
reason: "pending-migrations",
|
||||
});
|
||||
|
||||
await applyPendingMigrations(connectionString);
|
||||
|
||||
const finalState = await inspectMigrations(connectionString);
|
||||
expect(finalState.status).toBe("upToDate");
|
||||
|
||||
const verifySql = postgres(connectionString, { max: 1, onnotice: () => {} });
|
||||
try {
|
||||
const columns = await verifySql.unsafe<{ column_name: string; is_nullable: string; column_default: string | null }[]>(
|
||||
`
|
||||
SELECT column_name, is_nullable, column_default
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'document_revisions'
|
||||
AND column_name IN ('title', 'format')
|
||||
ORDER BY column_name
|
||||
`,
|
||||
);
|
||||
expect(columns).toEqual([
|
||||
expect.objectContaining({
|
||||
column_name: "format",
|
||||
is_nullable: "NO",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
column_name: "title",
|
||||
is_nullable: "YES",
|
||||
}),
|
||||
]);
|
||||
expect(columns[0]?.column_default).toContain("'markdown'");
|
||||
} finally {
|
||||
await verifySql.end();
|
||||
}
|
||||
},
|
||||
20_000,
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
ALTER TABLE "document_revisions" ADD COLUMN "title" text;--> statement-breakpoint
|
||||
ALTER TABLE "document_revisions" ADD COLUMN "format" text DEFAULT 'markdown' NOT NULL;
|
||||
ALTER TABLE "document_revisions" ADD COLUMN IF NOT EXISTS "title" text;--> statement-breakpoint
|
||||
ALTER TABLE "document_revisions" ADD COLUMN IF NOT EXISTS "format" text;--> statement-breakpoint
|
||||
ALTER TABLE "document_revisions" ALTER COLUMN "format" SET DEFAULT 'markdown';
|
||||
--> statement-breakpoint
|
||||
UPDATE "document_revisions" AS "dr"
|
||||
SET
|
||||
"title" = "d"."title",
|
||||
"format" = COALESCE("d"."format", 'markdown')
|
||||
"title" = COALESCE("dr"."title", "d"."title"),
|
||||
"format" = COALESCE("dr"."format", "d"."format", 'markdown')
|
||||
FROM "documents" AS "d"
|
||||
WHERE "d"."id" = "dr"."document_id";
|
||||
WHERE "d"."id" = "dr"."document_id";--> statement-breakpoint
|
||||
ALTER TABLE "document_revisions" ALTER COLUMN "format" SET NOT NULL;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue