fix(db): desacopla configuracao administrativa das migrations
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
93f280621b
commit
8cfeeb0464
7 files changed
+356
-29
No files matched your search
@@ -29,12 +29,46 @@ export function isShimMigration(file: string): boolean {
|
||||
|
||||
export type PendingOptions = { applyIdentityShim?: boolean };
|
||||
|
||||
export type MigrationLedger = { state: "ausente" } | { state: "presente"; ids: string[] };
|
||||
|
||||
/** A leitura do histórico falhou. Não é o mesmo que tabela ausente. */
|
||||
export class MigrationLedgerError extends Error {
|
||||
readonly code = "historico_indisponivel";
|
||||
|
||||
constructor() {
|
||||
super("historico_indisponivel");
|
||||
this.name = "MigrationLedgerError";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lê o histórico sem criá-lo. Tabela ausente é um estado explícito. Falha de
|
||||
* permissão, conexão ou consulta interrompe: não vira lista vazia.
|
||||
*/
|
||||
export async function readMigrationLedger(db: Db): Promise<MigrationLedger> {
|
||||
let presence: { name: string | null }[];
|
||||
try {
|
||||
presence = await db.withService((query) =>
|
||||
query.query<{ name: string | null }>("select to_regclass('public.schema_migrations')::text as name"),
|
||||
);
|
||||
} catch {
|
||||
throw new MigrationLedgerError();
|
||||
}
|
||||
if (!presence[0]?.name) return { state: "ausente" };
|
||||
try {
|
||||
const rows = await db.withService((query) =>
|
||||
query.query<{ id: string }>("select id from public.schema_migrations order by id"),
|
||||
);
|
||||
return { state: "presente", ids: rows.map((row) => row.id) };
|
||||
} catch {
|
||||
throw new MigrationLedgerError();
|
||||
}
|
||||
}
|
||||
|
||||
/** Migrations esperadas que ainda não constam em `schema_migrations`. */
|
||||
export async function pendingMigrations(db: Db, options: PendingOptions = {}): Promise<string[]> {
|
||||
const applyShim = options.applyIdentityShim ?? identityShimEnabled();
|
||||
const appliedRows = await db
|
||||
.withService((query) => query.query<{ id: string }>("select id from public.schema_migrations"))
|
||||
.catch(() => [] as { id: string }[]);
|
||||
const applied = new Set(appliedRows.map((row) => row.id));
|
||||
const ledger = await readMigrationLedger(db);
|
||||
const applied = new Set(ledger.state === "presente" ? ledger.ids : []);
|
||||
return EXPECTED_MIGRATIONS.filter((file) => !applied.has(file) && (applyShim || !isShimMigration(file)));
|
||||
}
|
||||
Reference in new issue
Block a user