Files
erika/scripts/repair-form-migration-ledger.ts
T

156 lines
4.7 KiB
TypeScript

import postgres from "postgres";
const databaseUrl = process.env.DATABASE_URL;
if (!databaseUrl) {
throw new Error("DATABASE_URL is not set");
}
const expectedMigrations = [
{
hash: "418d5afb86b4866e697a0abfc992b913da1533e8df41cc0b618a9e23cbb70ba5",
createdAt: 1782731728406,
},
{
hash: "5e060f0fdac0296f4953f707182eb1c872f69d44e9ef89ba75c69fbc9c895851",
createdAt: 1782731936083,
},
{
hash: "b3d35909be61ab7fbffc6c36916d6444833385db517a302abe28cfea2b0ef544",
createdAt: 1782731954122,
},
{
hash: "1ad2b86e381f0d8ef17839a952c30f0ea6f0452367d1dcd19aa11a65d8eeecbd",
createdAt: 1783089081925,
},
{
hash: "f2c279f21375de159981c439e622e4ddcd8415384f7ca7287c3f1598bcb42fc4",
createdAt: 1783613113217,
},
{
hash: "38e26a4313f207b04bb1646f6a303c0f216ad687062d16100e4ca01db5fa74c2",
createdAt: 1785152117830,
},
{
hash: "8a65ae9a4fe4c7933d0d40182dab6da9654c8cb0f1275a8ebb43e1e0f8719256",
createdAt: 1785169071234,
},
] as const;
const sql = postgres(databaseUrl, { max: 1 });
try {
const [schemaState] = await sql<{
form_tables: number;
allowed_roles: boolean;
denied_roles: boolean;
cdn_table: boolean;
image_cdn_id: boolean;
allow_multiple_submissions: boolean;
image_answer_mode: boolean;
submitted_at_index: boolean;
answer_image_fk: boolean;
unique_submission_index: boolean;
legacy_public_tables: boolean;
}[]>`
select
(
select count(*)::integer
from information_schema.tables
where table_schema = 'form'
and table_name in ('answer', 'form', 'question', 'submission')
) as form_tables,
exists (
select 1 from information_schema.columns
where table_schema = 'form'
and table_name = 'form'
and column_name = 'allowed_roles'
) as allowed_roles,
exists (
select 1 from information_schema.columns
where table_schema = 'form'
and table_name = 'form'
and column_name = 'denied_roles'
) as denied_roles,
to_regclass('form.cdn') is not null as cdn_table,
exists (
select 1 from information_schema.columns
where table_schema = 'form'
and table_name = 'answer'
and column_name = 'image_cdn_id'
) as image_cdn_id,
exists (
select 1 from information_schema.columns
where table_schema = 'form'
and table_name = 'form'
and column_name = 'allow_multiple_submissions'
) as allow_multiple_submissions,
exists (
select 1 from information_schema.columns
where table_schema = 'form'
and table_name = 'question'
and column_name = 'image_answer_mode'
) as image_answer_mode,
to_regclass('form.submission_form_submitted_at_id_idx') is not null
as submitted_at_index,
exists (
select 1
from information_schema.table_constraints
where constraint_schema = 'form'
and table_name = 'answer'
and constraint_name = 'answer_image_cdn_id_cdn_id_fk'
) as answer_image_fk,
to_regclass('form.submission_form_user_discord_id_unique') is not null
as unique_submission_index,
exists (
select 1
from information_schema.tables
where table_schema = 'public'
and table_name in ('answer', 'form', 'question', 'submission')
) as legacy_public_tables
`;
const matchesExpectedSchema =
schemaState?.form_tables === 4 &&
schemaState.allowed_roles &&
schemaState.denied_roles &&
schemaState.cdn_table &&
schemaState.image_cdn_id &&
schemaState.allow_multiple_submissions &&
schemaState.image_answer_mode &&
schemaState.submitted_at_index &&
schemaState.answer_image_fk &&
!schemaState.unique_submission_index &&
!schemaState.legacy_public_tables;
if (!matchesExpectedSchema) {
throw new Error(
"The database does not match the expected schema through migration 0013. Refusing to change the migration ledger."
);
}
await sql.begin(async (transaction) => {
await transaction`lock table drizzle.__drizzle_migrations in exclusive mode`;
for (const migration of expectedMigrations) {
await transaction`
insert into drizzle.__drizzle_migrations (hash, created_at)
select ${migration.hash}, ${migration.createdAt}
where not exists (
select 1
from drizzle.__drizzle_migrations
where hash = ${migration.hash}
)
`;
await transaction`
update drizzle.__drizzle_migrations
set created_at = ${migration.createdAt}
where hash = ${migration.hash}
`;
}
});
console.log("Reconciled the Drizzle migration ledger through 0013.");
} finally {
await sql.end();
}