@zmdb/migrations 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +36 -0
- package/dist/declarations/emit.d.ts +23 -0
- package/dist/declarations/emit.d.ts.map +1 -0
- package/dist/declarations/emit.js +581 -0
- package/dist/declarations/emit.js.map +1 -0
- package/dist/declarations/index.d.ts +3 -0
- package/dist/declarations/index.d.ts.map +1 -0
- package/dist/declarations/index.js +3 -0
- package/dist/declarations/index.js.map +1 -0
- package/dist/declarations/tagged-property.d.ts +33 -0
- package/dist/declarations/tagged-property.d.ts.map +1 -0
- package/dist/declarations/tagged-property.js +148 -0
- package/dist/declarations/tagged-property.js.map +1 -0
- package/dist/embedded.d.ts +25 -0
- package/dist/embedded.d.ts.map +1 -0
- package/dist/embedded.js +133 -0
- package/dist/embedded.js.map +1 -0
- package/dist/file-io.d.ts +15 -0
- package/dist/file-io.d.ts.map +1 -0
- package/dist/file-io.js +92 -0
- package/dist/file-io.js.map +1 -0
- package/dist/files.d.ts +11 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +10 -0
- package/dist/files.js.map +1 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +350 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect/common.d.ts +26 -0
- package/dist/introspect/common.d.ts.map +1 -0
- package/dist/introspect/common.js +155 -0
- package/dist/introspect/common.js.map +1 -0
- package/dist/introspect/drift.d.ts +45 -0
- package/dist/introspect/drift.d.ts.map +1 -0
- package/dist/introspect/drift.js +84 -0
- package/dist/introspect/drift.js.map +1 -0
- package/dist/introspect/index.d.ts +8 -0
- package/dist/introspect/index.d.ts.map +1 -0
- package/dist/introspect/index.js +10 -0
- package/dist/introspect/index.js.map +1 -0
- package/dist/operations/check.d.ts +16 -0
- package/dist/operations/check.d.ts.map +1 -0
- package/dist/operations/check.js +236 -0
- package/dist/operations/check.js.map +1 -0
- package/dist/operations/embed.d.ts +23 -0
- package/dist/operations/embed.d.ts.map +1 -0
- package/dist/operations/embed.js +52 -0
- package/dist/operations/embed.js.map +1 -0
- package/dist/operations/export.d.ts +9 -0
- package/dist/operations/export.d.ts.map +1 -0
- package/dist/operations/export.js +15 -0
- package/dist/operations/export.js.map +1 -0
- package/dist/operations/generate.d.ts +17 -0
- package/dist/operations/generate.d.ts.map +1 -0
- package/dist/operations/generate.js +115 -0
- package/dist/operations/generate.js.map +1 -0
- package/dist/operations/migrate.d.ts +23 -0
- package/dist/operations/migrate.d.ts.map +1 -0
- package/dist/operations/migrate.js +67 -0
- package/dist/operations/migrate.js.map +1 -0
- package/dist/operations/pull.d.ts +40 -0
- package/dist/operations/pull.d.ts.map +1 -0
- package/dist/operations/pull.js +100 -0
- package/dist/operations/pull.js.map +1 -0
- package/dist/operations/push.d.ts +20 -0
- package/dist/operations/push.d.ts.map +1 -0
- package/dist/operations/push.js +82 -0
- package/dist/operations/push.js.map +1 -0
- package/dist/operations/upgrade.d.ts +10 -0
- package/dist/operations/upgrade.d.ts.map +1 -0
- package/dist/operations/upgrade.js +38 -0
- package/dist/operations/upgrade.js.map +1 -0
- package/dist/project.d.ts +46 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +42 -0
- package/dist/project.js.map +1 -0
- package/dist/runner.d.ts +59 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +163 -0
- package/dist/runner.js.map +1 -0
- package/dist/testing/official-dialects.fixture.d.ts +16 -0
- package/dist/testing/official-dialects.fixture.d.ts.map +1 -0
- package/dist/testing/official-dialects.fixture.js +21 -0
- package/dist/testing/official-dialects.fixture.js.map +1 -0
- package/dist/testing.d.ts +8 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +27 -0
- package/dist/testing.js.map +1 -0
- package/package.json +81 -0
- package/src/declarations/emit.ts +705 -0
- package/src/declarations/index.ts +13 -0
- package/src/declarations/tagged-property.ts +163 -0
- package/src/embedded.ts +192 -0
- package/src/file-io.ts +114 -0
- package/src/files.ts +34 -0
- package/src/index.ts +502 -0
- package/src/introspect/__fixtures__/mysql-8.4.11.json +371 -0
- package/src/introspect/common.ts +203 -0
- package/src/introspect/drift.ts +157 -0
- package/src/introspect/index.ts +33 -0
- package/src/operations/check.ts +309 -0
- package/src/operations/embed.ts +87 -0
- package/src/operations/export.ts +21 -0
- package/src/operations/generate.ts +144 -0
- package/src/operations/migrate.ts +110 -0
- package/src/operations/pull.ts +160 -0
- package/src/operations/push.ts +98 -0
- package/src/operations/upgrade.ts +56 -0
- package/src/project.ts +93 -0
- package/src/runner.ts +260 -0
- package/src/testing/official-dialects.fixture.ts +24 -0
- package/src/testing.ts +32 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type ChangeOp, type ExtensionType, type MigrationDialect, type ReferentialAction, type SchemaSnapshot, type SchemaObjectOperation, type SqlDialect, type TableOptions } from '@zmdb/sql';
|
|
2
|
+
import { ddlType, type DdlSqlType } from '@zmdb/sql/schema-objects';
|
|
3
|
+
export { type ChangeOp, type ColumnSnapshot, type ExtensionSnapshot, type ExtensionType, type ForeignKeySnapshot, type ReferentialAction, type SchemaSnapshot, type TableOptions, type TableSnapshot, } from '@zmdb/sql';
|
|
4
|
+
export { type MigrationDialect, type SchemaObjectOperation } from '@zmdb/sql';
|
|
5
|
+
export { ddlType };
|
|
6
|
+
export type { DdlSqlType };
|
|
7
|
+
export { down, downTo, driverMigrationConnection, ensureVersionTable, rollbackTo, status, up } from './runner.js';
|
|
8
|
+
export type { AppliedMigration, Migration, MigrationConnection, MigrationDriver, MigrationRunOptions, MigrationStatus, MigrationTableOptions, } from './runner.js';
|
|
9
|
+
export type { MigrationProject } from './project.js';
|
|
10
|
+
export declare function emitSchemaObject(operation: SchemaObjectOperation, target: SqlDialect | MigrationDialect): readonly string[];
|
|
11
|
+
/**
|
|
12
|
+
* The slice of a schema a snapshot reads.
|
|
13
|
+
*
|
|
14
|
+
* Declared structurally so callers can supply the required snapshot data.
|
|
15
|
+
* `CoreSchema` satisfies this shape. Migrations also depends on
|
|
16
|
+
* `@zmdb/schema/naming` for canonical names.
|
|
17
|
+
*/
|
|
18
|
+
export interface SnapshotableSchema {
|
|
19
|
+
readonly table: string;
|
|
20
|
+
readonly primaryKey: readonly string[];
|
|
21
|
+
readonly columns: Readonly<Record<string, {
|
|
22
|
+
readonly type: string | ExtensionType;
|
|
23
|
+
readonly flags: {
|
|
24
|
+
readonly nullable: boolean;
|
|
25
|
+
readonly primaryKey?: boolean | undefined;
|
|
26
|
+
readonly length?: number | undefined;
|
|
27
|
+
readonly unique?: boolean | undefined;
|
|
28
|
+
};
|
|
29
|
+
readonly references?: {
|
|
30
|
+
readonly target: string;
|
|
31
|
+
};
|
|
32
|
+
}>>;
|
|
33
|
+
readonly ir?: {
|
|
34
|
+
readonly table: string;
|
|
35
|
+
readonly physicalTable?: string;
|
|
36
|
+
readonly columns: readonly {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly physicalName?: string;
|
|
39
|
+
readonly references?: string;
|
|
40
|
+
readonly onDelete?: ReferentialAction;
|
|
41
|
+
readonly onUpdate?: ReferentialAction;
|
|
42
|
+
}[];
|
|
43
|
+
readonly foreignKeys?: readonly {
|
|
44
|
+
readonly columns: readonly string[];
|
|
45
|
+
readonly targetTable: string;
|
|
46
|
+
readonly targetColumns: readonly string[];
|
|
47
|
+
}[];
|
|
48
|
+
readonly tableOptions?: TableOptions;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export declare function snapshot(schemas: readonly SnapshotableSchema[]): SchemaSnapshot;
|
|
52
|
+
export declare const CHANGE_PHASES: readonly [readonly ["create_extension"], readonly ["drop_foreign_key"], readonly ["drop_table"], readonly ["create_table", "add_column"], readonly ["alter_column_type", "alter_primary_key"], readonly ["drop_column"], readonly ["add_foreign_key"]];
|
|
53
|
+
export interface DiffOptions {
|
|
54
|
+
readonly dialect?: SqlDialect | undefined;
|
|
55
|
+
}
|
|
56
|
+
export interface MigrationPlan {
|
|
57
|
+
readonly operations: readonly ChangeOp[];
|
|
58
|
+
readonly up: readonly string[];
|
|
59
|
+
readonly down: readonly string[];
|
|
60
|
+
}
|
|
61
|
+
export interface MigrationPlanDialect {
|
|
62
|
+
readonly dialect: SqlDialect;
|
|
63
|
+
emitUp(operation: ChangeOp): string;
|
|
64
|
+
emitDown(operation: ChangeOp): string;
|
|
65
|
+
}
|
|
66
|
+
export declare function diff(prev: SchemaSnapshot, next: SchemaSnapshot, options?: DiffOptions): readonly ChangeOp[];
|
|
67
|
+
export declare function planMigration(previous: SchemaSnapshot, next: SchemaSnapshot, database: MigrationPlanDialect): MigrationPlan;
|
|
68
|
+
export declare function emitUp(operation: ChangeOp, target: SqlDialect | MigrationDialect): string;
|
|
69
|
+
export declare function emitDown(operation: ChangeOp, target: SqlDialect | MigrationDialect): string;
|
|
70
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
// Migrations (#41–#44): snapshot a set of schemas, diff two snapshots into
|
|
2
|
+
// change ops, and emit up/down DDL per dialect. Deterministic throughout —
|
|
3
|
+
// tables and columns are sorted by name so a snapshot is byte-stable.
|
|
4
|
+
import { UnsupportedFeatureError, dialectName, } from '@zmdb/sql';
|
|
5
|
+
import { ddlType } from '@zmdb/sql/schema-objects';
|
|
6
|
+
export {} from '@zmdb/sql';
|
|
7
|
+
export {} from '@zmdb/sql';
|
|
8
|
+
export { ddlType };
|
|
9
|
+
export { down, downTo, driverMigrationConnection, ensureVersionTable, rollbackTo, status, up } from './runner.js';
|
|
10
|
+
function migrationsOf(target) {
|
|
11
|
+
return 'migrations' in target ? target.migrations : target;
|
|
12
|
+
}
|
|
13
|
+
export function emitSchemaObject(operation, target) {
|
|
14
|
+
return migrationsOf(target).emitSchemaObject(operation);
|
|
15
|
+
}
|
|
16
|
+
function generatedForeignKeyName(table, columns) {
|
|
17
|
+
const name = `${table}_${columns.join('_')}_fkey`;
|
|
18
|
+
if (name.length > 63) {
|
|
19
|
+
throw new TypeError(`generated foreign key name "${name}" is ${name.length} characters long; PostgreSQL's limit is 63, ` +
|
|
20
|
+
'so give the table or columns shorter names');
|
|
21
|
+
}
|
|
22
|
+
return name;
|
|
23
|
+
}
|
|
24
|
+
function referencedTarget(target) {
|
|
25
|
+
const separator = target.indexOf('.');
|
|
26
|
+
if (separator <= 0 || separator !== target.lastIndexOf('.') || separator === target.length - 1) {
|
|
27
|
+
throw new TypeError(`foreign key target "${target}" must be written as "table.column"`);
|
|
28
|
+
}
|
|
29
|
+
return { table: target.slice(0, separator), column: target.slice(separator + 1) };
|
|
30
|
+
}
|
|
31
|
+
function physicalColumn(schema, declared) {
|
|
32
|
+
const column = schema.ir?.columns.find(candidate => candidate.name === declared);
|
|
33
|
+
return column?.physicalName ?? declared;
|
|
34
|
+
}
|
|
35
|
+
function physicalTarget(target, schemasByDeclaredTable) {
|
|
36
|
+
const declared = referencedTarget(target);
|
|
37
|
+
const schema = schemasByDeclaredTable.get(declared.table);
|
|
38
|
+
return schema === undefined
|
|
39
|
+
? declared
|
|
40
|
+
: {
|
|
41
|
+
table: schema.table,
|
|
42
|
+
column: physicalColumn(schema, declared.column),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function physicalTableOptions(schema) {
|
|
46
|
+
const options = schema.ir?.tableOptions;
|
|
47
|
+
if (options === undefined)
|
|
48
|
+
return undefined;
|
|
49
|
+
return {
|
|
50
|
+
...(options.shardKey === undefined
|
|
51
|
+
? {}
|
|
52
|
+
: { shardKey: options.shardKey.map(column => physicalColumn(schema, column)) }),
|
|
53
|
+
...(options.sortKey === undefined
|
|
54
|
+
? {}
|
|
55
|
+
: { sortKey: options.sortKey.map(column => physicalColumn(schema, column)) }),
|
|
56
|
+
...(options.rowstore === undefined ? {} : { rowstore: options.rowstore }),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function snapshot(schemas) {
|
|
60
|
+
const schemasByDeclaredTable = new Map(schemas.map(schema => [schema.ir?.table ?? schema.table, schema]));
|
|
61
|
+
const extensions = new Map();
|
|
62
|
+
const tables = schemas
|
|
63
|
+
.map(schema => {
|
|
64
|
+
const irColumns = new Map(schema.ir?.columns.flatMap(column => [
|
|
65
|
+
[column.name, column],
|
|
66
|
+
[column.physicalName ?? column.name, column],
|
|
67
|
+
]) ?? []);
|
|
68
|
+
const columns = Object.entries(schema.columns)
|
|
69
|
+
.map(([name, meta]) => {
|
|
70
|
+
if (typeof meta.type !== 'string') {
|
|
71
|
+
extensions.set(meta.type.extension, { name: meta.type.extension });
|
|
72
|
+
}
|
|
73
|
+
const ir = irColumns.get(name);
|
|
74
|
+
return {
|
|
75
|
+
name: ir?.physicalName ?? name,
|
|
76
|
+
type: meta.type,
|
|
77
|
+
nullable: meta.flags.nullable,
|
|
78
|
+
primaryKey: meta.flags.primaryKey === true,
|
|
79
|
+
// Written only when there is one, so columns that are not `varchar` do not
|
|
80
|
+
// acquire a meaningless field in the version-1 snapshot.
|
|
81
|
+
...(meta.flags.length === undefined ? {} : { length: meta.flags.length }),
|
|
82
|
+
...(meta.flags.unique === true ? { unique: true } : {}),
|
|
83
|
+
};
|
|
84
|
+
})
|
|
85
|
+
.toSorted((a, b) => a.name.localeCompare(b.name));
|
|
86
|
+
const foreignKeys = [];
|
|
87
|
+
for (const [name, meta] of Object.entries(schema.columns)) {
|
|
88
|
+
if (meta.references === undefined)
|
|
89
|
+
continue;
|
|
90
|
+
const target = physicalTarget(meta.references.target, schemasByDeclaredTable);
|
|
91
|
+
const ir = irColumns.get(name);
|
|
92
|
+
const localName = ir?.physicalName ?? name;
|
|
93
|
+
foreignKeys.push({
|
|
94
|
+
name: generatedForeignKeyName(schema.table, [localName]),
|
|
95
|
+
columns: [localName],
|
|
96
|
+
targetTable: target.table,
|
|
97
|
+
targetColumns: [target.column],
|
|
98
|
+
onDelete: ir?.onDelete ?? 'no action',
|
|
99
|
+
onUpdate: ir?.onUpdate ?? 'no action',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
for (const foreignKey of schema.ir?.foreignKeys ?? []) {
|
|
103
|
+
const localColumns = foreignKey.columns.map(column => physicalColumn(schema, column));
|
|
104
|
+
const targetSchema = schemasByDeclaredTable.get(foreignKey.targetTable);
|
|
105
|
+
foreignKeys.push({
|
|
106
|
+
name: generatedForeignKeyName(schema.table, localColumns),
|
|
107
|
+
columns: localColumns,
|
|
108
|
+
targetTable: targetSchema?.table ?? foreignKey.targetTable,
|
|
109
|
+
targetColumns: targetSchema === undefined
|
|
110
|
+
? foreignKey.targetColumns
|
|
111
|
+
: foreignKey.targetColumns.map(column => physicalColumn(targetSchema, column)),
|
|
112
|
+
onDelete: 'no action',
|
|
113
|
+
onUpdate: 'no action',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
const tableOptions = physicalTableOptions(schema);
|
|
117
|
+
return {
|
|
118
|
+
name: schema.table,
|
|
119
|
+
columns,
|
|
120
|
+
primaryKey: schema.primaryKey.map(column => physicalColumn(schema, column)),
|
|
121
|
+
foreignKeys: foreignKeys.toSorted((a, b) => a.name.localeCompare(b.name)),
|
|
122
|
+
...(tableOptions === undefined ? {} : { tableOptions }),
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
.toSorted((a, b) => a.name.localeCompare(b.name));
|
|
126
|
+
return {
|
|
127
|
+
version: 1,
|
|
128
|
+
tables,
|
|
129
|
+
extensions: [...extensions.values()].toSorted((a, b) => a.name.localeCompare(b.name)),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function sameType(previous, next) {
|
|
133
|
+
if (typeof previous === 'string' || typeof next === 'string')
|
|
134
|
+
return previous === next;
|
|
135
|
+
if (previous.extension !== next.extension || previous.name !== next.name)
|
|
136
|
+
return false;
|
|
137
|
+
const previousArgs = previous.args ?? [];
|
|
138
|
+
const nextArgs = next.args ?? [];
|
|
139
|
+
return previousArgs.length === nextArgs.length && previousArgs.every((value, index) => value === nextArgs[index]);
|
|
140
|
+
}
|
|
141
|
+
export const CHANGE_PHASES = [
|
|
142
|
+
['create_extension'],
|
|
143
|
+
['drop_foreign_key'],
|
|
144
|
+
['drop_table'],
|
|
145
|
+
['create_table', 'add_column'],
|
|
146
|
+
['alter_column_type', 'alter_primary_key'],
|
|
147
|
+
['drop_column'],
|
|
148
|
+
['add_foreign_key'],
|
|
149
|
+
];
|
|
150
|
+
const CHANGE_PHASE = new Map(CHANGE_PHASES.flatMap((kinds, phase) => kinds.map(kind => [kind, phase])));
|
|
151
|
+
function orderChanges(ops) {
|
|
152
|
+
const phaseOf = (kind) => {
|
|
153
|
+
const phase = CHANGE_PHASE.get(kind);
|
|
154
|
+
if (phase === undefined)
|
|
155
|
+
throw new Error(`change kind "${kind}" has no migration phase`);
|
|
156
|
+
return phase;
|
|
157
|
+
};
|
|
158
|
+
return ops.toSorted((left, right) => phaseOf(left.kind) - phaseOf(right.kind));
|
|
159
|
+
}
|
|
160
|
+
function sameSequence(previous, next) {
|
|
161
|
+
return previous.length === next.length && previous.every((value, index) => value === next[index]);
|
|
162
|
+
}
|
|
163
|
+
function sameTableOptions(previous, next) {
|
|
164
|
+
if (previous?.rowstore !== next?.rowstore)
|
|
165
|
+
return false;
|
|
166
|
+
return (sameSequence(previous?.shardKey ?? [], next?.shardKey ?? []) &&
|
|
167
|
+
sameSequence(previous?.sortKey ?? [], next?.sortKey ?? []));
|
|
168
|
+
}
|
|
169
|
+
function foreignKeysOf(table) {
|
|
170
|
+
// Stored snapshots written before referential actions landed have no field.
|
|
171
|
+
// Reading them as [] lets the first post-upgrade diff add the declared constraints
|
|
172
|
+
// instead of failing while loading the migration history.
|
|
173
|
+
return table.foreignKeys ?? [];
|
|
174
|
+
}
|
|
175
|
+
function foreignKeyIdentity(foreignKey) {
|
|
176
|
+
return JSON.stringify([foreignKey.columns, foreignKey.targetTable, foreignKey.targetColumns]);
|
|
177
|
+
}
|
|
178
|
+
function sameForeignKeyActions(previous, next) {
|
|
179
|
+
return previous.onDelete === next.onDelete && previous.onUpdate === next.onUpdate;
|
|
180
|
+
}
|
|
181
|
+
function diffForeignKeys(table, previous, next, ops) {
|
|
182
|
+
const unmatchedPrevious = new Map(previous.map(foreignKey => [foreignKeyIdentity(foreignKey), foreignKey]));
|
|
183
|
+
for (const foreignKey of next) {
|
|
184
|
+
const identity = foreignKeyIdentity(foreignKey);
|
|
185
|
+
const before = unmatchedPrevious.get(identity);
|
|
186
|
+
if (before === undefined) {
|
|
187
|
+
ops.push({ kind: 'add_foreign_key', table, fk: foreignKey });
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
unmatchedPrevious.delete(identity);
|
|
191
|
+
if (sameForeignKeyActions(before, foreignKey))
|
|
192
|
+
continue;
|
|
193
|
+
ops.push({ kind: 'drop_foreign_key', table, name: before.name });
|
|
194
|
+
ops.push({ kind: 'add_foreign_key', table, fk: foreignKey });
|
|
195
|
+
}
|
|
196
|
+
for (const foreignKey of unmatchedPrevious.values()) {
|
|
197
|
+
ops.push({ kind: 'drop_foreign_key', table, name: foreignKey.name });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function createdTablesInOrder(previous, next, dialect) {
|
|
201
|
+
const created = new Map(next.filter(table => !previous.has(table.name)).map(table => [table.name, table]));
|
|
202
|
+
const dependencies = new Map();
|
|
203
|
+
const dependants = new Map();
|
|
204
|
+
for (const table of created.values()) {
|
|
205
|
+
const targets = new Set(foreignKeysOf(table)
|
|
206
|
+
.map(foreignKey => foreignKey.targetTable)
|
|
207
|
+
.filter(target => target !== table.name && created.has(target)));
|
|
208
|
+
dependencies.set(table.name, targets);
|
|
209
|
+
for (const target of targets) {
|
|
210
|
+
const children = dependants.get(target) ?? new Set();
|
|
211
|
+
children.add(table.name);
|
|
212
|
+
dependants.set(target, children);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const ready = [...created.keys()]
|
|
216
|
+
.filter(name => dependencies.get(name)?.size === 0)
|
|
217
|
+
.toSorted((left, right) => left.localeCompare(right));
|
|
218
|
+
const ordered = [];
|
|
219
|
+
while (ready.length > 0) {
|
|
220
|
+
const name = ready.shift();
|
|
221
|
+
if (name === undefined)
|
|
222
|
+
break;
|
|
223
|
+
const table = created.get(name);
|
|
224
|
+
if (table !== undefined)
|
|
225
|
+
ordered.push(table);
|
|
226
|
+
for (const child of dependants.get(name) ?? []) {
|
|
227
|
+
const remaining = dependencies.get(child);
|
|
228
|
+
remaining?.delete(name);
|
|
229
|
+
if (remaining?.size === 0) {
|
|
230
|
+
ready.push(child);
|
|
231
|
+
ready.sort((left, right) => left.localeCompare(right));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (ordered.length === created.size)
|
|
236
|
+
return ordered;
|
|
237
|
+
const orderedNames = new Set(ordered.map(table => table.name));
|
|
238
|
+
const cyclic = [...created.keys()]
|
|
239
|
+
.filter(name => !orderedNames.has(name))
|
|
240
|
+
.toSorted((left, right) => left.localeCompare(right));
|
|
241
|
+
if (dialect?.migrations.foreignKeyMode === 'inline') {
|
|
242
|
+
const databaseName = dialectName(dialect);
|
|
243
|
+
throw new UnsupportedFeatureError(`creating mutually-referencing tables ${cyclic.map(tableName => `"${tableName}"`).join(', ')}`, databaseName, `${databaseName} cannot create the mutually-referencing tables ${cyclic
|
|
244
|
+
.map(tableName => `"${tableName}"`)
|
|
245
|
+
.join(' and ')}; ` +
|
|
246
|
+
'their foreign keys must be inline, so neither table can be created before the other — ' +
|
|
247
|
+
'use a hand-written table rebuild or remove the cycle');
|
|
248
|
+
}
|
|
249
|
+
return [...ordered, ...cyclic.map(name => created.get(name)).filter(table => table !== undefined)];
|
|
250
|
+
}
|
|
251
|
+
export function diff(prev, next, options = {}) {
|
|
252
|
+
const selectedDialect = options.dialect;
|
|
253
|
+
const ops = [];
|
|
254
|
+
const prevTables = new Map(prev.tables.map(t => [t.name, t]));
|
|
255
|
+
const nextTables = new Map(next.tables.map(t => [t.name, t]));
|
|
256
|
+
const prevExtensions = new Set(prev.extensions.map(extension => extension.name));
|
|
257
|
+
for (const extension of next.extensions) {
|
|
258
|
+
if (!prevExtensions.has(extension.name)) {
|
|
259
|
+
ops.push({
|
|
260
|
+
kind: 'create_extension',
|
|
261
|
+
name: extension.name,
|
|
262
|
+
...(extension.schema === undefined ? {} : { schema: extension.schema }),
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Dropped tables.
|
|
267
|
+
for (const t of prev.tables) {
|
|
268
|
+
if (!nextTables.has(t.name))
|
|
269
|
+
ops.push({ kind: 'drop_table', table: t.name });
|
|
270
|
+
}
|
|
271
|
+
// Column-level and foreign-key diffs on tables that already exist.
|
|
272
|
+
for (const t of next.tables) {
|
|
273
|
+
const before = prevTables.get(t.name);
|
|
274
|
+
if (!before)
|
|
275
|
+
continue;
|
|
276
|
+
if (!sameTableOptions(before.tableOptions, t.tableOptions)) {
|
|
277
|
+
const target = selectedDialect === undefined ? 'the selected migration dialect' : dialectName(selectedDialect);
|
|
278
|
+
throw new UnsupportedFeatureError('table options change', target, `${target} cannot alter the shard key, sort key, or rowstore setting of "${t.name}"; ` +
|
|
279
|
+
'create a replacement table and copy the data');
|
|
280
|
+
}
|
|
281
|
+
const beforeCols = new Map(before.columns.map(c => [c.name, c]));
|
|
282
|
+
const afterCols = new Map(t.columns.map(c => [c.name, c]));
|
|
283
|
+
for (const c of before.columns) {
|
|
284
|
+
if (!afterCols.has(c.name))
|
|
285
|
+
ops.push({ kind: 'drop_column', table: t.name, column: c.name });
|
|
286
|
+
}
|
|
287
|
+
for (const c of t.columns) {
|
|
288
|
+
const bc = beforeCols.get(c.name);
|
|
289
|
+
if (!bc) {
|
|
290
|
+
ops.push({ kind: 'add_column', table: t.name, column: c });
|
|
291
|
+
}
|
|
292
|
+
else if (!sameType(bc.type, c.type)) {
|
|
293
|
+
ops.push({
|
|
294
|
+
kind: 'alter_column_type',
|
|
295
|
+
table: t.name,
|
|
296
|
+
column: c.name,
|
|
297
|
+
from: bc.type,
|
|
298
|
+
to: c.type,
|
|
299
|
+
fromNullable: bc.nullable,
|
|
300
|
+
toNullable: c.nullable,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (!sameSequence(before.primaryKey, t.primaryKey)) {
|
|
305
|
+
ops.push({ kind: 'alter_primary_key', table: t.name, from: before.primaryKey, to: t.primaryKey });
|
|
306
|
+
}
|
|
307
|
+
diffForeignKeys(t.name, foreignKeysOf(before), foreignKeysOf(t), ops);
|
|
308
|
+
}
|
|
309
|
+
// Created tables are target-before-child for inline constraints. Deferred
|
|
310
|
+
// strategies get the same deterministic order before their ALTER statements.
|
|
311
|
+
for (const table of createdTablesInOrder(prevTables, next.tables, selectedDialect)) {
|
|
312
|
+
const foreignKeys = foreignKeysOf(table);
|
|
313
|
+
ops.push({
|
|
314
|
+
kind: 'create_table',
|
|
315
|
+
table: table.name,
|
|
316
|
+
columns: table.columns,
|
|
317
|
+
primaryKey: table.primaryKey,
|
|
318
|
+
foreignKeys,
|
|
319
|
+
...(table.tableOptions === undefined ? {} : { tableOptions: table.tableOptions }),
|
|
320
|
+
});
|
|
321
|
+
if (selectedDialect?.migrations.foreignKeyMode !== 'inline') {
|
|
322
|
+
for (const foreignKey of foreignKeys) {
|
|
323
|
+
ops.push({ kind: 'add_foreign_key', table: table.name, fk: foreignKey });
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const operations = orderChanges(ops);
|
|
328
|
+
selectedDialect?.migrations.validatePlan({
|
|
329
|
+
before: prev,
|
|
330
|
+
after: next,
|
|
331
|
+
operations,
|
|
332
|
+
});
|
|
333
|
+
return operations;
|
|
334
|
+
}
|
|
335
|
+
export function planMigration(previous, next, database) {
|
|
336
|
+
const operations = diff(previous, next, { dialect: database.dialect });
|
|
337
|
+
return {
|
|
338
|
+
operations,
|
|
339
|
+
up: operations.map(operation => database.emitUp(operation)),
|
|
340
|
+
down: operations.toReversed().map(operation => database.emitDown(operation)),
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
// Database packages own every DDL spelling; this package only delegates the planned operation.
|
|
344
|
+
export function emitUp(operation, target) {
|
|
345
|
+
return migrationsOf(target).emitUp(operation);
|
|
346
|
+
}
|
|
347
|
+
export function emitDown(operation, target) {
|
|
348
|
+
return migrationsOf(target).emitDown(operation);
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type CatalogSelection, type CatalogWarning, type CompiledQuery, type ReferentialAction } from '@zmdb/sql';
|
|
2
|
+
export { type CatalogColumnSnapshot, type CatalogForeignKeySnapshot, type CatalogIndexColumn, type CatalogIndexSnapshot, type CatalogSchemaSnapshot, type CatalogSelection, type CatalogTableSnapshot, type CatalogWarning, type IntrospectionDriver, type Introspector, type IntrospectOptions, type ReferentialAction, } from '@zmdb/sql';
|
|
3
|
+
export { normalizeDriftSnapshot } from './drift.js';
|
|
4
|
+
export declare class CatalogRowError extends TypeError {
|
|
5
|
+
readonly catalog: string;
|
|
6
|
+
readonly row: number;
|
|
7
|
+
readonly field: string;
|
|
8
|
+
readonly expected: string;
|
|
9
|
+
constructor(catalog: string, row: number, field: string, expected: string, value: unknown);
|
|
10
|
+
}
|
|
11
|
+
export declare function textField(row: Readonly<Record<string, unknown>>, field: string, catalog: string, index: number): string;
|
|
12
|
+
export declare function nullableTextField(row: Readonly<Record<string, unknown>>, field: string, catalog: string, index: number): string | null;
|
|
13
|
+
export declare function integerField(row: Readonly<Record<string, unknown>>, field: string, catalog: string, index: number): number;
|
|
14
|
+
export declare function nullableIntegerField(row: Readonly<Record<string, unknown>>, field: string, catalog: string, index: number): number | null;
|
|
15
|
+
export declare function flagField(row: Readonly<Record<string, unknown>>, field: string, catalog: string, index: number): boolean;
|
|
16
|
+
export declare function booleanField(row: Readonly<Record<string, unknown>>, field: string, catalog: string, index: number): boolean;
|
|
17
|
+
export declare function query(text: string, parameters?: readonly unknown[]): CompiledQuery;
|
|
18
|
+
export declare function tableSelected(name: string, selection: CatalogSelection): boolean;
|
|
19
|
+
export declare function action(value: string, catalog: string, row: number, field: string): ReferentialAction;
|
|
20
|
+
export declare function deterministicForeignKeyName(table: string, columns: readonly string[]): string;
|
|
21
|
+
export declare function sortByName<T extends {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
}>(values: readonly T[]): readonly T[];
|
|
24
|
+
export declare function sortWarnings(values: readonly CatalogWarning[]): readonly CatalogWarning[];
|
|
25
|
+
export declare function splitSqlList(value: string): readonly string[];
|
|
26
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/introspect/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import {} from '@zmdb/sql';
|
|
2
|
+
export {} from '@zmdb/sql';
|
|
3
|
+
export { normalizeDriftSnapshot } from './drift.js';
|
|
4
|
+
export class CatalogRowError extends TypeError {
|
|
5
|
+
catalog;
|
|
6
|
+
row;
|
|
7
|
+
field;
|
|
8
|
+
expected;
|
|
9
|
+
constructor(catalog, row, field, expected, value) {
|
|
10
|
+
super(`${catalog} row ${String(row)} field "${field}" must be ${expected}; received ${describeValue(value)}`);
|
|
11
|
+
this.name = 'CatalogRowError';
|
|
12
|
+
this.catalog = catalog;
|
|
13
|
+
this.row = row;
|
|
14
|
+
this.field = field;
|
|
15
|
+
this.expected = expected;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function describeValue(value) {
|
|
19
|
+
if (value === null)
|
|
20
|
+
return 'null';
|
|
21
|
+
if (Array.isArray(value))
|
|
22
|
+
return 'an array';
|
|
23
|
+
return typeof value;
|
|
24
|
+
}
|
|
25
|
+
function valueAt(row, field) {
|
|
26
|
+
return Reflect.get(row, field);
|
|
27
|
+
}
|
|
28
|
+
export function textField(row, field, catalog, index) {
|
|
29
|
+
const value = valueAt(row, field);
|
|
30
|
+
if (typeof value !== 'string')
|
|
31
|
+
throw new CatalogRowError(catalog, index, field, 'a string', value);
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
export function nullableTextField(row, field, catalog, index) {
|
|
35
|
+
const value = valueAt(row, field);
|
|
36
|
+
if (value === null)
|
|
37
|
+
return null;
|
|
38
|
+
if (typeof value !== 'string') {
|
|
39
|
+
throw new CatalogRowError(catalog, index, field, 'a string or null', value);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
export function integerField(row, field, catalog, index) {
|
|
44
|
+
const value = valueAt(row, field);
|
|
45
|
+
if (typeof value === 'number' && Number.isSafeInteger(value))
|
|
46
|
+
return value;
|
|
47
|
+
if (typeof value === 'string' && /^-?\d+$/.test(value)) {
|
|
48
|
+
const parsed = Number(value);
|
|
49
|
+
if (Number.isSafeInteger(parsed))
|
|
50
|
+
return parsed;
|
|
51
|
+
}
|
|
52
|
+
throw new CatalogRowError(catalog, index, field, 'a safe integer or decimal integer string', value);
|
|
53
|
+
}
|
|
54
|
+
export function nullableIntegerField(row, field, catalog, index) {
|
|
55
|
+
const value = valueAt(row, field);
|
|
56
|
+
if (value === null)
|
|
57
|
+
return null;
|
|
58
|
+
return integerField(row, field, catalog, index);
|
|
59
|
+
}
|
|
60
|
+
export function flagField(row, field, catalog, index) {
|
|
61
|
+
const value = integerField(row, field, catalog, index);
|
|
62
|
+
if (value === 0)
|
|
63
|
+
return false;
|
|
64
|
+
if (value === 1)
|
|
65
|
+
return true;
|
|
66
|
+
throw new CatalogRowError(catalog, index, field, '0 or 1', valueAt(row, field));
|
|
67
|
+
}
|
|
68
|
+
export function booleanField(row, field, catalog, index) {
|
|
69
|
+
const value = valueAt(row, field);
|
|
70
|
+
if (typeof value === 'boolean')
|
|
71
|
+
return value;
|
|
72
|
+
throw new CatalogRowError(catalog, index, field, 'a boolean', value);
|
|
73
|
+
}
|
|
74
|
+
export function query(text, parameters = []) {
|
|
75
|
+
return { text, parameters };
|
|
76
|
+
}
|
|
77
|
+
function globExpression(glob) {
|
|
78
|
+
let source = '^';
|
|
79
|
+
for (const character of glob) {
|
|
80
|
+
if (character === '*')
|
|
81
|
+
source += '.*';
|
|
82
|
+
else if (character === '?')
|
|
83
|
+
source += '.';
|
|
84
|
+
else
|
|
85
|
+
source += character.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
|
|
86
|
+
}
|
|
87
|
+
return new RegExp(`${source}$`);
|
|
88
|
+
}
|
|
89
|
+
function matchesAny(name, globs) {
|
|
90
|
+
return globs.some(glob => globExpression(glob).test(name));
|
|
91
|
+
}
|
|
92
|
+
export function tableSelected(name, selection) {
|
|
93
|
+
const include = selection.include;
|
|
94
|
+
if (include !== undefined && include.length > 0 && !matchesAny(name, include))
|
|
95
|
+
return false;
|
|
96
|
+
const exclude = selection.exclude ?? ['_zmdb_migrations'];
|
|
97
|
+
return !matchesAny(name, exclude);
|
|
98
|
+
}
|
|
99
|
+
export function action(value, catalog, row, field) {
|
|
100
|
+
const normalized = value.toLowerCase().replaceAll('_', ' ');
|
|
101
|
+
switch (normalized) {
|
|
102
|
+
case 'no action':
|
|
103
|
+
case 'restrict':
|
|
104
|
+
case 'cascade':
|
|
105
|
+
case 'set null':
|
|
106
|
+
case 'set default':
|
|
107
|
+
return normalized;
|
|
108
|
+
default:
|
|
109
|
+
throw new CatalogRowError(catalog, row, field, 'a referential action', value);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export function deterministicForeignKeyName(table, columns) {
|
|
113
|
+
return `${table}_${columns.join('_')}_fkey`;
|
|
114
|
+
}
|
|
115
|
+
export function sortByName(values) {
|
|
116
|
+
return values.toSorted((left, right) => left.name.localeCompare(right.name));
|
|
117
|
+
}
|
|
118
|
+
export function sortWarnings(values) {
|
|
119
|
+
return values.toSorted((left, right) => left.table.localeCompare(right.table) ||
|
|
120
|
+
(left.column ?? '').localeCompare(right.column ?? '') ||
|
|
121
|
+
left.reason.localeCompare(right.reason));
|
|
122
|
+
}
|
|
123
|
+
export function splitSqlList(value) {
|
|
124
|
+
const parts = [];
|
|
125
|
+
let start = 0;
|
|
126
|
+
let depth = 0;
|
|
127
|
+
let quote;
|
|
128
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
129
|
+
const character = value[index];
|
|
130
|
+
if (quote !== undefined) {
|
|
131
|
+
if (character === quote) {
|
|
132
|
+
if (value[index + 1] === quote)
|
|
133
|
+
index += 1;
|
|
134
|
+
else
|
|
135
|
+
quote = undefined;
|
|
136
|
+
}
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (character === "'" || character === '"' || character === '`') {
|
|
140
|
+
quote = character;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (character === '(')
|
|
144
|
+
depth += 1;
|
|
145
|
+
else if (character === ')')
|
|
146
|
+
depth -= 1;
|
|
147
|
+
else if (character === ',' && depth === 0) {
|
|
148
|
+
parts.push(value.slice(start, index).trim());
|
|
149
|
+
start = index + 1;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
parts.push(value.slice(start).trim());
|
|
153
|
+
return parts;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=common.js.map
|