qubu 0.6.0 → 0.6.2
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/README.md +112 -0
- package/dist/{complete-DP7pliuY.mjs → canonical-B5_ouh-c.mjs} +466 -241
- package/dist/codegen.d.mts +2 -2
- package/dist/codegen.mjs +180 -90
- package/dist/column-Cyc2CMnG.mjs +116 -0
- package/dist/column-DDRvD7SF.mjs +721 -0
- package/dist/{constraints-YGyNPQ_z.mjs → constraints-CAmi18Uk.mjs} +8 -3
- package/dist/core.d.mts +3 -3
- package/dist/core.mjs +4 -5
- package/dist/diagnostics-I9vVtXkc.mjs +40 -0
- package/dist/diff.d.mts +9 -9
- package/dist/diff.mjs +152 -102
- package/dist/{explain-CkIK13L_.mjs → explain-BIqEmZha.mjs} +1 -1
- package/dist/expressions-_6JF_J77.mjs +130 -0
- package/dist/index-CaxrMD1A.d.mts +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +414 -77
- package/dist/introspection/mysql.d.mts +26 -0
- package/dist/introspection/mysql.mjs +1278 -0
- package/dist/introspection/postgres.d.mts +43 -0
- package/dist/introspection/postgres.mjs +1889 -0
- package/dist/introspection/sqlite.d.mts +15 -0
- package/dist/introspection/sqlite.mjs +1172 -0
- package/dist/introspection.d.mts +26 -87
- package/dist/introspection.mjs +3 -4351
- package/dist/mysql.d.mts +3 -3
- package/dist/mysql.mjs +8 -7
- package/dist/{errors-Dxv73YJu.mjs → omit-VEr9Ydux.mjs} +5 -1
- package/dist/{on-conflict-DZQ85f1t.mjs → on-conflict-B2rFyHGF.mjs} +78 -8
- package/dist/on-duplicate-key-update-Czsw1Yq-.mjs +95 -0
- package/dist/postgres-hFhd0I9n.mjs +68 -0
- package/dist/postgres.d.mts +3 -3
- package/dist/postgres.mjs +3 -52
- package/dist/registry-BXE_4M9P.mjs +127 -0
- package/dist/{relational-CxnLCqZQ.mjs → relational-CoPBETjI.mjs} +3 -3
- package/dist/schema.d.mts +2 -2
- package/dist/schema.mjs +8 -7
- package/dist/{serialize-BN07IK0v.mjs → serialize-CyobNEx-.mjs} +174 -30
- package/dist/serialize-Du2UPZMt.d.mts +92 -0
- package/dist/snapshot/mysql.d.mts +5 -5
- package/dist/snapshot/mysql.mjs +32 -32
- package/dist/snapshot/postgres.d.mts +5 -5
- package/dist/snapshot/postgres.mjs +25 -25
- package/dist/snapshot/sqlite.d.mts +5 -5
- package/dist/snapshot/sqlite.mjs +30 -30
- package/dist/snapshot-mIb-Zzb5.mjs +1489 -0
- package/dist/snapshot.d.mts +4 -5
- package/dist/snapshot.mjs +3 -4
- package/dist/{source-SqrKWjFJ.mjs → source-DYSUqzvb.mjs} +2 -2
- package/dist/sqlite.d.mts +2 -2
- package/dist/sqlite.mjs +10 -10
- package/dist/{table-BwflqeAj.mjs → table-B8zEq0az.mjs} +4 -4
- package/dist/{types-BIJsj2fJ.mjs → types-CYHpSPwj.mjs} +10 -7
- package/dist/{types-CTCqtFlS.d.mts → types-CiMvKi5V.d.mts} +14 -4
- package/dist/{types-C0VkiwpR.d.mts → types-Dqr4o2I1.d.mts} +640 -189
- package/dist/value-CpaUFtjw.mjs +45 -0
- package/dist/vite/ambient.d.ts +2 -0
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +2 -0
- package/docs/dialects-and-execution.md +61 -11
- package/docs/getting-started.md +1 -1
- package/docs/guides/compose-queries.md +22 -0
- package/docs/guides/drizzle.md +11 -11
- package/docs/guides/extensions/typed-expressions.md +5 -3
- package/docs/guides/json.md +95 -2
- package/docs/guides/mutations.md +125 -0
- package/docs/guides/valtio-sync.md +113 -0
- package/docs/index.md +1 -1
- package/docs/migrations/adapters.md +58 -21
- package/docs/migrations/index.md +50 -12
- package/docs/migrations/operations.md +20 -6
- package/docs/migrations/recovery.md +7 -1
- package/docs/query-model/fragments.md +21 -1
- package/docs/reference/introspection-support.md +16 -18
- package/docs/reference/supported-surface.md +23 -11
- package/docs/schema/catalog-model.md +20 -7
- package/docs/schema/code-generation.md +4 -3
- package/docs/schema/diff.md +2 -2
- package/docs/schema/introspection.md +24 -16
- package/docs/schema/snapshots.md +18 -8
- package/docs/schema/storage-and-schema-sql.md +7 -2
- package/docs/sql-semantic-types.md +8 -0
- package/package.json +14 -1
- package/dist/canonical-DMvR9yBe.mjs +0 -972
- package/dist/column-Da37jYSD.mjs +0 -309
- package/dist/column-r1Y4ivwt.mjs +0 -327
- package/dist/complete-types-CY0KbzNw.d.mts +0 -371
- package/dist/index-B2rZf3-2.d.mts +0 -32
- package/dist/json-Db7XRD91.mjs +0 -169
- package/dist/omit-OxV58AwX.mjs +0 -5
- package/dist/registry-BRcUuazJ.mjs +0 -256
- package/dist/serialize-CEIIlWhC.d.mts +0 -66
- package/dist/snapshot-Xam8-q0j.mjs +0 -392
- package/dist/standard-DfcZEVOj.mjs +0 -12
- package/dist/value-D14I_XgL.mjs +0 -29
|
@@ -0,0 +1,1489 @@
|
|
|
1
|
+
import { a as toSnapshotJsonValue, d as assertCompleteSchemaSnapshot } from "./canonical-B5_ouh-c.mjs";
|
|
2
|
+
import "./snapshot.mjs";
|
|
3
|
+
import { storageAffinity } from "./snapshot/sqlite.mjs";
|
|
4
|
+
import { n as createIntrospectionDiagnostic } from "./diagnostics-I9vVtXkc.mjs";
|
|
5
|
+
//#region src/snapshot/candidate-key.ts
|
|
6
|
+
/** Return the column IDs for an index whose shape can prove a candidate key. */
|
|
7
|
+
function candidateKeyIndexColumns(index) {
|
|
8
|
+
if (!index.unique || index.predicate !== void 0 || index.terms.length === 0) return;
|
|
9
|
+
const columns = [];
|
|
10
|
+
for (const term of index.terms) {
|
|
11
|
+
if (term.kind !== "column" || term.prefixLength !== void 0 || term.operatorClass !== void 0) return;
|
|
12
|
+
columns.push(term.column);
|
|
13
|
+
}
|
|
14
|
+
return columns;
|
|
15
|
+
}
|
|
16
|
+
/** Return whether an index's facts prove a non-null, non-lossy candidate key. */
|
|
17
|
+
function hasCandidateKeyShape(index, columns) {
|
|
18
|
+
const indexColumns = candidateKeyIndexColumns(index);
|
|
19
|
+
return indexColumns !== void 0 && indexColumns.every((column) => {
|
|
20
|
+
const nullable = columns.get(column);
|
|
21
|
+
return (typeof nullable === "boolean" ? nullable : nullable?.nullable) === false;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** Return whether the snapshot explicitly marks a shape-proven index as a candidate key. */
|
|
25
|
+
function isCandidateKeyIndex(index, columns) {
|
|
26
|
+
return index.candidateKey && hasCandidateKeyShape(index, columns);
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/introspection/catalog.ts
|
|
30
|
+
/**
|
|
31
|
+
* Materialize every optional object-family collection and deeply freeze the normalized catalog.
|
|
32
|
+
* Catalog text and extension data remain values; this helper never evaluates SQL or assigns
|
|
33
|
+
* persisted logical identities.
|
|
34
|
+
*/
|
|
35
|
+
function createCompleteIntrospectionCatalog(catalog) {
|
|
36
|
+
return deepFreeze({
|
|
37
|
+
dialect: catalog.dialect,
|
|
38
|
+
server: catalog.server,
|
|
39
|
+
capabilities: catalog.capabilities ?? catalog.server.capabilities,
|
|
40
|
+
namespace: catalog.namespace,
|
|
41
|
+
tables: sortTables(catalog.tables),
|
|
42
|
+
views: sortObjects(catalog.views ?? []),
|
|
43
|
+
sequences: sortObjects(catalog.sequences ?? []),
|
|
44
|
+
enums: sortObjects(catalog.enums ?? []),
|
|
45
|
+
domains: sortObjects(catalog.domains ?? []),
|
|
46
|
+
collations: sortObjects(catalog.collations ?? []),
|
|
47
|
+
triggers: sortObjects(catalog.triggers ?? []),
|
|
48
|
+
routines: sortObjects(catalog.routines ?? []),
|
|
49
|
+
partitions: sortObjects(catalog.partitions ?? []),
|
|
50
|
+
policies: sortObjects(catalog.policies ?? []),
|
|
51
|
+
extensionObjects: sortObjects(catalog.extensionObjects ?? []),
|
|
52
|
+
deferredObjects: [...catalog.deferredObjects].sort(compareDeferred),
|
|
53
|
+
opaqueObjects: sortObjects(catalog.opaqueObjects ?? []),
|
|
54
|
+
comments: [...catalog.comments ?? []].sort(compareId$1),
|
|
55
|
+
ownership: [...catalog.ownership ?? []].sort(compareId$1),
|
|
56
|
+
diagnostics: [...catalog.diagnostics]
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** Alias for callers that already use the normalized-catalog terminology. */
|
|
60
|
+
const freezeIntrospectionCatalog = createCompleteIntrospectionCatalog;
|
|
61
|
+
/** Convert a complete catalog back to the optional reader-facing contract. */
|
|
62
|
+
function toIntrospectionCatalog(catalog) {
|
|
63
|
+
return deepFreeze({
|
|
64
|
+
...catalog,
|
|
65
|
+
capabilities: catalog.capabilities
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function sortTables(tables) {
|
|
69
|
+
return [...tables].map((table) => deepFreeze({
|
|
70
|
+
...table,
|
|
71
|
+
columns: [...table.columns].sort(compareColumn),
|
|
72
|
+
constraints: [...table.constraints].sort(compareId$1),
|
|
73
|
+
indexes: [...table.indexes].sort(compareId$1)
|
|
74
|
+
})).sort(compareId$1);
|
|
75
|
+
}
|
|
76
|
+
function sortObjects(objects) {
|
|
77
|
+
return [...objects].sort(compareId$1);
|
|
78
|
+
}
|
|
79
|
+
function compareId$1(left, right) {
|
|
80
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
81
|
+
}
|
|
82
|
+
function compareDeferred(left, right) {
|
|
83
|
+
const leftId = left.id ?? left.physicalName;
|
|
84
|
+
const rightId = right.id ?? right.physicalName;
|
|
85
|
+
return leftId < rightId ? -1 : leftId > rightId ? 1 : 0;
|
|
86
|
+
}
|
|
87
|
+
function compareColumn(left, right) {
|
|
88
|
+
return left.ordinalPosition - right.ordinalPosition || compareId$1(left, right);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Freeze nested catalog values without imposing JSON semantics on bigint or opaque driver values.
|
|
92
|
+
* The normalized contract is expected to contain plain records, arrays, and scalar values;
|
|
93
|
+
* unsupported prototypes are retained but still frozen so the operation remains non-destructive.
|
|
94
|
+
*/
|
|
95
|
+
function deepFreeze(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
96
|
+
if (value === null || typeof value !== "object") return value;
|
|
97
|
+
if (seen.has(value)) return value;
|
|
98
|
+
seen.add(value);
|
|
99
|
+
if (Array.isArray(value)) for (const item of value) deepFreeze(item, seen);
|
|
100
|
+
else for (const child of Object.values(value)) deepFreeze(child, seen);
|
|
101
|
+
return Object.freeze(value);
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/introspection/identity.ts
|
|
105
|
+
/** The naming policy used by the first introspection snapshot mapper. */
|
|
106
|
+
const introspectedPhysicalIdentityPolicy = Object.freeze({
|
|
107
|
+
name: "introspected-physical",
|
|
108
|
+
version: 1,
|
|
109
|
+
fallback: "escaped",
|
|
110
|
+
precedence: Object.freeze([
|
|
111
|
+
"explicit-hint",
|
|
112
|
+
"previous-snapshot",
|
|
113
|
+
"physical-name",
|
|
114
|
+
"deterministic-fallback"
|
|
115
|
+
])
|
|
116
|
+
});
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/introspection/complete-snapshot.ts
|
|
119
|
+
/**
|
|
120
|
+
* Map a normalized catalog to validated Snapshot v1 data.
|
|
121
|
+
*
|
|
122
|
+
* Strict mode reports mapping errors as failure. Explicit lossy mode may omit only recoverable
|
|
123
|
+
* unsafe facts and marks a successful result as lossy. Complete objects are never fabricated as
|
|
124
|
+
* tables, and catalog references remain evidence rather than logical IDs.
|
|
125
|
+
*/
|
|
126
|
+
function mapCatalogToCompleteSnapshot(input, options) {
|
|
127
|
+
const catalog = createCompleteIntrospectionCatalog(applyIdentityOptions(input, options));
|
|
128
|
+
const normalizedDiagnostics = normalizeCatalogDiagnostics(catalog.diagnostics, options?.mode ?? "strict");
|
|
129
|
+
const context = {
|
|
130
|
+
mode: options?.mode ?? "strict",
|
|
131
|
+
diagnostics: normalizedDiagnostics.diagnostics,
|
|
132
|
+
lossy: normalizedDiagnostics.lossy,
|
|
133
|
+
references: createCatalogReferenceLookup(catalog)
|
|
134
|
+
};
|
|
135
|
+
const tableByPhysicalName = new Map(catalog.tables.map((table) => [table.physicalName, table]));
|
|
136
|
+
const tables = catalog.tables.map((table) => mapTable(table, catalog.dialect, tableByPhysicalName, context));
|
|
137
|
+
const views = catalog.views.map((view, index) => mapView(view, catalog.dialect, context, ["views", index]));
|
|
138
|
+
const sequences = catalog.sequences.map((sequence, index) => mapSequence(sequence, catalog.dialect, context, ["sequences", index])).filter((sequence) => sequence !== void 0);
|
|
139
|
+
const enums = catalog.enums.map((item) => mapEnum(item, catalog.dialect));
|
|
140
|
+
const domains = catalog.domains.map((domain) => mapDomain(domain, catalog.dialect));
|
|
141
|
+
const collations = catalog.collations.map((collation) => ({
|
|
142
|
+
kind: "collation",
|
|
143
|
+
id: collation.id,
|
|
144
|
+
physicalName: collation.physicalName,
|
|
145
|
+
...collation.provider === void 0 ? {} : { provider: collation.provider },
|
|
146
|
+
...collation.locale === void 0 ? {} : { locale: collation.locale },
|
|
147
|
+
...collation.deterministic === void 0 ? {} : { deterministic: collation.deterministic },
|
|
148
|
+
...collation.version === void 0 ? {} : { version: collation.version },
|
|
149
|
+
...mapMetadata(collation.provenance, collation.dialect, catalog.dialect, collation.reference)
|
|
150
|
+
}));
|
|
151
|
+
const triggers = catalog.triggers.map((trigger, index) => mapTrigger(trigger, catalog.dialect, context, ["triggers", index]));
|
|
152
|
+
const routines = catalog.routines.map((routine, index) => mapRoutine(routine, catalog.dialect, context, ["routines", index]));
|
|
153
|
+
const partitions = catalog.partitions.map((partition, index) => mapPartition(partition, catalog.dialect, context, ["partitions", index]));
|
|
154
|
+
const policies = catalog.policies.map((policy, index) => mapPolicy(policy, catalog.dialect, context, ["policies", index]));
|
|
155
|
+
const extensions = catalog.extensionObjects.map((extension) => mapExtensionObject(extension, catalog.dialect));
|
|
156
|
+
const deferredObjects = catalog.deferredObjects.map((object) => mapDeferredObject(object, catalog.dialect));
|
|
157
|
+
const opaqueObjects = catalog.opaqueObjects.map((object) => mapOpaqueObject(object, catalog.dialect));
|
|
158
|
+
for (const object of catalogObjectsWithUnknownFields(catalog)) for (const field of object.unknownFields ?? []) opaqueObjects.push(mapUnknownField(object, field, catalog.dialect));
|
|
159
|
+
const comments = (catalog.comments ?? []).map((comment, index) => mapComment(comment, catalog.dialect, context, ["comments", index])).filter((comment) => comment !== void 0);
|
|
160
|
+
const ownership = (catalog.ownership ?? []).map((item, index) => mapOwnership(item, catalog.dialect, context, ["ownership", index])).filter((item) => item !== void 0);
|
|
161
|
+
for (const object of catalogObjectList(catalog)) {
|
|
162
|
+
if (object.comment && !comments.some((item) => item.id === object.comment?.id)) {
|
|
163
|
+
const comment = mapComment(object.comment, catalog.dialect, context, ["comments"], object.ownerScope);
|
|
164
|
+
if (comment !== void 0) comments.push(comment);
|
|
165
|
+
}
|
|
166
|
+
if (object.ownership && !ownership.some((item) => item.id === object.ownership?.id)) {
|
|
167
|
+
const ownershipRecord = mapOwnership(object.ownership, catalog.dialect, context, ["ownership"], object.ownerScope);
|
|
168
|
+
if (ownershipRecord !== void 0) ownership.push(ownershipRecord);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const snapshot = {
|
|
172
|
+
format: "qubu-schema",
|
|
173
|
+
version: 1,
|
|
174
|
+
dialect: {
|
|
175
|
+
name: catalog.dialect,
|
|
176
|
+
version: 1
|
|
177
|
+
},
|
|
178
|
+
namingPolicy: {
|
|
179
|
+
name: (options?.identityPolicy ?? introspectedPhysicalIdentityPolicy).name,
|
|
180
|
+
version: (options?.identityPolicy ?? introspectedPhysicalIdentityPolicy).version
|
|
181
|
+
},
|
|
182
|
+
namespace: {
|
|
183
|
+
kind: catalog.namespace.kind,
|
|
184
|
+
name: catalog.namespace.name,
|
|
185
|
+
...mapMetadata(catalog.namespace.provenance, catalog.namespace.dialect, catalog.dialect, catalog.namespace.reference)
|
|
186
|
+
},
|
|
187
|
+
capabilities: catalog.capabilities,
|
|
188
|
+
tables: tables.sort(compareId),
|
|
189
|
+
views: views.sort(compareId),
|
|
190
|
+
sequences: sequences.sort(compareId),
|
|
191
|
+
enums: enums.sort(compareId),
|
|
192
|
+
domains: domains.sort(compareId),
|
|
193
|
+
collations: collations.sort(compareId),
|
|
194
|
+
triggers: triggers.filter((trigger) => trigger !== void 0).sort(compareId),
|
|
195
|
+
routines: routines.filter((routine) => routine !== void 0).sort(compareId),
|
|
196
|
+
partitions: partitions.filter((partition) => partition !== void 0).sort(compareId),
|
|
197
|
+
policies: policies.filter((policy) => policy !== void 0).sort(compareId),
|
|
198
|
+
extensions: extensions.sort(compareId),
|
|
199
|
+
deferredObjects: deferredObjects.sort(compareId),
|
|
200
|
+
opaqueObjects: opaqueObjects.sort(compareId),
|
|
201
|
+
comments: comments.sort(compareId),
|
|
202
|
+
ownership: ownership.sort(compareId)
|
|
203
|
+
};
|
|
204
|
+
let validatedSnapshot;
|
|
205
|
+
try {
|
|
206
|
+
validatedSnapshot = assertCompleteSchemaSnapshot(snapshot);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
context.diagnostics.push(createIntrospectionDiagnostic({
|
|
209
|
+
severity: "error",
|
|
210
|
+
code: "invalid-catalog-row",
|
|
211
|
+
message: error instanceof Error ? `Catalog facts could not form Snapshot v1: ${error.message}` : "Catalog facts could not form Snapshot v1",
|
|
212
|
+
path: [],
|
|
213
|
+
remediation: "Inspect the catalog diagnostics and complete object mappings."
|
|
214
|
+
}));
|
|
215
|
+
return Object.freeze({
|
|
216
|
+
ok: false,
|
|
217
|
+
catalog,
|
|
218
|
+
diagnostics: Object.freeze(context.diagnostics),
|
|
219
|
+
lossy: false
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (context.diagnostics.some((diagnostic) => diagnostic.severity === "error")) return Object.freeze({
|
|
223
|
+
ok: false,
|
|
224
|
+
catalog,
|
|
225
|
+
diagnostics: Object.freeze(context.diagnostics),
|
|
226
|
+
lossy: false
|
|
227
|
+
});
|
|
228
|
+
const diagnostics = Object.freeze(context.diagnostics);
|
|
229
|
+
if (context.lossy) return Object.freeze({
|
|
230
|
+
ok: true,
|
|
231
|
+
catalog,
|
|
232
|
+
snapshot: validatedSnapshot,
|
|
233
|
+
diagnostics,
|
|
234
|
+
lossy: true
|
|
235
|
+
});
|
|
236
|
+
return Object.freeze({
|
|
237
|
+
ok: true,
|
|
238
|
+
catalog,
|
|
239
|
+
snapshot: validatedSnapshot,
|
|
240
|
+
diagnostics,
|
|
241
|
+
lossy: false
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
/** Numbered alias for callers that prefer the explicit Snapshot v1 mapper name. */
|
|
245
|
+
const mapCatalogToSnapshotV1 = mapCatalogToCompleteSnapshot;
|
|
246
|
+
function applyIdentityOptions(input, options) {
|
|
247
|
+
if (options?.identityHints === void 0 && options?.previousSnapshot === void 0 && options?.identityPolicy === void 0) return input;
|
|
248
|
+
const policy = options?.identityPolicy ?? introspectedPhysicalIdentityPolicy;
|
|
249
|
+
const identityDiagnostics = [];
|
|
250
|
+
const previous = selectPreviousSnapshot(input, options?.previousSnapshot, options?.namespace ?? input.namespace.name, identityDiagnostics);
|
|
251
|
+
const entries = collectIdentityEntries(input);
|
|
252
|
+
const previousIndex = previous === void 0 ? void 0 : collectPreviousIdentities(previous);
|
|
253
|
+
return rewriteCatalog(input, createIdentityResolver(entries, options?.identityHints ?? [], previousIndex, policy, identityDiagnostics), identityDiagnostics);
|
|
254
|
+
}
|
|
255
|
+
function normalizeCatalogDiagnostics(diagnostics, mode) {
|
|
256
|
+
const normalized = [];
|
|
257
|
+
let lossy = false;
|
|
258
|
+
for (const diagnostic of diagnostics) {
|
|
259
|
+
if (diagnostic.code === "lossy-mapping") lossy = true;
|
|
260
|
+
if (mode === "lossy" && isRecoverableMappingDiagnostic(diagnostic)) {
|
|
261
|
+
lossy = true;
|
|
262
|
+
normalized.push(createIntrospectionDiagnostic({
|
|
263
|
+
...diagnostic,
|
|
264
|
+
severity: "warning",
|
|
265
|
+
code: "lossy-mapping",
|
|
266
|
+
message: `Lossy mapping omitted an unsafe catalog fact: ${diagnostic.message}`
|
|
267
|
+
}));
|
|
268
|
+
} else normalized.push(diagnostic);
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
diagnostics: normalized,
|
|
272
|
+
lossy
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function isRecoverableMappingDiagnostic(diagnostic) {
|
|
276
|
+
if (diagnostic.severity !== "error") return false;
|
|
277
|
+
if (diagnostic.code === "unresolved-reference" || diagnostic.code === "expression-parse-failed" || diagnostic.code === "unsupported-feature" || diagnostic.code === "ambiguous-identity") return true;
|
|
278
|
+
return diagnostic.code === "dialect-mismatch" && diagnostic.path[0] === "previousSnapshot";
|
|
279
|
+
}
|
|
280
|
+
function reportMappingIssue(context, input, recoverable = true) {
|
|
281
|
+
if (context.mode === "lossy" && recoverable) {
|
|
282
|
+
context.lossy = true;
|
|
283
|
+
context.diagnostics.push(createIntrospectionDiagnostic({
|
|
284
|
+
...input,
|
|
285
|
+
severity: "warning",
|
|
286
|
+
code: "lossy-mapping",
|
|
287
|
+
message: `Lossy mapping omitted an unsafe catalog fact: ${input.message}`
|
|
288
|
+
}));
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
context.diagnostics.push(createIntrospectionDiagnostic({
|
|
292
|
+
...input,
|
|
293
|
+
severity: "error"
|
|
294
|
+
}));
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
function createCatalogReferenceLookup(catalog) {
|
|
298
|
+
const keys = /* @__PURE__ */ new Set();
|
|
299
|
+
const scopedKeys = /* @__PURE__ */ new Set();
|
|
300
|
+
const inferredOwners = /* @__PURE__ */ new Map();
|
|
301
|
+
const add = (kind, id) => keys.add(referenceKey(kind, id));
|
|
302
|
+
const addScoped = (kind, id, ownerKind, ownerId) => {
|
|
303
|
+
add(kind, id);
|
|
304
|
+
scopedKeys.add(referenceKey(`${kind}:${ownerKind}:${ownerId}`, id));
|
|
305
|
+
const key = referenceKey(normalizeReferenceKind(kind), id);
|
|
306
|
+
const owner = {
|
|
307
|
+
kind: ownerKind,
|
|
308
|
+
id: ownerId
|
|
309
|
+
};
|
|
310
|
+
const existing = inferredOwners.get(key);
|
|
311
|
+
inferredOwners.set(key, existing === void 0 ? owner : existing === null || existing.kind !== owner.kind || existing.id !== owner.id ? null : existing);
|
|
312
|
+
};
|
|
313
|
+
add("namespace", catalog.namespace.name);
|
|
314
|
+
for (const table of catalog.tables) {
|
|
315
|
+
add("table", table.id);
|
|
316
|
+
for (const column of table.columns) addScoped("column", column.id, "table", table.id);
|
|
317
|
+
for (const constraint of table.constraints) {
|
|
318
|
+
addScoped("constraint", constraint.id, "table", table.id);
|
|
319
|
+
addScoped(constraint.kind, constraint.id, "table", table.id);
|
|
320
|
+
}
|
|
321
|
+
for (const index of table.indexes) addScoped("index", index.id, "table", table.id);
|
|
322
|
+
}
|
|
323
|
+
for (const view of catalog.views) {
|
|
324
|
+
add(view.kind, view.id);
|
|
325
|
+
for (const column of view.columns) addScoped("column", column.id, view.kind, view.id);
|
|
326
|
+
}
|
|
327
|
+
for (const sequence of catalog.sequences) add("sequence", sequence.id);
|
|
328
|
+
for (const item of catalog.enums) add("enum", item.id);
|
|
329
|
+
for (const domain of catalog.domains) {
|
|
330
|
+
add("domain", domain.id);
|
|
331
|
+
for (const constraint of domain.constraints ?? []) {
|
|
332
|
+
addScoped("constraint", constraint.id, "domain", domain.id);
|
|
333
|
+
addScoped("check", constraint.id, "domain", domain.id);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
for (const collation of catalog.collations) add("collation", collation.id);
|
|
337
|
+
for (const trigger of catalog.triggers) add("trigger", trigger.id);
|
|
338
|
+
for (const routine of catalog.routines) add("routine", routine.id);
|
|
339
|
+
for (const partition of catalog.partitions) add("partition", partition.id);
|
|
340
|
+
for (const policy of catalog.policies) add("policy", policy.id);
|
|
341
|
+
for (const extension of catalog.extensionObjects) add("extension", extension.id);
|
|
342
|
+
for (const object of catalog.deferredObjects) add("deferred-object", object.id ?? `deferred:${object.objectKind}:${object.physicalName}`);
|
|
343
|
+
for (const object of catalog.opaqueObjects) add("opaque-object", object.id);
|
|
344
|
+
for (const comment of catalog.comments) add("comment", comment.id);
|
|
345
|
+
for (const ownership of catalog.ownership) add("ownership", ownership.id);
|
|
346
|
+
return {
|
|
347
|
+
has(reference) {
|
|
348
|
+
if (!keys.has(referenceKey(reference.kind, reference.id))) return false;
|
|
349
|
+
const owner = reference.owner ?? (isEntityReference(reference) && reference.tableId !== void 0 ? {
|
|
350
|
+
kind: "table",
|
|
351
|
+
id: reference.tableId
|
|
352
|
+
} : void 0);
|
|
353
|
+
if (owner === void 0) return true;
|
|
354
|
+
return scopedKeys.has(referenceKey(`${normalizeReferenceKind(reference.kind)}:${owner.kind}:${owner.id}`, reference.id));
|
|
355
|
+
},
|
|
356
|
+
owner(reference) {
|
|
357
|
+
const owner = inferredOwners.get(referenceKey(normalizeReferenceKind(reference.kind), reference.id));
|
|
358
|
+
return owner === null ? void 0 : owner;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function isEntityReference(reference) {
|
|
363
|
+
return "tableId" in reference;
|
|
364
|
+
}
|
|
365
|
+
function referenceKey(kind, id) {
|
|
366
|
+
return `${kind}\u0000${id}`;
|
|
367
|
+
}
|
|
368
|
+
function selectPreviousSnapshot(input, previous, selectedNamespace, diagnostics) {
|
|
369
|
+
if (previous === void 0) return;
|
|
370
|
+
const dialectMatches = previous.dialect.name === input.dialect;
|
|
371
|
+
const namespaceMatches = previous.namespace.kind === input.namespace.kind && previous.namespace.name === selectedNamespace && input.namespace.name === selectedNamespace;
|
|
372
|
+
if (!dialectMatches || !namespaceMatches) {
|
|
373
|
+
diagnostics.push(createIntrospectionDiagnostic({
|
|
374
|
+
severity: "error",
|
|
375
|
+
code: "dialect-mismatch",
|
|
376
|
+
message: !dialectMatches ? `Previous snapshot dialect ${previous.dialect.name} does not match ${input.dialect}` : `Previous snapshot namespace ${previous.namespace.name} does not match ${selectedNamespace}`,
|
|
377
|
+
path: ["previousSnapshot", !dialectMatches ? "dialect" : "namespace"],
|
|
378
|
+
remediation: "Use a previous snapshot from the same dialect and selected namespace."
|
|
379
|
+
}));
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
return previous;
|
|
383
|
+
}
|
|
384
|
+
function collectIdentityEntries(input) {
|
|
385
|
+
const entries = [];
|
|
386
|
+
const seen = /* @__PURE__ */ new Set();
|
|
387
|
+
const add = (object, kind, currentId, physicalName, scopePhysicalName, scopeId, physicalIdentityName = physicalName) => {
|
|
388
|
+
if (seen.has(object)) return;
|
|
389
|
+
seen.add(object);
|
|
390
|
+
entries.push({
|
|
391
|
+
object,
|
|
392
|
+
kind,
|
|
393
|
+
currentId,
|
|
394
|
+
physicalName,
|
|
395
|
+
physicalIdentityName,
|
|
396
|
+
...scopePhysicalName === void 0 ? {} : { scopePhysicalName },
|
|
397
|
+
...scopeId === void 0 ? {} : { scopeId }
|
|
398
|
+
});
|
|
399
|
+
};
|
|
400
|
+
for (const table of input.tables) {
|
|
401
|
+
add(table, "table", table.id, table.physicalName);
|
|
402
|
+
for (const column of table.columns) add(column, "column", column.id, column.physicalName, table.physicalName, table.id);
|
|
403
|
+
for (const constraint of table.constraints) add(constraint, "constraint", constraint.id, constraint.physicalName ?? constraint.id, table.physicalName, table.id);
|
|
404
|
+
for (const index of table.indexes) add(index, "index", index.id, index.physicalName ?? index.id, table.physicalName, table.id);
|
|
405
|
+
}
|
|
406
|
+
for (const view of input.views ?? []) {
|
|
407
|
+
add(view, view.kind, view.id, view.physicalName);
|
|
408
|
+
for (const column of view.columns) add(column, "column", column.id, column.physicalName, view.physicalName, view.id);
|
|
409
|
+
}
|
|
410
|
+
for (const sequence of input.sequences ?? []) addObject(sequence, sequence.kind);
|
|
411
|
+
for (const item of input.enums ?? []) addObject(item, item.kind);
|
|
412
|
+
for (const domain of input.domains ?? []) {
|
|
413
|
+
add(domain, "domain", domain.id, domain.physicalName);
|
|
414
|
+
for (const constraint of domain.constraints ?? []) add(constraint, "constraint", constraint.id, constraint.physicalName ?? constraint.id, domain.physicalName, domain.id);
|
|
415
|
+
}
|
|
416
|
+
for (const collation of input.collations ?? []) addObject(collation, collation.kind);
|
|
417
|
+
for (const trigger of input.triggers ?? []) addObject(trigger, trigger.kind);
|
|
418
|
+
for (const routine of input.routines ?? []) addObject(routine, routine.kind);
|
|
419
|
+
for (const partition of input.partitions ?? []) addObject(partition, partition.kind);
|
|
420
|
+
for (const policy of input.policies ?? []) addObject(policy, policy.kind);
|
|
421
|
+
for (const extension of input.extensionObjects ?? []) addObject(extension, extension.kind);
|
|
422
|
+
for (const object of input.opaqueObjects ?? []) addObject(object, object.kind);
|
|
423
|
+
for (const comment of input.comments ?? []) addMetadataObject(comment, "comment");
|
|
424
|
+
for (const ownership of input.ownership ?? []) addMetadataObject(ownership, "ownership");
|
|
425
|
+
const metadataObjects = [
|
|
426
|
+
input.namespace,
|
|
427
|
+
...input.tables,
|
|
428
|
+
...input.views ?? [],
|
|
429
|
+
...input.sequences ?? [],
|
|
430
|
+
...input.enums ?? [],
|
|
431
|
+
...input.domains ?? [],
|
|
432
|
+
...input.collations ?? [],
|
|
433
|
+
...input.triggers ?? [],
|
|
434
|
+
...input.routines ?? [],
|
|
435
|
+
...input.partitions ?? [],
|
|
436
|
+
...input.policies ?? [],
|
|
437
|
+
...input.extensionObjects ?? [],
|
|
438
|
+
...input.opaqueObjects ?? [],
|
|
439
|
+
...input.deferredObjects,
|
|
440
|
+
...input.tables.flatMap((table) => [
|
|
441
|
+
...table.columns,
|
|
442
|
+
...table.constraints,
|
|
443
|
+
...table.indexes
|
|
444
|
+
]),
|
|
445
|
+
...(input.views ?? []).flatMap((view) => view.columns),
|
|
446
|
+
...(input.domains ?? []).flatMap((domain) => domain.constraints ?? [])
|
|
447
|
+
];
|
|
448
|
+
for (const object of metadataObjects) {
|
|
449
|
+
if (object.comment) addMetadataObject(object.comment, "comment");
|
|
450
|
+
if (object.ownership) addMetadataObject(object.ownership, "ownership");
|
|
451
|
+
}
|
|
452
|
+
return entries;
|
|
453
|
+
function addObject(object, kind) {
|
|
454
|
+
add(object, kind, object.id, object.physicalName);
|
|
455
|
+
}
|
|
456
|
+
function addMetadataObject(object, kind) {
|
|
457
|
+
add(object, kind, object.id, object.reference?.name ?? object.id, void 0, void 0, object.id);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
function collectPreviousIdentities(snapshot) {
|
|
461
|
+
const result = [];
|
|
462
|
+
const add = (kind, id, physicalName, scopePhysicalName) => result.push({
|
|
463
|
+
kind,
|
|
464
|
+
id,
|
|
465
|
+
physicalName,
|
|
466
|
+
...scopePhysicalName === void 0 ? {} : { scopePhysicalName }
|
|
467
|
+
});
|
|
468
|
+
for (const table of snapshot.tables) {
|
|
469
|
+
add("table", table.id, table.physicalName);
|
|
470
|
+
for (const column of table.columns) add("column", column.id, column.physicalName, table.physicalName);
|
|
471
|
+
for (const constraint of table.constraints) add("constraint", constraint.id, constraint.physicalName, table.physicalName);
|
|
472
|
+
for (const index of table.indexes) add("index", index.id, index.physicalName, table.physicalName);
|
|
473
|
+
}
|
|
474
|
+
for (const view of snapshot.views) {
|
|
475
|
+
add(view.kind, view.id, view.physicalName);
|
|
476
|
+
for (const column of view.columns) add("column", column.id, column.physicalName, view.physicalName);
|
|
477
|
+
}
|
|
478
|
+
for (const sequence of snapshot.sequences) add("sequence", sequence.id, sequence.physicalName);
|
|
479
|
+
for (const item of snapshot.enums) add("enum", item.id, item.physicalName);
|
|
480
|
+
for (const domain of snapshot.domains) {
|
|
481
|
+
add("domain", domain.id, domain.physicalName);
|
|
482
|
+
for (const constraint of domain.constraints ?? []) add("constraint", constraint.id, constraint.physicalName, domain.physicalName);
|
|
483
|
+
}
|
|
484
|
+
for (const item of snapshot.collations) add("collation", item.id, item.physicalName);
|
|
485
|
+
for (const item of snapshot.triggers) add("trigger", item.id, item.physicalName);
|
|
486
|
+
for (const item of snapshot.routines) add("routine", item.id, item.physicalName);
|
|
487
|
+
for (const item of snapshot.partitions) add("partition", item.id, item.physicalName);
|
|
488
|
+
for (const item of snapshot.policies) add("policy", item.id, item.physicalName);
|
|
489
|
+
for (const item of snapshot.extensions) add("extension", item.id, item.physicalName);
|
|
490
|
+
for (const item of snapshot.opaqueObjects) add("opaque-object", item.id, item.physicalName);
|
|
491
|
+
for (const item of snapshot.comments) add("comment", item.id, item.physicalName);
|
|
492
|
+
for (const item of snapshot.ownership) add("ownership", item.id, item.physicalName);
|
|
493
|
+
return result;
|
|
494
|
+
}
|
|
495
|
+
function createIdentityResolver(entries, hints, previous, policy, diagnostics) {
|
|
496
|
+
const byObject = /* @__PURE__ */ new Map();
|
|
497
|
+
const byGlobal = /* @__PURE__ */ new Map();
|
|
498
|
+
const byScope = /* @__PURE__ */ new Map();
|
|
499
|
+
const previousBySelector = /* @__PURE__ */ new Map();
|
|
500
|
+
for (const item of previous ?? []) {
|
|
501
|
+
const key = identitySelectorKey(item.kind, item.physicalName, item.scopePhysicalName);
|
|
502
|
+
const existing = previousBySelector.get(key);
|
|
503
|
+
previousBySelector.set(key, existing === void 0 ? item : null);
|
|
504
|
+
}
|
|
505
|
+
for (const entry of entries) {
|
|
506
|
+
const identity = resolveIdentityEntry(entry, hints, previousBySelector, policy, diagnostics);
|
|
507
|
+
byObject.set(entry.object, identity);
|
|
508
|
+
registerIdentity(byGlobal, referenceKey(entry.kind, entry.currentId), {
|
|
509
|
+
object: entry.object,
|
|
510
|
+
identity
|
|
511
|
+
});
|
|
512
|
+
if (entry.scopeId !== void 0) registerIdentity(byScope, referenceKey(`${entry.kind}:${entry.scopeId}`, entry.currentId), {
|
|
513
|
+
object: entry.object,
|
|
514
|
+
identity
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
forObject(object) {
|
|
519
|
+
return byObject.get(object);
|
|
520
|
+
},
|
|
521
|
+
resolveReference(kind, id, scopeId) {
|
|
522
|
+
const normalizedKind = normalizeIdentityKind(kind);
|
|
523
|
+
if (scopeId !== void 0 && normalizedKind !== void 0) {
|
|
524
|
+
const scoped = byScope.get(referenceKey(`${normalizedKind}:${scopeId}`, id));
|
|
525
|
+
if (scoped !== void 0 && scoped !== null) return scoped.identity;
|
|
526
|
+
if (scoped === null) return;
|
|
527
|
+
}
|
|
528
|
+
const global = byGlobal.get(referenceKey(normalizedKind ?? kind, id));
|
|
529
|
+
return global === void 0 || global === null ? void 0 : global.identity;
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
function registerIdentity(map, key, value) {
|
|
534
|
+
const existing = map.get(key);
|
|
535
|
+
map.set(key, existing === void 0 ? value : null);
|
|
536
|
+
}
|
|
537
|
+
function resolveIdentityEntry(entry, hints, previous, policy, diagnostics) {
|
|
538
|
+
for (const source of policy.precedence) if (source === "explicit-hint") {
|
|
539
|
+
const matching = hints.filter((hint) => hint.kind === entry.kind && hint.physicalName === entry.physicalName && hint.tablePhysicalName === entry.scopePhysicalName);
|
|
540
|
+
const logicalIds = [...new Set(matching.map((hint) => hint.logicalId))];
|
|
541
|
+
if (logicalIds.length > 1) diagnostics.push(createIntrospectionDiagnostic({
|
|
542
|
+
severity: "error",
|
|
543
|
+
code: "ambiguous-identity",
|
|
544
|
+
message: `Multiple identity hints match ${entry.kind} ${entry.physicalName}`,
|
|
545
|
+
path: [entry.kind, entry.physicalName],
|
|
546
|
+
remediation: "Provide one identity hint for each physical selector."
|
|
547
|
+
}));
|
|
548
|
+
else if (logicalIds[0] !== void 0) return {
|
|
549
|
+
logicalId: logicalIds[0],
|
|
550
|
+
source
|
|
551
|
+
};
|
|
552
|
+
} else if (source === "previous-snapshot") {
|
|
553
|
+
const match = previous.get(identitySelectorKey(entry.kind, entry.physicalName, entry.scopePhysicalName));
|
|
554
|
+
if (match !== void 0 && match !== null) return {
|
|
555
|
+
logicalId: match.id,
|
|
556
|
+
source
|
|
557
|
+
};
|
|
558
|
+
if (match === null) diagnostics.push(createIntrospectionDiagnostic({
|
|
559
|
+
severity: "error",
|
|
560
|
+
code: "ambiguous-identity",
|
|
561
|
+
message: `Previous snapshot contains multiple ${entry.kind} objects named ${entry.physicalName}`,
|
|
562
|
+
path: [
|
|
563
|
+
"previousSnapshot",
|
|
564
|
+
entry.kind,
|
|
565
|
+
entry.physicalName
|
|
566
|
+
],
|
|
567
|
+
remediation: "Use an explicit identity hint for the ambiguous object."
|
|
568
|
+
}));
|
|
569
|
+
} else if (source === "physical-name" && isSafeIdentityName(entry.physicalIdentityName)) return {
|
|
570
|
+
logicalId: entry.physicalIdentityName,
|
|
571
|
+
source
|
|
572
|
+
};
|
|
573
|
+
else if (source === "deterministic-fallback") return {
|
|
574
|
+
logicalId: fallbackIdentity(entry, policy),
|
|
575
|
+
source
|
|
576
|
+
};
|
|
577
|
+
return {
|
|
578
|
+
logicalId: fallbackIdentity(entry, policy),
|
|
579
|
+
source: "deterministic-fallback"
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
function identitySelectorKey(kind, physicalName, scopePhysicalName) {
|
|
583
|
+
return `${kind}\u0000${scopePhysicalName ?? ""}\u0000${physicalName}`;
|
|
584
|
+
}
|
|
585
|
+
function normalizeIdentityKind(kind) {
|
|
586
|
+
if (kind === "primary-key" || kind === "unique" || kind === "foreign-key" || kind === "check") return "constraint";
|
|
587
|
+
if (kind === "namespace" || kind === "deferred-object") return;
|
|
588
|
+
return kind;
|
|
589
|
+
}
|
|
590
|
+
function fallbackIdentity(entry, policy) {
|
|
591
|
+
const seed = [
|
|
592
|
+
entry.kind,
|
|
593
|
+
entry.scopePhysicalName ?? "",
|
|
594
|
+
entry.physicalName,
|
|
595
|
+
entry.physicalIdentityName,
|
|
596
|
+
entry.currentId
|
|
597
|
+
].join(":");
|
|
598
|
+
if (policy.fallback === "hashed") return `introspected_${fnv1a32(seed)}`;
|
|
599
|
+
return escapeIdentity(entry.physicalIdentityName || entry.currentId || entry.physicalName || seed);
|
|
600
|
+
}
|
|
601
|
+
function isSafeIdentityName(value) {
|
|
602
|
+
if (value.length === 0 || value !== value.trim()) return false;
|
|
603
|
+
for (const character of value) {
|
|
604
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
605
|
+
if (character === "." || character === "\\" || character === "/" || character === "\"" || character === "'" || codePoint <= 31 || codePoint === 127) return false;
|
|
606
|
+
}
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
609
|
+
function escapeIdentity(value) {
|
|
610
|
+
let result = "";
|
|
611
|
+
for (const character of value) if (isSafeIdentityName(character)) result += character;
|
|
612
|
+
else result += `_x${character.codePointAt(0)?.toString(16) ?? "0"}_`;
|
|
613
|
+
return result || "introspected_object";
|
|
614
|
+
}
|
|
615
|
+
function fnv1a32(value) {
|
|
616
|
+
let hash = 2166136261;
|
|
617
|
+
for (const byte of new TextEncoder().encode(value)) {
|
|
618
|
+
hash ^= byte;
|
|
619
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
620
|
+
}
|
|
621
|
+
return hash.toString(16).padStart(8, "0");
|
|
622
|
+
}
|
|
623
|
+
function rewriteCatalog(input, resolver, diagnostics) {
|
|
624
|
+
return {
|
|
625
|
+
...input,
|
|
626
|
+
namespace: rewriteNamespace(input.namespace, resolver),
|
|
627
|
+
tables: input.tables.map((table) => rewriteTable(table, resolver)),
|
|
628
|
+
...input.views === void 0 ? {} : { views: input.views.map((view) => rewriteView(view, resolver)) },
|
|
629
|
+
...input.sequences === void 0 ? {} : { sequences: input.sequences.map((sequence) => rewriteSequence(sequence, resolver)) },
|
|
630
|
+
...input.enums === void 0 ? {} : { enums: input.enums.map((item) => rewriteEnum(item, resolver)) },
|
|
631
|
+
...input.domains === void 0 ? {} : { domains: input.domains.map((domain) => rewriteDomain(domain, resolver)) },
|
|
632
|
+
...input.collations === void 0 ? {} : { collations: input.collations.map((item) => rewriteCollation(item, resolver)) },
|
|
633
|
+
...input.triggers === void 0 ? {} : { triggers: input.triggers.map((item) => rewriteTrigger(item, resolver)) },
|
|
634
|
+
...input.routines === void 0 ? {} : { routines: input.routines.map((item) => rewriteRoutine(item, resolver)) },
|
|
635
|
+
...input.partitions === void 0 ? {} : { partitions: input.partitions.map((item) => rewritePartition(item, resolver)) },
|
|
636
|
+
...input.policies === void 0 ? {} : { policies: input.policies.map((item) => rewritePolicy(item, resolver)) },
|
|
637
|
+
...input.extensionObjects === void 0 ? {} : { extensionObjects: input.extensionObjects.map((item) => rewriteExtension(item, resolver)) },
|
|
638
|
+
deferredObjects: input.deferredObjects.map((item) => rewriteDeferred(item, resolver)),
|
|
639
|
+
...input.opaqueObjects === void 0 ? {} : { opaqueObjects: input.opaqueObjects.map((item) => rewriteOpaque(item, resolver)) },
|
|
640
|
+
...input.comments === void 0 ? {} : { comments: input.comments.map((item) => rewriteComment(item, resolver)) },
|
|
641
|
+
...input.ownership === void 0 ? {} : { ownership: input.ownership.map((item) => rewriteOwnership(item, resolver)) },
|
|
642
|
+
diagnostics: [...input.diagnostics, ...diagnostics]
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
function rewriteNamespace(namespace, resolver) {
|
|
646
|
+
return { ...rewriteMetadata(namespace, resolver) };
|
|
647
|
+
}
|
|
648
|
+
function rewriteTable(table, resolver) {
|
|
649
|
+
const owner = {
|
|
650
|
+
kind: "table",
|
|
651
|
+
id: table.id
|
|
652
|
+
};
|
|
653
|
+
return {
|
|
654
|
+
...rewriteMetadata(table, resolver),
|
|
655
|
+
...rewriteIdentityFields(table, resolver),
|
|
656
|
+
columns: table.columns.map((column) => ({
|
|
657
|
+
...rewriteMetadata(column, resolver, owner),
|
|
658
|
+
...rewriteIdentityFields(column, resolver)
|
|
659
|
+
})),
|
|
660
|
+
constraints: table.constraints.map((constraint) => rewriteConstraint(constraint, resolver, owner)),
|
|
661
|
+
indexes: table.indexes.map((index) => rewriteIndex(index, resolver, owner))
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
function rewriteConstraint(constraint, resolver, owner) {
|
|
665
|
+
const backingIndex = (constraint.kind === "primary-key" || constraint.kind === "unique") && constraint.backingIndex !== void 0 ? rewriteCatalogReference(constraint.backingIndex, resolver, owner) : void 0;
|
|
666
|
+
return {
|
|
667
|
+
...rewriteMetadata(constraint, resolver, owner),
|
|
668
|
+
...rewriteIdentityFields(constraint, resolver),
|
|
669
|
+
...backingIndex === void 0 ? {} : { backingIndex }
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
function rewriteIndex(index, resolver, owner) {
|
|
673
|
+
return {
|
|
674
|
+
...rewriteMetadata(index, resolver, owner),
|
|
675
|
+
...rewriteIdentityFields(index, resolver),
|
|
676
|
+
...index.backingConstraint === void 0 ? {} : { backingConstraint: rewriteCatalogReference(index.backingConstraint, resolver, owner) }
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
function rewriteView(view, resolver) {
|
|
680
|
+
const owner = {
|
|
681
|
+
kind: view.kind,
|
|
682
|
+
id: view.id
|
|
683
|
+
};
|
|
684
|
+
return {
|
|
685
|
+
...rewriteMetadata(view, resolver),
|
|
686
|
+
...rewriteIdentityFields(view, resolver),
|
|
687
|
+
columns: view.columns.map((column) => ({
|
|
688
|
+
...rewriteMetadata(column, resolver, owner),
|
|
689
|
+
...rewriteIdentityFields(column, resolver)
|
|
690
|
+
})),
|
|
691
|
+
...view.dependencies === void 0 ? {} : { dependencies: view.dependencies.map((reference) => rewriteCatalogReference(reference, resolver)) }
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function rewriteSequence(sequence, resolver) {
|
|
695
|
+
return {
|
|
696
|
+
...rewriteMetadata(sequence, resolver),
|
|
697
|
+
...rewriteIdentityFields(sequence, resolver),
|
|
698
|
+
...sequence.ownedBy === void 0 ? {} : { ownedBy: rewriteCatalogReference(sequence.ownedBy, resolver) }
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
function rewriteEnum(item, resolver) {
|
|
702
|
+
return {
|
|
703
|
+
...rewriteMetadata(item, resolver),
|
|
704
|
+
...rewriteIdentityFields(item, resolver)
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
function rewriteDomain(domain, resolver) {
|
|
708
|
+
const owner = {
|
|
709
|
+
kind: "domain",
|
|
710
|
+
id: domain.id
|
|
711
|
+
};
|
|
712
|
+
return {
|
|
713
|
+
...rewriteMetadata(domain, resolver),
|
|
714
|
+
...rewriteIdentityFields(domain, resolver),
|
|
715
|
+
...domain.constraints === void 0 ? {} : { constraints: domain.constraints.map((constraint) => ({
|
|
716
|
+
...rewriteMetadata(constraint, resolver, owner),
|
|
717
|
+
...rewriteIdentityFields(constraint, resolver)
|
|
718
|
+
})) }
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
function rewriteCollation(item, resolver) {
|
|
722
|
+
return {
|
|
723
|
+
...rewriteMetadata(item, resolver),
|
|
724
|
+
...rewriteIdentityFields(item, resolver)
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
function rewriteTrigger(trigger, resolver) {
|
|
728
|
+
return {
|
|
729
|
+
...rewriteMetadata(trigger, resolver),
|
|
730
|
+
...rewriteIdentityFields(trigger, resolver),
|
|
731
|
+
table: rewriteCatalogReference(trigger.table, resolver)
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function rewriteRoutine(routine, resolver) {
|
|
735
|
+
return {
|
|
736
|
+
...rewriteMetadata(routine, resolver),
|
|
737
|
+
...rewriteIdentityFields(routine, resolver),
|
|
738
|
+
...routine.dependencies === void 0 ? {} : { dependencies: routine.dependencies.map((reference) => rewriteCatalogReference(reference, resolver)) }
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
function rewritePartition(partition, resolver) {
|
|
742
|
+
return {
|
|
743
|
+
...rewriteMetadata(partition, resolver),
|
|
744
|
+
...rewriteIdentityFields(partition, resolver),
|
|
745
|
+
parent: rewriteCatalogReference(partition.parent, resolver)
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
function rewritePolicy(policy, resolver) {
|
|
749
|
+
return {
|
|
750
|
+
...rewriteMetadata(policy, resolver),
|
|
751
|
+
...rewriteIdentityFields(policy, resolver),
|
|
752
|
+
table: rewriteCatalogReference(policy.table, resolver)
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
function rewriteExtension(extension, resolver) {
|
|
756
|
+
return {
|
|
757
|
+
...rewriteMetadata(extension, resolver),
|
|
758
|
+
...rewriteIdentityFields(extension, resolver)
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
function rewriteOpaque(object, resolver) {
|
|
762
|
+
return {
|
|
763
|
+
...rewriteMetadata(object, resolver),
|
|
764
|
+
...rewriteIdentityFields(object, resolver)
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
function rewriteDeferred(object, resolver) {
|
|
768
|
+
return rewriteMetadata(object, resolver);
|
|
769
|
+
}
|
|
770
|
+
function rewriteMetadata(object, resolver, fallbackOwner) {
|
|
771
|
+
return {
|
|
772
|
+
...object,
|
|
773
|
+
...object.comment === void 0 ? {} : { comment: rewriteComment(object.comment, resolver, fallbackOwner) },
|
|
774
|
+
...object.ownership === void 0 ? {} : { ownership: rewriteOwnership(object.ownership, resolver, fallbackOwner) }
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
function rewriteIdentityFields(object, resolver) {
|
|
778
|
+
const identity = resolver.forObject(object);
|
|
779
|
+
return identity === void 0 ? {
|
|
780
|
+
id: object.id,
|
|
781
|
+
identitySource: object.identitySource
|
|
782
|
+
} : {
|
|
783
|
+
id: identity.logicalId,
|
|
784
|
+
identitySource: identity.source
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
function rewriteCatalogReference(reference, resolver, fallbackOwner) {
|
|
788
|
+
const tableId = isEntityReference(reference) ? reference.tableId : void 0;
|
|
789
|
+
const referenceOwner = reference.owner ?? (tableId === void 0 ? fallbackOwner : {
|
|
790
|
+
kind: "table",
|
|
791
|
+
id: tableId
|
|
792
|
+
});
|
|
793
|
+
const identity = resolver.resolveReference(reference.kind, reference.id, referenceOwner?.id);
|
|
794
|
+
const tableIdentity = referenceOwner?.kind === "table" ? resolver.resolveReference("table", referenceOwner.id) : void 0;
|
|
795
|
+
const rewrittenOwner = referenceOwner === void 0 ? void 0 : rewriteCatalogOwner(referenceOwner, resolver);
|
|
796
|
+
return {
|
|
797
|
+
...reference,
|
|
798
|
+
id: identity?.logicalId ?? reference.id,
|
|
799
|
+
...reference.owner !== void 0 || fallbackOwner !== void 0 && tableId === void 0 ? { owner: rewrittenOwner } : {},
|
|
800
|
+
...tableId === void 0 ? {} : { tableId: tableIdentity?.logicalId ?? tableId }
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
function rewriteCatalogOwner(owner, resolver) {
|
|
804
|
+
const identity = resolver.resolveReference(owner.kind, owner.id);
|
|
805
|
+
return {
|
|
806
|
+
...owner,
|
|
807
|
+
id: identity?.logicalId ?? owner.id
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
function rewriteComment(comment, resolver, fallbackOwner) {
|
|
811
|
+
const identity = resolver.forObject(comment);
|
|
812
|
+
return {
|
|
813
|
+
...comment,
|
|
814
|
+
...identity === void 0 ? {} : { id: identity.logicalId },
|
|
815
|
+
object: rewriteCatalogReference(comment.object, resolver, fallbackOwner)
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
function rewriteOwnership(ownership, resolver, fallbackOwner) {
|
|
819
|
+
const identity = resolver.forObject(ownership);
|
|
820
|
+
return {
|
|
821
|
+
...ownership,
|
|
822
|
+
...identity === void 0 ? {} : { id: identity.logicalId },
|
|
823
|
+
object: rewriteCatalogReference(ownership.object, resolver, fallbackOwner)
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
function mapTable(table, dialect, tables, context) {
|
|
827
|
+
const owner = {
|
|
828
|
+
kind: "table",
|
|
829
|
+
id: table.id
|
|
830
|
+
};
|
|
831
|
+
const columns = table.columns.map((column) => mapColumn(column, dialect)).sort(compareId);
|
|
832
|
+
const columnIds = new Map(table.columns.map((column) => [column.physicalName, column.id]));
|
|
833
|
+
const columnNullability = new Map(table.columns.map((column) => [column.physicalName, column.nullable]));
|
|
834
|
+
const snapshotColumnNullability = new Map(table.columns.map((column) => [column.id, column.nullable]));
|
|
835
|
+
const constraints = table.constraints.map((constraint) => mapConstraint(constraint, dialect, columnIds, columnNullability, tables, context, [
|
|
836
|
+
"tables",
|
|
837
|
+
table.id,
|
|
838
|
+
"constraints",
|
|
839
|
+
constraint.id
|
|
840
|
+
], owner)).filter((value) => value !== void 0).sort(compareId);
|
|
841
|
+
const indexes = table.indexes.map((index) => mapIndex(index, dialect, columnIds, snapshotColumnNullability, context, [
|
|
842
|
+
"tables",
|
|
843
|
+
table.id,
|
|
844
|
+
"indexes",
|
|
845
|
+
index.id
|
|
846
|
+
], owner)).filter((index) => index !== void 0).sort(compareId);
|
|
847
|
+
return {
|
|
848
|
+
kind: "table",
|
|
849
|
+
id: table.id,
|
|
850
|
+
physicalName: table.physicalName,
|
|
851
|
+
columns,
|
|
852
|
+
constraints,
|
|
853
|
+
indexes,
|
|
854
|
+
...mapMetadata(table.provenance, table.dialect, dialect, table.reference)
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
|
+
function mapColumn(column, dialect) {
|
|
858
|
+
const defaultValue = column.default ? mapValueFact(column.default) : void 0;
|
|
859
|
+
const generatedColumn = column.generated ? column.generated.mode === "unknown" ? { kind: "external" } : {
|
|
860
|
+
kind: "expression",
|
|
861
|
+
expression: mapExpression(column.generated.expression),
|
|
862
|
+
mode: column.generated.mode
|
|
863
|
+
} : void 0;
|
|
864
|
+
const identity = column.identity ? mapIdentity(column.identity, dialect) : void 0;
|
|
865
|
+
return {
|
|
866
|
+
kind: "column",
|
|
867
|
+
id: column.id,
|
|
868
|
+
physicalName: column.physicalName,
|
|
869
|
+
ordinalPosition: column.ordinalPosition,
|
|
870
|
+
nullable: column.nullable,
|
|
871
|
+
hasDefault: defaultValue !== void 0,
|
|
872
|
+
generated: generatedColumn !== void 0 || identity !== void 0,
|
|
873
|
+
storage: mapStorage(column.storage, dialect),
|
|
874
|
+
...defaultValue === void 0 ? {} : { default: defaultValue },
|
|
875
|
+
...generatedColumn === void 0 ? {} : { generatedColumn },
|
|
876
|
+
...identity === void 0 ? {} : { identity },
|
|
877
|
+
...column.onUpdate === void 0 ? {} : { onUpdate: mapExpression(column.onUpdate) },
|
|
878
|
+
...mapMetadata(column.provenance, column.dialect, dialect, column.reference)
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
function mapConstraint(constraint, dialect, columns, columnNullability, tables, context, path, owner) {
|
|
882
|
+
const physicalName = constraint.physicalName ?? constraint.id;
|
|
883
|
+
const common = {
|
|
884
|
+
id: constraint.id,
|
|
885
|
+
physicalName,
|
|
886
|
+
...mapMetadata(constraint.provenance, constraint.dialect, dialect, constraint.reference)
|
|
887
|
+
};
|
|
888
|
+
const mappedColumns = constraint.kind === "check" ? void 0 : mapColumnNames(constraint.columns, columns, context, [...path, "columns"]);
|
|
889
|
+
if (mappedColumns === void 0 && context.mode === "lossy") return;
|
|
890
|
+
const backingIndex = constraint.kind === "primary-key" || constraint.kind === "unique" ? constraint.backingIndex === void 0 ? void 0 : mapReference(constraint.backingIndex, context, [...path, "backingIndex"], "index", owner) : void 0;
|
|
891
|
+
if (constraint.kind === "check") return {
|
|
892
|
+
kind: "check",
|
|
893
|
+
...common,
|
|
894
|
+
expression: mapExpression(constraint.expression),
|
|
895
|
+
...constraint.deferrable === void 0 ? {} : { deferrable: constraint.deferrable },
|
|
896
|
+
...constraint.initially === void 0 ? {} : { initially: constraint.initially },
|
|
897
|
+
...constraint.validated === void 0 ? {} : { validated: constraint.validated }
|
|
898
|
+
};
|
|
899
|
+
if (constraint.kind === "primary-key") return {
|
|
900
|
+
kind: "primary-key",
|
|
901
|
+
...common,
|
|
902
|
+
columns: mappedColumns ?? [],
|
|
903
|
+
...backingIndex === void 0 ? {} : { backingIndex },
|
|
904
|
+
...constraint.deferrable === void 0 ? {} : { deferrable: constraint.deferrable },
|
|
905
|
+
...constraint.initially === void 0 ? {} : { initially: constraint.initially },
|
|
906
|
+
...constraint.validated === void 0 ? {} : { validated: constraint.validated }
|
|
907
|
+
};
|
|
908
|
+
if (constraint.kind === "unique") {
|
|
909
|
+
if (!constraint.columns.some((column) => columnNullability.get(column) === true) && constraint.nulls === "distinct") return {
|
|
910
|
+
kind: "unique",
|
|
911
|
+
...common,
|
|
912
|
+
columns: mappedColumns ?? [],
|
|
913
|
+
...backingIndex === void 0 ? {} : { backingIndex },
|
|
914
|
+
...constraint.deferrable === void 0 ? {} : { deferrable: constraint.deferrable },
|
|
915
|
+
...constraint.initially === void 0 ? {} : { initially: constraint.initially },
|
|
916
|
+
...constraint.validated === void 0 ? {} : { validated: constraint.validated }
|
|
917
|
+
};
|
|
918
|
+
return {
|
|
919
|
+
kind: "unique-constraint",
|
|
920
|
+
...common,
|
|
921
|
+
columns: mappedColumns ?? [],
|
|
922
|
+
nulls: constraint.nulls,
|
|
923
|
+
...backingIndex === void 0 ? {} : { backingIndex },
|
|
924
|
+
...constraint.deferrable === void 0 ? {} : { deferrable: constraint.deferrable },
|
|
925
|
+
...constraint.initially === void 0 ? {} : { initially: constraint.initially },
|
|
926
|
+
...constraint.validated === void 0 ? {} : { validated: constraint.validated }
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
const targetTable = tables.get(constraint.target.table);
|
|
930
|
+
const targetId = targetTable?.id;
|
|
931
|
+
if (targetId === void 0) {
|
|
932
|
+
if (reportMappingIssue(context, {
|
|
933
|
+
code: "unresolved-reference",
|
|
934
|
+
message: `Foreign-key target table ${constraint.target.table} was not found`,
|
|
935
|
+
path: [
|
|
936
|
+
...path,
|
|
937
|
+
"target",
|
|
938
|
+
"table"
|
|
939
|
+
]
|
|
940
|
+
})) return;
|
|
941
|
+
}
|
|
942
|
+
const targetColumnIds = targetTable ? new Map(targetTable.columns.map((column) => [column.physicalName, column.id])) : /* @__PURE__ */ new Map();
|
|
943
|
+
const targetColumns = mapColumnNames(constraint.target.columns, targetColumnIds, context, [
|
|
944
|
+
...path,
|
|
945
|
+
"target",
|
|
946
|
+
"columns"
|
|
947
|
+
]);
|
|
948
|
+
if (targetColumns === void 0 && context.mode === "lossy") return;
|
|
949
|
+
return {
|
|
950
|
+
kind: "foreign-key",
|
|
951
|
+
...common,
|
|
952
|
+
columns: mappedColumns ?? [],
|
|
953
|
+
target: {
|
|
954
|
+
table: {
|
|
955
|
+
kind: "table",
|
|
956
|
+
id: targetId ?? constraint.target.table
|
|
957
|
+
},
|
|
958
|
+
columns: targetColumns ?? []
|
|
959
|
+
},
|
|
960
|
+
...constraint.onUpdate === void 0 ? {} : { onUpdate: constraint.onUpdate },
|
|
961
|
+
...constraint.onDelete === void 0 ? {} : { onDelete: constraint.onDelete },
|
|
962
|
+
...constraint.match === void 0 ? {} : { match: constraint.match },
|
|
963
|
+
...constraint.deferrable === void 0 ? {} : { deferrable: constraint.deferrable },
|
|
964
|
+
...constraint.initially === void 0 ? {} : { initially: constraint.initially },
|
|
965
|
+
...constraint.validated === void 0 ? {} : { validated: constraint.validated }
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
function mapColumnNames(names, columns, context, path) {
|
|
969
|
+
let missing = false;
|
|
970
|
+
const result = names.map((name, index) => {
|
|
971
|
+
const id = columns.get(name);
|
|
972
|
+
if (id !== void 0) return id;
|
|
973
|
+
missing = true;
|
|
974
|
+
reportMappingIssue(context, {
|
|
975
|
+
code: "unresolved-reference",
|
|
976
|
+
message: `Column ${name} was not found`,
|
|
977
|
+
path: [...path, index]
|
|
978
|
+
});
|
|
979
|
+
return name;
|
|
980
|
+
});
|
|
981
|
+
return missing && context.mode === "lossy" ? void 0 : result;
|
|
982
|
+
}
|
|
983
|
+
function mapOptionalColumnNames(names, columns, context, path) {
|
|
984
|
+
if (names === void 0) return;
|
|
985
|
+
return mapColumnNames(names, columns, context, path);
|
|
986
|
+
}
|
|
987
|
+
function mapIndex(index, dialect, columns, snapshotColumnNullability, context, path, owner) {
|
|
988
|
+
const terms = index.terms.map((term, position) => mapIndexTerm(term, columns, context, [
|
|
989
|
+
...path,
|
|
990
|
+
"terms",
|
|
991
|
+
position
|
|
992
|
+
]));
|
|
993
|
+
if (terms.some((term) => term === void 0) && context.mode === "lossy") return;
|
|
994
|
+
const includedColumns = mapOptionalColumnNames(index.includedColumns, columns, context, [...path, "includedColumns"]);
|
|
995
|
+
const backingConstraint = index.backingConstraint === void 0 ? void 0 : mapReference(index.backingConstraint, context, [...path, "backingConstraint"], "constraint", owner);
|
|
996
|
+
const mapped = {
|
|
997
|
+
kind: "index",
|
|
998
|
+
id: index.id,
|
|
999
|
+
physicalName: index.physicalName ?? index.id,
|
|
1000
|
+
terms: terms.filter((term) => term !== void 0).sort((left, right) => left.position - right.position),
|
|
1001
|
+
unique: index.unique,
|
|
1002
|
+
candidateKey: false,
|
|
1003
|
+
...index.predicate === void 0 ? {} : { predicate: mapExpression(index.predicate) },
|
|
1004
|
+
...includedColumns === void 0 ? {} : { includedColumns },
|
|
1005
|
+
...backingConstraint === void 0 ? {} : { backingConstraint },
|
|
1006
|
+
...index.method === void 0 ? {} : { method: index.method },
|
|
1007
|
+
...mapMetadata(void 0, index.dialect, dialect, index.reference)
|
|
1008
|
+
};
|
|
1009
|
+
return {
|
|
1010
|
+
...mapped,
|
|
1011
|
+
candidateKey: hasCandidateKeyShape(mapped, snapshotColumnNullability)
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
function mapIndexTerm(term, columns, context, path) {
|
|
1015
|
+
if (term.kind === "column") {
|
|
1016
|
+
const column = columns.get(term.column);
|
|
1017
|
+
if (column === void 0) {
|
|
1018
|
+
if (reportMappingIssue(context, {
|
|
1019
|
+
code: "unresolved-reference",
|
|
1020
|
+
message: `Index column ${term.column} was not found`,
|
|
1021
|
+
path
|
|
1022
|
+
})) return;
|
|
1023
|
+
}
|
|
1024
|
+
return {
|
|
1025
|
+
kind: "column",
|
|
1026
|
+
column: column ?? term.column,
|
|
1027
|
+
position: term.position,
|
|
1028
|
+
...term.direction === void 0 ? {} : { direction: term.direction },
|
|
1029
|
+
...term.nulls === void 0 ? {} : { nulls: term.nulls },
|
|
1030
|
+
...term.prefixLength === void 0 ? {} : { prefixLength: mapValueFact(term.prefixLength) },
|
|
1031
|
+
...term.operatorClass === void 0 ? {} : { operatorClass: term.operatorClass }
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
return {
|
|
1035
|
+
kind: "expression",
|
|
1036
|
+
expression: mapExpression(term.expression),
|
|
1037
|
+
position: term.position,
|
|
1038
|
+
...term.direction === void 0 ? {} : { direction: term.direction },
|
|
1039
|
+
...term.nulls === void 0 ? {} : { nulls: term.nulls },
|
|
1040
|
+
...term.operatorClass === void 0 ? {} : { operatorClass: term.operatorClass }
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
function mapView(view, dialect, context, path) {
|
|
1044
|
+
const dependencies = view.dependencies?.flatMap((reference, index) => {
|
|
1045
|
+
const mapped = mapReference(reference, context, [
|
|
1046
|
+
...path,
|
|
1047
|
+
"dependencies",
|
|
1048
|
+
index
|
|
1049
|
+
]);
|
|
1050
|
+
return mapped === void 0 ? [] : [mapped];
|
|
1051
|
+
});
|
|
1052
|
+
return {
|
|
1053
|
+
kind: view.kind,
|
|
1054
|
+
id: view.id,
|
|
1055
|
+
physicalName: view.physicalName,
|
|
1056
|
+
columns: view.columns.map((column) => mapColumn(column, dialect)).sort(compareId),
|
|
1057
|
+
definition: mapExpression(view.definition),
|
|
1058
|
+
...dependencies === void 0 ? {} : { dependencies },
|
|
1059
|
+
...view.checkOption === void 0 ? {} : { checkOption: view.checkOption },
|
|
1060
|
+
...view.securityBarrier === void 0 ? {} : { securityBarrier: view.securityBarrier },
|
|
1061
|
+
...view.securityInvoker === void 0 ? {} : { securityInvoker: view.securityInvoker },
|
|
1062
|
+
...mapMetadata(view.provenance, view.dialect, dialect, view.reference)
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
function mapSequence(sequence, dialect, context, path) {
|
|
1066
|
+
const ownedBy = sequence.ownedBy === void 0 ? void 0 : mapReference(sequence.ownedBy, context, [...path, "ownedBy"]);
|
|
1067
|
+
return {
|
|
1068
|
+
kind: "sequence",
|
|
1069
|
+
id: sequence.id,
|
|
1070
|
+
physicalName: sequence.physicalName,
|
|
1071
|
+
...sequence.storage === void 0 ? {} : { storage: mapStorage(sequence.storage, dialect) },
|
|
1072
|
+
...sequence.start === void 0 ? {} : { start: mapValueFact(sequence.start) },
|
|
1073
|
+
...sequence.increment === void 0 ? {} : { increment: mapValueFact(sequence.increment) },
|
|
1074
|
+
...sequence.minimum === void 0 ? {} : { minimum: mapValueFact(sequence.minimum) },
|
|
1075
|
+
...sequence.maximum === void 0 ? {} : { maximum: mapValueFact(sequence.maximum) },
|
|
1076
|
+
...sequence.cache === void 0 ? {} : { cache: mapValueFact(sequence.cache) },
|
|
1077
|
+
...sequence.cycle === void 0 ? {} : { cycle: sequence.cycle },
|
|
1078
|
+
...ownedBy === void 0 ? {} : { ownedBy },
|
|
1079
|
+
...sequence.identity === void 0 ? {} : { identity: mapIdentity(sequence.identity, dialect) },
|
|
1080
|
+
...mapMetadata(sequence.provenance, sequence.dialect, dialect, sequence.reference)
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
function mapEnum(item, dialect) {
|
|
1084
|
+
return {
|
|
1085
|
+
kind: "enum",
|
|
1086
|
+
id: item.id,
|
|
1087
|
+
physicalName: item.physicalName,
|
|
1088
|
+
values: [...item.values].sort((left, right) => left.ordinalPosition - right.ordinalPosition).map((value) => ({
|
|
1089
|
+
value: value.value,
|
|
1090
|
+
ordinalPosition: value.ordinalPosition,
|
|
1091
|
+
...value.provenance === void 0 ? {} : { provenance: mapProvenance(value.provenance) }
|
|
1092
|
+
})),
|
|
1093
|
+
...mapMetadata(item.provenance, item.dialect, dialect, item.reference)
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
function mapDomain(domain, dialect) {
|
|
1097
|
+
return {
|
|
1098
|
+
kind: "domain",
|
|
1099
|
+
id: domain.id,
|
|
1100
|
+
physicalName: domain.physicalName,
|
|
1101
|
+
storage: mapStorage(domain.storage, dialect),
|
|
1102
|
+
...domain.nullable === void 0 ? {} : { nullable: domain.nullable },
|
|
1103
|
+
...domain.default === void 0 ? {} : { default: mapValueFact(domain.default) },
|
|
1104
|
+
...domain.constraints === void 0 ? {} : { constraints: domain.constraints.map((constraint) => mapCheckConstraint(constraint, dialect)).sort(compareId) },
|
|
1105
|
+
...mapMetadata(domain.provenance, domain.dialect, dialect, domain.reference)
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
function mapCheckConstraint(constraint, dialect) {
|
|
1109
|
+
return {
|
|
1110
|
+
kind: "check",
|
|
1111
|
+
id: constraint.id,
|
|
1112
|
+
physicalName: constraint.physicalName ?? constraint.id,
|
|
1113
|
+
expression: mapExpression(constraint.expression),
|
|
1114
|
+
...constraint.deferrable === void 0 ? {} : { deferrable: constraint.deferrable },
|
|
1115
|
+
...constraint.initially === void 0 ? {} : { initially: constraint.initially },
|
|
1116
|
+
...constraint.validated === void 0 ? {} : { validated: constraint.validated },
|
|
1117
|
+
...mapMetadata(constraint.provenance, constraint.dialect, dialect, constraint.reference)
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
function mapTrigger(trigger, dialect, context, path) {
|
|
1121
|
+
const table = mapReference(trigger.table, context, [...path, "table"], "table");
|
|
1122
|
+
if (table === void 0 && context.mode === "lossy") return;
|
|
1123
|
+
return {
|
|
1124
|
+
kind: "trigger",
|
|
1125
|
+
id: trigger.id,
|
|
1126
|
+
physicalName: trigger.physicalName,
|
|
1127
|
+
table: table ?? {
|
|
1128
|
+
kind: "table",
|
|
1129
|
+
id: trigger.table.id
|
|
1130
|
+
},
|
|
1131
|
+
timing: trigger.timing,
|
|
1132
|
+
events: [...trigger.events].sort(),
|
|
1133
|
+
...trigger.orientation === void 0 ? {} : { orientation: trigger.orientation },
|
|
1134
|
+
...trigger.condition === void 0 ? {} : { condition: mapExpression(trigger.condition) },
|
|
1135
|
+
body: mapExpression(trigger.body),
|
|
1136
|
+
...trigger.enabled === void 0 ? {} : { enabled: trigger.enabled },
|
|
1137
|
+
...mapMetadata(trigger.provenance, trigger.dialect, dialect, trigger.reference)
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
function mapRoutine(routine, dialect, context, path) {
|
|
1141
|
+
const dependencies = routine.dependencies?.flatMap((reference, index) => {
|
|
1142
|
+
const mapped = mapReference(reference, context, [
|
|
1143
|
+
...path,
|
|
1144
|
+
"dependencies",
|
|
1145
|
+
index
|
|
1146
|
+
]);
|
|
1147
|
+
return mapped === void 0 ? [] : [mapped];
|
|
1148
|
+
});
|
|
1149
|
+
return {
|
|
1150
|
+
kind: "routine",
|
|
1151
|
+
id: routine.id,
|
|
1152
|
+
physicalName: routine.physicalName,
|
|
1153
|
+
routineKind: routine.routineKind,
|
|
1154
|
+
parameters: [...routine.parameters].sort((left, right) => left.ordinalPosition - right.ordinalPosition).map((parameter) => mapRoutineParameter(parameter, dialect)),
|
|
1155
|
+
...routine.returnType === void 0 ? {} : { returnType: mapStorage(routine.returnType, dialect) },
|
|
1156
|
+
...routine.language === void 0 ? {} : { language: routine.language },
|
|
1157
|
+
...routine.body === void 0 ? {} : { body: mapExpression(routine.body) },
|
|
1158
|
+
...routine.volatility === void 0 ? {} : { volatility: routine.volatility },
|
|
1159
|
+
...routine.parallel === void 0 ? {} : { parallel: routine.parallel },
|
|
1160
|
+
...routine.security === void 0 ? {} : { security: routine.security },
|
|
1161
|
+
...dependencies === void 0 ? {} : { dependencies },
|
|
1162
|
+
...mapMetadata(routine.provenance, routine.dialect, dialect, routine.reference)
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
function mapRoutineParameter(parameter, dialect) {
|
|
1166
|
+
return {
|
|
1167
|
+
...parameter.name === void 0 ? {} : { name: parameter.name },
|
|
1168
|
+
...parameter.mode === void 0 ? {} : { mode: parameter.mode },
|
|
1169
|
+
storage: mapStorage(parameter.storage, dialect),
|
|
1170
|
+
...parameter.default === void 0 ? {} : { default: mapValueFact(parameter.default) },
|
|
1171
|
+
ordinalPosition: parameter.ordinalPosition,
|
|
1172
|
+
...parameter.provenance === void 0 ? {} : { provenance: mapProvenance(parameter.provenance) }
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
function mapPartition(partition, dialect, context, path) {
|
|
1176
|
+
const parent = mapReference(partition.parent, context, [...path, "parent"], "table");
|
|
1177
|
+
if (parent === void 0 && context.mode === "lossy") return;
|
|
1178
|
+
return {
|
|
1179
|
+
kind: "partition",
|
|
1180
|
+
id: partition.id,
|
|
1181
|
+
physicalName: partition.physicalName,
|
|
1182
|
+
parent: parent ?? {
|
|
1183
|
+
kind: "table",
|
|
1184
|
+
id: partition.parent.id
|
|
1185
|
+
},
|
|
1186
|
+
strategy: partition.strategy,
|
|
1187
|
+
...partition.keyColumns === void 0 ? {} : { keyColumns: [...partition.keyColumns] },
|
|
1188
|
+
...partition.bound === void 0 ? {} : { bound: mapExpression(partition.bound) },
|
|
1189
|
+
...partition.default === void 0 ? {} : { default: partition.default },
|
|
1190
|
+
...mapMetadata(partition.provenance, partition.dialect, dialect, partition.reference)
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
function mapPolicy(policy, dialect, context, path) {
|
|
1194
|
+
const table = mapReference(policy.table, context, [...path, "table"], "table");
|
|
1195
|
+
if (table === void 0 && context.mode === "lossy") return;
|
|
1196
|
+
return {
|
|
1197
|
+
kind: "policy",
|
|
1198
|
+
id: policy.id,
|
|
1199
|
+
physicalName: policy.physicalName,
|
|
1200
|
+
table: table ?? {
|
|
1201
|
+
kind: "table",
|
|
1202
|
+
id: policy.table.id
|
|
1203
|
+
},
|
|
1204
|
+
command: policy.command,
|
|
1205
|
+
...policy.roles === void 0 ? {} : { roles: [...policy.roles].sort() },
|
|
1206
|
+
...policy.permissive === void 0 ? {} : { permissive: policy.permissive },
|
|
1207
|
+
...policy.using === void 0 ? {} : { using: mapExpression(policy.using) },
|
|
1208
|
+
...policy.check === void 0 ? {} : { check: mapExpression(policy.check) },
|
|
1209
|
+
...mapMetadata(policy.provenance, policy.dialect, dialect, policy.reference)
|
|
1210
|
+
};
|
|
1211
|
+
}
|
|
1212
|
+
function mapExtensionObject(extension, dialect) {
|
|
1213
|
+
return {
|
|
1214
|
+
kind: "extension",
|
|
1215
|
+
id: extension.id,
|
|
1216
|
+
physicalName: extension.physicalName,
|
|
1217
|
+
extensionName: extension.extensionName,
|
|
1218
|
+
...extension.extensionVersion === void 0 ? {} : { extensionVersion: extension.extensionVersion },
|
|
1219
|
+
...extension.schema === void 0 ? {} : { schema: extension.schema },
|
|
1220
|
+
data: toSnapshotJsonValue(extension.data),
|
|
1221
|
+
...extension.configuration === void 0 ? {} : { configuration: toSnapshotJsonValue(extension.configuration) },
|
|
1222
|
+
...mapMetadata(extension.provenance, extension.dialect, dialect, extension.reference)
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
function mapDeferredObject(object, dialect) {
|
|
1226
|
+
const data = object.unknownFields ? Object.fromEntries(object.unknownFields.map((field) => [field.name, toSnapshotJsonValue(isCatalogSqlExpression(field.value) ? field.value.text : field.value)])) : void 0;
|
|
1227
|
+
return {
|
|
1228
|
+
kind: "deferred-object",
|
|
1229
|
+
id: object.id ?? `deferred:${object.objectKind}:${object.physicalName}`,
|
|
1230
|
+
objectKind: object.objectKind,
|
|
1231
|
+
physicalName: object.physicalName,
|
|
1232
|
+
...data === void 0 ? {} : { data: toSnapshotJsonValue(data) },
|
|
1233
|
+
...mapMetadata(object.provenance, object.dialect, dialect, object.reference)
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
function mapOpaqueObject(object, dialect) {
|
|
1237
|
+
return {
|
|
1238
|
+
kind: "opaque-object",
|
|
1239
|
+
id: object.id,
|
|
1240
|
+
objectKind: object.objectKind,
|
|
1241
|
+
physicalName: object.physicalName,
|
|
1242
|
+
data: toSnapshotJsonValue(object.data),
|
|
1243
|
+
...object.sql === void 0 ? {} : { sql: mapExpression(object.sql) },
|
|
1244
|
+
...mapMetadata(object.provenance, object.dialect, dialect, object.reference)
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
function mapComment(comment, dialect, context, path, fallbackOwner) {
|
|
1248
|
+
const object = mapReference(comment.object, context, [...path, "object"], void 0, fallbackOwner);
|
|
1249
|
+
if (object === void 0 && context.mode === "lossy") return;
|
|
1250
|
+
return {
|
|
1251
|
+
kind: "comment",
|
|
1252
|
+
id: comment.id,
|
|
1253
|
+
physicalName: comment.reference?.name ?? comment.id,
|
|
1254
|
+
object: object ?? comment.object,
|
|
1255
|
+
text: comment.text,
|
|
1256
|
+
...mapMetadata(comment.provenance, comment.dialect, dialect, comment.reference)
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
function mapOwnership(ownership, dialect, context, path, fallbackOwner) {
|
|
1260
|
+
const object = mapReference(ownership.object, context, [...path, "object"], void 0, fallbackOwner);
|
|
1261
|
+
if (object === void 0 && context.mode === "lossy") return;
|
|
1262
|
+
return {
|
|
1263
|
+
kind: "ownership",
|
|
1264
|
+
id: ownership.id,
|
|
1265
|
+
physicalName: ownership.reference?.name ?? ownership.id,
|
|
1266
|
+
object: object ?? ownership.object,
|
|
1267
|
+
owner: ownership.owner,
|
|
1268
|
+
...mapMetadata(ownership.provenance, ownership.dialect, dialect, ownership.reference)
|
|
1269
|
+
};
|
|
1270
|
+
}
|
|
1271
|
+
function mapStorage(storage, dialect) {
|
|
1272
|
+
return {
|
|
1273
|
+
kind: "native",
|
|
1274
|
+
dialect,
|
|
1275
|
+
type: storage.nativeType,
|
|
1276
|
+
...dialect === "sqlite" ? { affinity: storageAffinity(storage.nativeType) } : {}
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1279
|
+
function mapValueFact(value) {
|
|
1280
|
+
if (value.kind === "literal") return {
|
|
1281
|
+
kind: "literal",
|
|
1282
|
+
value: mapLiteral(value)
|
|
1283
|
+
};
|
|
1284
|
+
return {
|
|
1285
|
+
kind: "expression",
|
|
1286
|
+
expression: mapExpression(value.expression)
|
|
1287
|
+
};
|
|
1288
|
+
}
|
|
1289
|
+
function mapLiteral(value) {
|
|
1290
|
+
if (value.value === null) return { kind: "null" };
|
|
1291
|
+
if (typeof value.value === "boolean") return {
|
|
1292
|
+
kind: "boolean",
|
|
1293
|
+
value: value.value
|
|
1294
|
+
};
|
|
1295
|
+
if (typeof value.value === "bigint") return {
|
|
1296
|
+
kind: "bigint",
|
|
1297
|
+
value: value.value.toString()
|
|
1298
|
+
};
|
|
1299
|
+
if (typeof value.value === "number") return {
|
|
1300
|
+
kind: "number",
|
|
1301
|
+
value: String(value.value)
|
|
1302
|
+
};
|
|
1303
|
+
return {
|
|
1304
|
+
kind: "string",
|
|
1305
|
+
value: value.value
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
function mapIdentity(identity, dialect) {
|
|
1309
|
+
return {
|
|
1310
|
+
kind: "identity",
|
|
1311
|
+
generation: identity.generation,
|
|
1312
|
+
options: Object.fromEntries(Object.entries(identity.options).map(([key, value]) => [key, mapValueFact(value)])),
|
|
1313
|
+
...mapMetadata(void 0, identity.dialect, dialect)
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
function mapExpression(value) {
|
|
1317
|
+
return {
|
|
1318
|
+
kind: "expression",
|
|
1319
|
+
expressionKind: "unsafe",
|
|
1320
|
+
sql: value.text.replace(/\r\n?/g, "\n").trim(),
|
|
1321
|
+
dialect: value.dialect
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
function mapMetadata(provenance, extension, dialect, reference) {
|
|
1325
|
+
const mappedProvenance = provenance ? mapProvenance(provenance) : void 0;
|
|
1326
|
+
const mappedExtension = extension ? {
|
|
1327
|
+
dialect: extension.dialect,
|
|
1328
|
+
version: extension.version,
|
|
1329
|
+
data: toSnapshotJsonValue(extension.data)
|
|
1330
|
+
} : void 0;
|
|
1331
|
+
const physicalReference = reference ? {
|
|
1332
|
+
kind: reference.kind,
|
|
1333
|
+
...reference.namespace === void 0 ? {} : { namespace: reference.namespace },
|
|
1334
|
+
...reference.table === void 0 ? {} : { table: reference.table },
|
|
1335
|
+
name: reference.name
|
|
1336
|
+
} : void 0;
|
|
1337
|
+
return {
|
|
1338
|
+
...mappedProvenance === void 0 ? {} : { provenance: mappedProvenance },
|
|
1339
|
+
...physicalReference === void 0 ? {} : { physicalReference },
|
|
1340
|
+
...mappedExtension === void 0 ? {} : { dialect: mappedExtension }
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
function mapProvenance(value) {
|
|
1344
|
+
return {
|
|
1345
|
+
kind: value.kind,
|
|
1346
|
+
dialect: value.dialect,
|
|
1347
|
+
...value.path === void 0 ? {} : { path: [...value.path] }
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
function mapReference(reference, context, path, expectedKind, fallbackOwner) {
|
|
1351
|
+
const kind = normalizeReferenceKind(reference.kind);
|
|
1352
|
+
const tableId = isEntityReference(reference) ? reference.tableId : void 0;
|
|
1353
|
+
const explicitOwner = reference.owner ?? (tableId === void 0 ? fallbackOwner : {
|
|
1354
|
+
kind: "table",
|
|
1355
|
+
id: tableId
|
|
1356
|
+
});
|
|
1357
|
+
const lookupReference = {
|
|
1358
|
+
...reference,
|
|
1359
|
+
kind,
|
|
1360
|
+
...explicitOwner === void 0 ? {} : { owner: explicitOwner }
|
|
1361
|
+
};
|
|
1362
|
+
const owner = explicitOwner ?? context.references.owner(lookupReference);
|
|
1363
|
+
const scopedLookupReference = {
|
|
1364
|
+
...lookupReference,
|
|
1365
|
+
...owner === void 0 ? {} : { owner }
|
|
1366
|
+
};
|
|
1367
|
+
const validKind = expectedKind === void 0 || kind === expectedKind;
|
|
1368
|
+
const ownerRequired = kind === "column" || kind === "constraint" || kind === "index";
|
|
1369
|
+
const validReference = context.references.has(scopedLookupReference);
|
|
1370
|
+
if (!validKind || !validReference || ownerRequired && owner === void 0) {
|
|
1371
|
+
if (reportMappingIssue(context, {
|
|
1372
|
+
code: "unresolved-reference",
|
|
1373
|
+
message: !validKind ? `Reference kind ${reference.kind} is not valid here` : ownerRequired && owner === void 0 ? `Reference ${reference.kind}:${reference.id} has no unique owner scope` : `Reference ${reference.kind}:${reference.id} was not found`,
|
|
1374
|
+
path
|
|
1375
|
+
})) return;
|
|
1376
|
+
}
|
|
1377
|
+
return {
|
|
1378
|
+
kind,
|
|
1379
|
+
id: reference.id,
|
|
1380
|
+
...owner === void 0 ? {} : { owner }
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
function normalizeReferenceKind(kind) {
|
|
1384
|
+
return kind === "primary-key" || kind === "unique" || kind === "foreign-key" || kind === "check" ? "constraint" : kind;
|
|
1385
|
+
}
|
|
1386
|
+
function catalogObjectList(catalog) {
|
|
1387
|
+
const topLevel = [
|
|
1388
|
+
catalog.namespace,
|
|
1389
|
+
...catalog.tables,
|
|
1390
|
+
...catalog.views,
|
|
1391
|
+
...catalog.sequences,
|
|
1392
|
+
...catalog.enums,
|
|
1393
|
+
...catalog.domains,
|
|
1394
|
+
...catalog.collations,
|
|
1395
|
+
...catalog.triggers,
|
|
1396
|
+
...catalog.routines,
|
|
1397
|
+
...catalog.partitions,
|
|
1398
|
+
...catalog.policies,
|
|
1399
|
+
...catalog.extensionObjects,
|
|
1400
|
+
...catalog.deferredObjects,
|
|
1401
|
+
...catalog.opaqueObjects,
|
|
1402
|
+
...catalog.comments,
|
|
1403
|
+
...catalog.ownership
|
|
1404
|
+
];
|
|
1405
|
+
const nested = [
|
|
1406
|
+
...catalog.tables.flatMap((table) => {
|
|
1407
|
+
const owner = {
|
|
1408
|
+
kind: "table",
|
|
1409
|
+
id: table.id
|
|
1410
|
+
};
|
|
1411
|
+
return [
|
|
1412
|
+
...table.columns.map((object) => ({
|
|
1413
|
+
...object,
|
|
1414
|
+
ownerScope: owner
|
|
1415
|
+
})),
|
|
1416
|
+
...table.constraints.map((object) => ({
|
|
1417
|
+
...object,
|
|
1418
|
+
ownerScope: owner
|
|
1419
|
+
})),
|
|
1420
|
+
...table.indexes.map((object) => ({
|
|
1421
|
+
...object,
|
|
1422
|
+
ownerScope: owner
|
|
1423
|
+
}))
|
|
1424
|
+
];
|
|
1425
|
+
}),
|
|
1426
|
+
...catalog.views.flatMap((view) => {
|
|
1427
|
+
const owner = {
|
|
1428
|
+
kind: view.kind,
|
|
1429
|
+
id: view.id
|
|
1430
|
+
};
|
|
1431
|
+
return view.columns.map((object) => ({
|
|
1432
|
+
...object,
|
|
1433
|
+
ownerScope: owner
|
|
1434
|
+
}));
|
|
1435
|
+
}),
|
|
1436
|
+
...catalog.domains.flatMap((domain) => {
|
|
1437
|
+
const owner = {
|
|
1438
|
+
kind: "domain",
|
|
1439
|
+
id: domain.id
|
|
1440
|
+
};
|
|
1441
|
+
return (domain.constraints ?? []).map((object) => ({
|
|
1442
|
+
...object,
|
|
1443
|
+
ownerScope: owner
|
|
1444
|
+
}));
|
|
1445
|
+
})
|
|
1446
|
+
];
|
|
1447
|
+
return [...topLevel, ...nested];
|
|
1448
|
+
}
|
|
1449
|
+
function catalogObjectsWithUnknownFields(catalog) {
|
|
1450
|
+
return catalogObjectList(catalog);
|
|
1451
|
+
}
|
|
1452
|
+
function mapUnknownField(object, field, dialect) {
|
|
1453
|
+
const sql = isCatalogSqlExpression(field.value) ? mapExpression(field.value) : void 0;
|
|
1454
|
+
const value = isCatalogSqlExpression(field.value) ? field.value.text : field.value;
|
|
1455
|
+
return {
|
|
1456
|
+
kind: "opaque-object",
|
|
1457
|
+
id: `unknown:${object.kind}:${object.id ?? object.physicalName ?? "object"}:${field.name}`,
|
|
1458
|
+
objectKind: "unknown-field",
|
|
1459
|
+
physicalName: object.physicalName ?? object.id ?? field.name,
|
|
1460
|
+
data: toSnapshotJsonValue({
|
|
1461
|
+
ownerKind: object.kind,
|
|
1462
|
+
ownerId: object.id ?? object.physicalName ?? field.name,
|
|
1463
|
+
field: field.name,
|
|
1464
|
+
value
|
|
1465
|
+
}),
|
|
1466
|
+
...sql === void 0 ? {} : { sql },
|
|
1467
|
+
...mapMetadata(field.provenance, void 0, dialect)
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
function compareId(left, right) {
|
|
1471
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
1472
|
+
}
|
|
1473
|
+
function isCatalogSqlExpression(value) {
|
|
1474
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && value.kind === "sql" && typeof value.text === "string";
|
|
1475
|
+
}
|
|
1476
|
+
//#endregion
|
|
1477
|
+
//#region src/introspection/snapshot.ts
|
|
1478
|
+
/**
|
|
1479
|
+
* Map a normalized catalog to the canonical Snapshot v1 object model.
|
|
1480
|
+
*
|
|
1481
|
+
* Snapshot identity and namespace facts come from the normalized catalog, with explicit identity
|
|
1482
|
+
* continuity options applied during the mapping step. Strict mode fails on mapping errors; lossy
|
|
1483
|
+
* mode may omit recoverable facts and marks successful output accordingly.
|
|
1484
|
+
*/
|
|
1485
|
+
function mapCatalogToSnapshot(catalog, options) {
|
|
1486
|
+
return mapCatalogToCompleteSnapshot(catalog, options);
|
|
1487
|
+
}
|
|
1488
|
+
//#endregion
|
|
1489
|
+
export { createCompleteIntrospectionCatalog as a, candidateKeyIndexColumns as c, introspectedPhysicalIdentityPolicy as i, hasCandidateKeyShape as l, mapCatalogToCompleteSnapshot as n, freezeIntrospectionCatalog as o, mapCatalogToSnapshotV1 as r, toIntrospectionCatalog as s, mapCatalogToSnapshot as t, isCandidateKeyIndex as u };
|