import type pg from "pg"; import { type ForeignKeyDef, type QualifiedName } from "./dump-sql.js"; export interface CheckedForeignKey { fk: ForeignKeyDef; /** 引用列全非空的行数(MATCH SIMPLE:有一列为空就不校验) */ rows: number; /** 其中在目标库找不到被引用行的 */ missingRows: number; } export interface ExternalReferenceCheck { checked: CheckedForeignKey[]; /** 恢复一定会失败的原因,一条一句 */ problems: string[]; /** 没能检查的,一条一句。恢复在一个事务里跑,这些真出问题也会整体回滚,所以只提示不拦 */ unchecked: string[]; /** 有外键要等扩展装上之后才查得了(见 pendingExtensions) */ waitingForExtensions: boolean; } /** * 读 dump,找出指向 dumpedSchemas 之外的外键,逐条拿目标库对行。只读:目标库上只跑 select。 * pg_restore 起不来、归档读不了时抛错,由调用方当成 blocker。单条外键查不成(目标端报错、 * 数据块读不了)只影响它自己,记进 unchecked,不拖累别的外键的结论。 */ export declare function checkExternalReferences(opts: { dumpPath: string; dumpedSchemas: string[]; targetUrl: string; /** * manifest 里记着、目标上还没装的扩展。有它们在,被引用的表不在、引用方列的类型不在,都可能是 * 扩展装上之后才有的(扩展可以往别的 schema 里建表,只看它登记的 schema 不够,交叉审查复现), * 这时报"装完扩展再查",不当成 blocker;正式恢复装完扩展会再查一遍。 */ pendingExtensions?: string[]; /** * 调用方开着的事务(正式恢复里"先装扩展再复查"的那个):在它里面查,看得到还没提交的扩展。 * 每条查询包在一个保存点里、查完就回滚到保存点,检查本身留不下任何东西。 */ inTransaction?: pg.Client; /** * 同一次恢复里会整表写进去的备份之外的表(带 Auth 的恢复:auth.users、auth.identities)。指向它们的外键 * 不算"指向备份之外":数据和引用方一起写进去,提交后按备份内的外键加,源库的孤儿行建成 NOT VALID */ restoredTables?: QualifiedName[]; }): Promise; export declare function describe(fk: ForeignKeyDef): string;