@voltro/database 0.12.0 → 0.13.0
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/CHANGELOG.md +93 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +11 -10
- package/dist/sql.d.ts +88 -0
- package/dist/sql.js +504 -451
- package/package.json +2 -2
package/dist/sql.js
CHANGED
|
@@ -39,7 +39,7 @@ var _ = (e, t, n, r = 400) => {
|
|
|
39
39
|
t !== void 0 && s.push(`db.${e}: ${t}`);
|
|
40
40
|
}
|
|
41
41
|
return s.push(""), s.join("\n");
|
|
42
|
-
}, v = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, y = (e) => e.replace(/"/g, "`"),
|
|
42
|
+
}, v = (e) => e.unique === !0 && typeof e.where == "string" && e.where.length > 0, y = (e) => e.replace(/"/g, "`"), b = (e) => typeof e == "string" ? e : e.name ?? String(e), te = (e, t) => `_ua_${t}_${e}`.slice(0, 64), x = (e, t) => {
|
|
43
43
|
if (t !== "mysql" && t !== "mariadb" || !e.appliedIndexes.some(v)) return e;
|
|
44
44
|
let n = { ...e.fields }, r = [], i = [];
|
|
45
45
|
for (let t of e.appliedIndexes) {
|
|
@@ -49,9 +49,9 @@ var _ = (e, t, n, r = 400) => {
|
|
|
49
49
|
}
|
|
50
50
|
let a = y(t.where), o = [];
|
|
51
51
|
for (let r of t.fields) {
|
|
52
|
-
let i =
|
|
52
|
+
let i = b(r);
|
|
53
53
|
if (!(i in e.fields)) throw Error(`@voltro/migrate: uniqueActive '${t.name}' on '${e.tableName}' references unknown column '${i}'.`);
|
|
54
|
-
let s =
|
|
54
|
+
let s = te(t.name, i);
|
|
55
55
|
o.push(s), n[s] = {
|
|
56
56
|
type: "text",
|
|
57
57
|
nullable: !0,
|
|
@@ -74,54 +74,54 @@ var _ = (e, t, n, r = 400) => {
|
|
|
74
74
|
appliedIndexes: r,
|
|
75
75
|
appliedUniques: [...e.appliedUniques ?? [], ...i]
|
|
76
76
|
};
|
|
77
|
-
},
|
|
77
|
+
}, S = (e, t) => `${e}::${t}`, ne = (e, t) => {
|
|
78
78
|
let n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = (e) => {
|
|
79
79
|
n.add(e);
|
|
80
80
|
let o = [...t(e)].filter((t) => t.target !== e).sort((e, t) => e.column.localeCompare(t.column));
|
|
81
|
-
for (let t of o) n.has(t.target) ? i.add(
|
|
81
|
+
for (let t of o) n.has(t.target) ? i.add(S(e, t.column)) : r.has(t.target) || a(t.target);
|
|
82
82
|
n.delete(e), r.add(e);
|
|
83
83
|
};
|
|
84
84
|
for (let t of [...e].sort()) r.has(t) || a(t);
|
|
85
85
|
return i;
|
|
86
|
-
},
|
|
86
|
+
}, re = 6322741009312437n, ie = 250, ae = () => {
|
|
87
87
|
let e = Number(process.env.VOLTRO_MIGRATION_LOCK_TIMEOUT_MS);
|
|
88
88
|
return Number.isFinite(e) && e > 0 ? e : 3e4;
|
|
89
|
-
},
|
|
90
|
-
let t =
|
|
89
|
+
}, oe = (e) => d.gen(function* () {
|
|
90
|
+
let t = ae(), n = Date.now();
|
|
91
91
|
for (;;) {
|
|
92
92
|
if ((yield* e`
|
|
93
93
|
SELECT pg_try_advisory_lock(${"6322741009312437"}::bigint) AS got`)[0]?.got) return;
|
|
94
|
-
Date.now() - n >= t && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(t / 1e3)}s. Another migration is in progress, or a prior boot crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* d.sleep(`${
|
|
94
|
+
Date.now() - n >= t && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the postgres migration advisory lock within ${Math.round(t / 1e3)}s. Another migration is in progress, or a prior boot crashed while holding it. (A crashed process's session-level advisory lock is released once its DB connection closes; if this persists, find + terminate the holder via pg_stat_activity, or raise VOLTRO_MIGRATION_LOCK_TIMEOUT_MS.)`))), yield* d.sleep(`${ie} millis`);
|
|
95
95
|
}
|
|
96
|
-
}),
|
|
97
|
-
yield* e`SELECT pg_advisory_unlock(${
|
|
98
|
-
}),
|
|
96
|
+
}), se = (e) => d.gen(function* () {
|
|
97
|
+
yield* e`SELECT pg_advisory_unlock(${re.toString()}::bigint)`;
|
|
98
|
+
}), ce = `voltro_migration_${re.toString(36)}`, le = 30, ue = (e) => d.gen(function* () {
|
|
99
99
|
(yield* e`
|
|
100
|
-
SELECT GET_LOCK(${
|
|
101
|
-
}),
|
|
102
|
-
yield* e`SELECT RELEASE_LOCK(${
|
|
103
|
-
}),
|
|
100
|
+
SELECT GET_LOCK(${ce}, ${le}) AS got`)[0]?.got !== 1 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${ce}' within ${le}s (another migration is in progress, or a prior one left it held).`)));
|
|
101
|
+
}), de = (e) => d.gen(function* () {
|
|
102
|
+
yield* e`SELECT RELEASE_LOCK(${ce})`;
|
|
103
|
+
}), fe = `voltro_migration_${re.toString(36)}`, pe = 3e4, me = (e) => d.gen(function* () {
|
|
104
104
|
let t = yield* e`
|
|
105
105
|
DECLARE @res int;
|
|
106
|
-
EXEC @res = sp_getapplock @Resource = ${
|
|
107
|
-
@LockOwner = 'Session', @LockTimeout = ${
|
|
106
|
+
EXEC @res = sp_getapplock @Resource = ${fe}, @LockMode = 'Exclusive',
|
|
107
|
+
@LockOwner = 'Session', @LockTimeout = ${pe};
|
|
108
108
|
SELECT @res AS res`;
|
|
109
|
-
(t[0]?.res ?? -999) < 0 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${
|
|
110
|
-
}),
|
|
111
|
-
yield* e`EXEC sp_releaseapplock @Resource = ${
|
|
112
|
-
}),
|
|
113
|
-
mysql: () => le(e),
|
|
114
|
-
mssql: () => pe(e),
|
|
115
|
-
sqlite: () => he,
|
|
116
|
-
orElse: () => ae(e)
|
|
117
|
-
}), T = (e) => e.onDialectOrElse({
|
|
109
|
+
(t[0]?.res ?? -999) < 0 && (yield* d.die(/* @__PURE__ */ Error(`could not acquire the migration lock '${fe}' (sp_getapplock returned ${t[0]?.res ?? "no row"}; another migration is in progress).`)));
|
|
110
|
+
}), he = (e) => d.gen(function* () {
|
|
111
|
+
yield* e`EXEC sp_releaseapplock @Resource = ${fe}, @LockOwner = 'Session'`;
|
|
112
|
+
}), ge = d.void, C = (e) => e.onDialectOrElse({
|
|
118
113
|
mysql: () => ue(e),
|
|
119
114
|
mssql: () => me(e),
|
|
120
|
-
sqlite: () =>
|
|
115
|
+
sqlite: () => ge,
|
|
121
116
|
orElse: () => oe(e)
|
|
122
|
-
}),
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
}), w = (e) => e.onDialectOrElse({
|
|
118
|
+
mysql: () => de(e),
|
|
119
|
+
mssql: () => he(e),
|
|
120
|
+
sqlite: () => ge,
|
|
121
|
+
orElse: () => se(e)
|
|
122
|
+
}), _e = (e, t) => d.acquireUseRelease(C(e), () => t, () => w(e).pipe(d.orDie)), ve = f({ scope: "voltro:migrate" }), T = (e) => {
|
|
123
|
+
ve.warn(e.replace(/^\[voltro:migrate\]\s*/, ""));
|
|
124
|
+
}, E = (t, n) => {
|
|
125
125
|
let r = t.type;
|
|
126
126
|
if (t.spatial) {
|
|
127
127
|
if (n === "postgres") return `${t.spatial.kind}(${t.spatial.geomKind},${t.spatial.srid})`;
|
|
@@ -132,7 +132,7 @@ var _ = (e, t, n, r = 400) => {
|
|
|
132
132
|
return t.rawDdl;
|
|
133
133
|
}
|
|
134
134
|
if (r === "array" && t.arrayElement) {
|
|
135
|
-
if (n === "postgres") return `${
|
|
135
|
+
if (n === "postgres") return `${E({
|
|
136
136
|
...t,
|
|
137
137
|
type: t.arrayElement,
|
|
138
138
|
arrayElement: void 0
|
|
@@ -232,14 +232,22 @@ var _ = (e, t, n, r = 400) => {
|
|
|
232
232
|
case "array": return "TEXT[]";
|
|
233
233
|
case "interval": return "INTERVAL";
|
|
234
234
|
}
|
|
235
|
-
},
|
|
235
|
+
}, ye = (t, n) => {
|
|
236
236
|
if (!t.hasDefault || t.defaultFactory !== void 0) return null;
|
|
237
237
|
let r = t.defaultValue;
|
|
238
|
-
return r === "now" ? e(n) ? "DEFAULT CURRENT_TIMESTAMP" : n === "mssql" ? "DEFAULT SYSUTCDATETIME()" : n === "mysql" || n === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof r == "boolean" ? n === "postgres" ? `DEFAULT ${r}` : `DEFAULT ${+!!r}` : typeof r == "number" ? `DEFAULT ${r}` : typeof r == "string" ? `DEFAULT '${r.replace(/'/g, "''")}'` : typeof r == "object" && r
|
|
239
|
-
},
|
|
238
|
+
return r === "now" ? e(n) ? "DEFAULT CURRENT_TIMESTAMP" : n === "mssql" ? "DEFAULT SYSUTCDATETIME()" : n === "mysql" || n === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof r == "boolean" ? n === "postgres" ? `DEFAULT ${r}` : `DEFAULT ${+!!r}` : typeof r == "number" ? `DEFAULT ${r}` : typeof r == "string" ? `DEFAULT '${r.replace(/'/g, "''")}'` : Array.isArray(r) ? be(r, t, n) : typeof r == "object" && r ? D(r, n) : null;
|
|
239
|
+
}, be = (e, t, n) => {
|
|
240
|
+
if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return D(e, n);
|
|
241
|
+
let r = E({
|
|
242
|
+
...t,
|
|
243
|
+
type: t.arrayElement,
|
|
244
|
+
arrayElement: void 0
|
|
245
|
+
}, n);
|
|
246
|
+
return `DEFAULT '{${e.map((e) => typeof e == "number" || typeof e == "boolean" ? String(e) : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",").replace(/'/g, "''")}}'::${r}[]`;
|
|
247
|
+
}, D = (e, t) => {
|
|
240
248
|
let n = JSON.stringify(e).replace(/'/g, "''");
|
|
241
249
|
return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CAST('${n}' AS JSON))` : `DEFAULT '${n}'`;
|
|
242
|
-
},
|
|
250
|
+
}, O = (e, t) => {
|
|
243
251
|
switch (t) {
|
|
244
252
|
case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
|
|
245
253
|
case "mysql":
|
|
@@ -248,7 +256,7 @@ var _ = (e, t, n, r = 400) => {
|
|
|
248
256
|
case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
|
|
249
257
|
case "turso": return `"${e}" INTEGER PRIMARY KEY`;
|
|
250
258
|
}
|
|
251
|
-
},
|
|
259
|
+
}, k = (e, t) => {
|
|
252
260
|
if (e === "restrict" && t === "mssql") return "NO ACTION";
|
|
253
261
|
switch (e) {
|
|
254
262
|
case "cascade": return "CASCADE";
|
|
@@ -256,38 +264,38 @@ var _ = (e, t, n, r = 400) => {
|
|
|
256
264
|
case "setNull": return "SET NULL";
|
|
257
265
|
case "noAction": return "NO ACTION";
|
|
258
266
|
}
|
|
259
|
-
},
|
|
267
|
+
}, xe = (e, t, n) => n === null ? u(e, t) : `${u(n, t)}.${u(e, t)}`, Se = 191, Ce = (e, t, n) => {
|
|
260
268
|
let r = u(e, n);
|
|
261
269
|
if (n !== "mysql" && n !== "mariadb") return r;
|
|
262
270
|
let i = t[e];
|
|
263
271
|
if (!i) return r;
|
|
264
|
-
let a =
|
|
265
|
-
return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${
|
|
266
|
-
},
|
|
272
|
+
let a = E(i, n).toUpperCase();
|
|
273
|
+
return a.endsWith("TEXT") || a.endsWith("BLOB") ? `${r}(${Se})` : r;
|
|
274
|
+
}, we = (e, t) => {
|
|
267
275
|
if (!e.generatedAs) return null;
|
|
268
276
|
let { expr: n, stored: r } = e.generatedAs;
|
|
269
|
-
if (t === "postgres") return r ||
|
|
277
|
+
if (t === "postgres") return r || T("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
|
|
270
278
|
if (t === "mysql" || t === "mariadb") return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
|
|
271
279
|
if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
|
|
272
280
|
if (t === "turso") throw Error("@voltro/sql-turso: generated columns (.generatedAs(...)) are not supported — Turso's MVCC mode (journal_mode=experimental_mvcc) rejects them. Drop the generated column, or use the 'sqlite' / 'postgres' dialect for this table.");
|
|
273
281
|
return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
|
|
274
|
-
},
|
|
275
|
-
if (n.type === "id" && n.idScheme?.kind === "numeric") return
|
|
276
|
-
let s = r === "mssql" && n.type === "text" && !n.generatedAs && n.maxLength === void 0 && i?.has(t) ? "NVARCHAR(450)" :
|
|
282
|
+
}, Te = (t, n, r, i, a = !1, o = !1) => {
|
|
283
|
+
if (n.type === "id" && n.idScheme?.kind === "numeric") return O(t, r);
|
|
284
|
+
let s = r === "mssql" && n.type === "text" && !n.generatedAs && n.maxLength === void 0 && i?.has(t) ? "NVARCHAR(450)" : E(n, r), c = [u(t, r), s];
|
|
277
285
|
n.type === "id" && !o && c.push("PRIMARY KEY");
|
|
278
|
-
let l =
|
|
286
|
+
let l = we(n, r);
|
|
279
287
|
if (l) c.push(l);
|
|
280
288
|
else {
|
|
281
289
|
n.nullable || c.push("NOT NULL"), n.unique && n.type !== "id" && c.push("UNIQUE");
|
|
282
|
-
let e =
|
|
290
|
+
let e = ye(n, r);
|
|
283
291
|
e && c.push(e);
|
|
284
292
|
}
|
|
285
293
|
if (n.type === "reference" && n.references && !a) {
|
|
286
294
|
let e = n.references();
|
|
287
295
|
c.push(`REFERENCES ${u(e.tableName, r)} (${u("id", r)})`);
|
|
288
|
-
let t =
|
|
296
|
+
let t = k(n.onDelete ?? "restrict", r);
|
|
289
297
|
c.push(`ON DELETE ${t}`);
|
|
290
|
-
let i =
|
|
298
|
+
let i = k(n.refOnUpdate ?? "noAction", r);
|
|
291
299
|
i !== "NO ACTION" && c.push(`ON UPDATE ${i}`);
|
|
292
300
|
}
|
|
293
301
|
if (n.oneOf && n.oneOf.length > 0) {
|
|
@@ -304,18 +312,18 @@ var _ = (e, t, n, r = 400) => {
|
|
|
304
312
|
e(r) ? c.push(`CHECK (${n} IS NULL OR json_valid(${n}))`) : r === "mssql" && c.push(`CHECK (${n} IS NULL OR ISJSON(${n}) = 1)`);
|
|
305
313
|
}
|
|
306
314
|
return c.join(" ");
|
|
307
|
-
},
|
|
315
|
+
}, Ee = (e, t, n = null, r) => {
|
|
308
316
|
let i = /* @__PURE__ */ new Set();
|
|
309
317
|
for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
|
|
310
318
|
for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && i.add(e);
|
|
311
|
-
let a = e.appliedPrimaryKey ?? [], o = a.length > 0, s = Object.entries(e.fields).map(([e, n]) => ` ${
|
|
312
|
-
let r = n.fields.map((n) =>
|
|
319
|
+
let a = e.appliedPrimaryKey ?? [], o = a.length > 0, s = Object.entries(e.fields).map(([e, n]) => ` ${Te(e, n, t, i, r?.has(e) ?? !1, o)}`).join(",\n"), c = (e.appliedUniques ?? []).map((n) => {
|
|
320
|
+
let r = n.fields.map((n) => Ce(n, e.fields, t)).join(", ");
|
|
313
321
|
return ` CONSTRAINT ${u(n.name, t)} UNIQUE (${r})`;
|
|
314
322
|
}), l = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${u(e.name, t)} CHECK (${e.expr})`), d = [
|
|
315
|
-
...o ? [` PRIMARY KEY (${a.map((n) =>
|
|
323
|
+
...o ? [` PRIMARY KEY (${a.map((n) => Ce(n, e.fields, t)).join(", ")})`] : [],
|
|
316
324
|
...c,
|
|
317
325
|
...l
|
|
318
|
-
], f = d.length > 0 ? `${s},\n${d.join(",\n")}` : s, p =
|
|
326
|
+
], f = d.length > 0 ? `${s},\n${d.join(",\n")}` : s, p = xe(e.tableName, t, n);
|
|
319
327
|
if (t === "mssql") {
|
|
320
328
|
let t = n === null ? e.tableName : `${n}.${e.tableName}`, r = `CREATE TABLE ${p} (\n${f}\n)`;
|
|
321
329
|
return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${r.replace(/'/g, "''")}');`;
|
|
@@ -325,10 +333,10 @@ var _ = (e, t, n, r = 400) => {
|
|
|
325
333
|
f,
|
|
326
334
|
");"
|
|
327
335
|
].join("\n");
|
|
328
|
-
},
|
|
336
|
+
}, De = (e, t, n) => {
|
|
329
337
|
let r = `${e}_${t.name}_fts`, i = (e) => u(e, n), a = t.columns.map(i).join(", "), o = t.columns.map((e) => `new.${i(e)}`).join(", "), s = [];
|
|
330
338
|
return s.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${i(r)} USING fts5(${a}, row_id UNINDEXED, tokenize='porter');`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ai`)} AFTER INSERT ON ${i(e)} BEGIN\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_ad`)} AFTER DELETE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\nEND;`), s.push(`CREATE TRIGGER IF NOT EXISTS ${i(`${r}_au`)} AFTER UPDATE ON ${i(e)} BEGIN\n DELETE FROM ${i(r)} WHERE row_id = old.${i("id")};\n INSERT INTO ${i(r)} (${a}, row_id) VALUES (${o}, new.${i("id")});\nEND;`), s;
|
|
331
|
-
},
|
|
339
|
+
}, Oe = (e, n, r = null) => {
|
|
332
340
|
let i = [], o = /* @__PURE__ */ new Set(), s = (e) => e.join("\0"), c = (e, r, i, a) => {
|
|
333
341
|
let o = {
|
|
334
342
|
using: "",
|
|
@@ -340,21 +348,21 @@ var _ = (e, t, n, r = 400) => {
|
|
|
340
348
|
using: " USING GIST",
|
|
341
349
|
withSuffix: "",
|
|
342
350
|
skip: !1
|
|
343
|
-
} : (
|
|
351
|
+
} : (T(`[voltro:migrate] index '${e}' on '${r}': ${n} doesn't support GiST — falling back to btree. Spatial queries on this column will fall back to sequential scan.`), o);
|
|
344
352
|
if (i === "gin") return n === "postgres" ? {
|
|
345
353
|
using: " USING GIN",
|
|
346
354
|
withSuffix: "",
|
|
347
355
|
skip: !1
|
|
348
|
-
} : n === "mysql" || n === "mariadb" ? (
|
|
356
|
+
} : n === "mysql" || n === "mariadb" ? (T(`[voltro:migrate] gin index '${e}' on '${r}': ${n} has no GIN access method — skipping (a btree on a JSON/array column can't serve containment/membership queries). Add a generated column for the specific path you query, then index that with .expressionIndex(...).`), {
|
|
349
357
|
using: "",
|
|
350
358
|
withSuffix: "",
|
|
351
359
|
skip: !0
|
|
352
|
-
}) : (
|
|
360
|
+
}) : (T(`[voltro:migrate] gin index '${e}' on '${r}': ${n} has no GIN access method — falling back to btree. Containment/membership queries won't use this index efficiently.`), o);
|
|
353
361
|
if (i === "brin") return n === "postgres" ? {
|
|
354
362
|
using: " USING BRIN",
|
|
355
363
|
withSuffix: "",
|
|
356
364
|
skip: !1
|
|
357
|
-
} : (
|
|
365
|
+
} : (T(`[voltro:migrate] brin index '${e}' on '${r}': ${n} has no BRIN access method — falling back to btree (larger on disk, but the range scan still works).`), o);
|
|
358
366
|
if (i === "hnsw") {
|
|
359
367
|
if (n === "postgres") {
|
|
360
368
|
let e = a?.hnsw?.m ?? 16, n = a?.hnsw?.efConstruction ?? 64, r = a?.hnsw?.opclass ?? t(a?.hnsw?.distance);
|
|
@@ -365,7 +373,7 @@ var _ = (e, t, n, r = 400) => {
|
|
|
365
373
|
skip: !1
|
|
366
374
|
};
|
|
367
375
|
}
|
|
368
|
-
return
|
|
376
|
+
return T(`[voltro:migrate] hnsw index '${e}' on '${r}': ${n} has no pgvector / HNSW access method — skipping. Nearest-neighbour queries on this column fall back to a sequential scan.`), {
|
|
369
377
|
using: "",
|
|
370
378
|
withSuffix: "",
|
|
371
379
|
skip: !0
|
|
@@ -374,7 +382,7 @@ var _ = (e, t, n, r = 400) => {
|
|
|
374
382
|
return o;
|
|
375
383
|
}, l = (t, r) => {
|
|
376
384
|
let i = t.map((t) => {
|
|
377
|
-
if (typeof t == "string") return
|
|
385
|
+
if (typeof t == "string") return Ce(t, e.fields, n);
|
|
378
386
|
if ("jsonPath" in t) {
|
|
379
387
|
let { column: e, path: r, numeric: i } = t.jsonPath;
|
|
380
388
|
return `(${a(e, r, n, { numeric: i })})`;
|
|
@@ -385,7 +393,7 @@ var _ = (e, t, n, r = 400) => {
|
|
|
385
393
|
}, d = (e, t, i, a, o, s = "", d = !1) => {
|
|
386
394
|
let f = c(e, t, a, o);
|
|
387
395
|
if (f.skip) return "";
|
|
388
|
-
let p = l(i, f.opclass), m = `${f.withSuffix}${s}`, h =
|
|
396
|
+
let p = l(i, f.opclass), m = `${f.withSuffix}${s}`, h = xe(t, n, r), g = d ? "UNIQUE " : "";
|
|
389
397
|
return n === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${e}') CREATE ${g}INDEX ${u(e, n)} ON ${h}${f.using} (${p})${m};` : n === "mysql" ? `CREATE ${g}INDEX ${u(e, n)} ON ${h}${f.using} (${p})${m};` : `CREATE ${g}INDEX IF NOT EXISTS ${u(e, n)} ON ${h}${f.using} (${p})${m};`;
|
|
390
398
|
};
|
|
391
399
|
for (let t of e.appliedFullText ?? []) if (n === "postgres") {
|
|
@@ -398,15 +406,15 @@ var _ = (e, t, n, r = 400) => {
|
|
|
398
406
|
let r = t.columns.map((e) => u(e, n)).join(", ");
|
|
399
407
|
i.push(`CREATE FULLTEXT INDEX ${u(t.name, n)} ON ${u(e.tableName, n)} (${r});`);
|
|
400
408
|
} else if (n === "turso") throw Error(`@voltro/sql-turso: full-text index '${t.name}' on '${e.tableName}' is not supported — Turso's MVCC mode has no FTS5 virtual tables. Drop .fullTextIndex(), or use the 'sqlite' / 'postgres' dialect for this table.`);
|
|
401
|
-
else n === "sqlite" ? i.push(...
|
|
409
|
+
else n === "sqlite" ? i.push(...De(e.tableName, t, n)) : T(`[voltro:migrate] full-text index '${t.name}' on '${e.tableName}': ${n} uses a ranked LIKE search at query time (no native FTS catalog required).`);
|
|
402
410
|
for (let t of e.appliedIndexes) {
|
|
403
411
|
if ((n === "mariadb" || n === "mssql") && t.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
|
|
404
|
-
|
|
412
|
+
T(`[voltro:migrate] json-path index '${t.name}' on '${e.tableName}': ${n} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${n}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
|
|
405
413
|
continue;
|
|
406
414
|
}
|
|
407
415
|
if (t.unique && t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb")) throw Error(`@voltro/migrate: uniqueActive index '${t.name}' on '${e.tableName}' cannot be expressed on ${n} — it has no partial (WHERE) index support, and a full UNIQUE index would forbid re-creating a soft-deleted row. Use a generated STORED column (text().generatedAs("CASE WHEN \`deletedAt\` IS NULL THEN <key> ELSE NULL END", { stored: true })) + .unique([...]) on ${n}, or move this table to postgres/sqlite/mssql.`);
|
|
408
416
|
let r = "";
|
|
409
|
-
t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb" ?
|
|
417
|
+
t.where !== void 0 && t.where.length > 0 && (n === "mysql" || n === "mariadb" ? T(`[voltro:migrate] partial index '${t.name}' on '${e.tableName}': ${n} does not support WHERE clauses on indexes — emitting a full index`) : r = ` WHERE ${t.where}`);
|
|
410
418
|
let a = d(t.name, e.tableName, t.fields, t.kind, t.kindOptions, r, t.unique === !0);
|
|
411
419
|
a !== "" && i.push(a), t.fields.every((e) => typeof e == "string") && o.add(s(t.fields));
|
|
412
420
|
}
|
|
@@ -416,14 +424,14 @@ var _ = (e, t, n, r = 400) => {
|
|
|
416
424
|
i.push(d(r, e.tableName, [t])), o.add(s([t]));
|
|
417
425
|
}
|
|
418
426
|
return i.join("\n");
|
|
419
|
-
},
|
|
427
|
+
}, ke = "CREATE OR REPLACE FUNCTION framework_notify_change() RETURNS trigger AS $$\nDECLARE\n payload TEXT;\nBEGIN\n payload := json_build_object(\n 'table', TG_TABLE_NAME,\n -- The schema the write landed in. Under namespace isolation this is\n -- the tenant schema (tenant_<id>); the CDC consumer uses it so a\n -- write in tenant A namespace does not spuriously wake tenant B\n -- subscriptions on the same-named table. public/absent = shared.\n 'schema', TG_TABLE_SCHEMA,\n 'op', lower(TG_OP),\n 'old', CASE WHEN TG_OP = 'INSERT' THEN NULL ELSE row_to_json(OLD) END,\n 'new', CASE WHEN TG_OP = 'DELETE' THEN NULL ELSE row_to_json(NEW) END\n )::text;\n -- pg_notify hard-caps the payload at 8000 bytes; a wide reactive row\n -- (big text / json column) would otherwise abort the write itself.\n -- Fall back to a body-less notice — the CDC consumer treats absent\n -- old/new as \"all columns changed\" and re-queries, so correctness is\n -- preserved; only the delta-diff fast path is skipped for that write.\n IF octet_length(payload) >= 7999 THEN\n payload := json_build_object(\n 'table', TG_TABLE_NAME,\n 'schema', TG_TABLE_SCHEMA,\n 'op', lower(TG_OP),\n 'old', NULL,\n 'new', NULL,\n 'oversized', true\n )::text;\n END IF;\n PERFORM pg_notify('framework_changes', payload);\n RETURN COALESCE(NEW, OLD);\nEND;\n$$ LANGUAGE plpgsql;", Ae = (e) => `
|
|
420
428
|
ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL;
|
|
421
429
|
DROP TRIGGER IF EXISTS framework_changes_${e.tableName} ON "${e.tableName}";
|
|
422
430
|
CREATE TRIGGER framework_changes_${e.tableName}
|
|
423
431
|
AFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"
|
|
424
432
|
FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
|
|
425
|
-
`.trim(),
|
|
426
|
-
let t = new Map(e.map((e) => [e.tableName, e])), n =
|
|
433
|
+
`.trim(), je = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), Me = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), Ne = (e) => {
|
|
434
|
+
let t = new Map(e.map((e) => [e.tableName, e])), n = ne(e.map((e) => e.tableName), (e) => {
|
|
427
435
|
let n = t.get(e);
|
|
428
436
|
return n ? Object.entries(n.fields).flatMap(([e, n]) => {
|
|
429
437
|
if (n.type !== "reference" || !n.references) return [];
|
|
@@ -434,7 +442,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
|
|
|
434
442
|
}] : [];
|
|
435
443
|
}) : [];
|
|
436
444
|
}), r = [];
|
|
437
|
-
for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(
|
|
445
|
+
for (let t of e) for (let [e, i] of Object.entries(t.fields)) i.type !== "reference" || !i.references || n.has(S(t.tableName, e)) && r.push({
|
|
438
446
|
table: t.tableName,
|
|
439
447
|
column: e,
|
|
440
448
|
targetTable: i.references().tableName,
|
|
@@ -445,7 +453,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
|
|
|
445
453
|
if (!(i.has(e.tableName) || a.has(e.tableName))) {
|
|
446
454
|
a.add(e.tableName);
|
|
447
455
|
for (let [r, i] of Object.entries(e.fields)) {
|
|
448
|
-
if (i.type !== "reference" || !i.references || n.has(
|
|
456
|
+
if (i.type !== "reference" || !i.references || n.has(S(e.tableName, r))) continue;
|
|
449
457
|
let a = i.references();
|
|
450
458
|
if (a.tableName === e.tableName) continue;
|
|
451
459
|
let o = t.get(a.tableName);
|
|
@@ -459,8 +467,8 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
|
|
|
459
467
|
sorted: o,
|
|
460
468
|
cyclic: r
|
|
461
469
|
};
|
|
462
|
-
},
|
|
463
|
-
let r = (e) => n ? `${u(n, t)}.${u(e, t)}` : u(e, t), i = `${e.table}_${e.column}_fkey`, a =
|
|
470
|
+
}, Pe = (e, t, n = null) => {
|
|
471
|
+
let r = (e) => n ? `${u(n, t)}.${u(e, t)}` : u(e, t), i = `${e.table}_${e.column}_fkey`, a = k(e.onDelete, t), o = k(e.onUpdate, t), s = ` ON DELETE ${a}${o === "NO ACTION" ? "" : ` ON UPDATE ${o}`}`, c = (n) => `ADD CONSTRAINT ${u(i, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${u(e.column, t)}) REFERENCES ${r(e.targetTable)} (${u("id", t)})${s}`;
|
|
464
472
|
switch (t) {
|
|
465
473
|
case "postgres": return [
|
|
466
474
|
"DO $$ BEGIN",
|
|
@@ -474,7 +482,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
|
|
|
474
482
|
case "mariadb": return `ALTER TABLE ${r(e.table)} ${c(!0)};`;
|
|
475
483
|
default: return `ALTER TABLE ${r(e.table)} ${c(!1)};`;
|
|
476
484
|
}
|
|
477
|
-
},
|
|
485
|
+
}, Fe = (t, n) => {
|
|
478
486
|
let r = /* @__PURE__ */ new Map();
|
|
479
487
|
if (e(n)) return r;
|
|
480
488
|
for (let e of t) {
|
|
@@ -482,7 +490,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
|
|
|
482
490
|
t.add(e.column), r.set(e.table, t);
|
|
483
491
|
}
|
|
484
492
|
return r;
|
|
485
|
-
},
|
|
493
|
+
}, Ie = (e, t) => {
|
|
486
494
|
if (t !== "postgres") return "";
|
|
487
495
|
let n = /* @__PURE__ */ new Map();
|
|
488
496
|
for (let t of e) for (let e of Object.values(t.fields)) {
|
|
@@ -498,7 +506,7 @@ FOR EACH ROW EXECUTE FUNCTION framework_notify_change();
|
|
|
498
506
|
r.push(`DO $$ BEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = '${e.replace(/'/g, "''")}') THEN\n CREATE TYPE "${e}" AS ENUM (${n});\n END IF;\nEND $$;`);
|
|
499
507
|
}
|
|
500
508
|
return r.join("\n\n");
|
|
501
|
-
},
|
|
509
|
+
}, Le = (e, t) => {
|
|
502
510
|
if (t !== "postgres") return "";
|
|
503
511
|
let n = /* @__PURE__ */ new Set();
|
|
504
512
|
for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
|
|
@@ -512,34 +520,34 @@ BEGIN
|
|
|
512
520
|
SELECT oid INTO type_oid FROM pg_type WHERE typname = '${i}';\n IF type_oid IS NOT NULL\n AND EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${a}')\n AND NOT EXISTS (SELECT 1 FROM pg_enum WHERE enumtypid = type_oid AND enumlabel = '${o}') THEN\n IF current_setting('server_version_num')::int >= 140000 THEN\n EXECUTE format('ALTER TYPE %I RENAME VALUE %L TO %L', '${i}', '${a}', '${o}');\n ELSE\n UPDATE pg_enum SET enumlabel = '${o}' WHERE enumtypid = type_oid AND enumlabel = '${a}';\n END IF;\n END IF;\nEND $$;`);
|
|
513
521
|
}
|
|
514
522
|
return r.join("\n\n");
|
|
515
|
-
},
|
|
523
|
+
}, Re = (e) => {
|
|
516
524
|
let t = [], r = [];
|
|
517
525
|
for (let i of e) n(i) ? r.push(i) : t.push(i);
|
|
518
526
|
return {
|
|
519
527
|
tables: t,
|
|
520
528
|
views: r
|
|
521
529
|
};
|
|
522
|
-
},
|
|
523
|
-
let { tables: i, views: a } =
|
|
524
|
-
n === "postgres" &&
|
|
525
|
-
let u =
|
|
530
|
+
}, A = (t, n) => {
|
|
531
|
+
let { tables: i, views: a } = Re(t), { sorted: o, cyclic: s } = Ne(i.map((e) => x(e, n))), c = Fe(s, n), l = [];
|
|
532
|
+
n === "postgres" && je(o) && l.push("CREATE EXTENSION IF NOT EXISTS vector;"), n === "postgres" && Me(o) && l.push("CREATE EXTENSION IF NOT EXISTS postgis;");
|
|
533
|
+
let u = Le(o, n);
|
|
526
534
|
u && l.push(u);
|
|
527
|
-
let d =
|
|
535
|
+
let d = Ie(o, n);
|
|
528
536
|
d && l.push(d);
|
|
529
|
-
for (let e of o) l.push(
|
|
530
|
-
if (!e(n)) for (let e of s) l.push(
|
|
537
|
+
for (let e of o) l.push(Ee(e, n, null, c.get(e.tableName)));
|
|
538
|
+
if (!e(n)) for (let e of s) l.push(Pe(e, n));
|
|
531
539
|
for (let e of o) {
|
|
532
|
-
let t =
|
|
540
|
+
let t = Oe(e, n);
|
|
533
541
|
t && l.push(t);
|
|
534
542
|
}
|
|
535
543
|
let f = o.filter((e) => e.isReactive);
|
|
536
544
|
if (f.length > 0 && n === "postgres") {
|
|
537
|
-
l.push(
|
|
538
|
-
for (let e of f) l.push(
|
|
545
|
+
l.push(ke);
|
|
546
|
+
for (let e of f) l.push(Ae(e));
|
|
539
547
|
}
|
|
540
548
|
for (let e of a) l.push(r(e, n));
|
|
541
549
|
return l.join("\n\n") + "\n";
|
|
542
|
-
},
|
|
550
|
+
}, ze = (e, t, n) => {
|
|
543
551
|
let r = u(e, t);
|
|
544
552
|
switch (t) {
|
|
545
553
|
case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${r};`;
|
|
@@ -549,57 +557,57 @@ BEGIN
|
|
|
549
557
|
case "turso":
|
|
550
558
|
case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${r};`;
|
|
551
559
|
}
|
|
552
|
-
},
|
|
553
|
-
let a =
|
|
554
|
-
if (n === "postgres") return `${a}\n\nSET search_path TO ${o};\n\n${
|
|
555
|
-
if (n === "mysql" || n === "mariadb") return `${a}\n\nUSE ${o};\n\n${
|
|
556
|
-
let { sorted: s, cyclic: c } =
|
|
557
|
-
for (let e of s) d.push(
|
|
558
|
-
if (!e(n)) for (let e of c) d.push(
|
|
560
|
+
}, Be = (t, n, r, i) => {
|
|
561
|
+
let a = ze(r, n, i), o = u(r, n);
|
|
562
|
+
if (n === "postgres") return `${a}\n\nSET search_path TO ${o};\n\n${A(t, n)}`;
|
|
563
|
+
if (n === "mysql" || n === "mariadb") return `${a}\n\nUSE ${o};\n\n${A(t, n)}`;
|
|
564
|
+
let { sorted: s, cyclic: c } = Ne(t), l = Fe(c, n), d = [a];
|
|
565
|
+
for (let e of s) d.push(Ee(e, n, r, l.get(e.tableName)));
|
|
566
|
+
if (!e(n)) for (let e of c) d.push(Pe(e, n, r));
|
|
559
567
|
for (let e of s) {
|
|
560
|
-
let t =
|
|
568
|
+
let t = Oe(e, n, r);
|
|
561
569
|
t && d.push(t);
|
|
562
570
|
}
|
|
563
571
|
return d.join("\n\n") + "\n";
|
|
564
|
-
},
|
|
565
|
-
if (t !== "postgres") return
|
|
566
|
-
let { sorted: n, cyclic: r } =
|
|
572
|
+
}, Ve = (e, t) => {
|
|
573
|
+
if (t !== "postgres") return A(e, t);
|
|
574
|
+
let { sorted: n, cyclic: r } = Ne(e), i = Fe(r, t), a = [], o = Le(n, t);
|
|
567
575
|
o && a.push(o);
|
|
568
|
-
let s =
|
|
576
|
+
let s = Ie(n, t);
|
|
569
577
|
s && a.push(s);
|
|
570
|
-
for (let e of n) a.push(
|
|
571
|
-
for (let e of r) a.push(
|
|
578
|
+
for (let e of n) a.push(Ee(e, t, null, i.get(e.tableName)));
|
|
579
|
+
for (let e of r) a.push(Pe(e, t));
|
|
572
580
|
for (let e of n) {
|
|
573
581
|
let n = Object.entries(e.fields);
|
|
574
582
|
if (n.length === 0) continue;
|
|
575
583
|
let r = n.map(([n, r]) => {
|
|
576
|
-
let a =
|
|
584
|
+
let a = Te(n, r, t, void 0, i.get(e.tableName)?.has(n) ?? !1);
|
|
577
585
|
return `ALTER TABLE ${u(e.tableName, t)} ADD COLUMN IF NOT EXISTS ${a};`;
|
|
578
586
|
});
|
|
579
587
|
a.push(r.join("\n"));
|
|
580
588
|
}
|
|
581
589
|
for (let e of n) {
|
|
582
|
-
let n =
|
|
590
|
+
let n = Oe(e, t);
|
|
583
591
|
n && a.push(n);
|
|
584
592
|
}
|
|
585
593
|
let c = n.filter((e) => e.isReactive);
|
|
586
594
|
if (c.length > 0) {
|
|
587
|
-
a.push(
|
|
588
|
-
for (let e of c) a.push(
|
|
595
|
+
a.push(ke);
|
|
596
|
+
for (let e of c) a.push(Ae(e));
|
|
589
597
|
}
|
|
590
598
|
return a.join("\n\n") + "\n";
|
|
591
|
-
},
|
|
599
|
+
}, He = (e, t = "postgres") => d.gen(function* () {
|
|
592
600
|
let n = yield* p.SqlClient;
|
|
593
|
-
yield*
|
|
594
|
-
}),
|
|
601
|
+
yield* _e(n, Ge(n, A(e, t), t)).pipe(d.orDie);
|
|
602
|
+
}), Ue = (e, t) => {
|
|
595
603
|
let n = t.cause ?? {};
|
|
596
604
|
return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
|
|
597
|
-
},
|
|
605
|
+
}, We = (e) => d.gen(function* () {
|
|
598
606
|
let t = yield* p.SqlClient;
|
|
599
|
-
for (let n of
|
|
600
|
-
|
|
607
|
+
for (let n of Ke(e)) process.env.VOLTRO_MIGRATE_DEBUG === "1" && ve.debug(`EXEC: ${n.replace(/\s+/g, " ").slice(0, 180)}`), yield* t.unsafe(n).pipe(d.catchIf((e) => Ue(n, e), () => d.void), d.tapError((e) => d.sync(() => {
|
|
608
|
+
ve.error(_("migrate: statement failed", n, e, 200));
|
|
601
609
|
})), d.orDieWith((e) => Error(_("migrate: statement failed", n, e, 400).trim())));
|
|
602
|
-
}),
|
|
610
|
+
}), Ge = (e, t, n) => (n === "turso" ? We(t) : e.withTransaction(We(t))).pipe(d.orDie), Ke = (e) => {
|
|
603
611
|
let t = [], n = "", r = !1;
|
|
604
612
|
for (let i = 0; i < e.length; i++) {
|
|
605
613
|
if (e.slice(i, i + 2) === "$$") {
|
|
@@ -614,40 +622,40 @@ BEGIN
|
|
|
614
622
|
}
|
|
615
623
|
let i = n.trim();
|
|
616
624
|
return i.length > 0 && t.push(i), t;
|
|
617
|
-
},
|
|
618
|
-
await d.runPromise(
|
|
619
|
-
},
|
|
620
|
-
let r =
|
|
621
|
-
yield*
|
|
622
|
-
}),
|
|
623
|
-
await d.runPromise(
|
|
624
|
-
},
|
|
625
|
+
}, qe = async (e, t, n = "postgres") => {
|
|
626
|
+
await d.runPromise(He(e, n).pipe(d.provide(t)));
|
|
627
|
+
}, Je = (e, t, n = "postgres") => d.gen(function* () {
|
|
628
|
+
let r = Be(e, n, t), i = yield* p.SqlClient;
|
|
629
|
+
yield* _e(i, Ge(i, r, n)).pipe(d.orDie);
|
|
630
|
+
}), Ye = async (e, t, n, r = "postgres") => {
|
|
631
|
+
await d.runPromise(Je(e, t, r).pipe(d.provide(n)));
|
|
632
|
+
}, Xe = async (e, t, n = "postgres") => {
|
|
625
633
|
await d.runPromise(d.gen(function* () {
|
|
626
|
-
let t =
|
|
627
|
-
yield*
|
|
634
|
+
let t = Ve(e, n), r = yield* p.SqlClient;
|
|
635
|
+
yield* _e(r, Ge(r, t, n)).pipe(d.orDie);
|
|
628
636
|
}).pipe(d.provide(t)));
|
|
629
|
-
},
|
|
637
|
+
}, Ze = (e) => {
|
|
630
638
|
if (e == null) return e;
|
|
631
|
-
if (Array.isArray(e)) return e.map(
|
|
639
|
+
if (Array.isArray(e)) return e.map(Ze);
|
|
632
640
|
if (typeof e != "object") return e;
|
|
633
641
|
let t = {};
|
|
634
642
|
for (let n of Object.keys(e).sort()) {
|
|
635
643
|
let r = e[n];
|
|
636
|
-
r !== void 0 && (t[n] =
|
|
644
|
+
r !== void 0 && (t[n] = Ze(r));
|
|
637
645
|
}
|
|
638
646
|
return t;
|
|
639
|
-
},
|
|
647
|
+
}, Qe = (e) => {
|
|
640
648
|
if (!e.idScheme && !e.sensitive && !e.safe) return e;
|
|
641
649
|
let { idScheme: t, sensitive: n, safe: r, ...i } = e;
|
|
642
650
|
return i;
|
|
643
|
-
},
|
|
651
|
+
}, $e = (e) => [...e].map(Qe).sort((e, t) => e.name.localeCompare(t.name)), et = (e) => [...e].sort((e, t) => e.name.localeCompare(t.name)), tt = (e) => [...e].map((e) => ({
|
|
644
652
|
name: e.name,
|
|
645
|
-
columns:
|
|
646
|
-
indexes:
|
|
647
|
-
})).sort((e, t) => e.name.localeCompare(t.name)),
|
|
648
|
-
let t = { tables:
|
|
653
|
+
columns: $e(e.columns),
|
|
654
|
+
indexes: et(e.indexes)
|
|
655
|
+
})).sort((e, t) => e.name.localeCompare(t.name)), j = (e) => {
|
|
656
|
+
let t = { tables: tt(e.tables) }, n = JSON.stringify(Ze(t));
|
|
649
657
|
return m("sha256").update(n).digest("hex");
|
|
650
|
-
},
|
|
658
|
+
}, M = (e) => e.slice(0, 16), nt = (e, t) => {
|
|
651
659
|
let n = t.references ? {
|
|
652
660
|
table: t.references().tableName,
|
|
653
661
|
column: "id",
|
|
@@ -677,9 +685,15 @@ BEGIN
|
|
|
677
685
|
...t.narrowedFrom.using === void 0 ? {} : { using: t.narrowedFrom.using }
|
|
678
686
|
} } : {},
|
|
679
687
|
...t.sensitive ? { sensitive: t.sensitive } : t.encrypted && !t.safe ? { sensitive: { class: "secret" } } : {},
|
|
680
|
-
...t.safe ? { safe: !0 } : {}
|
|
688
|
+
...t.safe ? { safe: !0 } : {},
|
|
689
|
+
...t.vectorDim === void 0 ? {} : { vectorDim: t.vectorDim },
|
|
690
|
+
...t.vectorPrecision === void 0 ? {} : { vectorPrecision: t.vectorPrecision },
|
|
691
|
+
...t.arrayElement === void 0 ? {} : { arrayElement: t.arrayElement },
|
|
692
|
+
...t.enumName === void 0 ? {} : { enumName: t.enumName },
|
|
693
|
+
...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
|
|
694
|
+
...t.spatial === void 0 ? {} : { spatial: t.spatial }
|
|
681
695
|
};
|
|
682
|
-
},
|
|
696
|
+
}, rt = (e) => {
|
|
683
697
|
let t = [], n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
684
698
|
n.has(e.name) || (n.add(e.name), t.push(e));
|
|
685
699
|
}, i = e.appliedPrimaryKey ?? [];
|
|
@@ -727,11 +741,11 @@ BEGIN
|
|
|
727
741
|
});
|
|
728
742
|
}
|
|
729
743
|
return t;
|
|
730
|
-
},
|
|
744
|
+
}, it = (e) => {
|
|
731
745
|
let t = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), n = [];
|
|
732
746
|
for (let [r, i] of Object.entries(e.fields)) {
|
|
733
747
|
if (i.dropped) continue;
|
|
734
|
-
let e =
|
|
748
|
+
let e = nt(r, i);
|
|
735
749
|
n.push(t.has(r) ? {
|
|
736
750
|
...e,
|
|
737
751
|
unique: !0
|
|
@@ -741,32 +755,32 @@ BEGIN
|
|
|
741
755
|
return {
|
|
742
756
|
name: e.tableName,
|
|
743
757
|
columns: n,
|
|
744
|
-
indexes:
|
|
758
|
+
indexes: rt(e),
|
|
745
759
|
...r.length > 0 ? { primaryKey: [...r] } : {}
|
|
746
760
|
};
|
|
747
|
-
},
|
|
761
|
+
}, at = (e) => {
|
|
748
762
|
let t = /* @__PURE__ */ new Map();
|
|
749
763
|
for (let n of e) for (let e of n.indexes) {
|
|
750
764
|
let r = t.get(e.name);
|
|
751
765
|
if (r !== void 0 && r !== n.name) throw Error(`duplicate index name '${e.name}' across tables '${r}' and '${n.name}'. Index names must be unique per SCHEMA, not just per table — the DB creates only one, so the other never applies and 'db plan' re-emits it forever. Give each an explicit, table-prefixed name (e.g. '${n.name}_${e.name}').`);
|
|
752
766
|
t.set(e.name, n.name);
|
|
753
767
|
}
|
|
754
|
-
},
|
|
755
|
-
let n = e.map((e) =>
|
|
756
|
-
return
|
|
757
|
-
},
|
|
768
|
+
}, N = (e, t) => {
|
|
769
|
+
let n = e.map((e) => it(x(e, t)));
|
|
770
|
+
return at(n), { tables: n };
|
|
771
|
+
}, ot = /* @__PURE__ */ new Set(["voltro_isr_cache"]), P = (e) => ot.has(e) || e.startsWith("_voltro_") || e.startsWith("_cloud_") || e.startsWith("cluster_"), st = {
|
|
758
772
|
postgres: !0,
|
|
759
773
|
mysql: !0,
|
|
760
774
|
mariadb: !0,
|
|
761
775
|
mssql: !0,
|
|
762
776
|
sqlite: !0
|
|
763
|
-
},
|
|
777
|
+
}, ct = {
|
|
764
778
|
postgres: !0,
|
|
765
779
|
mysql: !1,
|
|
766
780
|
mariadb: !1,
|
|
767
781
|
mssql: !0,
|
|
768
782
|
sqlite: !0
|
|
769
|
-
},
|
|
783
|
+
}, lt = (e) => {
|
|
770
784
|
switch (e) {
|
|
771
785
|
case "add-column":
|
|
772
786
|
case "drop-column":
|
|
@@ -776,22 +790,22 @@ BEGIN
|
|
|
776
790
|
case "add-foreign-key":
|
|
777
791
|
case "add-unique":
|
|
778
792
|
case "add-unique-composite":
|
|
779
|
-
case "add-check": return
|
|
780
|
-
default: return
|
|
793
|
+
case "add-check": return ct;
|
|
794
|
+
default: return st;
|
|
781
795
|
}
|
|
782
|
-
},
|
|
796
|
+
}, ut = (e, t) => {
|
|
783
797
|
let n = new Map(t.tables.map((e) => [e.name, e]));
|
|
784
798
|
return new Map(e.map((e) => [e.tableName, {
|
|
785
799
|
table: e,
|
|
786
800
|
snapshot: n.get(e.tableName),
|
|
787
801
|
columnDefs: e.fields
|
|
788
802
|
}]));
|
|
789
|
-
},
|
|
803
|
+
}, dt = (e) => (t, n) => t.name === e ? -1 : n.name === e ? 1 : t.name.localeCompare(n.name), F = (e) => {
|
|
790
804
|
if (typeof e != "object" || !e) return JSON.stringify(e);
|
|
791
805
|
if (Array.isArray(e)) return `[${e.map(F).join(",")}]`;
|
|
792
806
|
let t = e;
|
|
793
807
|
return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${F(t[e])}`).join(",")}}`;
|
|
794
|
-
},
|
|
808
|
+
}, ft = (e) => {
|
|
795
809
|
if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
|
|
796
810
|
let t = e.defaultValue;
|
|
797
811
|
if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
|
|
@@ -807,8 +821,8 @@ BEGIN
|
|
|
807
821
|
return F(JSON.parse(a));
|
|
808
822
|
} catch {}
|
|
809
823
|
return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
|
|
810
|
-
},
|
|
811
|
-
let n =
|
|
824
|
+
}, pt = (e, t) => {
|
|
825
|
+
let n = ft(e), r = ft(t);
|
|
812
826
|
if (n === r) return !0;
|
|
813
827
|
let i = (e) => e === "1" || e === "true" ? "__BOOL_TRUE__" : e === "0" || e === "false" ? "__BOOL_FALSE__" : e;
|
|
814
828
|
return i(n) === i(r);
|
|
@@ -821,18 +835,18 @@ BEGIN
|
|
|
821
835
|
onDelete: t(e.onDelete),
|
|
822
836
|
onUpdate: t(e.onUpdate)
|
|
823
837
|
};
|
|
824
|
-
},
|
|
838
|
+
}, mt = (e, t) => {
|
|
825
839
|
let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
|
|
826
840
|
if (!n && !r) return !0;
|
|
827
841
|
if (!n || !r || n.length !== r.length) return !1;
|
|
828
842
|
let i = [...n].sort(), a = [...r].sort();
|
|
829
843
|
return i.every((e, t) => e === a[t]);
|
|
830
|
-
},
|
|
844
|
+
}, ht = (e, t) => e.type === t.type && e.nullable === t.nullable && e.unique === t.unique && pt(e, t) && JSON.stringify(I(e.references)) === JSON.stringify(I(t.references)) && mt(e.oneOf, t.oneOf), gt = (e, t) => t.oneOf && t.oneOf.length > 0 ? L({
|
|
831
845
|
kind: "add-check",
|
|
832
846
|
table: e,
|
|
833
847
|
column: t.name,
|
|
834
848
|
values: t.oneOf
|
|
835
|
-
}, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0,
|
|
849
|
+
}, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, _t = (e, t) => e.unique === t.unique && (e.expression || t.expression ? !0 : e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), vt = (e, t) => {
|
|
836
850
|
let n = new Map(t.columns.map((e) => [e.name, e])), r = new Map(e.columns.map((e) => [e.name, e])), i = [], a = [], o = [];
|
|
837
851
|
for (let t of e.columns) {
|
|
838
852
|
let e = n.get(t.name);
|
|
@@ -840,7 +854,7 @@ BEGIN
|
|
|
840
854
|
i.push(t);
|
|
841
855
|
continue;
|
|
842
856
|
}
|
|
843
|
-
|
|
857
|
+
ht(t, e) || o.push({
|
|
844
858
|
declared: t,
|
|
845
859
|
live: e
|
|
846
860
|
});
|
|
@@ -851,11 +865,11 @@ BEGIN
|
|
|
851
865
|
removed: a,
|
|
852
866
|
changed: o
|
|
853
867
|
};
|
|
854
|
-
},
|
|
868
|
+
}, yt = (e, t) => {
|
|
855
869
|
let n = new Map(t.indexes.map((e) => [e.name, e])), r = new Map(e.indexes.map((e) => [e.name, e])), i = [], a = [];
|
|
856
870
|
for (let t of e.indexes) {
|
|
857
871
|
let e = n.get(t.name);
|
|
858
|
-
(!e || !
|
|
872
|
+
(!e || !_t(t, e)) && i.push(t);
|
|
859
873
|
}
|
|
860
874
|
for (let e of t.indexes) r.has(e.name) || a.push(e);
|
|
861
875
|
return {
|
|
@@ -865,33 +879,33 @@ BEGIN
|
|
|
865
879
|
}, L = (e, t, n, r) => ({
|
|
866
880
|
op: e,
|
|
867
881
|
classification: t,
|
|
868
|
-
atomicByDialect:
|
|
882
|
+
atomicByDialect: lt(e.kind),
|
|
869
883
|
...n ? { reason: n } : {},
|
|
870
884
|
...r ? { blocked: r } : {}
|
|
871
|
-
}),
|
|
885
|
+
}), bt = (e, t, n) => {
|
|
872
886
|
let r = {
|
|
873
887
|
kind: "add-column",
|
|
874
888
|
table: e,
|
|
875
889
|
column: t
|
|
876
890
|
};
|
|
877
891
|
return t.nullable ? L(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? L(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? L(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : L(r, "needs-backfill", "NOT NULL column on a table whose row count is unknown", { fix: `declare \`${t.name}: <type>().backfill(sql\`...\`)\` OR \`.default(value)\` so existing rows survive the migration` });
|
|
878
|
-
},
|
|
892
|
+
}, xt = (e, t, n) => {
|
|
879
893
|
let r = {
|
|
880
894
|
kind: "drop-column",
|
|
881
895
|
table: e,
|
|
882
896
|
column: t.name
|
|
883
897
|
};
|
|
884
898
|
return n?.dropped ? L(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : L(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
|
|
885
|
-
},
|
|
899
|
+
}, St = (e, t, n, r) => L({
|
|
886
900
|
kind: "create-table",
|
|
887
901
|
table: e,
|
|
888
902
|
columns: t,
|
|
889
903
|
indexes: n,
|
|
890
904
|
...r && r.length > 0 ? { primaryKey: r } : {}
|
|
891
|
-
}, "safe", "new table — no data to preserve"),
|
|
905
|
+
}, "safe", "new table — no data to preserve"), Ct = (e) => L({
|
|
892
906
|
kind: "drop-table",
|
|
893
907
|
table: e
|
|
894
|
-
}, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }),
|
|
908
|
+
}, "lossy", "table missing from declared schema", { fix: "if intentional, set VOLTRO_DESTRUCTIVE_OK=1 OR add a file-based migration. If a typo, restore the table declaration" }), wt = 5e4, Tt = (e, t, n, r) => {
|
|
895
909
|
let i = (n ?? 0) >= r, a;
|
|
896
910
|
return a = t.unique ? t.columns.length === 1 ? {
|
|
897
911
|
kind: "add-unique",
|
|
@@ -907,7 +921,7 @@ BEGIN
|
|
|
907
921
|
table: e,
|
|
908
922
|
index: t
|
|
909
923
|
}, i ? L(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : L(a, "safe", t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : "add B-tree index");
|
|
910
|
-
},
|
|
924
|
+
}, Et = (e, t) => t.unique && t.columns.length > 1 ? L({
|
|
911
925
|
kind: "drop-unique-composite",
|
|
912
926
|
table: e,
|
|
913
927
|
name: t.name
|
|
@@ -915,7 +929,7 @@ BEGIN
|
|
|
915
929
|
kind: "drop-index",
|
|
916
930
|
table: e,
|
|
917
931
|
index: t.name
|
|
918
|
-
}, "safe", "drop index (no data loss — index is derived data)"),
|
|
932
|
+
}, "safe", "drop index (no data loss — index is derived data)"), Dt = (e, t) => {
|
|
919
933
|
if (e === "reference") return "text";
|
|
920
934
|
switch (t) {
|
|
921
935
|
case "sqlite":
|
|
@@ -923,7 +937,7 @@ BEGIN
|
|
|
923
937
|
case "mssql": return e === "json" ? "text" : e;
|
|
924
938
|
default: return e;
|
|
925
939
|
}
|
|
926
|
-
},
|
|
940
|
+
}, Ot = (e, t, n, r, i, a) => {
|
|
927
941
|
let o = [];
|
|
928
942
|
if (t.nullable !== n.nullable) {
|
|
929
943
|
let n = {
|
|
@@ -946,7 +960,7 @@ BEGIN
|
|
|
946
960
|
table: e,
|
|
947
961
|
column: t.name
|
|
948
962
|
}, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
|
|
949
|
-
if (
|
|
963
|
+
if (Dt(t.type, r) !== Dt(n.type, r)) {
|
|
950
964
|
let r = t.narrowedFrom;
|
|
951
965
|
if (r && r.from === n.type) {
|
|
952
966
|
let i = {
|
|
@@ -969,7 +983,7 @@ BEGIN
|
|
|
969
983
|
o.push(L(r, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: `acknowledge it on the column: \`.narrowedFrom('${n.type}', { using: '${t.name}::${t.type}' })\` (drop \`using\` if the cast is implicit), or use a file-based migration` }));
|
|
970
984
|
}
|
|
971
985
|
}
|
|
972
|
-
if (!
|
|
986
|
+
if (!pt(t, n)) {
|
|
973
987
|
let n = {
|
|
974
988
|
kind: "alter-column-default",
|
|
975
989
|
table: e,
|
|
@@ -979,13 +993,13 @@ BEGIN
|
|
|
979
993
|
};
|
|
980
994
|
o.push(L(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
|
|
981
995
|
}
|
|
982
|
-
if (!
|
|
996
|
+
if (!mt(t.oneOf, n.oneOf)) {
|
|
983
997
|
n.oneOf && n.oneOf.length > 0 && o.push(L({
|
|
984
998
|
kind: "drop-check",
|
|
985
999
|
table: e,
|
|
986
1000
|
column: t.name
|
|
987
1001
|
}, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
|
|
988
|
-
let r =
|
|
1002
|
+
let r = gt(e, t);
|
|
989
1003
|
r && o.push(r);
|
|
990
1004
|
}
|
|
991
1005
|
if (JSON.stringify(I(t.references)) !== JSON.stringify(I(n.references)) && (n.references && o.push(L({
|
|
@@ -1008,7 +1022,7 @@ BEGIN
|
|
|
1008
1022
|
}, "lossy", r === "delete" ? `add FK ${e}.${t.name} → ${n}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${n}` : `add FK ${e}.${t.name} → ${n}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${n}`)) : o.push(L(i, "needs-backfill", `add FK ${e}.${t.name} → ${n} — existing rows must already reference a valid ${n} (else set orphanPolicy:'null'/'delete')`));
|
|
1009
1023
|
}
|
|
1010
1024
|
return o;
|
|
1011
|
-
},
|
|
1025
|
+
}, kt = (e, t, n) => {
|
|
1012
1026
|
let r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = new Set(n.removed.map((e) => e.name)), s = new Set(n.added.map((e) => e.name));
|
|
1013
1027
|
for (let [n, c] of Object.entries(t)) {
|
|
1014
1028
|
let t = c.renamedFrom;
|
|
@@ -1024,7 +1038,7 @@ BEGIN
|
|
|
1024
1038
|
consumedAddedNames: i,
|
|
1025
1039
|
consumedRemovedNames: a
|
|
1026
1040
|
};
|
|
1027
|
-
},
|
|
1041
|
+
}, At = (e) => {
|
|
1028
1042
|
let t = {
|
|
1029
1043
|
safe: 0,
|
|
1030
1044
|
needsDefault: 0,
|
|
@@ -1059,37 +1073,37 @@ BEGIN
|
|
|
1059
1073
|
break;
|
|
1060
1074
|
}
|
|
1061
1075
|
return t;
|
|
1062
|
-
},
|
|
1063
|
-
let t =
|
|
1076
|
+
}, jt = (e) => {
|
|
1077
|
+
let t = N(e.declared, e.dialect), n = ut(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? wt, a = [];
|
|
1064
1078
|
for (let e of t.tables) if (!r.has(e.name)) {
|
|
1065
|
-
a.push(
|
|
1079
|
+
a.push(St(e.name, e.columns, e.indexes, e.primaryKey));
|
|
1066
1080
|
for (let t of e.columns) {
|
|
1067
|
-
let n =
|
|
1081
|
+
let n = gt(e.name, t);
|
|
1068
1082
|
n && a.push(n);
|
|
1069
1083
|
}
|
|
1070
1084
|
}
|
|
1071
1085
|
let o = new Set(e.ignoreTables ?? []);
|
|
1072
|
-
for (let t of e.live.tables) n.has(t.name) ||
|
|
1086
|
+
for (let t of e.live.tables) n.has(t.name) || P(t.name) || o.has(t.name) || a.push(Ct(t.name));
|
|
1073
1087
|
for (let o of t.tables) {
|
|
1074
1088
|
let t = r.get(o.name);
|
|
1075
1089
|
if (!t) continue;
|
|
1076
|
-
let s = n.get(o.name), c =
|
|
1090
|
+
let s = n.get(o.name), c = vt(o, t), l = yt(o, t), u = kt(s.table, s.columnDefs, c);
|
|
1077
1091
|
a.push(...u.ops);
|
|
1078
1092
|
for (let e of c.removed) {
|
|
1079
1093
|
if (u.consumedRemovedNames.has(e.name)) continue;
|
|
1080
1094
|
let t = s.columnDefs[e.name];
|
|
1081
|
-
a.push(
|
|
1095
|
+
a.push(xt(o.name, e, t));
|
|
1082
1096
|
}
|
|
1083
1097
|
for (let e of c.added) {
|
|
1084
1098
|
if (u.consumedAddedNames.has(e.name)) continue;
|
|
1085
1099
|
let t = s.columnDefs[e.name];
|
|
1086
|
-
a.push(
|
|
1087
|
-
let n =
|
|
1100
|
+
a.push(bt(o.name, e, t));
|
|
1101
|
+
let n = gt(o.name, e);
|
|
1088
1102
|
n && a.push(n);
|
|
1089
1103
|
}
|
|
1090
|
-
for (let e of l.added) a.push(
|
|
1091
|
-
for (let e of l.removed) a.push(
|
|
1092
|
-
for (let { declared: n, live: r } of c.changed) a.push(...
|
|
1104
|
+
for (let e of l.added) a.push(Tt(o.name, e, t.rowCount, i));
|
|
1105
|
+
for (let e of l.removed) a.push(Et(o.name, e));
|
|
1106
|
+
for (let { declared: n, live: r } of c.changed) a.push(...Ot(o.name, n, r, e.dialect, t.rowCount, i));
|
|
1093
1107
|
}
|
|
1094
1108
|
let s = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), c = new Map(t.tables.map((e) => [e.name, e])), l = (e) => {
|
|
1095
1109
|
let t = c.get(e);
|
|
@@ -1097,8 +1111,8 @@ BEGIN
|
|
|
1097
1111
|
column: e.name,
|
|
1098
1112
|
target: e.references.table
|
|
1099
1113
|
}] : []) : [];
|
|
1100
|
-
}, u =
|
|
1101
|
-
for (let e of t.tables) if (s.has(e.name)) for (let t of e.columns) !t.references || !u.has(
|
|
1114
|
+
}, u = ne([...s], l), d = [];
|
|
1115
|
+
for (let e of t.tables) if (s.has(e.name)) for (let t of e.columns) !t.references || !u.has(S(e.name, t.name)) || d.push(L({
|
|
1102
1116
|
kind: "add-foreign-key",
|
|
1103
1117
|
table: e.name,
|
|
1104
1118
|
column: t.name,
|
|
@@ -1113,8 +1127,8 @@ BEGIN
|
|
|
1113
1127
|
let n = a[t];
|
|
1114
1128
|
if (n.op.kind !== "create-table") continue;
|
|
1115
1129
|
let r = n.op;
|
|
1116
|
-
if (!r.columns.some((e) => u.has(
|
|
1117
|
-
let i = r.columns.map((t) => u.has(
|
|
1130
|
+
if (!r.columns.some((e) => u.has(S(r.table, e.name)))) continue;
|
|
1131
|
+
let i = r.columns.map((t) => u.has(S(r.table, t.name)) ? e(t) : t);
|
|
1118
1132
|
a[t] = {
|
|
1119
1133
|
...n,
|
|
1120
1134
|
op: {
|
|
@@ -1134,7 +1148,7 @@ BEGIN
|
|
|
1134
1148
|
let i = new Set(t).add(e), a = 0;
|
|
1135
1149
|
for (let t of r.columns) {
|
|
1136
1150
|
let n = t.references?.table;
|
|
1137
|
-
n && n !== e && !u.has(
|
|
1151
|
+
n && n !== e && !u.has(S(e, t.name)) && (a = Math.max(a, m(n, i) + 1));
|
|
1138
1152
|
}
|
|
1139
1153
|
return p.set(e, a), a;
|
|
1140
1154
|
}, h = (e) => e === "create-table" ? 0 : e === "drop-table" ? 2 : 1, g = (e) => {
|
|
@@ -1169,11 +1183,11 @@ BEGIN
|
|
|
1169
1183
|
});
|
|
1170
1184
|
return {
|
|
1171
1185
|
operations: v,
|
|
1172
|
-
fromFingerprint:
|
|
1173
|
-
toFingerprint:
|
|
1174
|
-
summary:
|
|
1186
|
+
fromFingerprint: j(e.live),
|
|
1187
|
+
toFingerprint: j(t),
|
|
1188
|
+
summary: At(v)
|
|
1175
1189
|
};
|
|
1176
|
-
},
|
|
1190
|
+
}, Mt = (e) => {
|
|
1177
1191
|
let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
|
|
1178
1192
|
if (!t) return null;
|
|
1179
1193
|
let n = [...e.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
|
|
@@ -1181,7 +1195,7 @@ BEGIN
|
|
|
1181
1195
|
column: t[1],
|
|
1182
1196
|
values: n
|
|
1183
1197
|
};
|
|
1184
|
-
},
|
|
1198
|
+
}, Nt = (e, t) => {
|
|
1185
1199
|
if (t === "vector") return "vector";
|
|
1186
1200
|
switch (e) {
|
|
1187
1201
|
case "text":
|
|
@@ -1216,25 +1230,25 @@ BEGIN
|
|
|
1216
1230
|
case "SET DEFAULT": return "noAction";
|
|
1217
1231
|
default: return "noAction";
|
|
1218
1232
|
}
|
|
1219
|
-
},
|
|
1233
|
+
}, Pt = (e, t) => {
|
|
1220
1234
|
let n = e !== void 0 && e !== "" ? Number(e) : NaN;
|
|
1221
1235
|
return Number.isInteger(n) && n > 0 ? n : t;
|
|
1222
|
-
},
|
|
1236
|
+
}, Ft = () => Pt(process.env.VOLTRO_INTROSPECT_BATCH, 20), It = 300, Lt = () => {
|
|
1223
1237
|
let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
|
|
1224
|
-
return e !== void 0 && e.trim() === "0" ? 0 :
|
|
1225
|
-
},
|
|
1238
|
+
return e !== void 0 && e.trim() === "0" ? 0 : Pt(e, 3e4);
|
|
1239
|
+
}, Rt = (e, t) => {
|
|
1226
1240
|
let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
|
|
1227
1241
|
for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
|
|
1228
1242
|
return r;
|
|
1229
|
-
},
|
|
1230
|
-
let t =
|
|
1243
|
+
}, zt = (e) => {
|
|
1244
|
+
let t = Lt(), n = d.gen(function* () {
|
|
1231
1245
|
t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
|
|
1232
|
-
let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i =
|
|
1246
|
+
let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Ft(), a = (e, t) => d.gen(function* () {
|
|
1233
1247
|
let r = [];
|
|
1234
|
-
for (let a of
|
|
1248
|
+
for (let a of Rt(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
|
|
1235
1249
|
return r;
|
|
1236
1250
|
}), o = [];
|
|
1237
|
-
for (let t = 0;; t +=
|
|
1251
|
+
for (let t = 0;; t += It) {
|
|
1238
1252
|
let n = yield* e`
|
|
1239
1253
|
SELECT c.relname AS table_name,
|
|
1240
1254
|
COALESCE(c.reltuples::bigint, 0) AS row_count
|
|
@@ -1242,9 +1256,9 @@ BEGIN
|
|
|
1242
1256
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
1243
1257
|
WHERE n.nspname = current_schema() AND c.relkind = 'r'
|
|
1244
1258
|
ORDER BY c.relname
|
|
1245
|
-
LIMIT ${r(
|
|
1259
|
+
LIMIT ${r(It)} OFFSET ${r(t)}
|
|
1246
1260
|
`;
|
|
1247
|
-
if (o.push(...n), n.length <
|
|
1261
|
+
if (o.push(...n), n.length < It) break;
|
|
1248
1262
|
}
|
|
1249
1263
|
let s = /* @__PURE__ */ new Set(), c = [];
|
|
1250
1264
|
for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
|
|
@@ -1329,7 +1343,7 @@ BEGIN
|
|
|
1329
1343
|
AND c.relname IN ${t}
|
|
1330
1344
|
)
|
|
1331
1345
|
SELECT * FROM ix ORDER BY table_name, index_name, position
|
|
1332
|
-
`), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(),
|
|
1346
|
+
`), _ = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), te = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map();
|
|
1333
1347
|
for (let e of u) {
|
|
1334
1348
|
let t = _.get(e.table_name);
|
|
1335
1349
|
t || (t = [], _.set(e.table_name, t)), t.push(e);
|
|
@@ -1338,25 +1352,25 @@ BEGIN
|
|
|
1338
1352
|
let t = v.get(e.table_name);
|
|
1339
1353
|
t || (t = /* @__PURE__ */ new Set(), v.set(e.table_name, t)), t.add(e.column_name);
|
|
1340
1354
|
}
|
|
1341
|
-
let
|
|
1355
|
+
let S = /* @__PURE__ */ new Map();
|
|
1342
1356
|
for (let e of p) {
|
|
1343
|
-
let t = `${e.table_name}${e.constraint_name}`, n =
|
|
1357
|
+
let t = `${e.table_name}${e.constraint_name}`, n = S.get(t);
|
|
1344
1358
|
n || (n = {
|
|
1345
1359
|
table: e.table_name,
|
|
1346
1360
|
columns: []
|
|
1347
|
-
},
|
|
1361
|
+
}, S.set(t, n)), n.columns.push({
|
|
1348
1362
|
name: e.column_name,
|
|
1349
1363
|
position: e.position
|
|
1350
1364
|
});
|
|
1351
1365
|
}
|
|
1352
|
-
for (let [e, t] of
|
|
1366
|
+
for (let [e, t] of S) {
|
|
1353
1367
|
let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
|
|
1354
1368
|
if (n.length === 1) {
|
|
1355
1369
|
let e = y.get(t.table);
|
|
1356
1370
|
e || (e = /* @__PURE__ */ new Set(), y.set(t.table, e)), e.add(n[0]);
|
|
1357
1371
|
} else {
|
|
1358
|
-
let r =
|
|
1359
|
-
r || (r = [],
|
|
1372
|
+
let r = b.get(t.table);
|
|
1373
|
+
r || (r = [], b.set(t.table, r)), r.push({
|
|
1360
1374
|
name: e.slice(e.indexOf("\0") + 1),
|
|
1361
1375
|
table: t.table,
|
|
1362
1376
|
columns: n,
|
|
@@ -1365,19 +1379,19 @@ BEGIN
|
|
|
1365
1379
|
}
|
|
1366
1380
|
}
|
|
1367
1381
|
for (let e of g) {
|
|
1368
|
-
let t =
|
|
1369
|
-
t || (t = [],
|
|
1382
|
+
let t = te.get(e.source_table);
|
|
1383
|
+
t || (t = [], te.set(e.source_table, t)), t.push(e);
|
|
1370
1384
|
}
|
|
1371
1385
|
for (let e of ee) {
|
|
1372
|
-
let t =
|
|
1373
|
-
t || (t = /* @__PURE__ */ new Map(),
|
|
1386
|
+
let t = x.get(e.table_name);
|
|
1387
|
+
t || (t = /* @__PURE__ */ new Map(), x.set(e.table_name, t));
|
|
1374
1388
|
let n = t.get(e.index_name);
|
|
1375
1389
|
n || (n = [], t.set(e.index_name, n)), n.push(e);
|
|
1376
1390
|
}
|
|
1377
|
-
let
|
|
1391
|
+
let ne = [];
|
|
1378
1392
|
for (let e of c) {
|
|
1379
|
-
let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a =
|
|
1380
|
-
let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" :
|
|
1393
|
+
let t = /* @__PURE__ */ new Set(), n = (_.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = v.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = te.get(e.table_name) ?? [], o = new Map(a.map((e) => [e.source_column, e])), s = new Set(n.filter((e) => e.udt_name === "tsvector").map((e) => e.column_name)), c = n.filter((e) => !s.has(e.column_name)).map((t) => {
|
|
1394
|
+
let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : Nt(t.data_type, t.udt_name), c = a ? {
|
|
1381
1395
|
table: a.target_table,
|
|
1382
1396
|
column: a.target_column,
|
|
1383
1397
|
onDelete: R(a.delete_rule),
|
|
@@ -1393,7 +1407,7 @@ BEGIN
|
|
|
1393
1407
|
...c ? { references: c } : {},
|
|
1394
1408
|
...l ? { oneOf: l } : {}
|
|
1395
1409
|
};
|
|
1396
|
-
}), l = [], u =
|
|
1410
|
+
}), l = [], u = x.get(e.table_name);
|
|
1397
1411
|
if (u) for (let [t, n] of u) {
|
|
1398
1412
|
let r = /* @__PURE__ */ new Set(), i = [...n].filter((e) => e.column_name !== null && e.position !== null).sort((e, t) => (e.position ?? 0) - (t.position ?? 0)).filter((e) => {
|
|
1399
1413
|
let t = e.position;
|
|
@@ -1409,7 +1423,7 @@ BEGIN
|
|
|
1409
1423
|
...a ? { expression: !0 } : {}
|
|
1410
1424
|
});
|
|
1411
1425
|
}
|
|
1412
|
-
for (let t of
|
|
1426
|
+
for (let t of b.get(e.table_name) ?? []) l.push(t);
|
|
1413
1427
|
r.size > 0 && l.push({
|
|
1414
1428
|
name: `${e.table_name}_pkey`,
|
|
1415
1429
|
table: e.table_name,
|
|
@@ -1417,20 +1431,20 @@ BEGIN
|
|
|
1417
1431
|
unique: !0
|
|
1418
1432
|
});
|
|
1419
1433
|
let d = Number(e.row_count ?? 0);
|
|
1420
|
-
|
|
1434
|
+
ne.push({
|
|
1421
1435
|
name: e.table_name,
|
|
1422
1436
|
columns: c,
|
|
1423
1437
|
indexes: l,
|
|
1424
1438
|
...d > 0 ? { rowCount: d } : {}
|
|
1425
1439
|
});
|
|
1426
1440
|
}
|
|
1427
|
-
return { tables:
|
|
1441
|
+
return { tables: ne };
|
|
1428
1442
|
});
|
|
1429
1443
|
return (t > 0 ? e.withTransaction(n) : n).pipe(d.catchAll((e) => {
|
|
1430
1444
|
let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
|
|
1431
1445
|
return n.includes("statement timeout") || n.includes("57014") ? d.die(/* @__PURE__ */ Error(`schema introspection exceeded VOLTRO_INTROSPECT_TIMEOUT_MS (${t}ms) — the schema is very large / FK-dense or the database is slow. Raise VOLTRO_INTROSPECT_TIMEOUT_MS, set it to 0 to disable the ceiling, or use DB_DIRECT_URL for a non-pooler connection.`)) : d.fail(e);
|
|
1432
1446
|
}));
|
|
1433
|
-
},
|
|
1447
|
+
}, Bt = (e, t) => {
|
|
1434
1448
|
switch (e.toLowerCase()) {
|
|
1435
1449
|
case "varchar":
|
|
1436
1450
|
case "char":
|
|
@@ -1466,7 +1480,7 @@ BEGIN
|
|
|
1466
1480
|
let t = e, n = {};
|
|
1467
1481
|
for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
|
|
1468
1482
|
return n;
|
|
1469
|
-
}),
|
|
1483
|
+
}), Vt = (e) => d.gen(function* () {
|
|
1470
1484
|
let t = z(yield* e`
|
|
1471
1485
|
SELECT table_name, COALESCE(table_rows, 0) AS table_rows
|
|
1472
1486
|
FROM information_schema.tables
|
|
@@ -1499,7 +1513,7 @@ BEGIN
|
|
|
1499
1513
|
o.add(`${e.table_name}.${t[1]}`);
|
|
1500
1514
|
continue;
|
|
1501
1515
|
}
|
|
1502
|
-
let n =
|
|
1516
|
+
let n = Mt(e.check_clause);
|
|
1503
1517
|
n && s.set(`${e.table_name}.${n.column}`, n.values);
|
|
1504
1518
|
}
|
|
1505
1519
|
let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
|
|
@@ -1522,7 +1536,7 @@ BEGIN
|
|
|
1522
1536
|
let t = c.get(e.table_name) ?? [], n = l.get(e.table_name) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = t.filter((e) => e.column_key === "PRI").map((e) => e.column_name), a = /* @__PURE__ */ new Set(), d = u.get(e.table_name);
|
|
1523
1537
|
if (d) for (let e of d.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
|
|
1524
1538
|
let p = t.map((t) => {
|
|
1525
|
-
let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" :
|
|
1539
|
+
let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : Bt(t.data_type, t.column_type), u = c ? {
|
|
1526
1540
|
table: c.target_table,
|
|
1527
1541
|
column: c.target_column,
|
|
1528
1542
|
onDelete: R(c.delete_rule),
|
|
@@ -1563,10 +1577,10 @@ BEGIN
|
|
|
1563
1577
|
});
|
|
1564
1578
|
}
|
|
1565
1579
|
return { tables: f };
|
|
1566
|
-
}),
|
|
1580
|
+
}), Ht = (e) => {
|
|
1567
1581
|
let t = e.toUpperCase();
|
|
1568
1582
|
return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
|
|
1569
|
-
},
|
|
1583
|
+
}, Ut = (e) => d.gen(function* () {
|
|
1570
1584
|
let t = yield* e`
|
|
1571
1585
|
SELECT name, sql FROM sqlite_master
|
|
1572
1586
|
WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
|
|
@@ -1583,7 +1597,7 @@ BEGIN
|
|
|
1583
1597
|
d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
|
|
1584
1598
|
}
|
|
1585
1599
|
let p = o.map((e) => {
|
|
1586
|
-
let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" :
|
|
1600
|
+
let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : Ht(e.type), a = r ? {
|
|
1587
1601
|
table: r.table,
|
|
1588
1602
|
column: r.to,
|
|
1589
1603
|
onDelete: R(r.on_delete),
|
|
@@ -1622,7 +1636,7 @@ BEGIN
|
|
|
1622
1636
|
});
|
|
1623
1637
|
}
|
|
1624
1638
|
return { tables: r };
|
|
1625
|
-
}),
|
|
1639
|
+
}), Wt = (e) => {
|
|
1626
1640
|
switch (e.toLowerCase()) {
|
|
1627
1641
|
case "int":
|
|
1628
1642
|
case "smallint":
|
|
@@ -1644,7 +1658,7 @@ BEGIN
|
|
|
1644
1658
|
case "image": return "bytes";
|
|
1645
1659
|
default: return "text";
|
|
1646
1660
|
}
|
|
1647
|
-
}, B = (e) => e === !0 || e === 1,
|
|
1661
|
+
}, B = (e) => e === !0 || e === 1, Gt = (e) => d.gen(function* () {
|
|
1648
1662
|
let t = yield* e`
|
|
1649
1663
|
SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
|
|
1650
1664
|
WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
|
|
@@ -1704,12 +1718,12 @@ BEGIN
|
|
|
1704
1718
|
else B(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
|
|
1705
1719
|
}
|
|
1706
1720
|
let p = t.map((t) => {
|
|
1707
|
-
let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" :
|
|
1721
|
+
let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : Wt(t.data_type), s = i ? {
|
|
1708
1722
|
table: i.target_table,
|
|
1709
1723
|
column: i.target_column,
|
|
1710
|
-
onDelete:
|
|
1711
|
-
onUpdate:
|
|
1712
|
-
} : void 0, c = t.column_default === null ? null :
|
|
1724
|
+
onDelete: Kt(i.delete_rule),
|
|
1725
|
+
onUpdate: Kt(i.update_rule)
|
|
1726
|
+
} : void 0, c = t.column_default === null ? null : qt(t.column_default), l = o.get(`${e}.${t.column_name}`);
|
|
1713
1727
|
return {
|
|
1714
1728
|
name: t.column_name,
|
|
1715
1729
|
type: a,
|
|
@@ -1742,23 +1756,31 @@ BEGIN
|
|
|
1742
1756
|
});
|
|
1743
1757
|
}
|
|
1744
1758
|
return { tables: u };
|
|
1745
|
-
}),
|
|
1759
|
+
}), Kt = (e) => {
|
|
1746
1760
|
switch (e.toUpperCase().replace(/_/g, " ")) {
|
|
1747
1761
|
case "CASCADE": return "cascade";
|
|
1748
1762
|
case "SET NULL": return "setNull";
|
|
1749
1763
|
case "SET DEFAULT": return "noAction";
|
|
1750
1764
|
default: return "noAction";
|
|
1751
1765
|
}
|
|
1752
|
-
},
|
|
1766
|
+
}, qt = (e) => {
|
|
1753
1767
|
let t = e.trim();
|
|
1754
1768
|
for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
|
|
1755
1769
|
return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
|
|
1756
|
-
},
|
|
1757
|
-
mysql: () =>
|
|
1758
|
-
mssql: () =>
|
|
1759
|
-
sqlite: () =>
|
|
1760
|
-
orElse: () =>
|
|
1761
|
-
}), Jt = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`,
|
|
1770
|
+
}, V = (e) => e.onDialectOrElse({
|
|
1771
|
+
mysql: () => Vt(e),
|
|
1772
|
+
mssql: () => Gt(e),
|
|
1773
|
+
sqlite: () => Ut(e),
|
|
1774
|
+
orElse: () => zt(e)
|
|
1775
|
+
}), Jt = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, H = (e, t) => {
|
|
1776
|
+
if (!e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
|
|
1777
|
+
let n = e.type === "vector" && e.vectorDim === void 0 ? "vector dimension" : e.type === "array" && e.arrayElement === void 0 ? "array element type" : e.type === "enum" && e.enumName === void 0 && e.enumValues === void 0 ? "enum name/values" : void 0;
|
|
1778
|
+
if (n !== void 0) throw Error(`migration applier: cannot render '${e.name}' (${e.type}) — the schema snapshot carries no ${n}. Rendering it as 'text' would emit DDL that applies successfully and changes nothing, so this fails instead. This is a framework bug: declaredSchema.ts must carry the parameter into the ColumnSnapshot.`);
|
|
1779
|
+
return E(e, t);
|
|
1780
|
+
}, U = (e) => {
|
|
1781
|
+
let t = H(e, "postgres");
|
|
1782
|
+
return t === void 0 ? Yt(e) : t;
|
|
1783
|
+
}, Yt = (e) => {
|
|
1762
1784
|
switch (e.type) {
|
|
1763
1785
|
case "id": return "text";
|
|
1764
1786
|
case "text": return "text";
|
|
@@ -1772,13 +1794,15 @@ BEGIN
|
|
|
1772
1794
|
case "json": return "jsonb";
|
|
1773
1795
|
case "bytes": return "bytea";
|
|
1774
1796
|
case "reference": return "text";
|
|
1775
|
-
case "vector":
|
|
1776
|
-
case "enum":
|
|
1777
|
-
case "array":
|
|
1797
|
+
case "vector":
|
|
1798
|
+
case "enum":
|
|
1799
|
+
case "array": throw Error(`snapshotPgType: '${e.type}' must go through parameterisedSqlType`);
|
|
1778
1800
|
case "interval": return "interval";
|
|
1779
1801
|
case "raw": return e.rawDdl ?? "text";
|
|
1780
1802
|
}
|
|
1781
|
-
},
|
|
1803
|
+
}, W = (e) => {
|
|
1804
|
+
let t = H(e, "mariadb");
|
|
1805
|
+
if (t !== void 0) return t;
|
|
1782
1806
|
switch (e.type) {
|
|
1783
1807
|
case "id": return "VARCHAR(64)";
|
|
1784
1808
|
case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
|
|
@@ -1792,80 +1816,89 @@ BEGIN
|
|
|
1792
1816
|
case "json": return "JSON";
|
|
1793
1817
|
case "bytes": return "LONGBLOB";
|
|
1794
1818
|
case "reference": return "VARCHAR(64)";
|
|
1795
|
-
case "vector":
|
|
1796
|
-
case "enum":
|
|
1797
|
-
case "array":
|
|
1819
|
+
case "vector":
|
|
1820
|
+
case "enum":
|
|
1821
|
+
case "array": throw Error(`snapshotMysqlType: '${e.type}' must go through parameterisedSqlType`);
|
|
1798
1822
|
case "interval": return "BIGINT";
|
|
1799
1823
|
case "raw": return e.rawDdl ?? "LONGTEXT";
|
|
1800
1824
|
}
|
|
1801
|
-
},
|
|
1802
|
-
let
|
|
1825
|
+
}, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, Xt = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, Zt = (e) => `ALTER TABLE ${K(e.table)} DROP COLUMN IF EXISTS ${K(e.column)}, ALGORITHM=COPY;`, Qt = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, $t = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Tn(t)}`)};`, en = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${tn(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, tn = (e, t) => {
|
|
1826
|
+
let n = t(e.defaultValue);
|
|
1827
|
+
if (n === null) throw Error(`migration applier: cannot render the declared default for '${e.table}.${e.column}' (${JSON.stringify(e.defaultValue)}). Emitting 'DEFAULT NULL' would apply cleanly and drop the default silently, so this fails instead. This is a framework bug — report the column type + default.`);
|
|
1828
|
+
return n;
|
|
1829
|
+
}, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], nn = (e, t, n) => {
|
|
1830
|
+
let r = q(e, t, n);
|
|
1831
|
+
return r ? nt(n, r) : void 0;
|
|
1832
|
+
}, rn = (e, t, n) => {
|
|
1833
|
+
let r = n ?? e.nullable, i = ye(e, "mariadb");
|
|
1803
1834
|
return [
|
|
1804
|
-
|
|
1805
|
-
|
|
1835
|
+
K(t),
|
|
1836
|
+
E(e, "mariadb"),
|
|
1806
1837
|
r ? null : "NOT NULL",
|
|
1807
1838
|
i
|
|
1808
1839
|
].filter(Boolean).join(" ");
|
|
1809
|
-
},
|
|
1840
|
+
}, an = (e, t) => e == null ? null : Array.isArray(e) ? on(e, t, "mariadb") : e === "now" ? "DEFAULT CURRENT_TIMESTAMP(6)" : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "mysql") : null, on = (e, t, n) => be(e, t ?? { type: "json" }, n), sn = (e, t) => e == null ? null : Array.isArray(e) ? on(e, t, "postgres") : e === "now" ? "DEFAULT now()" : typeof e == "boolean" || typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|::|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "postgres") : null, J = (e, t) => {
|
|
1810
1841
|
if (!e.generatedAs) return null;
|
|
1811
1842
|
let { expr: n, stored: r } = e.generatedAs;
|
|
1812
1843
|
return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
|
|
1813
|
-
},
|
|
1814
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
1815
|
-
let t =
|
|
1816
|
-
if (t) return `${
|
|
1817
|
-
let n = [
|
|
1844
|
+
}, cn = (e) => {
|
|
1845
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "postgres");
|
|
1846
|
+
let t = J(e, "postgres");
|
|
1847
|
+
if (t) return `${G(e.name)} ${U(e)} ${t}`;
|
|
1848
|
+
let n = [G(e.name), U(e)];
|
|
1818
1849
|
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
|
|
1819
|
-
let t =
|
|
1850
|
+
let t = sn(e.defaultValue, e);
|
|
1820
1851
|
t && n.push(t);
|
|
1821
1852
|
}
|
|
1822
|
-
return e.references && (n.push(`REFERENCES ${
|
|
1853
|
+
return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
|
|
1823
1854
|
cascade: "CASCADE",
|
|
1824
1855
|
restrict: "RESTRICT",
|
|
1825
1856
|
setNull: "SET NULL",
|
|
1826
1857
|
noAction: "NO ACTION"
|
|
1827
1858
|
}[e.references.onDelete]}`)), n.join(" ");
|
|
1828
|
-
},
|
|
1829
|
-
let t = e.columns.map((e) => ` ${
|
|
1830
|
-
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${
|
|
1859
|
+
}, ln = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", un = (e) => {
|
|
1860
|
+
let t = e.columns.map((e) => ` ${cn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${ln(e, G)}\n)`];
|
|
1861
|
+
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(An).join(", ")})`);
|
|
1831
1862
|
return n;
|
|
1832
|
-
},
|
|
1833
|
-
let t =
|
|
1863
|
+
}, dn = 191, fn = (e) => {
|
|
1864
|
+
let t = W(e).toUpperCase();
|
|
1834
1865
|
return t.endsWith("TEXT") || t.endsWith("BLOB");
|
|
1835
|
-
},
|
|
1836
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
1837
|
-
let t =
|
|
1838
|
-
if (t) return `${
|
|
1839
|
-
let n = [
|
|
1840
|
-
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !
|
|
1841
|
-
let t =
|
|
1866
|
+
}, pn = (e) => {
|
|
1867
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mariadb");
|
|
1868
|
+
let t = J(e, "mariadb");
|
|
1869
|
+
if (t) return `${K(e.name)} ${W(e)} ${t}`;
|
|
1870
|
+
let n = [K(e.name), W(e)];
|
|
1871
|
+
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !fn(e) && n.push("UNIQUE"), e.hasDefault) {
|
|
1872
|
+
let t = an(e.defaultValue, e);
|
|
1842
1873
|
t && n.push(t);
|
|
1843
1874
|
}
|
|
1844
|
-
return e.references && (n.push(`REFERENCES ${
|
|
1875
|
+
return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
|
|
1845
1876
|
cascade: "CASCADE",
|
|
1846
1877
|
restrict: "RESTRICT",
|
|
1847
1878
|
setNull: "SET NULL",
|
|
1848
1879
|
noAction: "NO ACTION"
|
|
1849
1880
|
}[e.references.onDelete]}`)), n.join(" ");
|
|
1850
|
-
},
|
|
1881
|
+
}, mn = (e) => {
|
|
1851
1882
|
let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
|
|
1852
1883
|
let n = t.get(e);
|
|
1853
|
-
return n &&
|
|
1854
|
-
}, r = e.columns.map((e) => ` ${
|
|
1855
|
-
for (let t of e.columns) t.unique && t.type !== "id" &&
|
|
1856
|
-
for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${
|
|
1884
|
+
return n && fn(n) ? `${K(e)}(${dn})` : K(e);
|
|
1885
|
+
}, r = e.columns.map((e) => ` ${pn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${r}${ln(e, n)}\n)`];
|
|
1886
|
+
for (let t of e.columns) t.unique && t.type !== "id" && fn(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${K(`${e.table}_${t.name}_key`)} ON ${K(e.table)} (${n(t.name)})`);
|
|
1887
|
+
for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(n).join(", ")})`);
|
|
1857
1888
|
return i;
|
|
1858
|
-
},
|
|
1889
|
+
}, hn = {
|
|
1859
1890
|
cascade: "CASCADE",
|
|
1860
1891
|
restrict: "RESTRICT",
|
|
1861
1892
|
setNull: "SET NULL",
|
|
1862
1893
|
noAction: "NO ACTION"
|
|
1863
|
-
},
|
|
1894
|
+
}, gn = {
|
|
1864
1895
|
cascade: "CASCADE",
|
|
1865
1896
|
restrict: "NO ACTION",
|
|
1866
1897
|
setNull: "SET NULL",
|
|
1867
1898
|
noAction: "NO ACTION"
|
|
1868
|
-
},
|
|
1899
|
+
}, _n = (e) => {
|
|
1900
|
+
let t = H(e, "sqlite");
|
|
1901
|
+
if (t !== void 0) return t;
|
|
1869
1902
|
switch (e.type) {
|
|
1870
1903
|
case "integer":
|
|
1871
1904
|
case "boolean": return "INTEGER";
|
|
@@ -1875,52 +1908,54 @@ BEGIN
|
|
|
1875
1908
|
case "bytes": return "BLOB";
|
|
1876
1909
|
default: return "TEXT";
|
|
1877
1910
|
}
|
|
1878
|
-
}, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object"
|
|
1879
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
1880
|
-
let t =
|
|
1881
|
-
if (t) return `${
|
|
1882
|
-
let n = [
|
|
1911
|
+
}, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? D(e, "sqlite") : null, vn = (e) => {
|
|
1912
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "sqlite");
|
|
1913
|
+
let t = J(e, "sqlite");
|
|
1914
|
+
if (t) return `${G(e.name)} ${_n(e)} ${t}`;
|
|
1915
|
+
let n = [G(e.name), _n(e)];
|
|
1883
1916
|
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
|
|
1884
1917
|
let t = Y(e.defaultValue, "CURRENT_TIMESTAMP");
|
|
1885
1918
|
t && n.push(t);
|
|
1886
1919
|
}
|
|
1887
|
-
if (e.references && (n.push(`REFERENCES ${
|
|
1920
|
+
if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${hn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
|
|
1888
1921
|
let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
|
|
1889
|
-
n.push(`CHECK (${
|
|
1922
|
+
n.push(`CHECK (${G(e.name)} IN (${t}))`);
|
|
1890
1923
|
}
|
|
1891
1924
|
return n.join(" ");
|
|
1892
|
-
},
|
|
1893
|
-
let t = e.columns.map((e) => ` ${
|
|
1894
|
-
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${
|
|
1925
|
+
}, yn = (e) => {
|
|
1926
|
+
let t = e.columns.map((e) => ` ${vn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${ln(e, G)}\n)`];
|
|
1927
|
+
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(G).join(", ")})`);
|
|
1895
1928
|
return n;
|
|
1896
1929
|
}, X = (e, t) => {
|
|
1897
1930
|
let n = t.find((t) => t.tableName === e);
|
|
1898
1931
|
if (!n) return [];
|
|
1899
|
-
let r =
|
|
1900
|
-
...
|
|
1932
|
+
let r = N([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
|
|
1933
|
+
...yn({
|
|
1901
1934
|
kind: "create-table",
|
|
1902
1935
|
table: i,
|
|
1903
1936
|
columns: r.columns,
|
|
1904
1937
|
indexes: [],
|
|
1905
1938
|
...r.primaryKey ? { primaryKey: r.primaryKey } : {}
|
|
1906
1939
|
}),
|
|
1907
|
-
`INSERT INTO ${
|
|
1908
|
-
`DROP TABLE ${
|
|
1909
|
-
`ALTER TABLE ${
|
|
1940
|
+
`INSERT INTO ${G(i)} (${a}) SELECT ${a} FROM ${G(e)}`,
|
|
1941
|
+
`DROP TABLE ${G(e)}`,
|
|
1942
|
+
`ALTER TABLE ${G(i)} RENAME TO ${G(e)}`
|
|
1910
1943
|
];
|
|
1911
|
-
for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${
|
|
1944
|
+
for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e)} (${t.columns.map(G).join(", ")})`);
|
|
1912
1945
|
return o;
|
|
1913
|
-
},
|
|
1946
|
+
}, bn = (e, t, n, r) => {
|
|
1914
1947
|
let i = r ?? e.nullable;
|
|
1915
|
-
return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${
|
|
1916
|
-
},
|
|
1948
|
+
return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${E(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
|
|
1949
|
+
}, xn = (e) => {
|
|
1917
1950
|
let t = `DECLARE @dc sysname; SELECT @dc = dc.name FROM sys.default_constraints dc JOIN sys.columns col ON col.object_id = dc.parent_object_id AND col.column_id = dc.parent_column_id WHERE dc.parent_object_id = OBJECT_ID(N'${e.table.replace(/'/g, "''")}') AND col.name = N'${e.column.replace(/'/g, "''")}'; IF @dc IS NOT NULL EXEC(N'ALTER TABLE ${Z(e.table)} DROP CONSTRAINT [' + @dc + ']');`;
|
|
1918
1951
|
if (!e.hasDefault) return t;
|
|
1919
1952
|
let n = Y(e.defaultValue, "SYSUTCDATETIME()");
|
|
1920
1953
|
if (!n) return t;
|
|
1921
1954
|
let r = n.replace(/^DEFAULT\s+/i, "");
|
|
1922
1955
|
return `${t} ALTER TABLE ${Z(e.table)} ADD DEFAULT ${r} FOR ${Z(e.column)};`;
|
|
1923
|
-
}, Z = (e) => `[${e.replace(/]/g, "]]")}]`,
|
|
1956
|
+
}, Z = (e) => `[${e.replace(/]/g, "]]")}]`, Sn = (e) => {
|
|
1957
|
+
let t = H(e, "mssql");
|
|
1958
|
+
if (t !== void 0) return t;
|
|
1924
1959
|
switch (e.type) {
|
|
1925
1960
|
case "id":
|
|
1926
1961
|
case "reference": return "NVARCHAR(64)";
|
|
@@ -1934,34 +1969,34 @@ BEGIN
|
|
|
1934
1969
|
case "bytes": return "VARBINARY(MAX)";
|
|
1935
1970
|
default: return "NVARCHAR(MAX)";
|
|
1936
1971
|
}
|
|
1937
|
-
},
|
|
1938
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
1939
|
-
let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" :
|
|
1972
|
+
}, Cn = (e, t) => {
|
|
1973
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return O(e.name, "mssql");
|
|
1974
|
+
let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Sn(e), r = J(e, "mssql");
|
|
1940
1975
|
if (r) return `${Z(e.name)} ${r}`;
|
|
1941
1976
|
let i = [Z(e.name), n];
|
|
1942
1977
|
if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
|
|
1943
1978
|
let t = Y(e.defaultValue, "SYSUTCDATETIME()");
|
|
1944
1979
|
t && i.push(t);
|
|
1945
1980
|
}
|
|
1946
|
-
return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${
|
|
1947
|
-
},
|
|
1948
|
-
let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${
|
|
1981
|
+
return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${gn[e.references.onDelete]}`)), i.join(" ");
|
|
1982
|
+
}, wn = (e) => {
|
|
1983
|
+
let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Cn(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${ln(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
|
|
1949
1984
|
for (let n of e.indexes) {
|
|
1950
1985
|
if (n.name === `${e.table}_pkey`) continue;
|
|
1951
1986
|
let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Z(n.name)} ON ${Z(e.table)} (${n.columns.map(Z).join(", ")})`;
|
|
1952
1987
|
a.push(`IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(n.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(r)}')`);
|
|
1953
1988
|
}
|
|
1954
1989
|
return a;
|
|
1955
|
-
},
|
|
1956
|
-
let r = `${e.table}${
|
|
1990
|
+
}, Tn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, En = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Dn = (e, t, n) => {
|
|
1991
|
+
let r = `${e.table}${Tn(t)}`;
|
|
1957
1992
|
return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
|
|
1958
|
-
},
|
|
1959
|
-
let r =
|
|
1960
|
-
return r ?
|
|
1961
|
-
},
|
|
1993
|
+
}, On = (e, t, n) => {
|
|
1994
|
+
let r = q(e, t, n);
|
|
1995
|
+
return r ? fn({ type: r.type }) : !1;
|
|
1996
|
+
}, kn = (e, t, n) => On(e, t, n) ? `${K(n)}(${dn})` : K(n), An = (e) => e.startsWith("(") ? e : G(e), jn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map(An).join(", ")});`, Mn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => kn(t, e.table, n)).join(", ")});`, Nn = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, Pn = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, Fn = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, In = (e) => {
|
|
1962
1997
|
let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Z(e.index.name)} ON ${Z(e.table)} (${e.index.columns.map(Z).join(", ")})`;
|
|
1963
1998
|
return `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'${t(e.index.name)}' AND object_id = OBJECT_ID(N'${t(e.table)}')) EXEC(N'${t(n)}');`;
|
|
1964
|
-
},
|
|
1999
|
+
}, Ln = (e, t, n) => {
|
|
1965
2000
|
let r = n.find((t) => t.tableName === e);
|
|
1966
2001
|
if (!r) return [];
|
|
1967
2002
|
let i = [];
|
|
@@ -1970,13 +2005,13 @@ BEGIN
|
|
|
1970
2005
|
t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Z(e)} ALTER COLUMN ${Z(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
|
|
1971
2006
|
}
|
|
1972
2007
|
return i;
|
|
1973
|
-
},
|
|
1974
|
-
let t = e.fields.map((e) =>
|
|
1975
|
-
return `ALTER TABLE ${
|
|
1976
|
-
},
|
|
1977
|
-
let n = e.fields.map((n) =>
|
|
1978
|
-
return `ALTER TABLE ${
|
|
1979
|
-
},
|
|
2008
|
+
}, Rn = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, zn = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${kn(t, e.table, e.column)});`, Bn = (e) => {
|
|
2009
|
+
let t = e.fields.map((e) => G(e)).join(", ");
|
|
2010
|
+
return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
|
|
2011
|
+
}, Vn = (e, t) => {
|
|
2012
|
+
let n = e.fields.map((n) => kn(t, e.table, n)).join(", ");
|
|
2013
|
+
return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
|
|
2014
|
+
}, Hn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, Un = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, Wn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, Gn = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, Kn = (e, t) => {
|
|
1980
2015
|
let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
|
|
1981
2016
|
if (e.orphanPolicy) {
|
|
1982
2017
|
let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
|
|
@@ -1994,11 +2029,11 @@ BEGIN
|
|
|
1994
2029
|
setNull: "SET NULL",
|
|
1995
2030
|
noAction: "NO ACTION"
|
|
1996
2031
|
}[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
|
|
1997
|
-
},
|
|
2032
|
+
}, qn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, Jn = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, Yn = (e, t) => {
|
|
1998
2033
|
let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
|
|
1999
2034
|
return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
|
|
2000
|
-
},
|
|
2001
|
-
let i = e.column, a = r === "mariadb", o = a ?
|
|
2035
|
+
}, Xn = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, Zn = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, Qn = (e, t, n, r) => {
|
|
2036
|
+
let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ? W(i) : r === "mssql" ? Sn(i) : r === "sqlite" ? _n(i) : U(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? an(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : sn(e, i), u = J(i, r);
|
|
2002
2037
|
if (u) {
|
|
2003
2038
|
let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
|
|
2004
2039
|
return {
|
|
@@ -2014,7 +2049,8 @@ BEGIN
|
|
|
2014
2049
|
};
|
|
2015
2050
|
}
|
|
2016
2051
|
if (t.classification === "needs-default") {
|
|
2017
|
-
let t = l(i.defaultValue)
|
|
2052
|
+
let t = l(i.defaultValue);
|
|
2053
|
+
if (t === null) throw Error(`migration applier: cannot render the declared default for '${e.table}.${i.name}' (${JSON.stringify(i.defaultValue)}) while adding it NOT NULL to a populated table. This is a framework bug — report the column type + default.`);
|
|
2018
2054
|
return {
|
|
2019
2055
|
pre: [`ALTER TABLE ${o(e.table)} ${c} ${o(i.name)} ${s} NOT NULL ${t};`],
|
|
2020
2056
|
post: []
|
|
@@ -2025,7 +2061,7 @@ BEGIN
|
|
|
2025
2061
|
post: f ? [f] : []
|
|
2026
2062
|
};
|
|
2027
2063
|
return d?.sql && (p.backfillKind = "sql", p.backfillSql = d.sql), d?.js && (p.backfillKind = "js", p.backfillJs = d.js), d?.batchSize !== void 0 && (p.batchSize = d.batchSize), d?.sleepMs !== void 0 && (p.sleepMs = d.sleepMs), p;
|
|
2028
|
-
},
|
|
2064
|
+
}, $n = (e) => {
|
|
2029
2065
|
let t = new Map(e.map((e) => [e.tableName, e]));
|
|
2030
2066
|
return (e, n) => {
|
|
2031
2067
|
let r = t.get(e);
|
|
@@ -2047,95 +2083,95 @@ BEGIN
|
|
|
2047
2083
|
};
|
|
2048
2084
|
}, Q = (e, t, n) => e.unsafe(t).pipe(d.tapError((e) => d.sync(() => {
|
|
2049
2085
|
process.stderr.write(_(`applier: statement failed (op=${n})`, t, e, 400));
|
|
2050
|
-
})), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }),
|
|
2051
|
-
let r = process.hrtime.bigint(), i =
|
|
2086
|
+
})), d.map(() => void 0)), $ = (e, t, n) => d.forEach(t, (t) => Q(e, t, n), { discard: !0 }), er = (e, t, n) => d.gen(function* () {
|
|
2087
|
+
let r = process.hrtime.bigint(), i = $n(n.declared), a = t.op;
|
|
2052
2088
|
switch (a.kind) {
|
|
2053
2089
|
case "create-table": {
|
|
2054
2090
|
let t = yield* e.onDialectOrElse({
|
|
2055
|
-
mysql: () => d.succeed(
|
|
2056
|
-
mssql: () => d.succeed(
|
|
2057
|
-
sqlite: () => d.succeed(
|
|
2058
|
-
orElse: () => d.succeed(
|
|
2091
|
+
mysql: () => d.succeed(mn(a)),
|
|
2092
|
+
mssql: () => d.succeed(wn(a)),
|
|
2093
|
+
sqlite: () => d.succeed(yn(a)),
|
|
2094
|
+
orElse: () => d.succeed(un(a))
|
|
2059
2095
|
});
|
|
2060
2096
|
for (let n of t) yield* Q(e, n, a.kind);
|
|
2061
2097
|
break;
|
|
2062
2098
|
}
|
|
2063
2099
|
case "drop-table": {
|
|
2064
|
-
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ?
|
|
2100
|
+
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Dn(a, n, e) : En(a, e);
|
|
2065
2101
|
yield* e.onDialectOrElse({
|
|
2066
|
-
mysql: () => Q(e, r(
|
|
2067
|
-
orElse: () => Q(e, r(
|
|
2102
|
+
mysql: () => Q(e, r(K), a.kind),
|
|
2103
|
+
orElse: () => Q(e, r(G), a.kind)
|
|
2068
2104
|
});
|
|
2069
2105
|
break;
|
|
2070
2106
|
}
|
|
2071
2107
|
case "drop-column": {
|
|
2072
2108
|
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
|
|
2073
2109
|
yield* e.onDialectOrElse({
|
|
2074
|
-
mysql: () => Q(e, t ?
|
|
2075
|
-
orElse: () => Q(e, t ?
|
|
2110
|
+
mysql: () => Q(e, t ? $t(a, n, K) : Zt(a), a.kind),
|
|
2111
|
+
orElse: () => Q(e, t ? $t(a, n, G) : Xt(a, G), a.kind)
|
|
2076
2112
|
});
|
|
2077
2113
|
break;
|
|
2078
2114
|
}
|
|
2079
2115
|
case "rename-column":
|
|
2080
2116
|
yield* e.onDialectOrElse({
|
|
2081
|
-
mysql: () => Q(e,
|
|
2117
|
+
mysql: () => Q(e, Qt(a, K), a.kind),
|
|
2082
2118
|
mssql: () => Q(e, `EXEC sp_rename N'${a.table.replace(/'/g, "''")}.${a.from.replace(/'/g, "''")}', N'${a.to.replace(/'/g, "''")}', 'COLUMN';`, a.kind),
|
|
2083
|
-
orElse: () => Q(e,
|
|
2119
|
+
orElse: () => Q(e, Qt(a, G), a.kind)
|
|
2084
2120
|
});
|
|
2085
2121
|
break;
|
|
2086
2122
|
case "add-index":
|
|
2087
2123
|
yield* e.onDialectOrElse({
|
|
2088
|
-
mysql: () => Q(e,
|
|
2089
|
-
mssql: () => $(e, [...
|
|
2090
|
-
orElse: () => Q(e,
|
|
2124
|
+
mysql: () => Q(e, Mn(a, n.declared), a.kind),
|
|
2125
|
+
mssql: () => $(e, [...Ln(a.table, a.index.columns, n.declared), In(a)], a.kind),
|
|
2126
|
+
orElse: () => Q(e, jn(a, t.classification === "online-required"), a.kind)
|
|
2091
2127
|
});
|
|
2092
2128
|
break;
|
|
2093
2129
|
case "drop-index":
|
|
2094
2130
|
yield* e.onDialectOrElse({
|
|
2095
|
-
mysql: () => Q(e,
|
|
2096
|
-
mssql: () => Q(e,
|
|
2097
|
-
orElse: () => Q(e,
|
|
2131
|
+
mysql: () => Q(e, Pn(a), a.kind),
|
|
2132
|
+
mssql: () => Q(e, Fn(a), a.kind),
|
|
2133
|
+
orElse: () => Q(e, Nn(a), a.kind)
|
|
2098
2134
|
});
|
|
2099
2135
|
break;
|
|
2100
2136
|
case "add-unique":
|
|
2101
2137
|
yield* e.onDialectOrElse({
|
|
2102
|
-
mysql: () => Q(e,
|
|
2138
|
+
mysql: () => Q(e, zn(a, n.declared), a.kind),
|
|
2103
2139
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2104
|
-
mssql: () => $(e, [...
|
|
2105
|
-
orElse: () => Q(e,
|
|
2140
|
+
mssql: () => $(e, [...Ln(a.table, [a.column], n.declared), Rn(a)], a.kind),
|
|
2141
|
+
orElse: () => Q(e, Rn(a), a.kind)
|
|
2106
2142
|
});
|
|
2107
2143
|
break;
|
|
2108
2144
|
case "drop-unique":
|
|
2109
2145
|
yield* e.onDialectOrElse({
|
|
2110
|
-
mysql: () => Q(e,
|
|
2146
|
+
mysql: () => Q(e, Gn(a), a.kind),
|
|
2111
2147
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2112
|
-
orElse: () => Q(e,
|
|
2148
|
+
orElse: () => Q(e, Wn(a), a.kind)
|
|
2113
2149
|
});
|
|
2114
2150
|
break;
|
|
2115
2151
|
case "add-unique-composite":
|
|
2116
2152
|
yield* e.onDialectOrElse({
|
|
2117
|
-
mysql: () => Q(e,
|
|
2153
|
+
mysql: () => Q(e, Vn(a, n.declared), a.kind),
|
|
2118
2154
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2119
|
-
mssql: () => $(e, [...
|
|
2120
|
-
orElse: () => Q(e,
|
|
2155
|
+
mssql: () => $(e, [...Ln(a.table, a.fields, n.declared), Bn(a)], a.kind),
|
|
2156
|
+
orElse: () => Q(e, Bn(a), a.kind)
|
|
2121
2157
|
});
|
|
2122
2158
|
break;
|
|
2123
2159
|
case "drop-unique-composite":
|
|
2124
2160
|
yield* e.onDialectOrElse({
|
|
2125
|
-
mysql: () => Q(e,
|
|
2161
|
+
mysql: () => Q(e, Un(a), a.kind),
|
|
2126
2162
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2127
|
-
orElse: () => Q(e,
|
|
2163
|
+
orElse: () => Q(e, Hn(a), a.kind)
|
|
2128
2164
|
});
|
|
2129
2165
|
break;
|
|
2130
2166
|
case "add-foreign-key":
|
|
2131
2167
|
yield* e.onDialectOrElse({
|
|
2132
|
-
mysql: () => $(e,
|
|
2168
|
+
mysql: () => $(e, Kn(a, K), a.kind),
|
|
2133
2169
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2134
|
-
orElse: () => $(e,
|
|
2170
|
+
orElse: () => $(e, Kn(a, G), a.kind)
|
|
2135
2171
|
});
|
|
2136
2172
|
break;
|
|
2137
2173
|
case "add-column": {
|
|
2138
|
-
let n =
|
|
2174
|
+
let n = Qn(a, t, i, yield* e.onDialectOrElse({
|
|
2139
2175
|
mysql: () => d.succeed("mariadb"),
|
|
2140
2176
|
mssql: () => d.succeed("mssql"),
|
|
2141
2177
|
sqlite: () => d.succeed("sqlite"),
|
|
@@ -2180,39 +2216,41 @@ BEGIN
|
|
|
2180
2216
|
case "alter-column-nullability":
|
|
2181
2217
|
yield* e.onDialectOrElse({
|
|
2182
2218
|
mysql: () => {
|
|
2183
|
-
let t =
|
|
2184
|
-
return t ? Q(e, `ALTER TABLE ${
|
|
2219
|
+
let t = q(n.declared, a.table, a.column);
|
|
2220
|
+
return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${rn(t, a.column, a.toNullable)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
|
|
2185
2221
|
},
|
|
2186
2222
|
mssql: () => {
|
|
2187
|
-
let t =
|
|
2188
|
-
return t ? Q(e,
|
|
2223
|
+
let t = q(n.declared, a.table, a.column);
|
|
2224
|
+
return t ? Q(e, bn(t, a.column, a.table, a.toNullable), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${a.table}.${a.column}'.`));
|
|
2189
2225
|
},
|
|
2190
2226
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2191
|
-
orElse: () => Q(e, `ALTER TABLE ${
|
|
2227
|
+
orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
|
|
2192
2228
|
});
|
|
2193
2229
|
break;
|
|
2194
|
-
case "alter-column-default":
|
|
2230
|
+
case "alter-column-default": {
|
|
2231
|
+
let t = nn(n.declared, a.table, a.column);
|
|
2195
2232
|
yield* e.onDialectOrElse({
|
|
2196
|
-
mysql: () => Q(e,
|
|
2197
|
-
mssql: () => Q(e,
|
|
2233
|
+
mysql: () => Q(e, en(a, K, (e) => an(e, t)), a.kind),
|
|
2234
|
+
mssql: () => Q(e, xn(a), a.kind),
|
|
2198
2235
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2199
|
-
orElse: () => Q(e,
|
|
2236
|
+
orElse: () => Q(e, en(a, G, (e) => sn(e, t)), a.kind)
|
|
2200
2237
|
});
|
|
2201
2238
|
break;
|
|
2239
|
+
}
|
|
2202
2240
|
case "alter-column-type": {
|
|
2203
|
-
let r =
|
|
2241
|
+
let r = U(nn(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
|
|
2204
2242
|
if (t.classification !== "online-required") {
|
|
2205
2243
|
yield* e.onDialectOrElse({
|
|
2206
2244
|
mysql: () => {
|
|
2207
|
-
let t =
|
|
2208
|
-
return t ? Q(e, `ALTER TABLE ${
|
|
2245
|
+
let t = q(n.declared, a.table, a.column);
|
|
2246
|
+
return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${rn(t, a.column)};`, a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
|
|
2209
2247
|
},
|
|
2210
2248
|
mssql: () => {
|
|
2211
|
-
let t =
|
|
2212
|
-
return t ? Q(e,
|
|
2249
|
+
let t = q(n.declared, a.table, a.column);
|
|
2250
|
+
return t ? Q(e, bn(t, a.column, a.table), a.kind) : d.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
|
|
2213
2251
|
},
|
|
2214
2252
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2215
|
-
orElse: () => Q(e, `ALTER TABLE ${
|
|
2253
|
+
orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} TYPE ${r}${i};`, a.kind)
|
|
2216
2254
|
});
|
|
2217
2255
|
break;
|
|
2218
2256
|
}
|
|
@@ -2221,35 +2259,35 @@ BEGIN
|
|
|
2221
2259
|
orElse: () => d.void
|
|
2222
2260
|
});
|
|
2223
2261
|
let o = `${a.column}__shadow`, s = `${a.column}__old`;
|
|
2224
|
-
yield* e.unsafe(`ALTER TABLE ${
|
|
2225
|
-
let c = a.using ??
|
|
2262
|
+
yield* e.unsafe(`ALTER TABLE ${G(a.table)} ADD COLUMN ${G(o)} ${r}`);
|
|
2263
|
+
let c = a.using ?? G(a.column), l;
|
|
2226
2264
|
for (;;) {
|
|
2227
2265
|
let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(o)} IS NULL ORDER BY ${e("id")} LIMIT 5000` : yield* e`SELECT ${e("id")} FROM ${e(a.table)} WHERE ${e(o)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} LIMIT 5000`;
|
|
2228
2266
|
if (t.length === 0) break;
|
|
2229
|
-
yield* e.unsafe(`UPDATE ${
|
|
2267
|
+
yield* e.unsafe(`UPDATE ${G(a.table)} SET ${G(o)} = ${c} WHERE ${G(a.column)} IS NOT NULL AND ${G(o)} IS NULL AND ${G("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
|
|
2230
2268
|
}
|
|
2231
|
-
yield* d.logInfo(`alter-column-type shadow ${a.table}.${a.column}: shadow populated`).pipe(d.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${
|
|
2269
|
+
yield* d.logInfo(`alter-column-type shadow ${a.table}.${a.column}: shadow populated`).pipe(d.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${G(a.table)} RENAME COLUMN ${G(a.column)} TO ${G(s)}`), yield* e.unsafe(`ALTER TABLE ${G(a.table)} RENAME COLUMN ${G(o)} TO ${G(a.column)}`), yield* e.unsafe(`ALTER TABLE ${G(a.table)} DROP COLUMN ${G(s)}`);
|
|
2232
2270
|
break;
|
|
2233
2271
|
}
|
|
2234
2272
|
case "drop-foreign-key":
|
|
2235
2273
|
yield* e.onDialectOrElse({
|
|
2236
|
-
mysql: () => Q(e,
|
|
2274
|
+
mysql: () => Q(e, Jn(a), a.kind),
|
|
2237
2275
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2238
|
-
orElse: () => Q(e,
|
|
2276
|
+
orElse: () => Q(e, qn(a), a.kind)
|
|
2239
2277
|
});
|
|
2240
2278
|
break;
|
|
2241
2279
|
case "add-check":
|
|
2242
2280
|
yield* e.onDialectOrElse({
|
|
2243
|
-
mysql: () => Q(e,
|
|
2281
|
+
mysql: () => Q(e, Yn(a, K), a.kind),
|
|
2244
2282
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2245
|
-
orElse: () => Q(e,
|
|
2283
|
+
orElse: () => Q(e, Yn(a, G), a.kind)
|
|
2246
2284
|
});
|
|
2247
2285
|
break;
|
|
2248
2286
|
case "drop-check":
|
|
2249
2287
|
yield* e.onDialectOrElse({
|
|
2250
|
-
mysql: () => Q(e,
|
|
2288
|
+
mysql: () => Q(e, Zn(a), a.kind),
|
|
2251
2289
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2252
|
-
orElse: () => Q(e,
|
|
2290
|
+
orElse: () => Q(e, Xn(a), a.kind)
|
|
2253
2291
|
});
|
|
2254
2292
|
break;
|
|
2255
2293
|
}
|
|
@@ -2258,10 +2296,10 @@ BEGIN
|
|
|
2258
2296
|
status: "applied",
|
|
2259
2297
|
durationMs: Number((process.hrtime.bigint() - r) / 1000000n)
|
|
2260
2298
|
};
|
|
2261
|
-
}),
|
|
2299
|
+
}), tr = (e, t, n) => d.gen(function* () {
|
|
2262
2300
|
let r = t.operations.filter((e) => e.blocked);
|
|
2263
2301
|
if (r.length > 0) return yield* d.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
|
|
2264
|
-
yield*
|
|
2302
|
+
yield* C(e);
|
|
2265
2303
|
let i = Date.now(), a = [];
|
|
2266
2304
|
try {
|
|
2267
2305
|
let r = yield* e.onDialectOrElse({
|
|
@@ -2271,15 +2309,20 @@ BEGIN
|
|
|
2271
2309
|
}), i = r ? t.operations.filter((e) => e.classification !== "online-required") : [], o = r ? t.operations.filter((e) => e.classification === "online-required") : t.operations;
|
|
2272
2310
|
i.length > 0 && (yield* e.withTransaction(d.gen(function* () {
|
|
2273
2311
|
let e = yield* p.SqlClient;
|
|
2274
|
-
for (let t of i) a.push(yield*
|
|
2312
|
+
for (let t of i) a.push(yield* er(e, t, n));
|
|
2275
2313
|
})));
|
|
2276
|
-
for (let t of o) a.push(yield*
|
|
2314
|
+
for (let t of o) a.push(yield* er(e, t, n));
|
|
2277
2315
|
} finally {
|
|
2278
|
-
yield*
|
|
2316
|
+
yield* w(e).pipe(d.orDie);
|
|
2279
2317
|
}
|
|
2280
|
-
let o =
|
|
2281
|
-
|
|
2282
|
-
|
|
2318
|
+
let o = yield* n.replan(e);
|
|
2319
|
+
if (o.operations.length > 0) {
|
|
2320
|
+
let e = o.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
|
|
2321
|
+
return yield* d.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${t.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${o.operations.length}:\n${e}${o.operations.length > 10 ? `\n … and ${o.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug: the DDL for these operations is a no-op. Report the operation kinds above with the column types involved.`));
|
|
2322
|
+
}
|
|
2323
|
+
let s = a.filter((e) => e.status === "applied").length, c = Date.now() - i, l = `plan_${Date.now().toString(36)}`, u = (/* @__PURE__ */ new Date()).toISOString(), f = yield* e.onDialectOrElse({
|
|
2324
|
+
mysql: () => d.succeed(u.replace("T", " ").replace("Z", "")),
|
|
2325
|
+
orElse: () => d.succeed(u)
|
|
2283
2326
|
});
|
|
2284
2327
|
return yield* e`
|
|
2285
2328
|
INSERT INTO ${e("_voltro_migration_plans")}
|
|
@@ -2287,33 +2330,34 @@ BEGIN
|
|
|
2287
2330
|
${e("appliedBy")}, ${e("environment")}, ${e("source")},
|
|
2288
2331
|
${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
|
|
2289
2332
|
VALUES
|
|
2290
|
-
(${
|
|
2333
|
+
(${l}, ${t.toFingerprint}, ${JSON.stringify(t.operations)},
|
|
2291
2334
|
${n.appliedBy}, ${n.environment}, ${n.source},
|
|
2292
|
-
${
|
|
2335
|
+
${c}, ${f}, ${n.notes ?? null})
|
|
2293
2336
|
`, {
|
|
2294
|
-
id:
|
|
2295
|
-
appliedAt:
|
|
2337
|
+
id: l,
|
|
2338
|
+
appliedAt: u,
|
|
2296
2339
|
fingerprint: t.toFingerprint,
|
|
2297
2340
|
operations: t.operations,
|
|
2298
2341
|
appliedBy: n.appliedBy,
|
|
2299
2342
|
environment: n.environment,
|
|
2300
|
-
durationMs:
|
|
2343
|
+
durationMs: c,
|
|
2344
|
+
appliedOps: s,
|
|
2301
2345
|
source: n.source,
|
|
2302
2346
|
...n.notes ? { notes: n.notes } : {}
|
|
2303
2347
|
};
|
|
2304
|
-
}),
|
|
2348
|
+
}), nr = (e) => e.operations.filter((e) => e.blocked).map((e) => ` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}: ${e.reason ?? "<no reason>"}\n fix: ${e.blocked?.fix ?? "<no fix>"}`).join("\n"), rr = (e) => e`
|
|
2305
2349
|
SELECT fingerprint
|
|
2306
2350
|
FROM _voltro_migration_plans
|
|
2307
2351
|
ORDER BY ${e("appliedAt")} DESC
|
|
2308
2352
|
LIMIT 1
|
|
2309
|
-
`.pipe(d.map((e) => e.length > 0 ? e[0].fingerprint : void 0), d.catchAll(() => d.succeed(void 0))),
|
|
2353
|
+
`.pipe(d.map((e) => e.length > 0 ? e[0].fingerprint : void 0), d.catchAll(() => d.succeed(void 0))), ir = (e) => e.onDialectOrElse({
|
|
2310
2354
|
pg: () => "postgres",
|
|
2311
2355
|
mysql: () => "mysql",
|
|
2312
2356
|
mssql: () => "mssql",
|
|
2313
2357
|
sqlite: () => "sqlite",
|
|
2314
2358
|
orElse: () => "sqlite"
|
|
2315
|
-
}),
|
|
2316
|
-
let n =
|
|
2359
|
+
}), ar = (e, t) => d.gen(function* () {
|
|
2360
|
+
let n = j(N(t, ir(e))), r = yield* rr(e);
|
|
2317
2361
|
return r === n ? {
|
|
2318
2362
|
kind: "up-to-date",
|
|
2319
2363
|
fingerprint: n
|
|
@@ -2322,48 +2366,48 @@ BEGIN
|
|
|
2322
2366
|
expected: n,
|
|
2323
2367
|
...r === void 0 ? {} : { actual: r }
|
|
2324
2368
|
};
|
|
2325
|
-
}),
|
|
2369
|
+
}), or = [
|
|
2326
2370
|
"pgeagertest_",
|
|
2327
2371
|
"mig_e2e_",
|
|
2328
2372
|
"mig_test_",
|
|
2329
2373
|
"mysqleagertest_",
|
|
2330
2374
|
"mssqleagertest_",
|
|
2331
2375
|
"sqliteeagertest_"
|
|
2332
|
-
],
|
|
2376
|
+
], sr = (e) => or.some((t) => e.startsWith(t)), cr = (e, t) => d.gen(function* () {
|
|
2333
2377
|
if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
|
|
2334
|
-
let n = t.filter((e) =>
|
|
2378
|
+
let n = t.filter((e) => sr(e.name)).map((e) => e.name);
|
|
2335
2379
|
if (n.length === 0) return [];
|
|
2336
2380
|
for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(d.catchAll(() => d.void));
|
|
2337
2381
|
return n;
|
|
2338
|
-
}),
|
|
2382
|
+
}), lr = () => {
|
|
2339
2383
|
let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
|
|
2340
2384
|
return e.length > 0 ? { ignoreTables: e } : {};
|
|
2341
|
-
},
|
|
2385
|
+
}, ur = (e) => ({
|
|
2342
2386
|
...e,
|
|
2343
2387
|
operations: e.operations.map((e) => {
|
|
2344
2388
|
if (!e.blocked || e.classification !== "lossy") return e;
|
|
2345
2389
|
let { blocked: t, ...n } = e;
|
|
2346
2390
|
return n;
|
|
2347
2391
|
})
|
|
2348
|
-
}),
|
|
2349
|
-
let r =
|
|
2392
|
+
}), dr = (e, t, n) => d.gen(function* () {
|
|
2393
|
+
let r = ir(e), i = t.filter((e) => !P(e.tableName));
|
|
2350
2394
|
if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
|
|
2351
|
-
let t =
|
|
2352
|
-
if ((yield*
|
|
2395
|
+
let t = j(N(i, r));
|
|
2396
|
+
if ((yield* rr(e)) === t) return {
|
|
2353
2397
|
kind: "up-to-date",
|
|
2354
2398
|
fingerprint: t
|
|
2355
2399
|
};
|
|
2356
2400
|
}
|
|
2357
|
-
let a = yield*
|
|
2401
|
+
let a = yield* V(e), o = yield* cr(e, a.tables);
|
|
2358
2402
|
o.length > 0 && (yield* d.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(d.annotateLogs({
|
|
2359
2403
|
scope: "voltro:migrate",
|
|
2360
2404
|
count: o.length
|
|
2361
|
-
})), a = yield*
|
|
2362
|
-
let s =
|
|
2405
|
+
})), a = yield* V(e));
|
|
2406
|
+
let s = jt({
|
|
2363
2407
|
declared: i,
|
|
2364
|
-
live: { tables: a.tables.filter((e) => !
|
|
2408
|
+
live: { tables: a.tables.filter((e) => !P(e.name)) },
|
|
2365
2409
|
dialect: r,
|
|
2366
|
-
...
|
|
2410
|
+
...lr()
|
|
2367
2411
|
});
|
|
2368
2412
|
if (s.summary.blocked > 0) {
|
|
2369
2413
|
let e = s.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy");
|
|
@@ -2371,39 +2415,48 @@ BEGIN
|
|
|
2371
2415
|
kind: "refused-blocked",
|
|
2372
2416
|
plan: s
|
|
2373
2417
|
};
|
|
2374
|
-
s =
|
|
2418
|
+
s = ur(s);
|
|
2375
2419
|
}
|
|
2376
2420
|
return s.operations.length === 0 ? {
|
|
2377
2421
|
kind: "up-to-date",
|
|
2378
2422
|
fingerprint: s.toFingerprint
|
|
2379
2423
|
} : {
|
|
2380
2424
|
kind: "applied",
|
|
2381
|
-
applied: yield*
|
|
2425
|
+
applied: yield* tr(e, s, {
|
|
2382
2426
|
declared: t,
|
|
2383
2427
|
appliedBy: n.appliedBy,
|
|
2384
2428
|
environment: n.environment === "prod" ? "dev" : n.environment,
|
|
2385
|
-
source: "auto-diff"
|
|
2429
|
+
source: "auto-diff",
|
|
2430
|
+
replan: (e) => d.gen(function* () {
|
|
2431
|
+
let t = yield* V(e);
|
|
2432
|
+
return jt({
|
|
2433
|
+
declared: i,
|
|
2434
|
+
live: { tables: t.tables.filter((e) => !P(e.name)) },
|
|
2435
|
+
dialect: r,
|
|
2436
|
+
...lr()
|
|
2437
|
+
});
|
|
2438
|
+
})
|
|
2386
2439
|
}),
|
|
2387
2440
|
plan: s
|
|
2388
2441
|
};
|
|
2389
|
-
}),
|
|
2442
|
+
}), fr = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? d.succeed({
|
|
2390
2443
|
kind: "skipped",
|
|
2391
2444
|
reason: "VOLTRO_AUTO_MIGRATE=0"
|
|
2392
|
-
}) : n.environment === "prod" ?
|
|
2445
|
+
}) : n.environment === "prod" ? ar(e, t) : dr(e, t, n), pr = (e, t) => {
|
|
2393
2446
|
switch (e.kind) {
|
|
2394
2447
|
case "skipped": return `auto-migrate: skipped (${e.reason})`;
|
|
2395
|
-
case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${
|
|
2448
|
+
case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${M(e.fingerprint)})`;
|
|
2396
2449
|
case "applied": {
|
|
2397
2450
|
let t = e.plan.summary;
|
|
2398
|
-
return `auto-migrate: applied ${e.
|
|
2451
|
+
return `auto-migrate: applied ${e.applied.appliedOps} op(s) in ${e.applied.durationMs}ms [safe=${t.safe} needs-default=${t.needsDefault} needs-backfill=${t.needsBackfill} rename=${t.needsRenameAnnotation} lossy=${t.lossy}] fingerprint=${M(e.applied.fingerprint)}`;
|
|
2399
2452
|
}
|
|
2400
|
-
case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${
|
|
2453
|
+
case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${M(e.expected)}` + (e.actual ? ` live=${M(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
|
|
2401
2454
|
case "refused-blocked": {
|
|
2402
|
-
let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "add-column").length, i = t.filter((e) => e.op.kind === "drop-column").length, a = t.filter((e) => e.classification === "needs-rename-annotation").length, o = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` +
|
|
2455
|
+
let t = e.plan.operations.filter((e) => e.blocked), n = t.filter((e) => e.op.kind === "drop-table").length, r = t.filter((e) => e.op.kind === "add-column").length, i = t.filter((e) => e.op.kind === "drop-column").length, a = t.filter((e) => e.classification === "needs-rename-annotation").length, o = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + nr(e.plan), s = [""];
|
|
2403
2456
|
return n > 0 && s.push(`${n} table(s) exist in the live DB but aren't in your declared schema.`, "This is usually one of three things:", " (a) You're iterating on the schema — the table file got renamed, moved, or temporarily commented out.", " → Restore the declaration. Your data stays intact.", " (b) You want to KEEP the table but NOT manage it with Voltro (a leftover from another tool —", " a Strapi/Rails/legacy migration artifact, or an externally-owned table).", ` → Set \`VOLTRO_DB_IGNORE_TABLES=${t.filter((e) => e.op.kind === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean).join(",")}\` (comma-separated).`, " The planner excludes those tables from the diff entirely — it never drops them, and they", " stop blocking your OTHER (additive) changes. This is the fix when a leftover freezes your schema.", " (c) You actually want to drop the table.", " → Add it to your declared set + chain `.dropped()` on it, OR", " write a file-based migration in `migrations/` that DROPs it, OR", " set `VOLTRO_DESTRUCTIVE_OK=1` for ONE `voltro dev` run (acknowledges data loss).", " Soft-drop: set `VOLTRO_SOFT_DROP=1` alongside DESTRUCTIVE_OK to RENAME instead of DROP", " (data survives as `<name>__dropped_<ts>` for ~7d; restorable via `voltro db restore-snapshot`)."), r > 0 && s.push(`${r} required column(s) need a backfill strategy before adding to a populated table.`, " → Annotate the column: `.backfill(sql`<expr>`)` or `.backfill(row => <fn>)` or `.default(<value>)`.", " Existing rows get the backfill value; the column then lands as NOT NULL."), i > 0 && s.push(`${i} column(s) are missing from your declared schema.`, " → If intentional: chain `.dropped()` on the column slot in the table declaration.", " → If a typo: restore the field. Data survives until you drop it."), a > 0 && s.push(`${a} column(s) look like renames (one column gone + a new one of same shape appeared).`, " → On the NEW column add `.renamedFrom('<oldName>')` so the planner emits RENAME instead of DROP+ADD."), s.push("", "See `voltro db plan` for the full machine-readable diff."), o + "\n" + s.join("\n");
|
|
2404
2457
|
}
|
|
2405
2458
|
}
|
|
2406
|
-
},
|
|
2459
|
+
}, mr = /* @__PURE__ */ new Set([
|
|
2407
2460
|
"node_modules",
|
|
2408
2461
|
"dist",
|
|
2409
2462
|
"build",
|
|
@@ -2412,11 +2465,11 @@ BEGIN
|
|
|
2412
2465
|
".next",
|
|
2413
2466
|
".git",
|
|
2414
2467
|
".framework"
|
|
2415
|
-
]),
|
|
2468
|
+
]), hr = async (e) => {
|
|
2416
2469
|
let t = [], n = async (e) => {
|
|
2417
2470
|
let r = await h.readdir(e, { withFileTypes: !0 }).catch(() => []);
|
|
2418
2471
|
for (let i of r) {
|
|
2419
|
-
if (
|
|
2472
|
+
if (mr.has(i.name)) continue;
|
|
2420
2473
|
let r = g(e, i.name);
|
|
2421
2474
|
i.isDirectory() ? await n(r) : i.isFile() && l.test(i.name) && t.push(r);
|
|
2422
2475
|
}
|
|
@@ -2425,7 +2478,7 @@ BEGIN
|
|
|
2425
2478
|
let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
|
|
2426
2479
|
return n.localeCompare(r);
|
|
2427
2480
|
});
|
|
2428
|
-
},
|
|
2481
|
+
}, gr = async (e) => {
|
|
2429
2482
|
let t = [];
|
|
2430
2483
|
for (let n of e) {
|
|
2431
2484
|
let e = (await import(ee(n).href)).default;
|
|
@@ -2439,11 +2492,11 @@ BEGIN
|
|
|
2439
2492
|
});
|
|
2440
2493
|
}
|
|
2441
2494
|
return t;
|
|
2442
|
-
},
|
|
2495
|
+
}, _r = (e) => e`
|
|
2443
2496
|
SELECT ${e("id")}
|
|
2444
2497
|
FROM ${e("_voltro_migration_plans")}
|
|
2445
2498
|
WHERE ${e("source")} = 'file'
|
|
2446
|
-
`.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))),
|
|
2499
|
+
`.pipe(d.map((e) => e.map((e) => e.id)), d.catchAll(() => d.succeed([]))), vr = (e, t, n, r) => d.gen(function* () {
|
|
2447
2500
|
let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
|
|
2448
2501
|
sql: e,
|
|
2449
2502
|
log: {
|
|
@@ -2476,9 +2529,9 @@ BEGIN
|
|
|
2476
2529
|
${r}, ${n}, ${"file"},
|
|
2477
2530
|
${c}, ${a}, ${t.migration.description})
|
|
2478
2531
|
`, { durationMs: c };
|
|
2479
|
-
}),
|
|
2532
|
+
}), yr = (e, t) => d.gen(function* () {
|
|
2480
2533
|
let n = yield* d.tryPromise({
|
|
2481
|
-
try: () =>
|
|
2534
|
+
try: () => hr(g(t.projectRoot, "migrations")),
|
|
2482
2535
|
catch: (e) => e
|
|
2483
2536
|
});
|
|
2484
2537
|
if (n.length === 0) return {
|
|
@@ -2486,19 +2539,19 @@ BEGIN
|
|
|
2486
2539
|
skipped: []
|
|
2487
2540
|
};
|
|
2488
2541
|
let r = yield* d.tryPromise({
|
|
2489
|
-
try: () =>
|
|
2542
|
+
try: () => gr(n),
|
|
2490
2543
|
catch: (e) => e
|
|
2491
2544
|
});
|
|
2492
2545
|
if (r.length === 0) return {
|
|
2493
2546
|
applied: [],
|
|
2494
2547
|
skipped: []
|
|
2495
2548
|
};
|
|
2496
|
-
let i = new Set(yield*
|
|
2549
|
+
let i = new Set(yield* _r(e)), a = r.filter((e) => !i.has(e.migration.id)), o = r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id);
|
|
2497
2550
|
if (a.length === 0) return {
|
|
2498
2551
|
applied: [],
|
|
2499
2552
|
skipped: o
|
|
2500
2553
|
};
|
|
2501
|
-
yield*
|
|
2554
|
+
yield* C(e);
|
|
2502
2555
|
let s = [];
|
|
2503
2556
|
try {
|
|
2504
2557
|
for (let n of a) {
|
|
@@ -2507,7 +2560,7 @@ BEGIN
|
|
|
2507
2560
|
id: n.migration.id,
|
|
2508
2561
|
file: n.file
|
|
2509
2562
|
}));
|
|
2510
|
-
let { durationMs: r } = yield*
|
|
2563
|
+
let { durationMs: r } = yield* vr(e, n, t.env, t.appliedBy);
|
|
2511
2564
|
s.push({
|
|
2512
2565
|
id: n.migration.id,
|
|
2513
2566
|
durationMs: r
|
|
@@ -2518,28 +2571,28 @@ BEGIN
|
|
|
2518
2571
|
}));
|
|
2519
2572
|
}
|
|
2520
2573
|
} finally {
|
|
2521
|
-
yield*
|
|
2574
|
+
yield* w(e).pipe(d.orDie);
|
|
2522
2575
|
}
|
|
2523
2576
|
return {
|
|
2524
2577
|
applied: s,
|
|
2525
2578
|
skipped: o
|
|
2526
2579
|
};
|
|
2527
|
-
}),
|
|
2580
|
+
}), br = (e, t) => e`
|
|
2528
2581
|
SELECT ${e("id")}
|
|
2529
2582
|
FROM ${e("_voltro_migration_plans")}
|
|
2530
2583
|
WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
|
|
2531
2584
|
LIMIT 1
|
|
2532
|
-
`,
|
|
2533
|
-
if (!(yield*
|
|
2585
|
+
`, xr = (e, t) => d.gen(function* () {
|
|
2586
|
+
if (!(yield* br(e, t.id))[0]) return yield* d.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
|
|
2534
2587
|
let n = yield* d.tryPromise({
|
|
2535
|
-
try: () =>
|
|
2588
|
+
try: () => hr(g(t.projectRoot, "migrations")),
|
|
2536
2589
|
catch: (e) => e
|
|
2537
2590
|
}), r = (yield* d.tryPromise({
|
|
2538
|
-
try: () =>
|
|
2591
|
+
try: () => gr(n),
|
|
2539
2592
|
catch: (e) => e
|
|
2540
2593
|
})).find((e) => e.migration.id === t.id);
|
|
2541
2594
|
if (!r) return yield* d.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
|
|
2542
|
-
yield*
|
|
2595
|
+
yield* C(e);
|
|
2543
2596
|
let i = Date.now();
|
|
2544
2597
|
try {
|
|
2545
2598
|
let n = {
|
|
@@ -2566,9 +2619,9 @@ BEGIN
|
|
|
2566
2619
|
durationMs: o
|
|
2567
2620
|
};
|
|
2568
2621
|
} finally {
|
|
2569
|
-
yield*
|
|
2622
|
+
yield* w(e).pipe(d.orDie);
|
|
2570
2623
|
}
|
|
2571
|
-
}),
|
|
2624
|
+
}), Sr = (e) => d.gen(function* () {
|
|
2572
2625
|
let t = yield* p.SqlClient, n = yield* t`
|
|
2573
2626
|
SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
|
|
2574
2627
|
WHERE source = 'auto-diff'
|
|
@@ -2613,10 +2666,10 @@ BEGIN
|
|
|
2613
2666
|
snapshotFingerprint: e.fingerprint,
|
|
2614
2667
|
snapshotId: i
|
|
2615
2668
|
};
|
|
2616
|
-
}),
|
|
2669
|
+
}), Cr = (e, ...t) => ({
|
|
2617
2670
|
_tag: "RawSqlFragment",
|
|
2618
2671
|
strings: [...e],
|
|
2619
2672
|
values: [...t]
|
|
2620
|
-
}),
|
|
2673
|
+
}), wr = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
|
|
2621
2674
|
//#endregion
|
|
2622
|
-
export { l as FILE_MIGRATION_PATTERN,
|
|
2675
|
+
export { l as FILE_MIGRATION_PATTERN, re as VOLTRO_MIGRATION_LOCK_KEY, dt as _internalCmp, C as acquireMigrationLock, Je as applyNamespacedSchema, tr as applyPlan, He as applySchema, Rt as chunkTables, N as declaredSnapshot, be as defaultArrayClause, ye as defaultClause, D as defaultJsonClause, pr as describeOutcome, Xt as emitDropColumnDdl, Zt as emitDropColumnDdlMysql, Ve as emitFrameworkBootstrapSql, ze as emitNamespaceProvisionDdl, Be as emitNamespacedSchemaSql, A as emitSchemaSql, j as fingerprintSchema, lr as ignoreTablesFromEnv, V as introspectSchema, o as isFileMigration, wr as isRawSqlFragment, Nt as mapPgType, c as migration, O as numericIdSql, Mt as parseEnumCheck, jt as planMigrations, Ye as provisionTenantNamespace, w as releaseMigrationLock, pn as renderColumnMysql, cn as renderColumnPg, xr as rollbackFileBasedMigration, yr as runFileBasedMigrations, Xe as runFrameworkBootstrap, qe as runMigrate, fr as runPlannedMigrations, M as shortFingerprint, nt as snapshotColumn, Cr as sql, E as sqlType, Sr as squashMigrationPlans, ur as unblockLossy, _e as withMigrationLock };
|