UNPKG

longcelot-sheet-db

Version:

Google Sheets-backed staging database adapter for Node.js with schema-first design

70 lines 4.35 kB
import { TableSchema } from '../../schema/types'; interface MigrateOptions { prisma?: boolean; sql?: boolean; output?: string; /** Apply the generated DDL (--sql) to a live database, or run `prisma migrate deploy` (--prisma). Phase 16.7. */ apply?: boolean; connectionString?: string; driver?: 'postgres' | 'mysql'; dryRun?: boolean; } export interface DDLOptions { /** Column injected into every non-admin table to scope rows to a tenant (Phase 16.3 ADR — see FAQ.md #13). Default: 'tenant_id'. */ tenantColumn?: string; /** * Back-relation fields to append to this model — Prisma requires every explicit `@relation` * to have a matching field on *both* sides ("missing an opposite relation field", found via * real `prisma generate`, Phase 16.2). generatePrismaModel() only sees one schema at a time, * so it can't discover these itself — pass the result of collectPrismaBackRelations(schemas). */ backRelations?: PrismaBackRelation[]; } export interface PrismaBackRelation { /** Field name to add on the referenced model, e.g. 'reviews_product_id_rel'. */ fieldName: string; /** The referencing model's name, e.g. 'reviews'. */ sourceModel: string; } /** * One pass over every schema, collecting — per referenced table — the list of back-relation * fields it needs so each `ref()` column's forward `@relation` has a matching opposite field. * Field names include both the source model and column name (not just the source model) so two * FK columns from the same table to the same target don't collide. */ export declare function collectPrismaBackRelations(schemas: TableSchema[]): Map<string, PrismaBackRelation[]>; export declare function generatePrismaModel(schema: TableSchema, options?: DDLOptions): string; export declare function generateSQLTable(schema: TableSchema, options?: DDLOptions): string; /** * Foreign keys are emitted inline inside CREATE TABLE (see generateSQLTable() above), so the * referenced table must already exist — physically, for `--apply`, or earlier in the file, for a * manually `psql -f`'d schema.sql — before the table that references it. loadSchemas() has no * ordering guarantee of its own (it's just fs.readdirSync() per actor directory), so a schema * whose ref() target happens to sort after it alphabetically broke both `--apply` (live "relation * ... does not exist") and a hand-applied schema.sql the same way. Fixed by topologically sorting * on col.ref edges before either output is generated. A true circular FK (A references B * references A) can't be resolved by reordering alone — one side would need its constraint * deferred to a post-creation ALTER TABLE instead, not handled by this first pass; such schemas * are left in their original relative order once every acyclic dependency is satisfied. */ export declare function sortSchemasByDependency(schemas: TableSchema[]): TableSchema[]; export declare function inferDriverFromConnectionString(connectionString: string): 'postgres' | 'mysql' | undefined; /** * Splits the multi-statement DDL text generateSQLTable() produces into individual statements so * --apply can execute (and idempotency-check) each one separately — needed because MySQL doesn't * run multi-statement query() calls without an extra multipleStatements connection flag we'd * rather not require. Known limitation: a semicolon inside a quoted default()/enum() string * value would be mis-split; not handled by this first-pass implementation. */ export declare function splitSQLStatements(ddl: string): string[]; /** * `CREATE TABLE IF NOT EXISTS` is already idempotent at the SQL level, but plain `CREATE INDEX` * has no such clause in MySQL (see generateSQLTable()'s comment) — so a rerun's only expected * failure is "index already exists", which --apply treats as success rather than an error. */ export declare function isAlreadyExistsError(err: unknown, driver: 'postgres' | 'mysql'): boolean; /** `--sql --apply`: execute generateSQLTable()'s output against a live database, statement by statement. */ export declare function applySQLToDatabase(schemas: TableSchema[], options: MigrateOptions): Promise<void>; export declare function migrateCommand(options: MigrateOptions): Promise<void>; export {}; //# sourceMappingURL=migrate.d.ts.map