@voltro/database 0.79.1 → 0.80.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 +79 -0
- package/dist/index.d.ts +6 -4
- package/dist/sql.d.ts +2 -0
- package/dist/sql.js +878 -878
- package/package.json +2 -2
package/dist/sql.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as e, B as t, Bn as n, C as r, Cn as i, Cr as a, D as o, Dn as s, E as c, En as l, Er as u, F as d, Fr as f, Ft as p, Gn as m, H as h, I as g, It as _, J as v, Kn as y, L as b, M as x, N as S, Nt as C, O as w, P as T, Pr as E, R as D, Rt as
|
|
1
|
+
import { A as e, B as t, Bn as n, C as r, Cn as i, Cr as a, D as o, Dn as s, E as c, En as l, Er as u, F as d, Fr as f, Ft as p, Gn as m, H as h, I as g, It as _, J as v, Kn as y, L as b, M as x, N as S, Nt as C, O as w, P as T, Pr as E, R as D, Rt as ee, S as te, Sn as O, Sr as ne, T as k, U as re, Vt as ie, Xn as ae, ct as oe, et as se, hn as ce, j as le, k as ue, p as de, r as fe, rr as pe, rt as me, t as he, w as ge, wt as _e, xn as ve, z as ye } from "./replaceInProgress-BmSjNTp0.js";
|
|
2
2
|
import { Cause as be, Effect as A, Equal as xe, Exit as Se, Schedule as Ce, Scope as we } from "effect";
|
|
3
3
|
import { createHash as Te } from "node:crypto";
|
|
4
4
|
import { createLogger as Ee } from "@voltro/logger";
|
|
@@ -196,7 +196,7 @@ var Ae = (e, t = "float32") => {
|
|
|
196
196
|
sqlite: "per-operation",
|
|
197
197
|
turso: "per-operation"
|
|
198
198
|
}, _t = (e) => gt[e], P = "_voltro_migration_ops", vt = l(P, {
|
|
199
|
-
id:
|
|
199
|
+
id: ne({ prefix: "mop" }),
|
|
200
200
|
runId: E(),
|
|
201
201
|
planFingerprint: E(),
|
|
202
202
|
opIndex: a(),
|
|
@@ -331,7 +331,7 @@ var kt = (e) => {
|
|
|
331
331
|
}, t)}[]`;
|
|
332
332
|
if (t === "mysql" || t === "mariadb") return "JSON";
|
|
333
333
|
if (t === "mssql") return "NVARCHAR(MAX)";
|
|
334
|
-
if (
|
|
334
|
+
if (O(t)) return "TEXT";
|
|
335
335
|
}
|
|
336
336
|
if (n === "vector") {
|
|
337
337
|
let n = e.vectorDim;
|
|
@@ -340,27 +340,27 @@ var kt = (e) => {
|
|
|
340
340
|
if (t === "postgres") return r ? `HALFVEC(${n})` : `VECTOR(${n})`;
|
|
341
341
|
if (t === "mysql" || t === "mariadb") return `VECTOR(${n})`;
|
|
342
342
|
if (t === "mssql") return "VARBINARY(MAX)";
|
|
343
|
-
if (
|
|
343
|
+
if (O(t)) return "BLOB";
|
|
344
344
|
}
|
|
345
345
|
if (n === "interval") {
|
|
346
346
|
if (t === "postgres") return "INTERVAL";
|
|
347
347
|
if (t === "mysql" || t === "mariadb" || t === "mssql") return "BIGINT";
|
|
348
|
-
if (
|
|
348
|
+
if (O(t)) return "INTEGER";
|
|
349
349
|
}
|
|
350
350
|
if (n === "decimal") {
|
|
351
351
|
let n = e.precision, r = e.scale ?? 0;
|
|
352
352
|
if (n === void 0) throw Error("decimal column is missing its precision — this is a framework bug.");
|
|
353
|
-
return
|
|
353
|
+
return O(t) ? "NUMERIC" : t === "postgres" ? `NUMERIC(${n}, ${r})` : `DECIMAL(${n}, ${r})`;
|
|
354
354
|
}
|
|
355
|
-
if (n === "bigint") return
|
|
355
|
+
if (n === "bigint") return O(t) ? "INTEGER" : "BIGINT";
|
|
356
356
|
if (n === "enum") {
|
|
357
357
|
if (t === "postgres") return e.enumName ?? "TEXT";
|
|
358
358
|
if (t === "mysql" || t === "mariadb") return `ENUM(${(e.enumValues ?? []).map((e) => `'${e.replace(/'/g, "''")}'`).join(", ")})`;
|
|
359
359
|
if (t === "mssql") return "NVARCHAR(255)";
|
|
360
|
-
if (
|
|
360
|
+
if (O(t)) return "TEXT";
|
|
361
361
|
}
|
|
362
|
-
if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` :
|
|
363
|
-
if (
|
|
362
|
+
if (n === "text" && e.maxLength !== void 0 && e.generatedAs === void 0) return t === "mssql" ? `NVARCHAR(${e.maxLength})` : O(t) ? "TEXT" : `VARCHAR(${e.maxLength})`;
|
|
363
|
+
if (O(t)) switch (n) {
|
|
364
364
|
case "id": return "TEXT";
|
|
365
365
|
case "text": return "TEXT";
|
|
366
366
|
case "integer": return "INTEGER";
|
|
@@ -430,19 +430,19 @@ var kt = (e) => {
|
|
|
430
430
|
}, Ut = (e, t) => {
|
|
431
431
|
if (!e.hasDefault || e.defaultFactory !== void 0) return null;
|
|
432
432
|
let n = e.defaultValue;
|
|
433
|
-
return n === "now" ?
|
|
433
|
+
return n === "now" ? O(t) ? "DEFAULT CURRENT_TIMESTAMP" : t === "mssql" ? "DEFAULT SYSUTCDATETIME()" : t === "mysql" || t === "mariadb" ? "DEFAULT CURRENT_TIMESTAMP(6)" : "DEFAULT now()" : typeof n == "boolean" ? t === "postgres" ? `DEFAULT ${n}` : `DEFAULT ${+!!n}` : typeof n == "number" ? `DEFAULT ${n}` : typeof n == "string" ? `DEFAULT '${n.replace(/'/g, "''")}'` : Array.isArray(n) ? Wt(n, e, t) : typeof n == "object" && n ? Gt(n, t) : null;
|
|
434
434
|
}, Wt = (e, t, n) => {
|
|
435
|
-
if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return
|
|
435
|
+
if (n !== "postgres" || t.type !== "array" || t.arrayElement === void 0) return Gt(e, n);
|
|
436
436
|
let r = I({
|
|
437
437
|
...t,
|
|
438
438
|
type: t.arrayElement,
|
|
439
439
|
arrayElement: void 0
|
|
440
440
|
}, n);
|
|
441
441
|
return `DEFAULT '{${e.map((e) => typeof e == "number" || typeof e == "boolean" ? String(e) : `"${String(e).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",").replace(/'/g, "''")}}'::${r}[]`;
|
|
442
|
-
},
|
|
442
|
+
}, Gt = (e, t) => {
|
|
443
443
|
let n = JSON.stringify(e).replace(/'/g, "''");
|
|
444
444
|
return t === "postgres" ? `DEFAULT '${n}'::jsonb` : t === "mysql" || t === "mariadb" ? `DEFAULT (CONVERT('${n}' USING utf8mb4))` : `DEFAULT '${n}'`;
|
|
445
|
-
},
|
|
445
|
+
}, Kt = (e, t) => {
|
|
446
446
|
switch (t) {
|
|
447
447
|
case "postgres": return `"${e}" BIGSERIAL PRIMARY KEY`;
|
|
448
448
|
case "mysql":
|
|
@@ -451,7 +451,7 @@ var kt = (e) => {
|
|
|
451
451
|
case "sqlite": return `"${e}" INTEGER PRIMARY KEY AUTOINCREMENT`;
|
|
452
452
|
case "turso": return `"${e}" INTEGER PRIMARY KEY`;
|
|
453
453
|
}
|
|
454
|
-
},
|
|
454
|
+
}, qt = (e, t) => {
|
|
455
455
|
if (e === "restrict" && t === "mssql") return "NO ACTION";
|
|
456
456
|
switch (e) {
|
|
457
457
|
case "cascade": return "CASCADE";
|
|
@@ -459,18 +459,18 @@ var kt = (e) => {
|
|
|
459
459
|
case "setNull": return "SET NULL";
|
|
460
460
|
case "noAction": return "NO ACTION";
|
|
461
461
|
}
|
|
462
|
-
},
|
|
462
|
+
}, Jt = (e, t, n) => n === null ? i(e, t) : `${i(n, t)}.${i(e, t)}`, Yt = 191, Xt = (e, t) => {
|
|
463
463
|
if (!e || t !== "mysql" && t !== "mariadb") return !1;
|
|
464
464
|
let n = I(e, t).toUpperCase();
|
|
465
465
|
return n.endsWith("TEXT") || n.endsWith("BLOB");
|
|
466
|
-
},
|
|
466
|
+
}, Zt = (e, t, n) => {
|
|
467
467
|
let r = i(e, n);
|
|
468
468
|
if (n !== "mysql" && n !== "mariadb") return r;
|
|
469
469
|
let a = t[e];
|
|
470
470
|
if (!a) return r;
|
|
471
471
|
let o = I(a, n).toUpperCase();
|
|
472
|
-
return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${r}(${
|
|
473
|
-
},
|
|
472
|
+
return o.endsWith("TEXT") || o.endsWith("BLOB") ? `${r}(${Yt})` : r;
|
|
473
|
+
}, Qt = (e, t) => {
|
|
474
474
|
if (!e.generatedAs) return null;
|
|
475
475
|
let { expr: n, stored: r } = e.generatedAs;
|
|
476
476
|
if (t === "postgres") return r || F("[voltro:migrate] generated column requested as VIRTUAL but postgres only supports STORED — promoting"), `GENERATED ALWAYS AS (${n}) STORED`;
|
|
@@ -478,23 +478,23 @@ var kt = (e) => {
|
|
|
478
478
|
if (t === "mssql") return `AS (${n})${r ? " PERSISTED" : ""}`;
|
|
479
479
|
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.");
|
|
480
480
|
return `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
|
|
481
|
-
},
|
|
482
|
-
if (t.type === "id" && t.idScheme?.kind === "numeric") return
|
|
481
|
+
}, $t = (e, t, n, r, a = !1, o = !1) => {
|
|
482
|
+
if (t.type === "id" && t.idScheme?.kind === "numeric") return Kt(e, n);
|
|
483
483
|
let s = n === "mssql" ? Vt(t, r?.has(e) ?? !1) : void 0, c = s === void 0 ? I(t, n) : `NVARCHAR(${s})`, l = [i(e, n), c];
|
|
484
484
|
t.type === "id" && !o && l.push("PRIMARY KEY");
|
|
485
|
-
let u =
|
|
485
|
+
let u = Qt(t, n);
|
|
486
486
|
if (u) l.push(u);
|
|
487
487
|
else {
|
|
488
|
-
t.nullable || l.push("NOT NULL"), t.unique && t.type !== "id" && !
|
|
488
|
+
t.nullable || l.push("NOT NULL"), t.unique && t.type !== "id" && !Xt(t, n) && l.push("UNIQUE");
|
|
489
489
|
let e = Ut(t, n);
|
|
490
490
|
e && l.push(e);
|
|
491
491
|
}
|
|
492
492
|
if (t.type === "reference" && t.references && !a && !ve(n)) {
|
|
493
493
|
let e = t.references();
|
|
494
494
|
l.push(`REFERENCES ${i(e.tableName, n)} (${i(t.referenceColumn ?? "id", n)})`);
|
|
495
|
-
let r =
|
|
495
|
+
let r = qt(t.onDelete ?? "restrict", n);
|
|
496
496
|
l.push(`ON DELETE ${r}`);
|
|
497
|
-
let a =
|
|
497
|
+
let a = qt(t.refOnUpdate ?? "noAction", n);
|
|
498
498
|
a !== "NO ACTION" && l.push(`ON UPDATE ${a}`);
|
|
499
499
|
}
|
|
500
500
|
if (t.oneOf && t.oneOf.length > 0) {
|
|
@@ -502,40 +502,40 @@ var kt = (e) => {
|
|
|
502
502
|
l.push(`CHECK (${i(e, n)} IN (${r}))`);
|
|
503
503
|
}
|
|
504
504
|
if (t.checks && t.checks.length > 0) for (let e of t.checks) l.push(`CHECK (${e})`);
|
|
505
|
-
if (t.type === "enum" && t.enumValues && t.enumValues.length > 0 && (n === "mssql" ||
|
|
505
|
+
if (t.type === "enum" && t.enumValues && t.enumValues.length > 0 && (n === "mssql" || O(n))) {
|
|
506
506
|
let r = t.enumValues.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
|
|
507
507
|
l.push(`CHECK (${i(e, n)} IN (${r}))`);
|
|
508
508
|
}
|
|
509
509
|
if (t.type === "json" || t.type === "array") {
|
|
510
510
|
let r = i(e, n);
|
|
511
|
-
|
|
511
|
+
O(n) ? l.push(`CHECK (${r} IS NULL OR json_valid(${r}))`) : n === "mssql" && l.push(t.type === "json" ? `CHECK ${kt(r)}` : `CHECK (${r} IS NULL OR ISJSON(${r}) = 1)`);
|
|
512
512
|
}
|
|
513
513
|
return l.join(" ");
|
|
514
|
-
},
|
|
514
|
+
}, en = (e, t) => {
|
|
515
515
|
if (t.charset !== void 0) {
|
|
516
516
|
if (!ve(e)) throw Error(`store charset '${t.charset}' is declared for a ${e} store — a character set is a MySQL / MariaDB setting. Remove \`charset\` from \`store\` in app.config.ts, or declare \`store: { dialect: 'mysql' | 'mariadb', charset }\`.`);
|
|
517
517
|
return t.charset;
|
|
518
518
|
}
|
|
519
|
-
},
|
|
519
|
+
}, tn = (e, t, n = null, r, a) => {
|
|
520
520
|
let o = /* @__PURE__ */ new Set();
|
|
521
521
|
for (let t of e.appliedIndexes ?? []) for (let e of t.fields) typeof e == "string" && o.add(e);
|
|
522
522
|
for (let t of e.appliedUniques ?? []) for (let e of t.fields) typeof e == "string" && o.add(e);
|
|
523
523
|
for (let [t, n] of Object.entries(e.fields)) n.unique && o.add(t);
|
|
524
524
|
let s = e.appliedPrimaryKey ?? [];
|
|
525
525
|
for (let e of s) o.add(e);
|
|
526
|
-
let c = s.length > 0, l = Object.entries(e.fields).map(([e, n]) => ` ${
|
|
527
|
-
let r = n.fields.map((n) =>
|
|
526
|
+
let c = s.length > 0, l = Object.entries(e.fields).map(([e, n]) => ` ${$t(e, n, t, o, r?.has(e) ?? !1, c)}`).join(",\n"), u = (e.appliedUniques ?? []).map((n) => {
|
|
527
|
+
let r = n.fields.map((n) => Zt(n, e.fields, t)).join(", ");
|
|
528
528
|
return ` CONSTRAINT ${i(n.name, t)} UNIQUE (${r})`;
|
|
529
|
-
}), d = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${i(e.name, t)} CHECK (${e.expr})`), f = c ? [` PRIMARY KEY (${s.map((n) =>
|
|
529
|
+
}), d = (e.appliedChecks ?? []).map((e) => ` CONSTRAINT ${i(e.name, t)} CHECK (${e.expr})`), f = c ? [` PRIMARY KEY (${s.map((n) => Zt(n, e.fields, t)).join(", ")})`] : [], p = ve(t) ? Object.entries(e.fields).flatMap(([a, o]) => {
|
|
530
530
|
if (o.type !== "reference" || !o.references || (r?.has(a) ?? !1)) return [];
|
|
531
|
-
let s = o.references(), c =
|
|
532
|
-
return [` CONSTRAINT ${i(`${e.tableName}_${a}_fkey`, t)} FOREIGN KEY (${i(a, t)}) REFERENCES ${
|
|
531
|
+
let s = o.references(), c = qt(o.onDelete ?? "restrict", t), l = qt(o.refOnUpdate ?? "noAction", t);
|
|
532
|
+
return [` CONSTRAINT ${i(`${e.tableName}_${a}_fkey`, t)} FOREIGN KEY (${i(a, t)}) REFERENCES ${Jt(s.tableName, t, n)} (${i(o.referenceColumn ?? "id", t)}) ON DELETE ${c}${l === "NO ACTION" ? "" : ` ON UPDATE ${l}`}`];
|
|
533
533
|
}) : [], m = [
|
|
534
534
|
...f,
|
|
535
535
|
...u,
|
|
536
536
|
...d,
|
|
537
537
|
...p
|
|
538
|
-
], h = m.length > 0 ? `${l},\n${m.join(",\n")}` : l, g =
|
|
538
|
+
], h = m.length > 0 ? `${l},\n${m.join(",\n")}` : l, g = Jt(e.tableName, t, n);
|
|
539
539
|
if (t === "mssql") {
|
|
540
540
|
let t = n === null ? e.tableName : `${n}.${e.tableName}`, r = `CREATE TABLE ${g} (\n${h}\n)`;
|
|
541
541
|
return `IF OBJECT_ID('${t.replace(/'/g, "''")}', 'U') IS NULL EXEC(N'${r.replace(/'/g, "''")}');`;
|
|
@@ -545,10 +545,10 @@ var kt = (e) => {
|
|
|
545
545
|
h,
|
|
546
546
|
`)${a !== void 0 && ve(t) ? ` DEFAULT CHARACTER SET ${a}` : ""};`
|
|
547
547
|
].join("\n");
|
|
548
|
-
},
|
|
548
|
+
}, nn = (e, t, n) => {
|
|
549
549
|
let r = `${e}_${t.name}_fts`, a = (e) => i(e, n), o = t.columns.map(a).join(", "), s = t.columns.map((e) => `new.${a(e)}`).join(", "), c = [];
|
|
550
550
|
return c.push(`CREATE VIRTUAL TABLE IF NOT EXISTS ${a(r)} USING fts5(${o}, row_id UNINDEXED, tokenize='porter');`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${r}_ai`)} AFTER INSERT ON ${a(e)} BEGIN\n INSERT INTO ${a(r)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${r}_ad`)} AFTER DELETE ON ${a(e)} BEGIN\n DELETE FROM ${a(r)} WHERE row_id = old.${a("id")};\nEND;`), c.push(`CREATE TRIGGER IF NOT EXISTS ${a(`${r}_au`)} AFTER UPDATE ON ${a(e)} BEGIN\n DELETE FROM ${a(r)} WHERE row_id = old.${a("id")};\n INSERT INTO ${a(r)} (${o}, row_id) VALUES (${s}, new.${a("id")});\nEND;`), c;
|
|
551
|
-
},
|
|
551
|
+
}, rn = (e, t, n = null) => {
|
|
552
552
|
let r = [], a = /* @__PURE__ */ new Set(), o = (e) => e.join("\0"), s = (e, n, r, i, a) => {
|
|
553
553
|
if (t === "postgres") return Ne(r, i, a);
|
|
554
554
|
let o = {
|
|
@@ -567,7 +567,7 @@ var kt = (e) => {
|
|
|
567
567
|
}) : o;
|
|
568
568
|
}, c = (n, r) => {
|
|
569
569
|
let i = n.map((n) => {
|
|
570
|
-
if (typeof n == "string") return
|
|
570
|
+
if (typeof n == "string") return Zt(n, e.fields, t);
|
|
571
571
|
if ("jsonPath" in n) {
|
|
572
572
|
let { column: e, path: r, numeric: i } = n.jsonPath;
|
|
573
573
|
return `(${C(e, r, t, { numeric: i })})`;
|
|
@@ -578,11 +578,11 @@ var kt = (e) => {
|
|
|
578
578
|
}, l = (r, a, o, l, u, d = "", f = !1) => {
|
|
579
579
|
let p = o[0], m = typeof p == "string" ? e.fields[p]?.vectorPrecision : void 0, h = s(r, a, l, u, m);
|
|
580
580
|
if (h.skip) return "";
|
|
581
|
-
let g = c(o, h.opclass), _ = `${h.withSuffix}${d}`, v =
|
|
581
|
+
let g = c(o, h.opclass), _ = `${h.withSuffix}${d}`, v = Jt(a, t, n), y = f ? "UNIQUE " : "";
|
|
582
582
|
return t === "mssql" ? `IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = '${r}') CREATE ${y}INDEX ${i(r, t)} ON ${v}${h.using} (${g})${_};` : t === "mysql" ? `CREATE ${y}INDEX ${i(r, t)} ON ${v}${h.using} (${g})${_};` : `CREATE ${y}INDEX IF NOT EXISTS ${i(r, t)} ON ${v}${h.using} (${g})${_};`;
|
|
583
583
|
};
|
|
584
584
|
if (t === "mysql" || t === "mariadb") for (let [n, i] of Object.entries(e.fields)) {
|
|
585
|
-
if (!i.unique || i.type === "id" || !
|
|
585
|
+
if (!i.unique || i.type === "id" || !Xt(i, t)) continue;
|
|
586
586
|
let a = l(`${e.tableName}_${n}_key`, e.tableName, [n], void 0, void 0, "", !0);
|
|
587
587
|
a && r.push(a);
|
|
588
588
|
}
|
|
@@ -596,7 +596,7 @@ var kt = (e) => {
|
|
|
596
596
|
let a = n.columns.map((e) => i(e, t)).join(", ");
|
|
597
597
|
r.push(`CREATE FULLTEXT INDEX ${i(n.name, t)} ON ${i(e.tableName, t)} (${a});`);
|
|
598
598
|
} else if (t === "turso") throw Error(`@voltro/sql-turso: full-text index '${n.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.`);
|
|
599
|
-
else t === "sqlite" ? r.push(...
|
|
599
|
+
else t === "sqlite" ? r.push(...nn(e.tableName, n, t)) : F(`[voltro:migrate] full-text index '${n.name}' on '${e.tableName}': ${t} uses a ranked LIKE search at query time (no native FTS catalog required).`);
|
|
600
600
|
for (let n of e.appliedIndexes) {
|
|
601
601
|
if ((t === "mariadb" || t === "mssql") && n.fields.some((e) => typeof e != "string" && "jsonPath" in e)) {
|
|
602
602
|
F(`[voltro:migrate] json-path index '${n.name}' on '${e.tableName}': ${t} cannot index a JSON expression directly — skipping. For an indexed JSON path on ${t}, add a generated column for the path (text().generatedAs(...) / .stored()) and .index([...]) it, then filter on that column instead of jsonField(...).`);
|
|
@@ -614,11 +614,11 @@ var kt = (e) => {
|
|
|
614
614
|
r.push(l(i, e.tableName, [t])), a.add(o([t]));
|
|
615
615
|
}
|
|
616
616
|
return r.join("\n");
|
|
617
|
-
},
|
|
617
|
+
}, an = (e, t, n = Nt) => {
|
|
618
618
|
if (t !== "postgres") return [];
|
|
619
619
|
let r = e.filter((e) => e.isReactive !== !1);
|
|
620
|
-
return r.length === 0 ? [] : [
|
|
621
|
-
},
|
|
620
|
+
return r.length === 0 ? [] : [on(n), ...r.map((e) => cn(e, n))];
|
|
621
|
+
}, on = (e) => `
|
|
622
622
|
CREATE OR REPLACE FUNCTION ${zt(e)}() RETURNS trigger AS $$
|
|
623
623
|
DECLARE
|
|
624
624
|
payload TEXT;
|
|
@@ -678,25 +678,25 @@ BEGIN
|
|
|
678
678
|
RETURN COALESCE(NEW, OLD);
|
|
679
679
|
END;
|
|
680
680
|
$$ LANGUAGE plpgsql;
|
|
681
|
-
`.trim(),
|
|
681
|
+
`.trim(), sn = (e, t) => {
|
|
682
682
|
let n = Ft(e.tableName, t);
|
|
683
683
|
return [
|
|
684
684
|
`ALTER TABLE "${e.tableName}" REPLICA IDENTITY FULL`,
|
|
685
685
|
`DROP TRIGGER IF EXISTS ${n} ON "${e.tableName}"`,
|
|
686
686
|
`CREATE TRIGGER ${n}\nAFTER INSERT OR UPDATE OR DELETE ON "${e.tableName}"\nFOR EACH ROW EXECUTE FUNCTION ${zt(t)}()`
|
|
687
687
|
];
|
|
688
|
-
},
|
|
688
|
+
}, cn = (e, t) => sn(e, t).map((e) => `${e};`).join("\n"), ln = (e) => {
|
|
689
689
|
if (e.dialect !== "postgres") return [];
|
|
690
690
|
let t = e.channel ?? "framework_changes", n = new Map(e.tables.map((e) => [e.tableName, e])), r = [], i = e.missing.filter((e) => n.has(e));
|
|
691
|
-
(i.length > 0 || e.functionOutdated === !0) && r.push(
|
|
692
|
-
for (let e of i) r.push(...
|
|
691
|
+
(i.length > 0 || e.functionOutdated === !0) && r.push(on(t));
|
|
692
|
+
for (let e of i) r.push(...sn(n.get(e), t));
|
|
693
693
|
for (let n of e.stale) r.push(`DROP TRIGGER IF EXISTS ${Ft(n, t)} ON "${n}"`), r.push(`ALTER TABLE "${n}" REPLICA IDENTITY DEFAULT`);
|
|
694
694
|
return r;
|
|
695
|
-
},
|
|
695
|
+
}, un = (e, t) => {
|
|
696
696
|
if (t !== "postgres") return;
|
|
697
697
|
let n = [];
|
|
698
|
-
return
|
|
699
|
-
},
|
|
698
|
+
return dn(e) && n.push("CREATE EXTENSION IF NOT EXISTS vector;"), fn(e) && n.push("CREATE EXTENSION IF NOT EXISTS postgis;"), n.length === 0 ? void 0 : n.join("\n");
|
|
699
|
+
}, dn = (e) => e.some((e) => Object.values(e.fields).some((e) => e.type === "vector")), fn = (e) => e.some((e) => Object.values(e.fields).some((e) => e.spatial !== void 0)), pn = (e) => {
|
|
700
700
|
let t = new Map(e.map((e) => [e.tableName, e])), n = Ve(e.map((e) => e.tableName), (e) => {
|
|
701
701
|
let n = t.get(e);
|
|
702
702
|
return n ? Object.entries(n.fields).flatMap(([e, n]) => {
|
|
@@ -734,8 +734,8 @@ $$ LANGUAGE plpgsql;
|
|
|
734
734
|
sorted: o,
|
|
735
735
|
cyclic: r
|
|
736
736
|
};
|
|
737
|
-
},
|
|
738
|
-
let r = (e) => n ? `${i(n, t)}.${i(e, t)}` : i(e, t), a = `${e.table}_${e.column}_fkey`, o =
|
|
737
|
+
}, mn = (e, t, n = null) => {
|
|
738
|
+
let r = (e) => n ? `${i(n, t)}.${i(e, t)}` : i(e, t), a = `${e.table}_${e.column}_fkey`, o = qt(e.onDelete, t), s = qt(e.onUpdate, t), c = ` ON DELETE ${o}${s === "NO ACTION" ? "" : ` ON UPDATE ${s}`}`, l = (n) => `ADD CONSTRAINT ${i(a, t)} FOREIGN KEY ${n ? "IF NOT EXISTS " : ""}(${i(e.column, t)}) REFERENCES ${r(e.targetTable)} (${i(e.targetColumn, t)})${c}`;
|
|
739
739
|
switch (t) {
|
|
740
740
|
case "postgres": return [
|
|
741
741
|
"DO $$ BEGIN",
|
|
@@ -749,15 +749,15 @@ $$ LANGUAGE plpgsql;
|
|
|
749
749
|
case "mariadb": return `ALTER TABLE ${r(e.table)} ${l(!0)};`;
|
|
750
750
|
default: return `ALTER TABLE ${r(e.table)} ${l(!1)};`;
|
|
751
751
|
}
|
|
752
|
-
},
|
|
752
|
+
}, hn = (e, t) => {
|
|
753
753
|
let n = /* @__PURE__ */ new Map();
|
|
754
|
-
if (
|
|
754
|
+
if (O(t)) return n;
|
|
755
755
|
for (let t of e) {
|
|
756
756
|
let e = n.get(t.table) ?? /* @__PURE__ */ new Set();
|
|
757
757
|
e.add(t.column), n.set(t.table, e);
|
|
758
758
|
}
|
|
759
759
|
return n;
|
|
760
|
-
},
|
|
760
|
+
}, gn = (e, t) => {
|
|
761
761
|
if (t !== "postgres") return "";
|
|
762
762
|
let n = /* @__PURE__ */ new Map();
|
|
763
763
|
for (let t of e) for (let e of Object.values(t.fields)) {
|
|
@@ -773,7 +773,7 @@ $$ LANGUAGE plpgsql;
|
|
|
773
773
|
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 $$;`);
|
|
774
774
|
}
|
|
775
775
|
return r.join("\n\n");
|
|
776
|
-
},
|
|
776
|
+
}, _n = (e, t) => {
|
|
777
777
|
if (t !== "postgres") return "";
|
|
778
778
|
let n = /* @__PURE__ */ new Set();
|
|
779
779
|
for (let t of e) for (let e of Object.values(t.fields)) e.type === "enum" && e.enumName && n.add(e.enumName);
|
|
@@ -787,30 +787,30 @@ BEGIN
|
|
|
787
787
|
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 $$;`);
|
|
788
788
|
}
|
|
789
789
|
return r.join("\n\n");
|
|
790
|
-
},
|
|
790
|
+
}, vn = (e) => {
|
|
791
791
|
let t = [], n = [];
|
|
792
|
-
for (let r of e)
|
|
792
|
+
for (let r of e) ee(r) ? n.push(r) : t.push(r);
|
|
793
793
|
return {
|
|
794
794
|
tables: t,
|
|
795
795
|
views: n
|
|
796
796
|
};
|
|
797
|
-
},
|
|
798
|
-
let i =
|
|
797
|
+
}, yn = (e, t, n = Nt, r = {}) => {
|
|
798
|
+
let i = en(t, r), { tables: a, views: o } = vn(e), { sorted: s, cyclic: c } = pn(a.map((e) => Be(e, t))), l = hn(c, t), u = [], d = un(s, t);
|
|
799
799
|
d && u.push(d);
|
|
800
|
-
let f =
|
|
800
|
+
let f = _n(s, t);
|
|
801
801
|
f && u.push(f);
|
|
802
|
-
let p =
|
|
802
|
+
let p = gn(s, t);
|
|
803
803
|
p && u.push(p);
|
|
804
|
-
for (let e of s) u.push(
|
|
805
|
-
if (!
|
|
804
|
+
for (let e of s) u.push(tn(e, t, null, l.get(e.tableName), i));
|
|
805
|
+
if (!O(t)) for (let e of c) u.push(mn(e, t));
|
|
806
806
|
for (let e of s) {
|
|
807
|
-
let n =
|
|
807
|
+
let n = rn(e, t);
|
|
808
808
|
n && u.push(n);
|
|
809
809
|
}
|
|
810
|
-
u.push(...
|
|
810
|
+
u.push(...an(s, t, n));
|
|
811
811
|
for (let e of o) u.push(ie(e, t));
|
|
812
812
|
return u.join("\n\n") + "\n";
|
|
813
|
-
},
|
|
813
|
+
}, bn = (e, t, n, r) => {
|
|
814
814
|
let a = i(e, t);
|
|
815
815
|
switch (t) {
|
|
816
816
|
case "postgres": return `CREATE SCHEMA IF NOT EXISTS ${a};`;
|
|
@@ -820,61 +820,61 @@ BEGIN
|
|
|
820
820
|
case "turso":
|
|
821
821
|
case "sqlite": return `ATTACH DATABASE '${(n ?? `${e}.db`).replace(/'/g, "''")}' AS ${a};`;
|
|
822
822
|
}
|
|
823
|
-
},
|
|
824
|
-
let o =
|
|
825
|
-
if (t === "postgres") return `${s}\n\nSET search_path TO ${c};\n\n${
|
|
826
|
-
let { sorted: l, cyclic: u } =
|
|
827
|
-
for (let e of l) f.push(
|
|
828
|
-
if (!
|
|
823
|
+
}, xn = (e, t, n, r, a = {}) => {
|
|
824
|
+
let o = en(t, a), s = bn(n, t, r, o), c = i(n, t);
|
|
825
|
+
if (t === "postgres") return `${s}\n\nSET search_path TO ${c};\n\n${yn(e, t)}`;
|
|
826
|
+
let { sorted: l, cyclic: u } = pn(e), d = hn(u, t), f = [s];
|
|
827
|
+
for (let e of l) f.push(tn(e, t, n, d.get(e.tableName), o));
|
|
828
|
+
if (!O(t)) for (let e of u) f.push(mn(e, t, n));
|
|
829
829
|
for (let e of l) {
|
|
830
|
-
let r =
|
|
830
|
+
let r = rn(e, t, n);
|
|
831
831
|
r && f.push(r);
|
|
832
832
|
}
|
|
833
833
|
return f.join("\n\n") + "\n";
|
|
834
|
-
},
|
|
835
|
-
let { sorted: r, cyclic: i } =
|
|
834
|
+
}, Sn = (e, t, n = Nt) => {
|
|
835
|
+
let { sorted: r, cyclic: i } = pn(e), a = hn(i, t), o = [], s = _n(r, t);
|
|
836
836
|
s && o.push(s);
|
|
837
|
-
let c =
|
|
837
|
+
let c = gn(r, t);
|
|
838
838
|
c && o.push(c);
|
|
839
|
-
for (let e of r) o.push(
|
|
840
|
-
for (let e of i) o.push(
|
|
841
|
-
return o.push(...
|
|
842
|
-
},
|
|
839
|
+
for (let e of r) o.push(tn(e, t, null, a.get(e.tableName)));
|
|
840
|
+
for (let e of i) o.push(mn(e, t));
|
|
841
|
+
return o.push(...an(r, t, n)), o.join("\n\n") + "\n";
|
|
842
|
+
}, Cn = (e, t = "postgres", n = Nt, r = {}) => A.gen(function* () {
|
|
843
843
|
let i = yield* j.SqlClient;
|
|
844
|
-
yield* ht(i,
|
|
845
|
-
}),
|
|
844
|
+
yield* ht(i, An(i, yn(e, t, n, { charset: r.charset }), t, r.retryFilter), { schema: r.lockSchema }).pipe(A.orDie);
|
|
845
|
+
}), wn = (e, t) => {
|
|
846
846
|
let n = t.cause ?? {};
|
|
847
847
|
return (n.errno === 1061 || n.code === "ER_DUP_KEYNAME") && /^\s*CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(e);
|
|
848
|
-
},
|
|
848
|
+
}, Tn = (e, t) => {
|
|
849
849
|
let n = e.trimStart();
|
|
850
850
|
return !!(/\bIF NOT EXISTS\b/i.test(n) || /^CREATE OR REPLACE\b/i.test(n) || /^DROP\s[\s\S]*?\bIF EXISTS\b/i.test(n) || /^SET search_path\b/i.test(n) || /^USE[\s`"[]/i.test(n) || /^IF\s/i.test(n) || (t === "mysql" || t === "mariadb") && /^CREATE\s+(UNIQUE\s+|FULLTEXT\s+)?INDEX\b/i.test(n));
|
|
851
|
-
},
|
|
851
|
+
}, En = () => {
|
|
852
852
|
let e = Number(process.env.VOLTRO_MIGRATION_DDL_RETRIES);
|
|
853
853
|
return Number.isInteger(e) && e >= 0 ? e : 4;
|
|
854
|
-
},
|
|
854
|
+
}, Dn = (e) => ({
|
|
855
855
|
while: e,
|
|
856
|
-
times:
|
|
856
|
+
times: En(),
|
|
857
857
|
schedule: Ce.jittered(Ce.exponential("50 millis"))
|
|
858
|
-
}),
|
|
858
|
+
}), On = class {
|
|
859
859
|
statement;
|
|
860
860
|
error;
|
|
861
861
|
_tag = "DdlStatementFailed";
|
|
862
862
|
constructor(e, t) {
|
|
863
863
|
this.statement = e, this.error = t;
|
|
864
864
|
}
|
|
865
|
-
},
|
|
865
|
+
}, kn = (e, t, n) => A.gen(function* () {
|
|
866
866
|
let r = yield* j.SqlClient, i = n !== void 0 && _t(t) === "per-operation";
|
|
867
|
-
for (let a of
|
|
867
|
+
for (let a of jn(e)) {
|
|
868
868
|
process.env.VOLTRO_MIGRATE_DEBUG === "1" && Ht.debug(`EXEC: ${a.replace(/\s+/g, " ").slice(0, 180)}`);
|
|
869
|
-
let e = r.unsafe(a).pipe(A.catchIf((e) =>
|
|
869
|
+
let e = r.unsafe(a).pipe(A.catchIf((e) => wn(a, e), () => A.succeed([])), A.tapError((e) => A.sync(() => {
|
|
870
870
|
Ht.error(Pe("migrate: statement failed", a, e, 200));
|
|
871
871
|
})));
|
|
872
|
-
yield* (i && n !== void 0 &&
|
|
872
|
+
yield* (i && n !== void 0 && Tn(a, t) ? e.pipe(A.retry(Dn((e) => n(e) === "retry"))) : e).pipe(A.mapError((e) => new On(a, e)));
|
|
873
873
|
}
|
|
874
|
-
}),
|
|
875
|
-
let i = n === "turso" ?
|
|
876
|
-
return (r !== void 0 && _t(n) === "plan-transactional" ? i.pipe(A.retry(
|
|
877
|
-
},
|
|
874
|
+
}), An = (e, t, n, r) => {
|
|
875
|
+
let i = n === "turso" ? kn(t, n, r) : e.withTransaction(kn(t, n, r)), a = (e) => e instanceof On ? e.error : e;
|
|
876
|
+
return (r !== void 0 && _t(n) === "plan-transactional" ? i.pipe(A.retry(Dn((e) => r(a(e)) === "retry"))) : i).pipe(A.orDieWith((e) => e instanceof On ? Error(Pe("migrate: statement failed", e.statement, e.error, 400).trim()) : e));
|
|
877
|
+
}, jn = (e) => {
|
|
878
878
|
let t = [], n = "", r = !1;
|
|
879
879
|
for (let i = 0; i < e.length; i++) {
|
|
880
880
|
if (e.slice(i, i + 2) === "$$") {
|
|
@@ -889,30 +889,30 @@ BEGIN
|
|
|
889
889
|
}
|
|
890
890
|
let i = n.trim();
|
|
891
891
|
return i.length > 0 && t.push(i), t;
|
|
892
|
-
},
|
|
893
|
-
await A.runPromise(
|
|
894
|
-
},
|
|
895
|
-
let i =
|
|
896
|
-
yield* ht(a,
|
|
897
|
-
}),
|
|
898
|
-
await A.runPromise(
|
|
892
|
+
}, Mn = async (e, t, n = "postgres", r = {}) => {
|
|
893
|
+
await A.runPromise(Cn(e, n, void 0, r).pipe(A.provide(t)));
|
|
894
|
+
}, Nn = (e, t, n = "postgres", r = {}) => A.gen(function* () {
|
|
895
|
+
let i = xn(e, n, t, void 0, { charset: r.charset }), a = yield* j.SqlClient;
|
|
896
|
+
yield* ht(a, An(a, i, n, r.retryFilter), { schema: r.lockSchema }).pipe(A.orDie);
|
|
897
|
+
}), Pn = async (e, t, n, r = "postgres", i = {}) => {
|
|
898
|
+
await A.runPromise(Nn(e, t, r, i).pipe(A.provide(n))), await re({
|
|
899
899
|
namespace: t,
|
|
900
900
|
dialect: r
|
|
901
901
|
});
|
|
902
|
-
},
|
|
902
|
+
}, Fn = async (e, t, n = "postgres", r = {}) => {
|
|
903
903
|
await A.runPromise(A.gen(function* () {
|
|
904
|
-
let t =
|
|
905
|
-
yield* ht(i,
|
|
904
|
+
let t = Sn(e, n), i = yield* j.SqlClient;
|
|
905
|
+
yield* ht(i, An(i, t, n, r.retryFilter), { schema: r.lockSchema }).pipe(A.orDie);
|
|
906
906
|
}).pipe(A.provide(t)));
|
|
907
|
-
},
|
|
907
|
+
}, In = /'(?:''|[^'])*'|"(?:""|[^"])*"|\[(?:\]\]|[^\]])*\]|`(?:``|[^`])*`|[A-Za-z_][A-Za-z_0-9$]*|\d+(?:\.\d+)?|::|<>|!=|<=|>=|\|\||[^\s]/g, Ln = (e) => {
|
|
908
908
|
let t = 0;
|
|
909
|
-
for (let n of e.matchAll(
|
|
910
|
-
},
|
|
909
|
+
for (let n of e.matchAll(In)) if (n[0] === "(" && t++, n[0] === ")" && t--, t === 0 && n[0].toLowerCase() === "where") return e.slice(n.index + n[0].length).trim().replace(/;$/, "").trim();
|
|
910
|
+
}, Rn = (e) => {
|
|
911
911
|
if (e === void 0) return;
|
|
912
|
-
let t = e.match(
|
|
912
|
+
let t = e.match(In) ?? [], n = "(?:'(?:''|[^'])*'(?:\\s*::\\s*text)?|[0-9]+)", r = RegExp(`^\\s*${n}(?:\\s*,\\s*${n})*\\s*$`, "i");
|
|
913
913
|
for (let e = 0; e < t.length - 5; e++) {
|
|
914
914
|
let n = t[e + 4];
|
|
915
|
-
t[e] === "=" && t[e + 1]?.toLowerCase() === "any" && t[e + 2] === "(" && t[e + 3]?.toLowerCase() === "array" && n.startsWith("[") && n.endsWith("]") && t[e + 5] === ")" && r.test(n.slice(1, -1)) && t.splice(e, 6, "in", "(", ...n.slice(1, -1).match(
|
|
915
|
+
t[e] === "=" && t[e + 1]?.toLowerCase() === "any" && t[e + 2] === "(" && t[e + 3]?.toLowerCase() === "array" && n.startsWith("[") && n.endsWith("]") && t[e + 5] === ")" && r.test(n.slice(1, -1)) && t.splice(e, 6, "in", "(", ...n.slice(1, -1).match(In) ?? [], ")");
|
|
916
916
|
}
|
|
917
917
|
let i = t.filter((e, n) => !(e === "::" && t[n - 1]?.startsWith("'") && t[n + 1]?.toLowerCase() === "text" || e.toLowerCase() === "text" && t[n - 1] === "::" && t[n - 2]?.startsWith("'"))).map((e) => {
|
|
918
918
|
if (e.startsWith("'")) return e;
|
|
@@ -950,64 +950,64 @@ BEGIN
|
|
|
950
950
|
return r;
|
|
951
951
|
};
|
|
952
952
|
return JSON.stringify(a(i));
|
|
953
|
-
},
|
|
953
|
+
}, zn = (e, t) => t.name === "id" && e.primaryKey?.length === 1 && e.primaryKey[0] === "id", Bn = /* @__PURE__ */ new Set(["integer", "bigint"]), Vn = (e) => Bn.has(e) ? "numeric" : "text", Hn = (e) => e.idScheme?.kind === "numeric" ? "numeric" : "text", Un = (e) => e.idStorage ?? (tr(e) ? "numeric" : "text"), Wn = (e) => e.idScheme ? Hn(e) : Un(e), Gn = (e) => e.type === "text" || e.type === "id" && Wn(e) === "text", Kn = (e, t) => t && (e.type === "text" || e.type === "id") ? {
|
|
954
954
|
...e,
|
|
955
955
|
type: "id",
|
|
956
956
|
unique: !0,
|
|
957
|
-
idStorage:
|
|
957
|
+
idStorage: Wn(e)
|
|
958
958
|
} : e.type === "id" ? {
|
|
959
959
|
...e,
|
|
960
|
-
idStorage:
|
|
961
|
-
} : e,
|
|
962
|
-
let r =
|
|
960
|
+
idStorage: Wn(e)
|
|
961
|
+
} : e, qn = (e, t, n) => {
|
|
962
|
+
let r = Kn(e, n), i = Kn(t, !1);
|
|
963
963
|
return n && r.type === "id" && i.type === "id" && r.idStorage === i.idStorage;
|
|
964
|
-
},
|
|
964
|
+
}, Jn = (e) => e.type !== "raw", Yn = (e) => ({
|
|
965
965
|
kind: e.kind,
|
|
966
966
|
geomKind: e.geomKind.toUpperCase(),
|
|
967
967
|
srid: e.srid
|
|
968
|
-
}),
|
|
968
|
+
}), Xn = (e, t) => {
|
|
969
969
|
if (e === void 0 || t === void 0) return e === t;
|
|
970
|
-
let n =
|
|
970
|
+
let n = Yn(e), r = Yn(t);
|
|
971
971
|
return n.kind === r.kind && n.geomKind === r.geomKind && n.srid === r.srid;
|
|
972
|
-
},
|
|
972
|
+
}, Zn = (e) => {
|
|
973
973
|
let { kind: t, kindOptions: n, ...r } = e, i = {
|
|
974
974
|
...r,
|
|
975
975
|
...Me(t, n),
|
|
976
|
-
...e.where === void 0 ? {} : { where:
|
|
976
|
+
...e.where === void 0 ? {} : { where: Rn(e.where) }
|
|
977
977
|
};
|
|
978
978
|
return e.expression ? {
|
|
979
979
|
...i,
|
|
980
980
|
columns: []
|
|
981
981
|
} : i;
|
|
982
|
-
},
|
|
982
|
+
}, Qn = (e) => {
|
|
983
983
|
if (typeof e != "object" || !e) return JSON.stringify(e);
|
|
984
|
-
if (Array.isArray(e)) return `[${e.map(
|
|
984
|
+
if (Array.isArray(e)) return `[${e.map(Qn).join(",")}]`;
|
|
985
985
|
let t = e;
|
|
986
|
-
return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${
|
|
987
|
-
},
|
|
986
|
+
return `{${Object.keys(t).sort().map((e) => `${JSON.stringify(e)}:${Qn(t[e])}`).join(",")}}`;
|
|
987
|
+
}, $n = (e) => {
|
|
988
988
|
if (!e.hasDefault || e.defaultValue === void 0 || e.defaultValue === null) return null;
|
|
989
989
|
let t = e.defaultValue;
|
|
990
990
|
if (typeof t == "boolean") return t ? "__BOOL_TRUE__" : "__BOOL_FALSE__";
|
|
991
991
|
if (typeof t == "number") return String(t);
|
|
992
|
-
if (typeof t != "string") return
|
|
992
|
+
if (typeof t != "string") return Qn(t);
|
|
993
993
|
let n = t.trim(), r = n.toLowerCase().replace(/\s+/g, "");
|
|
994
994
|
if (r === "now" || r === "now()" || /^current_timestamp(\(\d*\))?$/.test(r) || r === "sysutcdatetime()" || r === "sysdatetime()" || r === "getutcdate()" || r === "getdate()") return "__NOW__";
|
|
995
995
|
let i = n.replace(/::[a-zA-Z0-9_ "]+$/, "").trim(), a = /^'(.*)'$/.test(i) ? i.slice(1, -1).replace(/''/g, "'") : i, o = /^cast\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+as\s+json\s*\)$/i.exec(a);
|
|
996
996
|
if (o) try {
|
|
997
|
-
return
|
|
997
|
+
return Qn(JSON.parse(o[1]));
|
|
998
998
|
} catch {}
|
|
999
999
|
let s = /^convert\(\s*(?:_\w+\s*)?\\?'(.*?)\\?'\s+using\s+[\w]+\s*\)$/i.exec(a);
|
|
1000
1000
|
if (s) try {
|
|
1001
|
-
return
|
|
1001
|
+
return Qn(JSON.parse(s[1]));
|
|
1002
1002
|
} catch {}
|
|
1003
1003
|
if (a.startsWith("{") || a.startsWith("[")) try {
|
|
1004
|
-
return
|
|
1004
|
+
return Qn(JSON.parse(a));
|
|
1005
1005
|
} catch {}
|
|
1006
1006
|
return /^-?\d+(\.\d+)?$/.test(a) ? String(Number(a)) : a;
|
|
1007
|
-
},
|
|
1008
|
-
let t =
|
|
1007
|
+
}, er = (e) => {
|
|
1008
|
+
let t = $n(e);
|
|
1009
1009
|
return t === "1" || t === "true" ? "__BOOL_TRUE__" : t === "0" || t === "false" ? "__BOOL_FALSE__" : t;
|
|
1010
|
-
},
|
|
1010
|
+
}, tr = (e) => typeof e.defaultValue == "string" && /^nextval\(.+::regclass\)$/i.test(e.defaultValue.trim()), nr = (e) => {
|
|
1011
1011
|
if (!e) return null;
|
|
1012
1012
|
let t = (e) => e === "restrict" ? "noAction" : e;
|
|
1013
1013
|
return {
|
|
@@ -1016,7 +1016,7 @@ BEGIN
|
|
|
1016
1016
|
onDelete: t(e.onDelete),
|
|
1017
1017
|
onUpdate: t(e.onUpdate)
|
|
1018
1018
|
};
|
|
1019
|
-
},
|
|
1019
|
+
}, rr = (e, t, n) => {
|
|
1020
1020
|
if (t === "mssql") {
|
|
1021
1021
|
let t = Vt(e, n);
|
|
1022
1022
|
if (t !== void 0) return t;
|
|
@@ -1027,46 +1027,46 @@ BEGIN
|
|
|
1027
1027
|
} catch {
|
|
1028
1028
|
return;
|
|
1029
1029
|
}
|
|
1030
|
-
},
|
|
1030
|
+
}, ir = (e) => {
|
|
1031
1031
|
if (e == null) return e;
|
|
1032
|
-
if (Array.isArray(e)) return e.map(
|
|
1032
|
+
if (Array.isArray(e)) return e.map(ir);
|
|
1033
1033
|
if (typeof e != "object") return e;
|
|
1034
1034
|
let t = {};
|
|
1035
1035
|
for (let n of Object.keys(e).sort()) {
|
|
1036
1036
|
let r = e[n];
|
|
1037
|
-
r !== void 0 && (t[n] =
|
|
1037
|
+
r !== void 0 && (t[n] = ir(r));
|
|
1038
1038
|
}
|
|
1039
1039
|
return t;
|
|
1040
|
-
},
|
|
1040
|
+
}, ar = (e) => {
|
|
1041
1041
|
if (!e.idScheme && !e.sensitive && !e.safe && !e.generatedAs && !e.jsonChecks && !e.narrowedFrom && !e.rawDdl && !e.charset) return e;
|
|
1042
1042
|
let { idScheme: t, sensitive: n, safe: r, generatedAs: i, jsonChecks: a, narrowedFrom: o, rawDdl: s, charset: c, ...l } = e;
|
|
1043
1043
|
return l;
|
|
1044
|
-
},
|
|
1045
|
-
let t =
|
|
1044
|
+
}, or = (e) => {
|
|
1045
|
+
let t = ar((() => {
|
|
1046
1046
|
if (e.storageType === void 0) return e;
|
|
1047
1047
|
let { storageType: t, enumValues: n, enumName: r, arrayElement: i, ...a } = e;
|
|
1048
1048
|
return {
|
|
1049
1049
|
...a,
|
|
1050
1050
|
type: t
|
|
1051
1051
|
};
|
|
1052
|
-
})()), { references: n, defaultValue: r, hasDefault: i, oneOf: a, spatial: o, enumValues: s, ...c } = t, l = t.type === "id" &&
|
|
1052
|
+
})()), { references: n, defaultValue: r, hasDefault: i, oneOf: a, spatial: o, enumValues: s, ...c } = t, l = t.type === "id" && tr(t) ? null : er(t), u = nr(t.references);
|
|
1053
1053
|
return {
|
|
1054
1054
|
...c,
|
|
1055
1055
|
hasDefault: l !== null,
|
|
1056
1056
|
...l === null ? {} : { defaultValue: l },
|
|
1057
1057
|
...u === null ? {} : { references: u },
|
|
1058
1058
|
...t.oneOf !== void 0 && t.oneOf.length > 0 ? { oneOf: [...t.oneOf].sort() } : {},
|
|
1059
|
-
...t.spatial === void 0 ? {} : { spatial:
|
|
1059
|
+
...t.spatial === void 0 ? {} : { spatial: Yn(t.spatial) },
|
|
1060
1060
|
...t.enumValues === void 0 ? {} : { enumValues: [...t.enumValues].sort() }
|
|
1061
1061
|
};
|
|
1062
|
-
},
|
|
1062
|
+
}, sr = (e) => e.columns.filter((e) => !k(e.name)).map((t) => or(Kn(t, zn(e, t)))).sort((e, t) => e.name.localeCompare(t.name)), cr = (e) => [...e].map(Zn).sort((e, t) => e.name.localeCompare(t.name)), lr = (e) => [...e].filter((e) => !k(e.name)).map((e) => ({
|
|
1063
1063
|
name: e.name,
|
|
1064
|
-
columns:
|
|
1065
|
-
indexes:
|
|
1066
|
-
})).sort((e, t) => e.name.localeCompare(t.name)),
|
|
1067
|
-
let t = { tables:
|
|
1064
|
+
columns: sr(e),
|
|
1065
|
+
indexes: cr(e.indexes)
|
|
1066
|
+
})).sort((e, t) => e.name.localeCompare(t.name)), L = (e) => {
|
|
1067
|
+
let t = { tables: lr(e.tables) }, n = JSON.stringify(ir(t));
|
|
1068
1068
|
return Te("sha256").update(n).digest("hex");
|
|
1069
|
-
},
|
|
1069
|
+
}, ur = (e) => e.slice(0, 16), dr = ["utf8mb3", "utf8mb4"], fr = (e) => e === "utf8mb3" || e === "utf8mb4", pr = (e) => {
|
|
1070
1070
|
switch (e.type) {
|
|
1071
1071
|
case "text":
|
|
1072
1072
|
case "enum": return !0;
|
|
@@ -1074,21 +1074,21 @@ BEGIN
|
|
|
1074
1074
|
case "reference": return e.referenceStorage !== "numeric";
|
|
1075
1075
|
default: return !1;
|
|
1076
1076
|
}
|
|
1077
|
-
},
|
|
1077
|
+
}, mr = (e, t) => e.map((e) => ({
|
|
1078
1078
|
...e,
|
|
1079
|
-
columns: e.columns.map((e) =>
|
|
1079
|
+
columns: e.columns.map((e) => pr(e) && e.charset === void 0 ? {
|
|
1080
1080
|
...e,
|
|
1081
1081
|
charset: t
|
|
1082
1082
|
} : e)
|
|
1083
|
-
})),
|
|
1083
|
+
})), hr = (e) => e.columns.flatMap((e) => e.charset === void 0 ? [] : [{
|
|
1084
1084
|
column: e.name,
|
|
1085
1085
|
charset: e.charset
|
|
1086
|
-
}]),
|
|
1086
|
+
}]), gr = "utf8mb4", _r = (e) => e.columns.some((e) => e.type === "json" || e.type === "array" || e.storageType === "json"), vr = (e) => {
|
|
1087
1087
|
if (!ve(e.dialect)) return [];
|
|
1088
1088
|
let t = [];
|
|
1089
1089
|
for (let n of [...e.live.tables].sort((e, t) => e.name.localeCompare(t.name))) {
|
|
1090
|
-
if (
|
|
1091
|
-
let r =
|
|
1090
|
+
if (k(n.name)) continue;
|
|
1091
|
+
let r = hr(n);
|
|
1092
1092
|
if (r.length === 0) continue;
|
|
1093
1093
|
if (e.charset !== void 0) {
|
|
1094
1094
|
let i = r.filter((t) => t.charset !== e.charset);
|
|
@@ -1100,13 +1100,13 @@ BEGIN
|
|
|
1100
1100
|
});
|
|
1101
1101
|
continue;
|
|
1102
1102
|
}
|
|
1103
|
-
if (
|
|
1104
|
-
let e = r.filter((e) => e.charset !==
|
|
1103
|
+
if (_r(n)) {
|
|
1104
|
+
let e = r.filter((e) => e.charset !== gr);
|
|
1105
1105
|
e.length > 0 && t.push({
|
|
1106
1106
|
table: n.name,
|
|
1107
1107
|
kind: "json-outruns-text",
|
|
1108
1108
|
columns: e,
|
|
1109
|
-
expected:
|
|
1109
|
+
expected: gr
|
|
1110
1110
|
});
|
|
1111
1111
|
continue;
|
|
1112
1112
|
}
|
|
@@ -1119,14 +1119,14 @@ BEGIN
|
|
|
1119
1119
|
});
|
|
1120
1120
|
}
|
|
1121
1121
|
return t;
|
|
1122
|
-
},
|
|
1122
|
+
}, yr = (e) => {
|
|
1123
1123
|
let t = e.columns.map((e) => `${e.column} (${e.charset})`).join(", ");
|
|
1124
1124
|
switch (e.kind) {
|
|
1125
1125
|
case "disagrees-with-declaration": return `${e.table}: declared ${e.expected}, stored otherwise — ${t}`;
|
|
1126
1126
|
case "json-outruns-text": return `${e.table}: its json column holds every character (utf8mb4); these text columns do not — ${t}`;
|
|
1127
1127
|
case "mixed": return `${e.table}: its string columns are not in one character set — ${t}`;
|
|
1128
1128
|
}
|
|
1129
|
-
},
|
|
1129
|
+
}, br = "declare the store's character set in app.config.ts — store: { dialect: 'mariadb' | 'mysql', charset: 'utf8mb4' } — and run `voltro db plan`: every table the app declares is created with it and converted to it (a table rewrite; foreign keys are re-created around it). `utf8mb3` is accepted too, for a database that must stay there.", xr = (e, t, n) => {
|
|
1130
1130
|
let r = t.references ? {
|
|
1131
1131
|
table: t.references().tableName,
|
|
1132
1132
|
column: t.referenceColumn ?? "id",
|
|
@@ -1169,7 +1169,7 @@ BEGIN
|
|
|
1169
1169
|
...t.enumValues === void 0 ? {} : { enumValues: t.enumValues },
|
|
1170
1170
|
...t.spatial === void 0 ? {} : { spatial: t.spatial }
|
|
1171
1171
|
};
|
|
1172
|
-
},
|
|
1172
|
+
}, Sr = (e, t) => {
|
|
1173
1173
|
let r = [], i = /* @__PURE__ */ new Set(), a = (e) => {
|
|
1174
1174
|
i.has(e.name) || (i.add(e.name), r.push(e));
|
|
1175
1175
|
}, o = e.appliedPrimaryKey ?? [];
|
|
@@ -1220,11 +1220,11 @@ BEGIN
|
|
|
1220
1220
|
});
|
|
1221
1221
|
}
|
|
1222
1222
|
return r;
|
|
1223
|
-
},
|
|
1223
|
+
}, Cr = (e, t) => {
|
|
1224
1224
|
let n = new Set((e.appliedUniques ?? []).filter((e) => e.fields.length === 1).map((e) => e.fields[0])), r = [];
|
|
1225
1225
|
for (let [i, a] of Object.entries(e.fields)) {
|
|
1226
1226
|
if (a.dropped) continue;
|
|
1227
|
-
let e =
|
|
1227
|
+
let e = xr(i, a, t);
|
|
1228
1228
|
r.push(n.has(i) ? {
|
|
1229
1229
|
...e,
|
|
1230
1230
|
unique: !0
|
|
@@ -1234,27 +1234,27 @@ BEGIN
|
|
|
1234
1234
|
return {
|
|
1235
1235
|
name: e.tableName,
|
|
1236
1236
|
columns: r,
|
|
1237
|
-
indexes:
|
|
1237
|
+
indexes: Sr(e, t),
|
|
1238
1238
|
...i.length > 0 ? { primaryKey: [...i] } : {},
|
|
1239
1239
|
...a === void 0 ? {} : { renamedFrom: a }
|
|
1240
1240
|
};
|
|
1241
|
-
},
|
|
1241
|
+
}, wr = (e) => {
|
|
1242
1242
|
let t = /* @__PURE__ */ new Map();
|
|
1243
1243
|
for (let n of e) for (let e of n.indexes) {
|
|
1244
1244
|
let r = t.get(e.name);
|
|
1245
1245
|
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}').`);
|
|
1246
1246
|
t.set(e.name, n.name);
|
|
1247
1247
|
}
|
|
1248
|
-
},
|
|
1248
|
+
}, Tr = (e, t, n = {}) => {
|
|
1249
1249
|
if (n.charset !== void 0 && t !== "mysql" && t !== "mariadb") throw Error(`store charset '${n.charset}' is declared for a ${t ?? "dialect-less"} store — a character set is a MySQL / MariaDB setting. Remove \`charset\` from \`store\` in app.config.ts, or declare \`store: { dialect: 'mysql' | 'mariadb', charset }\`.`);
|
|
1250
|
-
let r = e.filter((e) => !c(e.tableName)).map((e) =>
|
|
1250
|
+
let r = e.filter((e) => !c(e.tableName)).map((e) => Cr(Be(e, t), t));
|
|
1251
1251
|
if (t === "mysql" || t === "mariadb") {
|
|
1252
1252
|
for (let e of r) for (let n of e.indexes) if (n.where !== void 0) throw Error(`Partial index '${n.name}' on '${e.name}' is not supported by ${t}. Use uniqueActive for portable conditional uniqueness.`);
|
|
1253
1253
|
}
|
|
1254
|
-
|
|
1255
|
-
let i = t === void 0 ? r : r.map((e) =>
|
|
1256
|
-
return { tables: n.charset === void 0 ? i :
|
|
1257
|
-
},
|
|
1254
|
+
wr(r);
|
|
1255
|
+
let i = t === void 0 ? r : r.map((e) => Er(e, t));
|
|
1256
|
+
return { tables: n.charset === void 0 ? i : mr(i, n.charset) };
|
|
1257
|
+
}, Er = (e, t) => {
|
|
1258
1258
|
let n = new Set(e.indexes.flatMap((e) => e.columns));
|
|
1259
1259
|
return {
|
|
1260
1260
|
...e,
|
|
@@ -1262,20 +1262,20 @@ BEGIN
|
|
|
1262
1262
|
if (t === "mssql" && !e.generatedAs && (e.type === "json" || e.type === "array") && (e = {
|
|
1263
1263
|
...e,
|
|
1264
1264
|
jsonValidation: e.type === "json" ? "value" : "container"
|
|
1265
|
-
}),
|
|
1265
|
+
}), O(t)) {
|
|
1266
1266
|
if (e.maxLength === void 0) return e;
|
|
1267
1267
|
let { maxLength: t, ...n } = e;
|
|
1268
1268
|
return n;
|
|
1269
1269
|
}
|
|
1270
1270
|
if (e.maxLength !== void 0) return e;
|
|
1271
|
-
let r =
|
|
1271
|
+
let r = rr(e, t, n.has(e.name) || e.unique);
|
|
1272
1272
|
return r === void 0 ? e : {
|
|
1273
1273
|
...e,
|
|
1274
1274
|
maxLength: r
|
|
1275
1275
|
};
|
|
1276
1276
|
})
|
|
1277
1277
|
};
|
|
1278
|
-
},
|
|
1278
|
+
}, Dr = (e, t, n = Nt) => A.gen(function* () {
|
|
1279
1279
|
let r = (yield* e`
|
|
1280
1280
|
SELECT p.prosrc
|
|
1281
1281
|
FROM pg_proc p
|
|
@@ -1316,7 +1316,7 @@ BEGIN
|
|
|
1316
1316
|
present: l.size
|
|
1317
1317
|
}
|
|
1318
1318
|
};
|
|
1319
|
-
}),
|
|
1319
|
+
}), Or = (e) => {
|
|
1320
1320
|
let t = [];
|
|
1321
1321
|
if (e.missing.length > 0) {
|
|
1322
1322
|
let n = e.missing.slice(0, 8).join(", "), r = e.missing.length > 8 ? `, … (+${e.missing.length - 8})` : "";
|
|
@@ -1327,19 +1327,19 @@ BEGIN
|
|
|
1327
1327
|
t.push(`${e.stale.length} .nonReactive() table(s) still carry a change trigger — ${n}. They keep paying REPLICA IDENTITY FULL and a NOTIFY on every write for a subscription nobody receives. \`voltro db apply\` removes them.`);
|
|
1328
1328
|
}
|
|
1329
1329
|
return e.functionOutdated && t.push("The change-notify function in this database is OLDER than the framework installed here. Its triggers fire, so nothing looks wrong — but a row too large for a NOTIFY payload (postgres caps it at 8000 bytes) is emitted without its primary key, and a change that carries no key cannot be re-read: it reaches subscriptions as a re-query and reaches every TAP — search index, analytics mirror, cdc-out, row history — as nothing at all. Run `voltro db apply` to replace it."), t.length > 0 ? t.join("\n") : void 0;
|
|
1330
|
-
},
|
|
1330
|
+
}, kr = {
|
|
1331
1331
|
postgres: !0,
|
|
1332
1332
|
mysql: !0,
|
|
1333
1333
|
mariadb: !0,
|
|
1334
1334
|
mssql: !0,
|
|
1335
1335
|
sqlite: !0
|
|
1336
|
-
},
|
|
1336
|
+
}, Ar = {
|
|
1337
1337
|
postgres: !0,
|
|
1338
1338
|
mysql: !1,
|
|
1339
1339
|
mariadb: !1,
|
|
1340
1340
|
mssql: !0,
|
|
1341
1341
|
sqlite: !0
|
|
1342
|
-
},
|
|
1342
|
+
}, jr = (e) => {
|
|
1343
1343
|
switch (e) {
|
|
1344
1344
|
case "add-column":
|
|
1345
1345
|
case "drop-column":
|
|
@@ -1350,33 +1350,33 @@ BEGIN
|
|
|
1350
1350
|
case "add-unique":
|
|
1351
1351
|
case "add-unique-composite":
|
|
1352
1352
|
case "add-check":
|
|
1353
|
-
case "convert-charset": return
|
|
1354
|
-
default: return
|
|
1353
|
+
case "convert-charset": return Ar;
|
|
1354
|
+
default: return kr;
|
|
1355
1355
|
}
|
|
1356
|
-
},
|
|
1356
|
+
}, Mr = (e, t) => {
|
|
1357
1357
|
let n = new Map(t.tables.map((e) => [e.name, e]));
|
|
1358
1358
|
return new Map(e.map((e) => [e.tableName, {
|
|
1359
1359
|
table: e,
|
|
1360
1360
|
snapshot: n.get(e.tableName),
|
|
1361
1361
|
columnDefs: e.fields
|
|
1362
1362
|
}]));
|
|
1363
|
-
}, Mr = (e, t) => {
|
|
1364
|
-
let n = Qn(e), r = Qn(t);
|
|
1365
|
-
if (n === r) return !0;
|
|
1366
|
-
let i = er, a = (e) => e.type === "id" && e.idScheme?.kind === "numeric";
|
|
1367
|
-
return e.type === "id" && t.type === "id" && (a(e) && n === null && i(t) || a(t) && r === null && i(e)) ? !0 : $n(e) === $n(t);
|
|
1368
1363
|
}, Nr = (e, t) => {
|
|
1364
|
+
let n = $n(e), r = $n(t);
|
|
1365
|
+
if (n === r) return !0;
|
|
1366
|
+
let i = tr, a = (e) => e.type === "id" && e.idScheme?.kind === "numeric";
|
|
1367
|
+
return e.type === "id" && t.type === "id" && (a(e) && n === null && i(t) || a(t) && r === null && i(e)) ? !0 : er(e) === er(t);
|
|
1368
|
+
}, Pr = (e, t) => {
|
|
1369
1369
|
let n = e && e.length > 0 ? e : void 0, r = t && t.length > 0 ? t : void 0;
|
|
1370
1370
|
if (!n && !r) return !0;
|
|
1371
1371
|
if (!n || !r || n.length !== r.length) return !1;
|
|
1372
1372
|
let i = [...n].sort(), a = [...r].sort();
|
|
1373
1373
|
return i.every((e, t) => e === a[t]);
|
|
1374
|
-
},
|
|
1374
|
+
}, Fr = (e, t, n, r) => n === void 0 || O(n) ? !0 : e.type !== "text" || !Gn(t) || rr(e, n, r) === t.maxLength, Ir = (e, t, n, r, i = !1) => (!Jn(e) || e.type === t.type || qn(e, t, i)) && Kn(e, i).idStorage === Kn(t, !1).idStorage && e.nullable === t.nullable && (e.unique === t.unique || qn(e, t, i)) && e.jsonValidation === t.jsonValidation && (t.enumValues === void 0 || e.enumValues === void 0 || e.enumValues.length === t.enumValues.length && e.enumValues.every((e) => t.enumValues.includes(e))) && (t.precision === void 0 || e.precision === t.precision && (e.scale ?? 0) === (t.scale ?? 0)) && Xn(e.spatial, t.spatial) && (e.storageType !== void 0 || t.storageType !== void 0 || t.arrayElement === void 0 || e.arrayElement === void 0 || e.arrayElement === t.arrayElement) && (t.vectorDim === void 0 || e.vectorDim === t.vectorDim) && (e.vectorPrecision ?? "float32") === (t.vectorPrecision ?? "float32") && Nr(e, t) && Fr(e, t, n, r) && (e.type !== "reference" || (e.referenceStorage ?? "text") === (t.referenceStorage ?? "text")) && JSON.stringify(nr(e.references)) === JSON.stringify(nr(t.references)) && Pr(e.oneOf, t.oneOf), Lr = (e, t) => t.oneOf && t.oneOf.length > 0 ? R({
|
|
1375
1375
|
kind: "add-check",
|
|
1376
1376
|
table: e,
|
|
1377
1377
|
column: t.name,
|
|
1378
1378
|
values: t.oneOf
|
|
1379
|
-
}, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0,
|
|
1379
|
+
}, "safe", `enum-membership CHECK on ${e}.${t.name}`) : void 0, Rr = (e, t) => e.unique === t.unique && e.valid !== !1 && t.valid !== !1 && Rn(e.where) === Rn(t.where) && JSON.stringify(Me(e.kind, e.kindOptions)) === JSON.stringify(Me(t.kind, t.kindOptions)) && (e.expression ?? !1) === (t.expression ?? !1) && (e.expression === !0 && t.expression === !0 || e.columns.length === t.columns.length && e.columns.every((e, n) => e === t.columns[n])), zr = (e, t, n) => {
|
|
1380
1380
|
let r = new Map(t.columns.map((e) => [e.name, e])), i = new Map(e.columns.map((e) => [e.name, e])), a = [], o = [], s = [], c = new Set(e.indexes.flatMap((e) => e.columns));
|
|
1381
1381
|
for (let t of e.columns) {
|
|
1382
1382
|
let i = r.get(t.name);
|
|
@@ -1384,7 +1384,7 @@ BEGIN
|
|
|
1384
1384
|
a.push(t);
|
|
1385
1385
|
continue;
|
|
1386
1386
|
}
|
|
1387
|
-
|
|
1387
|
+
Ir(t, i, n, c.has(t.name) || t.unique, zn(e, t)) || s.push({
|
|
1388
1388
|
declared: t,
|
|
1389
1389
|
live: i
|
|
1390
1390
|
});
|
|
@@ -1395,50 +1395,50 @@ BEGIN
|
|
|
1395
1395
|
removed: o,
|
|
1396
1396
|
changed: s
|
|
1397
1397
|
};
|
|
1398
|
-
},
|
|
1398
|
+
}, Br = (e, t, n) => {
|
|
1399
1399
|
let r = (e) => n === "turso" || n === "sqlite" ? e.toLowerCase() : e, i = new Map(t.indexes.map((e) => [r(e.name), e])), a = new Map(e.indexes.map((e) => [r(e.name), e])), o = [], s = [];
|
|
1400
1400
|
for (let t of e.indexes) {
|
|
1401
1401
|
let e = i.get(r(t.name));
|
|
1402
|
-
(!e || !
|
|
1402
|
+
(!e || !Rr(t, e)) && o.push(t);
|
|
1403
1403
|
}
|
|
1404
1404
|
for (let e of t.indexes) {
|
|
1405
1405
|
let t = a.get(r(e.name));
|
|
1406
|
-
(!t || !
|
|
1406
|
+
(!t || !Rr(t, e)) && s.push(e);
|
|
1407
1407
|
}
|
|
1408
1408
|
return {
|
|
1409
1409
|
added: o,
|
|
1410
1410
|
removed: s
|
|
1411
1411
|
};
|
|
1412
|
-
},
|
|
1412
|
+
}, R = (e, t, n, r) => ({
|
|
1413
1413
|
op: e,
|
|
1414
1414
|
classification: t,
|
|
1415
|
-
atomicByDialect:
|
|
1415
|
+
atomicByDialect: jr(e.kind),
|
|
1416
1416
|
...n ? { reason: n } : {},
|
|
1417
1417
|
...r ? { blocked: r } : {}
|
|
1418
|
-
}),
|
|
1418
|
+
}), Vr = (e, t, n) => {
|
|
1419
1419
|
let r = {
|
|
1420
1420
|
kind: "add-column",
|
|
1421
1421
|
table: e,
|
|
1422
1422
|
column: t
|
|
1423
1423
|
};
|
|
1424
|
-
return t.nullable ?
|
|
1425
|
-
},
|
|
1424
|
+
return t.nullable ? R(r, "safe", "nullable column add — no backfill needed") : t.hasDefault && t.defaultValue !== void 0 ? R(r, "needs-default", "NOT NULL with literal default — DDL DEFAULT will populate existing rows") : n?.backfill ? R(r, "needs-backfill", `backfill declared (kind=${n.backfill.kind}) — applier will run 3-step add/update/set-not-null`) : R(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` });
|
|
1425
|
+
}, Hr = (e, t, n) => {
|
|
1426
1426
|
let r = {
|
|
1427
1427
|
kind: "drop-column",
|
|
1428
1428
|
table: e,
|
|
1429
1429
|
column: t.name
|
|
1430
1430
|
};
|
|
1431
|
-
return n?.dropped ?
|
|
1432
|
-
},
|
|
1431
|
+
return n?.dropped ? R(r, "lossy", `column dropped via \`${t.name}: dropped()\` marker — intentional`) : R(r, "lossy", "column missing from declared schema", { fix: `if intentional, add \`${t.name}: dropped()\` to the schema. If a typo, restore the field` });
|
|
1432
|
+
}, Ur = (e, t, n, r, i) => R({
|
|
1433
1433
|
kind: "create-table",
|
|
1434
1434
|
table: e,
|
|
1435
1435
|
columns: t,
|
|
1436
1436
|
indexes: n,
|
|
1437
1437
|
...r && r.length > 0 ? { primaryKey: r } : {}
|
|
1438
|
-
}, "safe", i ?? "new table — no data to preserve"),
|
|
1438
|
+
}, "safe", i ?? "new table — no data to preserve"), Wr = (e) => R({
|
|
1439
1439
|
kind: "drop-table",
|
|
1440
1440
|
table: e
|
|
1441
|
-
}, "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" }),
|
|
1441
|
+
}, "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" }), Gr = 5e4, Kr = (e, t, n, r) => {
|
|
1442
1442
|
let i = (n ?? 0) >= r, a;
|
|
1443
1443
|
return a = !t.unique || t.where !== void 0 ? {
|
|
1444
1444
|
kind: "add-index",
|
|
@@ -1453,20 +1453,20 @@ BEGIN
|
|
|
1453
1453
|
table: e,
|
|
1454
1454
|
name: t.name,
|
|
1455
1455
|
fields: t.columns
|
|
1456
|
-
}, i ?
|
|
1457
|
-
},
|
|
1456
|
+
}, i ? R(a, "online-required", `online build on ${n} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(a, "safe", t.where === void 0 ? t.unique ? t.columns.length === 1 ? "add unique constraint" : "add composite UNIQUE constraint" : `add ${t.kind === void 0 || t.kind === "btree" ? "B-tree" : t.kind.toUpperCase()} index` : `add ${t.unique ? "unique " : ""}partial index`);
|
|
1457
|
+
}, qr = (e, t) => t.unique && t.where === void 0 && t.columns.length > 1 ? R({
|
|
1458
1458
|
kind: "drop-unique-composite",
|
|
1459
1459
|
table: e,
|
|
1460
1460
|
name: t.name
|
|
1461
|
-
}, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") :
|
|
1461
|
+
}, "safe", "drop composite UNIQUE constraint (no data loss — constraint is derived metadata)") : R({
|
|
1462
1462
|
kind: "drop-index",
|
|
1463
1463
|
table: e,
|
|
1464
1464
|
index: t.name
|
|
1465
|
-
}, "safe", "drop index (no data loss — index is derived data)"),
|
|
1465
|
+
}, "safe", "drop index (no data loss — index is derived data)"), Jr = (e, t) => {
|
|
1466
1466
|
let n = e.type;
|
|
1467
|
-
if (n === "id") return
|
|
1467
|
+
if (n === "id") return Wn(e) === "numeric" ? "bigint" : "text";
|
|
1468
1468
|
if (n === "array") return t === void 0 || t === "postgres" ? "array" : t === "mysql" || t === "mariadb" ? "json" : "text";
|
|
1469
|
-
if (n === "enum") return t === "mssql" ||
|
|
1469
|
+
if (n === "enum") return t === "mssql" || O(t ?? "postgres") ? "text" : "enum";
|
|
1470
1470
|
if (n === "reference") return e.referenceStorage === "numeric" ? "bigint" : "text";
|
|
1471
1471
|
switch (t) {
|
|
1472
1472
|
case "sqlite":
|
|
@@ -1474,10 +1474,10 @@ BEGIN
|
|
|
1474
1474
|
case "mssql": return n === "json" ? "text" : n;
|
|
1475
1475
|
default: return n;
|
|
1476
1476
|
}
|
|
1477
|
-
},
|
|
1477
|
+
}, Yr = (e, t, n) => {
|
|
1478
1478
|
let r = `acknowledge it on the column: \`.narrowedFrom('${e}')\``;
|
|
1479
1479
|
return n === "postgres" ? `${r} — add \`{ using: '${t.name}::${t.type}' }\` when the cast is not implicit, or use a file-based migration` : `${r} — ${n === void 0 ? "this dialect" : n} converts in place (\`using\` is postgres-only and is ignored here), so verify the conversion is value-preserving for your data, or use a file-based migration`;
|
|
1480
|
-
},
|
|
1480
|
+
}, Xr = (e, t, n, r, i, a) => {
|
|
1481
1481
|
let o = [];
|
|
1482
1482
|
if (t.nullable !== n.nullable) {
|
|
1483
1483
|
let n = {
|
|
@@ -1486,7 +1486,7 @@ BEGIN
|
|
|
1486
1486
|
column: t.name,
|
|
1487
1487
|
toNullable: t.nullable
|
|
1488
1488
|
};
|
|
1489
|
-
o.push(t.nullable ?
|
|
1489
|
+
o.push(t.nullable ? R(n, "safe", `loosen ${e}.${t.name} to nullable`) : R(n, "needs-backfill", `tighten ${e}.${t.name} to NOT NULL — existing rows must already be non-null`));
|
|
1490
1490
|
}
|
|
1491
1491
|
if (t.unique !== n.unique) {
|
|
1492
1492
|
if (t.unique) {
|
|
@@ -1495,14 +1495,14 @@ BEGIN
|
|
|
1495
1495
|
table: e,
|
|
1496
1496
|
column: t.name
|
|
1497
1497
|
}, r = (i ?? 0) >= a;
|
|
1498
|
-
o.push(r ?
|
|
1499
|
-
} else o.push(
|
|
1498
|
+
o.push(r ? R(n, "online-required", `online unique build on ${i} rows — CONCURRENTLY / INPLACE / WITH(ONLINE=ON) depending on dialect`) : R(n, "safe", `add unique constraint on ${e}.${t.name} — existing rows must already be distinct (else the DB rejects at migrate)`));
|
|
1499
|
+
} else o.push(R({
|
|
1500
1500
|
kind: "drop-unique",
|
|
1501
1501
|
table: e,
|
|
1502
1502
|
column: t.name
|
|
1503
1503
|
}, "safe", `drop unique constraint on ${e}.${t.name} — constraint is derived metadata, no data loss`));
|
|
1504
1504
|
}
|
|
1505
|
-
if (
|
|
1505
|
+
if (Jn(t) && Jr(t, r) !== Jr(n, r)) {
|
|
1506
1506
|
let i = t.narrowedFrom;
|
|
1507
1507
|
if (i && i.from === n.type) {
|
|
1508
1508
|
let r = {
|
|
@@ -1513,7 +1513,7 @@ BEGIN
|
|
|
1513
1513
|
to: t.type,
|
|
1514
1514
|
...i.using === void 0 ? {} : { using: i.using }
|
|
1515
1515
|
};
|
|
1516
|
-
o.push(
|
|
1516
|
+
o.push(R(r, "needs-backfill", `type change ${n.type} → ${t.type} on ${e}.${t.name} — narrowedFrom('${i.from}') declared` + (i.using ? ` with USING ${i.using}` : " (implicit cast)")));
|
|
1517
1517
|
} else {
|
|
1518
1518
|
let i = {
|
|
1519
1519
|
kind: "alter-column-type",
|
|
@@ -1522,12 +1522,12 @@ BEGIN
|
|
|
1522
1522
|
from: n.type,
|
|
1523
1523
|
to: t.type
|
|
1524
1524
|
};
|
|
1525
|
-
o.push(
|
|
1525
|
+
o.push(R(i, "lossy", `type change ${n.type} → ${t.type} on ${e}.${t.name} may not be value-preserving`, { fix: Yr(n.type, t, r) }));
|
|
1526
1526
|
}
|
|
1527
1527
|
}
|
|
1528
|
-
if (t.type === "text" &&
|
|
1528
|
+
if (t.type === "text" && Gn(n) && !O(r ?? "postgres") && t.maxLength !== n.maxLength) {
|
|
1529
1529
|
let r = t.maxLength === void 0 || n.maxLength !== void 0 && t.maxLength > n.maxLength, i = n.maxLength === void 0 ? "unbounded" : `varchar(${n.maxLength})`, a = t.maxLength === void 0 ? "unbounded" : `varchar(${t.maxLength})`;
|
|
1530
|
-
o.push(
|
|
1530
|
+
o.push(R({
|
|
1531
1531
|
kind: "alter-column-type",
|
|
1532
1532
|
table: e,
|
|
1533
1533
|
column: t.name,
|
|
@@ -1538,7 +1538,7 @@ BEGIN
|
|
|
1538
1538
|
if (t.type === "enum" && n.type === "enum" && n.enumValues !== void 0 && t.enumValues !== void 0) {
|
|
1539
1539
|
let r = new Set(n.enumValues);
|
|
1540
1540
|
new Set(t.enumValues);
|
|
1541
|
-
for (let n of t.enumValues) r.has(n) || o.push(
|
|
1541
|
+
for (let n of t.enumValues) r.has(n) || o.push(R({
|
|
1542
1542
|
kind: "add-enum-value",
|
|
1543
1543
|
table: e,
|
|
1544
1544
|
column: t.name,
|
|
@@ -1546,9 +1546,9 @@ BEGIN
|
|
|
1546
1546
|
...t.enumName === void 0 ? {} : { enumName: t.enumName }
|
|
1547
1547
|
}, "safe", `add '${n}' to the enum on ${e}.${t.name} — existing rows are untouched, and the label is what the declaration already promises`));
|
|
1548
1548
|
}
|
|
1549
|
-
if (!
|
|
1549
|
+
if (!Xn(t.spatial, n.spatial)) {
|
|
1550
1550
|
let r = t.spatial, i = n.spatial, a = (e) => e === void 0 ? "plain text" : `${e.kind}(${e.geomKind},${String(e.srid)})`, s = r !== void 0 && i !== void 0 && r.kind === i.kind && r.geomKind.toUpperCase() === i.geomKind.toUpperCase() && r.srid !== i.srid, c = r === void 0 ? void 0 : r.kind === "geography" ? `ST_Transform("${t.name}"::geometry, ${String(r.srid)})::geography` : `ST_Transform("${t.name}", ${String(r.srid)})`, l = t.narrowedFrom, u = l !== void 0 && l.from === n.type, d = s ? c : u ? l.using : void 0;
|
|
1551
|
-
o.push(
|
|
1551
|
+
o.push(R({
|
|
1552
1552
|
kind: "alter-column-type",
|
|
1553
1553
|
table: e,
|
|
1554
1554
|
column: t.name,
|
|
@@ -1559,7 +1559,7 @@ BEGIN
|
|
|
1559
1559
|
}
|
|
1560
1560
|
if (t.type === "array" && n.type === "array" && n.arrayElement !== void 0 && t.arrayElement !== void 0 && t.arrayElement !== n.arrayElement) {
|
|
1561
1561
|
let r = t.narrowedFrom, i = r !== void 0 && r.from === n.type;
|
|
1562
|
-
o.push(
|
|
1562
|
+
o.push(R({
|
|
1563
1563
|
kind: "alter-column-type",
|
|
1564
1564
|
table: e,
|
|
1565
1565
|
column: t.name,
|
|
@@ -1570,7 +1570,7 @@ BEGIN
|
|
|
1570
1570
|
}
|
|
1571
1571
|
if (t.type === "vector" && n.type === "vector" && (n.vectorDim !== void 0 && t.vectorDim !== n.vectorDim || (t.vectorPrecision ?? "float32") !== (n.vectorPrecision ?? "float32"))) {
|
|
1572
1572
|
let r = (e) => `${e.vectorPrecision === "half" ? "halfvec" : "vector"}(${String(e.vectorDim ?? "?")})`, i = t.narrowedFrom, a = i !== void 0 && i.from === n.type;
|
|
1573
|
-
o.push(
|
|
1573
|
+
o.push(R({
|
|
1574
1574
|
kind: "alter-column-type",
|
|
1575
1575
|
table: e,
|
|
1576
1576
|
column: t.name,
|
|
@@ -1581,7 +1581,7 @@ BEGIN
|
|
|
1581
1581
|
}
|
|
1582
1582
|
if (t.type === "decimal" && n.type === "decimal" && n.precision !== void 0 && (t.precision !== n.precision || (t.scale ?? 0) !== (n.scale ?? 0))) {
|
|
1583
1583
|
let r = (e) => `${String(e.precision)},${String(e.scale ?? 0)}`, i = t.precision !== void 0 && n.precision !== void 0 && t.precision - (t.scale ?? 0) >= n.precision - (n.scale ?? 0) && (t.scale ?? 0) >= (n.scale ?? 0);
|
|
1584
|
-
o.push(
|
|
1584
|
+
o.push(R({
|
|
1585
1585
|
kind: "alter-column-type",
|
|
1586
1586
|
table: e,
|
|
1587
1587
|
column: t.name,
|
|
@@ -1589,7 +1589,7 @@ BEGIN
|
|
|
1589
1589
|
to: "decimal"
|
|
1590
1590
|
}, i ? "safe" : "needs-backfill", i ? `decimal(${r(n)}) → decimal(${r(t)}) on ${e}.${t.name} — widening, every value survives` : `decimal(${r(n)}) → decimal(${r(t)}) on ${e}.${t.name} — NARROWING; the engine ROUNDS to the new scale and rejects a value that no longer fits. Check first: SELECT COUNT(*) FROM ${e} WHERE ${t.name} <> ROUND(${t.name}, ${String(t.scale ?? 0)})`));
|
|
1591
1591
|
}
|
|
1592
|
-
if (!
|
|
1592
|
+
if (!Nr(t, n)) {
|
|
1593
1593
|
let n = {
|
|
1594
1594
|
kind: "alter-column-default",
|
|
1595
1595
|
table: e,
|
|
@@ -1597,11 +1597,11 @@ BEGIN
|
|
|
1597
1597
|
hasDefault: t.hasDefault,
|
|
1598
1598
|
...t.defaultValue === void 0 ? {} : { defaultValue: t.defaultValue }
|
|
1599
1599
|
};
|
|
1600
|
-
o.push(
|
|
1600
|
+
o.push(R(n, "safe", `default change on ${e}.${t.name} affects only future inserts`));
|
|
1601
1601
|
}
|
|
1602
1602
|
if (r === "mssql" && t.jsonValidation !== void 0 && t.jsonValidation !== "unverified" && t.jsonValidation !== n.jsonValidation) {
|
|
1603
1603
|
let r = t.jsonValidation === "value" && n.jsonValidation === "container";
|
|
1604
|
-
o.push(
|
|
1604
|
+
o.push(R({
|
|
1605
1605
|
kind: "reconcile-json-check",
|
|
1606
1606
|
table: e,
|
|
1607
1607
|
column: t.name,
|
|
@@ -1610,21 +1610,21 @@ BEGIN
|
|
|
1610
1610
|
dropConstraints: (n.jsonChecks ?? []).map((e) => e.name).sort()
|
|
1611
1611
|
}, r ? "safe" : "needs-backfill", r ? `allow every JSON value on ${e}.${t.name}; preserve existing rows` : `validate existing JSON on ${e}.${t.name}; invalid rows refuse the migration without being rewritten`));
|
|
1612
1612
|
}
|
|
1613
|
-
if (!
|
|
1614
|
-
n.oneOf && n.oneOf.length > 0 && o.push(
|
|
1613
|
+
if (!Pr(t.oneOf, n.oneOf)) {
|
|
1614
|
+
n.oneOf && n.oneOf.length > 0 && o.push(R({
|
|
1615
1615
|
kind: "drop-check",
|
|
1616
1616
|
table: e,
|
|
1617
1617
|
column: t.name
|
|
1618
1618
|
}, "safe", `drop stale enum CHECK on ${e}.${t.name}`));
|
|
1619
|
-
let r =
|
|
1619
|
+
let r = Lr(e, t);
|
|
1620
1620
|
r && o.push(r);
|
|
1621
1621
|
}
|
|
1622
|
-
return JSON.stringify(
|
|
1622
|
+
return JSON.stringify(nr(t.references)) !== JSON.stringify(nr(n.references)) && (n.references && o.push(R({
|
|
1623
1623
|
kind: "drop-foreign-key",
|
|
1624
1624
|
table: e,
|
|
1625
1625
|
column: t.name
|
|
1626
|
-
}, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...
|
|
1627
|
-
},
|
|
1626
|
+
}, "safe", `drop FK on ${e}.${t.name} (→ ${n.references.table})`)), o.push(...Zr(e, t))), o;
|
|
1627
|
+
}, Zr = (e, t) => {
|
|
1628
1628
|
let n = [];
|
|
1629
1629
|
if (!t.references) return n;
|
|
1630
1630
|
let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
|
|
@@ -1636,15 +1636,15 @@ BEGIN
|
|
|
1636
1636
|
...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
|
|
1637
1637
|
...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
|
|
1638
1638
|
};
|
|
1639
|
-
return i === "null" && !t.nullable ? n.push(
|
|
1639
|
+
return i === "null" && !t.nullable ? n.push(R(a, "lossy", `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' needs a nullable column (the NULL-out would violate NOT NULL)`, { fix: `make ${t.name} \`.nullable()\`, OR use \`orphanPolicy: 'delete'\`, OR clean the orphans and drop the policy` })) : i === "null" || i === "delete" ? n.push(R({
|
|
1640
1640
|
...a,
|
|
1641
1641
|
orphanPolicy: i
|
|
1642
|
-
}, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(
|
|
1643
|
-
},
|
|
1642
|
+
}, "lossy", i === "delete" ? `add FK ${e}.${t.name} → ${r}: orphanPolicy 'delete' first DELETES rows whose ${t.name} points at a missing ${r}` : `add FK ${e}.${t.name} → ${r}: orphanPolicy 'null' first NULLs ${t.name} where it points at a missing ${r}`)) : n.push(R(a, "needs-backfill", `add FK ${e}.${t.name} → ${r} — existing rows must already reference a valid ${r} (else set orphanPolicy:'null'/'delete')`)), n;
|
|
1643
|
+
}, Qr = (e, t, n) => {
|
|
1644
1644
|
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));
|
|
1645
1645
|
for (let [n, c] of Object.entries(t)) {
|
|
1646
1646
|
let t = c.renamedFrom;
|
|
1647
|
-
t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(
|
|
1647
|
+
t && o.has(t) && s.has(n) && (i.add(n), a.add(t), r.push(R({
|
|
1648
1648
|
kind: "rename-column",
|
|
1649
1649
|
table: e.tableName,
|
|
1650
1650
|
from: t,
|
|
@@ -1656,26 +1656,26 @@ BEGIN
|
|
|
1656
1656
|
consumedAddedNames: i,
|
|
1657
1657
|
consumedRemovedNames: a
|
|
1658
1658
|
};
|
|
1659
|
-
},
|
|
1659
|
+
}, $r = /* @__PURE__ */ new Set([
|
|
1660
1660
|
"postgres",
|
|
1661
1661
|
"mysql",
|
|
1662
1662
|
"mariadb",
|
|
1663
1663
|
"mssql"
|
|
1664
|
-
]),
|
|
1664
|
+
]), ei = {
|
|
1665
1665
|
ops: [],
|
|
1666
1666
|
consumedAddedNames: /* @__PURE__ */ new Set(),
|
|
1667
1667
|
consumedRemovedNames: /* @__PURE__ */ new Set()
|
|
1668
|
-
},
|
|
1669
|
-
if (i === void 0 ||
|
|
1670
|
-
let a = t.added.filter((e) =>
|
|
1671
|
-
if (a.length === 0) return
|
|
1668
|
+
}, ti = (e) => !e.unique && !e.expression && e.where === void 0 && (e.kind === void 0 || e.kind === "btree"), ni = (e, t, n, r, i) => {
|
|
1669
|
+
if (i === void 0 || !$r.has(i)) return ei;
|
|
1670
|
+
let a = t.added.filter((e) => ti(e) && !r.has(e.name));
|
|
1671
|
+
if (a.length === 0) return ei;
|
|
1672
1672
|
let o = (e) => e.columns.map((e) => n.get(e) ?? e).join("\0"), s = (e) => e.columns.join("\0"), c = [], l = /* @__PURE__ */ new Set(), u = /* @__PURE__ */ new Set();
|
|
1673
1673
|
for (let n of t.removed) {
|
|
1674
|
-
if (!
|
|
1674
|
+
if (!ti(n) || t.added.some((e) => e.name === n.name)) continue;
|
|
1675
1675
|
let r = o(n), i = a.filter((e) => !l.has(e.name) && s(e) === r);
|
|
1676
1676
|
if (i.length !== 1) continue;
|
|
1677
1677
|
let d = i[0];
|
|
1678
|
-
d.name !== n.name && (l.add(d.name), u.add(n.name), c.push(
|
|
1678
|
+
d.name !== n.name && (l.add(d.name), u.add(n.name), c.push(R({
|
|
1679
1679
|
kind: "rename-index",
|
|
1680
1680
|
table: e,
|
|
1681
1681
|
from: n.name,
|
|
@@ -1687,7 +1687,7 @@ BEGIN
|
|
|
1687
1687
|
consumedAddedNames: l,
|
|
1688
1688
|
consumedRemovedNames: u
|
|
1689
1689
|
};
|
|
1690
|
-
},
|
|
1690
|
+
}, ri = (e, t, n) => {
|
|
1691
1691
|
let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
|
|
1692
1692
|
for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
|
|
1693
1693
|
for (let c of e.tables) {
|
|
@@ -1698,7 +1698,7 @@ BEGIN
|
|
|
1698
1698
|
continue;
|
|
1699
1699
|
}
|
|
1700
1700
|
if (t.has(c.name)) {
|
|
1701
|
-
r.push(
|
|
1701
|
+
r.push(R({
|
|
1702
1702
|
kind: "rename-table",
|
|
1703
1703
|
from: e,
|
|
1704
1704
|
to: c.name
|
|
@@ -1706,14 +1706,14 @@ BEGIN
|
|
|
1706
1706
|
continue;
|
|
1707
1707
|
}
|
|
1708
1708
|
if ((s.get(e) ?? 0) !== 1) {
|
|
1709
|
-
r.push(
|
|
1709
|
+
r.push(R({
|
|
1710
1710
|
kind: "rename-table",
|
|
1711
1711
|
from: e,
|
|
1712
1712
|
to: c.name
|
|
1713
1713
|
}, "needs-rename-annotation", `.renamedFrom('${e}') is claimed by ${s.get(e)} tables — nothing says which receives its rows`, { fix: `remove the \`.renamedFrom('${e}')\` marker from all but one of them.` }));
|
|
1714
1714
|
continue;
|
|
1715
1715
|
}
|
|
1716
|
-
i.set(c.name, e), a.add(e), r.push(
|
|
1716
|
+
i.set(c.name, e), a.add(e), r.push(R({
|
|
1717
1717
|
kind: "rename-table",
|
|
1718
1718
|
from: e,
|
|
1719
1719
|
to: c.name
|
|
@@ -1727,19 +1727,19 @@ BEGIN
|
|
|
1727
1727
|
claimedOldNames: c,
|
|
1728
1728
|
refusals: o
|
|
1729
1729
|
};
|
|
1730
|
-
},
|
|
1730
|
+
}, ii = (e, t, n, r) => {
|
|
1731
1731
|
if (t === void 0) return {
|
|
1732
1732
|
live: e,
|
|
1733
1733
|
ops: []
|
|
1734
1734
|
};
|
|
1735
|
-
let i = r !== void 0 &&
|
|
1735
|
+
let i = r !== void 0 && $r.has(r), a = [], o = e.indexes.map((e) => {
|
|
1736
1736
|
if (!e.name.startsWith(t)) return e;
|
|
1737
1737
|
let r = `${n}${e.name.slice(t.length)}`;
|
|
1738
1738
|
return r === e.name ? e : e.name === `${t}_pkey` ? {
|
|
1739
1739
|
...e,
|
|
1740
1740
|
name: r,
|
|
1741
1741
|
table: n
|
|
1742
|
-
} : i ? (a.push(
|
|
1742
|
+
} : i ? (a.push(R({
|
|
1743
1743
|
kind: "rename-index",
|
|
1744
1744
|
table: n,
|
|
1745
1745
|
from: e.name,
|
|
@@ -1758,7 +1758,7 @@ BEGIN
|
|
|
1758
1758
|
},
|
|
1759
1759
|
ops: a
|
|
1760
1760
|
};
|
|
1761
|
-
},
|
|
1761
|
+
}, ai = (e) => {
|
|
1762
1762
|
let t = {
|
|
1763
1763
|
safe: 0,
|
|
1764
1764
|
needsDefault: 0,
|
|
@@ -1791,19 +1791,19 @@ BEGIN
|
|
|
1791
1791
|
case "multi-step": t.multiStep++;
|
|
1792
1792
|
}
|
|
1793
1793
|
return t;
|
|
1794
|
-
},
|
|
1794
|
+
}, oi = (e, t) => {
|
|
1795
1795
|
let n = t.flatMap((e) => [e.table, e.targetTable]).flatMap((e) => {
|
|
1796
1796
|
let t = w(e);
|
|
1797
1797
|
return t === void 0 ? [] : [t.getTime()];
|
|
1798
1798
|
}), r = new Date(Math.max(...n)), i = new Date(Date.UTC(r.getUTCFullYear(), r.getUTCMonth(), r.getUTCDate() + 1)).toISOString().slice(0, 10);
|
|
1799
1799
|
return `${e.join("; ")}. Reclaim the snapshots first — \`voltro db gc-snapshots --before ${i}\` drops every snapshot older than that date, so run it with --dry-run to see the list — or, if a snapshot's data is still wanted, bring it back with \`voltro db restore-snapshot <plan-id>\` and declare it, so it converts in the same plan.`;
|
|
1800
|
-
},
|
|
1800
|
+
}, si = (e, t, n, r) => {
|
|
1801
1801
|
let i = /* @__PURE__ */ new Map();
|
|
1802
1802
|
for (let a of e.tables) {
|
|
1803
1803
|
let e = t.get(a.name) ?? (n.has(a.name) ? t.get(n.get(a.name)) : void 0);
|
|
1804
1804
|
if (e === void 0) continue;
|
|
1805
|
-
let o = new Set(a.columns.filter(
|
|
1806
|
-
|
|
1805
|
+
let o = new Set(a.columns.filter(pr).map((e) => e.name));
|
|
1806
|
+
hr(e).filter((e) => o.has(e.column) && e.charset !== r).length > 0 && i.set(a.name, {
|
|
1807
1807
|
declared: a,
|
|
1808
1808
|
live: e
|
|
1809
1809
|
});
|
|
@@ -1828,14 +1828,14 @@ BEGIN
|
|
|
1828
1828
|
}
|
|
1829
1829
|
let o = [];
|
|
1830
1830
|
for (let [e, { declared: t, live: n }] of i) {
|
|
1831
|
-
let s = t.columns.filter(
|
|
1831
|
+
let s = t.columns.filter(pr).map((e) => e.name), c = new Map(n.columns.map((e) => [e.name, e])), l = [...new Set(s.flatMap((e) => {
|
|
1832
1832
|
let t = c.get(e);
|
|
1833
1833
|
return t?.charset === void 0 ? [] : [t.charset];
|
|
1834
1834
|
}))].sort(), u = s.filter((e) => c.has(e)), d = a.filter((t) => t.table === e || t.targetTable === e), f = [], p = [], m = d.map((t) => {
|
|
1835
1835
|
let n = t.table === e ? t.targetTable : t.table, a = n === e || i.has(n), o = t.table === e ? t.targetCharset : t.sourceCharset;
|
|
1836
1836
|
if (!a && o !== void 0 && o !== r) {
|
|
1837
1837
|
let e = `${t.name} (${t.table}.${t.column} → ${t.targetTable}.${t.targetColumn})`;
|
|
1838
|
-
|
|
1838
|
+
k(n) ? p.push(`${e}: "${n}" is a soft-drop snapshot, stored ${o}`) : f.push(`${e}: "${n}" stays ${o} — it is not a declared table, so the plan does not convert it`);
|
|
1839
1839
|
}
|
|
1840
1840
|
let { sourceCharset: s, targetCharset: c, ...l } = t, u = a && n !== e && n.localeCompare(e) > 0 ? "peer" : "here";
|
|
1841
1841
|
return {
|
|
@@ -1851,20 +1851,20 @@ BEGIN
|
|
|
1851
1851
|
foreignKeys: m
|
|
1852
1852
|
};
|
|
1853
1853
|
if (f.length > 0 || p.length > 0) {
|
|
1854
|
-
let t = [...f.length > 0 ? [`${f.join("; ")}. Declare that table so it converts in the same plan, convert it by hand first, or leave the store charset undeclared.`] : [], ...p.length > 0 ? [
|
|
1855
|
-
o.push(
|
|
1854
|
+
let t = [...f.length > 0 ? [`${f.join("; ")}. Declare that table so it converts in the same plan, convert it by hand first, or leave the store charset undeclared.`] : [], ...p.length > 0 ? [oi(p, d)] : []];
|
|
1855
|
+
o.push(R(_, "lossy", g, { fix: `converting "${e}" to ${r} would break a foreign key the plan cannot carry: ${t.join(" ")}` }));
|
|
1856
1856
|
continue;
|
|
1857
1857
|
}
|
|
1858
|
-
o.push(h ?
|
|
1858
|
+
o.push(h ? R(_, "safe", g) : R(_, "lossy", g, { fix: `${e}: narrowing to ${r} can refuse or truncate 4-byte characters the columns already hold. Declare charset: 'utf8mb4' instead, or — after checking the data — allow it with the destructive opt-in (VOLTRO_DESTRUCTIVE_OK=1).` }));
|
|
1859
1859
|
}
|
|
1860
1860
|
return o;
|
|
1861
|
-
},
|
|
1862
|
-
let t =
|
|
1861
|
+
}, ci = (e) => {
|
|
1862
|
+
let t = Tr(e.declared, e.dialect, { charset: e.charset }), n = Mr(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Gr, a = [], o = ri(t, r, n);
|
|
1863
1863
|
a.push(...o.ops);
|
|
1864
1864
|
for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
|
|
1865
|
-
a.push(
|
|
1865
|
+
a.push(Ur(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
|
|
1866
1866
|
for (let t of e.columns) {
|
|
1867
|
-
let n =
|
|
1867
|
+
let n = Lr(e.name, t);
|
|
1868
1868
|
n && a.push(n);
|
|
1869
1869
|
}
|
|
1870
1870
|
}
|
|
@@ -1878,7 +1878,7 @@ BEGIN
|
|
|
1878
1878
|
c.push(t.name);
|
|
1879
1879
|
continue;
|
|
1880
1880
|
}
|
|
1881
|
-
if (
|
|
1881
|
+
if (k(t.name)) {
|
|
1882
1882
|
c.push(t.name);
|
|
1883
1883
|
continue;
|
|
1884
1884
|
}
|
|
@@ -1886,28 +1886,28 @@ BEGIN
|
|
|
1886
1886
|
c.push(t.name);
|
|
1887
1887
|
continue;
|
|
1888
1888
|
}
|
|
1889
|
-
a.push(
|
|
1889
|
+
a.push(Wr(t.name));
|
|
1890
1890
|
}
|
|
1891
1891
|
for (let s of t.tables) {
|
|
1892
1892
|
let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
|
|
1893
1893
|
if (!c) continue;
|
|
1894
|
-
let l =
|
|
1894
|
+
let l = ii(c, t, s.name, e.dialect);
|
|
1895
1895
|
a.push(...l.ops);
|
|
1896
|
-
let u = l.live, d = n.get(s.name), f =
|
|
1896
|
+
let u = l.live, d = n.get(s.name), f = zr(s, u, e.dialect), p = Br(s, u, e.dialect), m = Qr(d.table, d.columnDefs, f);
|
|
1897
1897
|
a.push(...m.ops);
|
|
1898
1898
|
for (let { op: t } of m.ops) {
|
|
1899
1899
|
if (t.kind !== "rename-column") continue;
|
|
1900
1900
|
let n = s.columns.find((e) => e.name === t.to), r = u.columns.find((e) => e.name === t.from);
|
|
1901
|
-
n && r && a.push(...
|
|
1901
|
+
n && r && a.push(...Xr(s.name, n, {
|
|
1902
1902
|
...r,
|
|
1903
1903
|
name: t.to
|
|
1904
1904
|
}, e.dialect, u.rowCount, i));
|
|
1905
1905
|
}
|
|
1906
1906
|
for (let e of f.removed) {
|
|
1907
|
-
if (m.consumedRemovedNames.has(e.name) ||
|
|
1908
|
-
let t = d.columnDefs[e.name], n =
|
|
1907
|
+
if (m.consumedRemovedNames.has(e.name) || k(e.name)) continue;
|
|
1908
|
+
let t = d.columnDefs[e.name], n = Hr(s.name, e, t);
|
|
1909
1909
|
e.references !== void 0 && a.push({
|
|
1910
|
-
...
|
|
1910
|
+
...R({
|
|
1911
1911
|
kind: "drop-foreign-key",
|
|
1912
1912
|
table: s.name,
|
|
1913
1913
|
column: e.name,
|
|
@@ -1919,17 +1919,17 @@ BEGIN
|
|
|
1919
1919
|
for (let e of f.added) {
|
|
1920
1920
|
if (m.consumedAddedNames.has(e.name)) continue;
|
|
1921
1921
|
let t = d.columnDefs[e.name];
|
|
1922
|
-
a.push(
|
|
1923
|
-
let n =
|
|
1924
|
-
n && a.push(n), a.push(...
|
|
1922
|
+
a.push(Vr(s.name, e, t));
|
|
1923
|
+
let n = Lr(s.name, e);
|
|
1924
|
+
n && a.push(n), a.push(...Zr(s.name, e));
|
|
1925
1925
|
}
|
|
1926
|
-
let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g =
|
|
1926
|
+
let h = new Map(m.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), g = ni(s.name, p, h, new Set(u.indexes.map((e) => e.name)), e.dialect);
|
|
1927
1927
|
a.push(...g.ops);
|
|
1928
|
-
for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(
|
|
1929
|
-
for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(
|
|
1930
|
-
for (let { declared: t, live: n } of f.changed) a.push(...
|
|
1928
|
+
for (let e of p.added) g.consumedAddedNames.has(e.name) || a.push(Kr(s.name, e, u.rowCount, i));
|
|
1929
|
+
for (let e of p.removed) g.consumedRemovedNames.has(e.name) || a.push(qr(s.name, e));
|
|
1930
|
+
for (let { declared: t, live: n } of f.changed) a.push(...Xr(s.name, t, n, e.dialect, u.rowCount, i));
|
|
1931
1931
|
}
|
|
1932
|
-
e.charset !== void 0 && a.push(...
|
|
1932
|
+
e.charset !== void 0 && a.push(...si(t, r, o.renamedInto, e.charset));
|
|
1933
1933
|
let l = new Set(a.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), u = new Map(t.tables.map((e) => [e.name, e])), d = (e) => {
|
|
1934
1934
|
let t = u.get(e);
|
|
1935
1935
|
return t ? t.columns.flatMap((e) => e.references && l.has(e.references.table) ? [{
|
|
@@ -1937,7 +1937,7 @@ BEGIN
|
|
|
1937
1937
|
target: e.references.table
|
|
1938
1938
|
}] : []) : [];
|
|
1939
1939
|
}, f = Ve([...l], d), p = [];
|
|
1940
|
-
for (let e of t.tables) if (l.has(e.name)) for (let t of e.columns) t.references && f.has(M(e.name, t.name)) && p.push(
|
|
1940
|
+
for (let e of t.tables) if (l.has(e.name)) for (let t of e.columns) t.references && f.has(M(e.name, t.name)) && p.push(R({
|
|
1941
1941
|
kind: "add-foreign-key",
|
|
1942
1942
|
table: e.name,
|
|
1943
1943
|
column: t.name,
|
|
@@ -2014,31 +2014,31 @@ BEGIN
|
|
|
2014
2014
|
for (let e of t.tables) {
|
|
2015
2015
|
if (S.has(e.name) || o.renamedInto.has(e.name)) continue;
|
|
2016
2016
|
let t = r.get(e.name);
|
|
2017
|
-
t !== void 0 &&
|
|
2017
|
+
t !== void 0 && L({ tables: [t] }) !== L({ tables: [e] }) && C.push(e.name);
|
|
2018
2018
|
}
|
|
2019
2019
|
return {
|
|
2020
2020
|
operations: x,
|
|
2021
|
-
fromFingerprint:
|
|
2022
|
-
toFingerprint:
|
|
2023
|
-
summary:
|
|
2021
|
+
fromFingerprint: L(e.live),
|
|
2022
|
+
toFingerprint: L(t),
|
|
2023
|
+
summary: ai(x),
|
|
2024
2024
|
fingerprintDivergence: {
|
|
2025
2025
|
outsideDiff: c,
|
|
2026
2026
|
diffEquivalent: C
|
|
2027
2027
|
}
|
|
2028
2028
|
};
|
|
2029
|
-
},
|
|
2030
|
-
id:
|
|
2029
|
+
}, z = "_voltro_deploys", li = l(z, {
|
|
2030
|
+
id: ne({ prefix: "dpl" }),
|
|
2031
2031
|
status: E(),
|
|
2032
2032
|
dialect: E(),
|
|
2033
2033
|
appliedBy: E(),
|
|
2034
2034
|
startedAt: E(),
|
|
2035
2035
|
baseline: E(),
|
|
2036
2036
|
report: E().nullable()
|
|
2037
|
-
}),
|
|
2038
|
-
VALUES (${t.id}, ${"running"}, ${t.dialect}, ${t.appliedBy}, ${(/* @__PURE__ */ new Date()).toISOString()}, ${t.baseline}, ${null})`.pipe(A.asVoid),
|
|
2037
|
+
}), ui = (e, t) => e`INSERT INTO ${e(z)} (${e("id")}, ${e("status")}, ${e("dialect")}, ${e("appliedBy")}, ${e("startedAt")}, ${e("baseline")}, ${e("report")})
|
|
2038
|
+
VALUES (${t.id}, ${"running"}, ${t.dialect}, ${t.appliedBy}, ${(/* @__PURE__ */ new Date()).toISOString()}, ${t.baseline}, ${null})`.pipe(A.asVoid), di = (e, t) => e`DELETE FROM ${e(z)} WHERE ${e("id")} = ${t}`.pipe(A.asVoid), fi = (e, t, n) => e`UPDATE ${e(z)} SET ${e("status")} = ${"failed"}, ${e("report")} = ${n} WHERE ${e("id")} = ${t}`.pipe(A.asVoid), pi = (e) => e`SELECT ${e("id")}, ${e("status")}, ${e("dialect")}, ${e("appliedBy")}, ${e("startedAt")}, ${e("baseline")}, ${e("report")} FROM ${e(z)}`.pipe(A.map((e) => e.map((e) => ({
|
|
2039
2039
|
...e,
|
|
2040
2040
|
startedAt: String(e.startedAt)
|
|
2041
|
-
}))), A.catchAll(() => A.succeed([]))),
|
|
2041
|
+
}))), A.catchAll(() => A.succeed([]))), mi = (e, t) => {
|
|
2042
2042
|
let n = (e.match(/'(?:''|[^'])*'|"(?:""|[^"])*"|::|[A-Za-z_][A-Za-z_0-9$]*|[^\s]/g) ?? []).filter((e) => e !== "(" && e !== ")"), r = 0, i = (e) => n[r]?.toLowerCase() === e && (r++, !0);
|
|
2043
2043
|
if (!i("check")) return null;
|
|
2044
2044
|
let a = n[r++];
|
|
@@ -2053,7 +2053,7 @@ BEGIN
|
|
|
2053
2053
|
if (e === void 0 || !/^'(?:''|[^'])*'$/.test(e) || (c.push(e.slice(1, -1).replace(/''/g, "'")), !o())) return null;
|
|
2054
2054
|
} while (s && i(","));
|
|
2055
2055
|
return s && (!i("]") || i("::") && (!i("text") || !i("[") || !i("]"))) ? null : r === n.length ? c : null;
|
|
2056
|
-
},
|
|
2056
|
+
}, hi = (e) => {
|
|
2057
2057
|
let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
|
|
2058
2058
|
if (!t) return null;
|
|
2059
2059
|
let n = [...e.replace(/\\'/g, "'").matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")).filter((e) => e.length > 0);
|
|
@@ -2061,7 +2061,7 @@ BEGIN
|
|
|
2061
2061
|
column: t[1],
|
|
2062
2062
|
values: n
|
|
2063
2063
|
};
|
|
2064
|
-
},
|
|
2064
|
+
}, gi = (e, t) => {
|
|
2065
2065
|
if (t === "vector" || t === "halfvec") return "vector";
|
|
2066
2066
|
switch (e) {
|
|
2067
2067
|
case "text":
|
|
@@ -2089,7 +2089,7 @@ BEGIN
|
|
|
2089
2089
|
case "USER-DEFINED": return "text";
|
|
2090
2090
|
default: return "text";
|
|
2091
2091
|
}
|
|
2092
|
-
},
|
|
2092
|
+
}, _i = {
|
|
2093
2093
|
_text: "text",
|
|
2094
2094
|
_varchar: "text",
|
|
2095
2095
|
_uuid: "text",
|
|
@@ -2105,10 +2105,10 @@ BEGIN
|
|
|
2105
2105
|
_date: "date",
|
|
2106
2106
|
_jsonb: "json",
|
|
2107
2107
|
_json: "json"
|
|
2108
|
-
},
|
|
2108
|
+
}, vi = (e) => e === void 0 ? void 0 : _i[e], yi = (e, t) => e == null || e === "" ? void 0 : { generatedAs: {
|
|
2109
2109
|
expr: e,
|
|
2110
2110
|
stored: t
|
|
2111
|
-
} },
|
|
2111
|
+
} }, bi = (e) => {
|
|
2112
2112
|
switch (e.toUpperCase()) {
|
|
2113
2113
|
case "CASCADE": return "cascade";
|
|
2114
2114
|
case "RESTRICT": return "restrict";
|
|
@@ -2116,25 +2116,25 @@ BEGIN
|
|
|
2116
2116
|
case "SET DEFAULT": return "noAction";
|
|
2117
2117
|
default: return "noAction";
|
|
2118
2118
|
}
|
|
2119
|
-
},
|
|
2119
|
+
}, xi = (e, t) => {
|
|
2120
2120
|
let n = e !== void 0 && e !== "" ? Number(e) : NaN;
|
|
2121
2121
|
return Number.isInteger(n) && n > 0 ? n : t;
|
|
2122
|
-
},
|
|
2122
|
+
}, Si = () => xi(process.env.VOLTRO_INTROSPECT_BATCH, 20), Ci = 300, wi = () => {
|
|
2123
2123
|
let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
|
|
2124
|
-
return e !== void 0 && e.trim() === "0" ? 0 :
|
|
2125
|
-
},
|
|
2124
|
+
return e !== void 0 && e.trim() === "0" ? 0 : xi(e, 3e4);
|
|
2125
|
+
}, Ti = (e, t) => {
|
|
2126
2126
|
let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
|
|
2127
2127
|
for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
|
|
2128
2128
|
return r;
|
|
2129
|
-
},
|
|
2130
|
-
let t =
|
|
2129
|
+
}, Ei = (e) => {
|
|
2130
|
+
let t = wi(), n = A.gen(function* () {
|
|
2131
2131
|
t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
|
|
2132
|
-
let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i =
|
|
2132
|
+
let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Si(), a = (e, t) => A.gen(function* () {
|
|
2133
2133
|
let r = [];
|
|
2134
|
-
for (let a of
|
|
2134
|
+
for (let a of Ti(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
|
|
2135
2135
|
return r;
|
|
2136
2136
|
}), o = [];
|
|
2137
|
-
for (let t = 0;; t +=
|
|
2137
|
+
for (let t = 0;; t += Ci) {
|
|
2138
2138
|
let n = yield* e`
|
|
2139
2139
|
SELECT c.relname AS table_name,
|
|
2140
2140
|
COALESCE(c.reltuples::bigint, 0) AS row_count
|
|
@@ -2142,9 +2142,9 @@ BEGIN
|
|
|
2142
2142
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
2143
2143
|
WHERE n.nspname = current_schema() AND c.relkind = 'r'
|
|
2144
2144
|
ORDER BY c.relname
|
|
2145
|
-
LIMIT ${r(
|
|
2145
|
+
LIMIT ${r(Ci)} OFFSET ${r(t)}
|
|
2146
2146
|
`;
|
|
2147
|
-
if (o.push(...n), n.length <
|
|
2147
|
+
if (o.push(...n), n.length < Ci) break;
|
|
2148
2148
|
}
|
|
2149
2149
|
let s = /* @__PURE__ */ new Set(), c = [];
|
|
2150
2150
|
for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
|
|
@@ -2207,7 +2207,7 @@ BEGIN
|
|
|
2207
2207
|
srid: e.srid
|
|
2208
2208
|
}])), y = /* @__PURE__ */ new Map();
|
|
2209
2209
|
for (let e of p) {
|
|
2210
|
-
let t =
|
|
2210
|
+
let t = mi(e.def, e.column_name);
|
|
2211
2211
|
t !== null && y.set(`${e.table_name}.${e.column_name}`, t);
|
|
2212
2212
|
}
|
|
2213
2213
|
let b = yield* a(l, (t) => e`
|
|
@@ -2286,18 +2286,18 @@ BEGIN
|
|
|
2286
2286
|
let t = C.get(e.table_name);
|
|
2287
2287
|
t || (t = /* @__PURE__ */ new Set(), C.set(e.table_name, t)), t.add(e.column_name);
|
|
2288
2288
|
}
|
|
2289
|
-
let
|
|
2289
|
+
let ee = /* @__PURE__ */ new Map();
|
|
2290
2290
|
for (let e of f) {
|
|
2291
|
-
let t = `${e.table_name}\u0000${e.constraint_name}`, n =
|
|
2291
|
+
let t = `${e.table_name}\u0000${e.constraint_name}`, n = ee.get(t);
|
|
2292
2292
|
n || (n = {
|
|
2293
2293
|
table: e.table_name,
|
|
2294
2294
|
columns: []
|
|
2295
|
-
},
|
|
2295
|
+
}, ee.set(t, n)), n.columns.push({
|
|
2296
2296
|
name: e.column_name,
|
|
2297
2297
|
position: e.position
|
|
2298
2298
|
});
|
|
2299
2299
|
}
|
|
2300
|
-
for (let [e, t] of
|
|
2300
|
+
for (let [e, t] of ee) {
|
|
2301
2301
|
let n = [...t.columns].sort((e, t) => e.position - t.position).map((e) => e.name);
|
|
2302
2302
|
if (n.length === 1) {
|
|
2303
2303
|
let e = w.get(t.table);
|
|
@@ -2322,14 +2322,14 @@ BEGIN
|
|
|
2322
2322
|
let n = t.get(e.index_name);
|
|
2323
2323
|
n || (n = [], t.set(e.index_name, n)), n.push(e);
|
|
2324
2324
|
}
|
|
2325
|
-
let
|
|
2325
|
+
let te = [];
|
|
2326
2326
|
for (let e of c) {
|
|
2327
2327
|
let t = /* @__PURE__ */ new Set(), n = (S.get(e.table_name) ?? []).filter((e) => !t.has(e.column_name) && (t.add(e.column_name), !0)), r = C.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = w.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = E.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) => {
|
|
2328
|
-
let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = t.data_type === "USER-DEFINED" && t.udt_name !== void 0 && g.has(t.udt_name), c = s ? "enum" :
|
|
2328
|
+
let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = t.data_type === "USER-DEFINED" && t.udt_name !== void 0 && g.has(t.udt_name), c = s ? "enum" : gi(t.data_type, t.udt_name), l = !a && n && t.column_name === "id", u = a ? "reference" : l ? "id" : c, d = a ? {
|
|
2329
2329
|
table: a.target_table,
|
|
2330
2330
|
column: a.target_column,
|
|
2331
|
-
onDelete:
|
|
2332
|
-
onUpdate:
|
|
2331
|
+
onDelete: bi(a.delete_rule),
|
|
2332
|
+
onUpdate: bi(a.update_rule),
|
|
2333
2333
|
constraintName: a.constraint_name
|
|
2334
2334
|
} : void 0, f = y.get(`${e.table_name}.${t.column_name}`);
|
|
2335
2335
|
return {
|
|
@@ -2339,14 +2339,14 @@ BEGIN
|
|
|
2339
2339
|
enumName: t.udt_name,
|
|
2340
2340
|
enumValues: h.get(t.udt_name) ?? []
|
|
2341
2341
|
} : {},
|
|
2342
|
-
...u === "array" &&
|
|
2342
|
+
...u === "array" && vi(t.udt_name) !== void 0 ? { arrayElement: vi(t.udt_name) } : {},
|
|
2343
2343
|
...v.has(`${e.table_name}.${t.column_name}`) ? { spatial: v.get(`${e.table_name}.${t.column_name}`) } : {},
|
|
2344
|
-
...l ? { idStorage:
|
|
2344
|
+
...l ? { idStorage: Vn(c) } : {},
|
|
2345
2345
|
...u === "vector" ? {
|
|
2346
2346
|
vectorPrecision: t.udt_name === "halfvec" ? "half" : "float32",
|
|
2347
2347
|
...t.type_modifier !== void 0 && t.type_modifier > 0 ? { vectorDim: t.type_modifier } : {}
|
|
2348
2348
|
} : {},
|
|
2349
|
-
...
|
|
2349
|
+
...Ri(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: Ri(t.data_type, t.character_maximum_length) },
|
|
2350
2350
|
...c === "decimal" && typeof t.numeric_precision == "number" ? {
|
|
2351
2351
|
precision: t.numeric_precision,
|
|
2352
2352
|
...typeof t.numeric_scale == "number" ? { scale: t.numeric_scale } : {}
|
|
@@ -2356,9 +2356,9 @@ BEGIN
|
|
|
2356
2356
|
hasDefault: t.column_default !== null,
|
|
2357
2357
|
...t.column_default === null ? {} : { defaultValue: t.column_default },
|
|
2358
2358
|
...d ? { references: d } : {},
|
|
2359
|
-
...a ? { referenceStorage: ["integer", "bigint"].includes(
|
|
2359
|
+
...a ? { referenceStorage: ["integer", "bigint"].includes(gi(t.data_type, t.udt_name)) ? "numeric" : "text" } : {},
|
|
2360
2360
|
...f ? { oneOf: f } : {},
|
|
2361
|
-
...
|
|
2361
|
+
...yi(t.is_generated === "ALWAYS" ? t.generation_expression ?? "generated" : null, !0) ?? {}
|
|
2362
2362
|
};
|
|
2363
2363
|
}), l = [], u = D.get(e.table_name);
|
|
2364
2364
|
if (u) for (let [t, n] of u) {
|
|
@@ -2395,20 +2395,20 @@ BEGIN
|
|
|
2395
2395
|
unique: !0
|
|
2396
2396
|
});
|
|
2397
2397
|
let d = Number(e.row_count ?? 0);
|
|
2398
|
-
|
|
2398
|
+
te.push({
|
|
2399
2399
|
name: e.table_name,
|
|
2400
2400
|
columns: c,
|
|
2401
2401
|
indexes: l,
|
|
2402
2402
|
...d > 0 ? { rowCount: d } : {}
|
|
2403
2403
|
});
|
|
2404
2404
|
}
|
|
2405
|
-
return { tables:
|
|
2405
|
+
return { tables: te };
|
|
2406
2406
|
});
|
|
2407
2407
|
return (t > 0 ? e.withTransaction(n) : n).pipe(A.catchAll((e) => {
|
|
2408
2408
|
let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
|
|
2409
2409
|
return n.includes("statement timeout") || n.includes("57014") ? A.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.`)) : A.fail(e);
|
|
2410
2410
|
}));
|
|
2411
|
-
},
|
|
2411
|
+
}, Di = (e, t) => {
|
|
2412
2412
|
switch (e.toLowerCase()) {
|
|
2413
2413
|
case "varchar":
|
|
2414
2414
|
case "char":
|
|
@@ -2440,22 +2440,22 @@ BEGIN
|
|
|
2440
2440
|
case "json": return "json";
|
|
2441
2441
|
default: return "text";
|
|
2442
2442
|
}
|
|
2443
|
-
},
|
|
2443
|
+
}, Oi = (e) => e.map((e) => {
|
|
2444
2444
|
let t = e, n = {};
|
|
2445
2445
|
for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
|
|
2446
2446
|
return n;
|
|
2447
|
-
}),
|
|
2448
|
-
let t =
|
|
2447
|
+
}), ki = (e) => A.gen(function* () {
|
|
2448
|
+
let t = Oi(yield* e`
|
|
2449
2449
|
SELECT table_name, COALESCE(table_rows, 0) AS table_rows
|
|
2450
2450
|
FROM information_schema.tables
|
|
2451
2451
|
WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'
|
|
2452
|
-
ORDER BY table_name`), n =
|
|
2452
|
+
ORDER BY table_name`), n = Oi(yield* e`
|
|
2453
2453
|
SELECT table_name, column_name, data_type, column_type, is_nullable, column_default, column_key,
|
|
2454
2454
|
character_maximum_length, numeric_precision, numeric_scale,
|
|
2455
2455
|
generation_expression, extra, character_set_name
|
|
2456
2456
|
FROM information_schema.columns
|
|
2457
2457
|
WHERE table_schema = DATABASE()
|
|
2458
|
-
ORDER BY table_name, ordinal_position`), r =
|
|
2458
|
+
ORDER BY table_name, ordinal_position`), r = Oi(yield* e`
|
|
2459
2459
|
SELECT k.table_name AS source_table,
|
|
2460
2460
|
k.column_name AS source_column,
|
|
2461
2461
|
k.referenced_table_name AS target_table,
|
|
@@ -2466,7 +2466,7 @@ BEGIN
|
|
|
2466
2466
|
JOIN information_schema.referential_constraints r
|
|
2467
2467
|
ON k.constraint_name = r.constraint_name
|
|
2468
2468
|
AND k.table_schema = r.constraint_schema
|
|
2469
|
-
WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i =
|
|
2469
|
+
WHERE k.table_schema = DATABASE() AND k.referenced_table_name IS NOT NULL`), i = Oi(yield* e`
|
|
2470
2470
|
SELECT table_name, index_name, non_unique, column_name, seq_in_index
|
|
2471
2471
|
FROM information_schema.statistics
|
|
2472
2472
|
WHERE table_schema = DATABASE() AND index_name <> 'PRIMARY'
|
|
@@ -2479,14 +2479,14 @@ BEGIN
|
|
|
2479
2479
|
JOIN information_schema.table_constraints tc
|
|
2480
2480
|
ON tc.constraint_schema = cc.constraint_schema
|
|
2481
2481
|
AND tc.constraint_name = cc.constraint_name
|
|
2482
|
-
WHERE cc.constraint_schema = DATABASE()`.unprepared, s =
|
|
2482
|
+
WHERE cc.constraint_schema = DATABASE()`.unprepared, s = Oi(yield* a.pipe(A.orElse(() => o), A.orElseSucceed(() => []))), c = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Map();
|
|
2483
2483
|
for (let e of s) {
|
|
2484
2484
|
let t = /json_valid\(`?([^`)]+)`?\)/i.exec(e.check_clause);
|
|
2485
2485
|
if (t) {
|
|
2486
2486
|
c.add(`${e.table_name}.${t[1]}`);
|
|
2487
2487
|
continue;
|
|
2488
2488
|
}
|
|
2489
|
-
let n =
|
|
2489
|
+
let n = hi(e.check_clause);
|
|
2490
2490
|
n && l.set(`${e.table_name}.${n.column}`, n.values);
|
|
2491
2491
|
}
|
|
2492
2492
|
let u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = /* @__PURE__ */ new Map();
|
|
@@ -2509,20 +2509,20 @@ BEGIN
|
|
|
2509
2509
|
let t = u.get(e.table_name) ?? [], n = d.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(), o = f.get(e.table_name);
|
|
2510
2510
|
if (o) for (let e of o.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
|
|
2511
2511
|
let s = t.map((t) => {
|
|
2512
|
-
let n = i.includes(t.column_name) && i.length === 1, o = r.get(t.column_name), s = c.has(`${e.table_name}.${t.column_name}`) ? "json" :
|
|
2512
|
+
let n = i.includes(t.column_name) && i.length === 1, o = r.get(t.column_name), s = c.has(`${e.table_name}.${t.column_name}`) ? "json" : Di(t.data_type, t.column_type), u = !o && n && t.column_name === "id", d = o ? "reference" : u ? "id" : s, f = o ? {
|
|
2513
2513
|
table: o.target_table,
|
|
2514
2514
|
column: o.target_column,
|
|
2515
|
-
onDelete:
|
|
2516
|
-
onUpdate:
|
|
2515
|
+
onDelete: bi(o.delete_rule),
|
|
2516
|
+
onUpdate: bi(o.update_rule),
|
|
2517
2517
|
constraintName: o.constraint_name
|
|
2518
2518
|
} : void 0, p = a.has(t.column_name) || n && t.column_name === "id", m = t.column_default === "NULL" ? null : t.column_default, h = l.get(`${e.table_name}.${t.column_name}`), g = t.data_type.toLowerCase() === "enum" ? [...t.column_type.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'")) : void 0;
|
|
2519
2519
|
return {
|
|
2520
2520
|
name: t.column_name,
|
|
2521
2521
|
type: d,
|
|
2522
|
-
...u ? { idStorage:
|
|
2522
|
+
...u ? { idStorage: Vn(s) } : {},
|
|
2523
2523
|
...d === "enum" && g !== void 0 ? { enumValues: g } : {},
|
|
2524
2524
|
nullable: t.is_nullable === "YES",
|
|
2525
|
-
...
|
|
2525
|
+
...Ri(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: Ri(t.data_type, t.character_maximum_length) },
|
|
2526
2526
|
...s === "decimal" && typeof t.numeric_precision == "number" ? {
|
|
2527
2527
|
precision: t.numeric_precision,
|
|
2528
2528
|
...typeof t.numeric_scale == "number" ? { scale: t.numeric_scale } : {}
|
|
@@ -2531,9 +2531,9 @@ BEGIN
|
|
|
2531
2531
|
hasDefault: m !== null,
|
|
2532
2532
|
...m === null ? {} : { defaultValue: m },
|
|
2533
2533
|
...f ? { references: f } : {},
|
|
2534
|
-
...o ? { referenceStorage: ["integer", "bigint"].includes(
|
|
2534
|
+
...o ? { referenceStorage: ["integer", "bigint"].includes(Di(t.data_type, t.column_type)) ? "numeric" : "text" } : {},
|
|
2535
2535
|
...h ? { oneOf: h } : {},
|
|
2536
|
-
...
|
|
2536
|
+
...yi(t.generation_expression, /STORED/i.test(t.extra ?? "")) ?? {},
|
|
2537
2537
|
...t.character_set_name !== null && t.character_set_name !== void 0 && d !== "json" ? { charset: t.character_set_name } : {}
|
|
2538
2538
|
};
|
|
2539
2539
|
}), m = new Set(n.map((e) => e.source_column)), h = [];
|
|
@@ -2561,10 +2561,10 @@ BEGIN
|
|
|
2561
2561
|
});
|
|
2562
2562
|
}
|
|
2563
2563
|
return { tables: p };
|
|
2564
|
-
}),
|
|
2564
|
+
}), Ai = (e) => {
|
|
2565
2565
|
let t = e.toUpperCase();
|
|
2566
2566
|
return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
|
|
2567
|
-
},
|
|
2567
|
+
}, ji = (e) => e === 1 || e === !0, Mi = (e) => A.gen(function* () {
|
|
2568
2568
|
let t = yield* e`
|
|
2569
2569
|
SELECT name, sql FROM sqlite_master
|
|
2570
2570
|
WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
|
|
@@ -2578,41 +2578,41 @@ BEGIN
|
|
|
2578
2578
|
let o = yield* e.unsafe(`PRAGMA table_xinfo(${n(i)})`), s = yield* e.unsafe(`PRAGMA foreign_key_list(${n(i)})`), c = yield* e.unsafe(`PRAGMA index_list(${n(i)})`), l = new Map(s.map((e) => [e.from, e])), u = o.filter((e) => e.pk > 0).sort((e, t) => e.pk - t.pk).map((e) => e.name), d = new Map(o.map((e) => [e.name.toLowerCase(), e.name])), f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Set();
|
|
2579
2579
|
for (let t of c) {
|
|
2580
2580
|
let r = (yield* e.unsafe(`PRAGMA index_info(${n(t.name)})`)).map((e) => e.name).filter((e) => e !== null).map((e) => d.get(e.toLowerCase()) ?? e);
|
|
2581
|
-
if (f.set(t.name, r), t.partial !== void 0 &&
|
|
2582
|
-
let n =
|
|
2581
|
+
if (f.set(t.name, r), t.partial !== void 0 && ji(t.partial)) {
|
|
2582
|
+
let n = Ln((yield* e`SELECT sql FROM sqlite_master WHERE type = 'index' AND name = ${t.name}`)[0]?.sql ?? "");
|
|
2583
2583
|
n !== void 0 && p.set(t.name, n);
|
|
2584
2584
|
}
|
|
2585
|
-
!p.has(t.name) &&
|
|
2585
|
+
!p.has(t.name) && ji(t.unique) && r.length === 1 && m.add(r[0]);
|
|
2586
2586
|
}
|
|
2587
2587
|
let h = o.map((e) => {
|
|
2588
|
-
let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i =
|
|
2588
|
+
let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = Ai(e.type), a = !r && n && e.name === "id", o = r ? "reference" : a ? "id" : i, s = r ? {
|
|
2589
2589
|
table: r.table,
|
|
2590
2590
|
column: r.to,
|
|
2591
|
-
onDelete:
|
|
2592
|
-
onUpdate:
|
|
2591
|
+
onDelete: bi(r.on_delete),
|
|
2592
|
+
onUpdate: bi(r.on_update)
|
|
2593
2593
|
} : void 0, c = t.get(e.name);
|
|
2594
2594
|
return {
|
|
2595
2595
|
name: e.name,
|
|
2596
2596
|
type: o,
|
|
2597
|
-
...a ? { idStorage:
|
|
2597
|
+
...a ? { idStorage: Vn(i) } : {},
|
|
2598
2598
|
nullable: e.notnull === 0,
|
|
2599
2599
|
unique: m.has(e.name) || n && e.name === "id",
|
|
2600
2600
|
hasDefault: e.dflt_value !== null,
|
|
2601
2601
|
...e.dflt_value === null ? {} : { defaultValue: e.dflt_value },
|
|
2602
2602
|
...s ? { references: s } : {},
|
|
2603
|
-
...r ? { referenceStorage: ["integer", "bigint"].includes(
|
|
2603
|
+
...r ? { referenceStorage: ["integer", "bigint"].includes(Ai(e.type)) ? "numeric" : "text" } : {},
|
|
2604
2604
|
...c ? { oneOf: c } : {},
|
|
2605
|
-
...
|
|
2605
|
+
...yi(e.hidden === 2 || e.hidden === 3 ? "generated" : null, e.hidden === 3) ?? {}
|
|
2606
2606
|
};
|
|
2607
2607
|
}), g = new Set(s.map((e) => e.from)), _ = [];
|
|
2608
2608
|
for (let e of c) {
|
|
2609
2609
|
if (e.origin === "pk") continue;
|
|
2610
2610
|
let t = f.get(e.name) ?? [], n = p.get(e.name);
|
|
2611
|
-
n === void 0 && t.length === 1 &&
|
|
2611
|
+
n === void 0 && t.length === 1 && ji(e.unique) || (n !== void 0 || t.length !== 1 || ji(e.unique) || !g.has(t[0]) || e.name.toLowerCase() === `${i}_${t[0]}_idx`.toLowerCase()) && _.push({
|
|
2612
2612
|
name: e.name,
|
|
2613
2613
|
table: i,
|
|
2614
2614
|
columns: t,
|
|
2615
|
-
unique:
|
|
2615
|
+
unique: ji(e.unique),
|
|
2616
2616
|
...n === void 0 ? {} : { where: n }
|
|
2617
2617
|
});
|
|
2618
2618
|
}
|
|
@@ -2628,7 +2628,7 @@ BEGIN
|
|
|
2628
2628
|
});
|
|
2629
2629
|
}
|
|
2630
2630
|
return { tables: r };
|
|
2631
|
-
}),
|
|
2631
|
+
}), Ni = (e) => {
|
|
2632
2632
|
switch (e.toLowerCase()) {
|
|
2633
2633
|
case "int":
|
|
2634
2634
|
case "smallint":
|
|
@@ -2650,7 +2650,7 @@ BEGIN
|
|
|
2650
2650
|
case "image": return "bytes";
|
|
2651
2651
|
default: return "text";
|
|
2652
2652
|
}
|
|
2653
|
-
},
|
|
2653
|
+
}, B = (e) => e === !0 || e === 1, Pi = (e) => A.gen(function* () {
|
|
2654
2654
|
let t = yield* e`
|
|
2655
2655
|
SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
|
|
2656
2656
|
WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
|
|
@@ -2690,7 +2690,7 @@ BEGIN
|
|
|
2690
2690
|
JOIN sys.tables t ON t.object_id = cc.parent_object_id
|
|
2691
2691
|
LEFT JOIN sys.columns c ON c.object_id = cc.parent_object_id AND c.column_id = cc.parent_column_id`, c = /* @__PURE__ */ new Map();
|
|
2692
2692
|
for (let e of s) {
|
|
2693
|
-
let t =
|
|
2693
|
+
let t = hi(e.def);
|
|
2694
2694
|
t?.column === e.column_name && c.set(`${e.table_name}.${e.column_name}`, t.values);
|
|
2695
2695
|
}
|
|
2696
2696
|
let l = /* @__PURE__ */ new Map();
|
|
@@ -2715,32 +2715,32 @@ BEGIN
|
|
|
2715
2715
|
let t = l.get(e) ?? [], n = u.get(e) ?? [], r = new Map(n.map((e) => [e.source_column, e])), a = new Set(n.map((e) => e.source_column)), o = d.get(e), p = [], m = /* @__PURE__ */ new Set();
|
|
2716
2716
|
if (o) for (let [, e] of o) {
|
|
2717
2717
|
let t = [...e].sort((e, t) => e.key_ordinal - t.key_ordinal);
|
|
2718
|
-
if (
|
|
2719
|
-
else t[0].predicate == null &&
|
|
2718
|
+
if (B(t[0].is_primary)) for (let e of t) p.push(e.column_name);
|
|
2719
|
+
else t[0].predicate == null && B(t[0].is_unique) && t.length === 1 && m.add(t[0].column_name);
|
|
2720
2720
|
}
|
|
2721
2721
|
let h = t.map((t) => {
|
|
2722
|
-
let n = p.length === 1 && p[0] === t.column_name, a = r.get(t.column_name), o =
|
|
2722
|
+
let n = p.length === 1 && p[0] === t.column_name, a = r.get(t.column_name), o = Ni(t.data_type), l = !a && n && t.column_name === "id", u = a ? "reference" : l ? "id" : o, d = a ? {
|
|
2723
2723
|
table: a.target_table,
|
|
2724
2724
|
column: a.target_column,
|
|
2725
|
-
onDelete:
|
|
2726
|
-
onUpdate:
|
|
2725
|
+
onDelete: Fi(a.delete_rule),
|
|
2726
|
+
onUpdate: Fi(a.update_rule),
|
|
2727
2727
|
constraintName: a.constraint_name
|
|
2728
|
-
} : void 0, f = t.column_default === null ? null :
|
|
2728
|
+
} : void 0, f = t.column_default === null ? null : Ii(t.column_default), h = c.get(`${e}.${t.column_name}`), g = s.flatMap((n) => {
|
|
2729
2729
|
if (n.table_name !== e || n.column_name !== null && n.column_name !== t.column_name) return [];
|
|
2730
2730
|
let r = jt(t.column_name, n.def);
|
|
2731
2731
|
return r ? [{
|
|
2732
2732
|
name: n.constraint_name,
|
|
2733
2733
|
validation: r,
|
|
2734
|
-
enabled: !
|
|
2735
|
-
trusted: !
|
|
2734
|
+
enabled: !B(n.is_disabled),
|
|
2735
|
+
trusted: !B(n.is_not_trusted)
|
|
2736
2736
|
}] : [];
|
|
2737
2737
|
}).sort((e, t) => e.name.localeCompare(t.name)), _ = Mt(g);
|
|
2738
2738
|
return {
|
|
2739
2739
|
name: t.column_name,
|
|
2740
2740
|
type: u,
|
|
2741
|
-
...l ? { idStorage:
|
|
2741
|
+
...l ? { idStorage: Vn(o) } : {},
|
|
2742
2742
|
nullable: t.is_nullable === "YES",
|
|
2743
|
-
...
|
|
2743
|
+
...Ri(t.data_type, t.character_maximum_length) === void 0 ? {} : { maxLength: Ri(t.data_type, t.character_maximum_length) },
|
|
2744
2744
|
...o === "decimal" && typeof t.numeric_precision == "number" ? {
|
|
2745
2745
|
precision: t.numeric_precision,
|
|
2746
2746
|
...typeof t.numeric_scale == "number" ? { scale: t.numeric_scale } : {}
|
|
@@ -2749,22 +2749,22 @@ BEGIN
|
|
|
2749
2749
|
hasDefault: f !== null,
|
|
2750
2750
|
...f === null ? {} : { defaultValue: f },
|
|
2751
2751
|
...d ? { references: d } : {},
|
|
2752
|
-
...a ? { referenceStorage: ["integer", "bigint"].includes(
|
|
2752
|
+
...a ? { referenceStorage: ["integer", "bigint"].includes(Ni(t.data_type)) ? "numeric" : "text" } : {},
|
|
2753
2753
|
...h ? { oneOf: h } : {},
|
|
2754
2754
|
...g.length > 0 ? { jsonChecks: g } : {},
|
|
2755
2755
|
..._ ? { jsonValidation: _ } : {},
|
|
2756
|
-
...
|
|
2756
|
+
...yi(i.get(`${e}.${t.column_name}`)?.definition ?? null, B(i.get(`${e}.${t.column_name}`)?.is_persisted ?? !1)) ?? {}
|
|
2757
2757
|
};
|
|
2758
2758
|
}), g = [];
|
|
2759
2759
|
if (o) for (let [t, n] of o) {
|
|
2760
2760
|
let r = [...n].sort((e, t) => e.key_ordinal - t.key_ordinal);
|
|
2761
|
-
if (
|
|
2761
|
+
if (B(r[0].is_primary)) continue;
|
|
2762
2762
|
let i = r[0].predicate ?? void 0;
|
|
2763
|
-
i === void 0 && r.length === 1 &&
|
|
2763
|
+
i === void 0 && r.length === 1 && B(r[0].is_unique) || (i !== void 0 || r.length !== 1 || B(r[0].is_unique) || !a.has(r[0].column_name) || t === `${e}_${r[0].column_name}_idx`) && g.push({
|
|
2764
2764
|
name: t,
|
|
2765
2765
|
table: e,
|
|
2766
2766
|
columns: r.map((e) => e.column_name),
|
|
2767
|
-
unique:
|
|
2767
|
+
unique: B(r[0].is_unique),
|
|
2768
2768
|
...i === void 0 ? {} : { where: i }
|
|
2769
2769
|
});
|
|
2770
2770
|
}
|
|
@@ -2780,81 +2780,81 @@ BEGIN
|
|
|
2780
2780
|
});
|
|
2781
2781
|
}
|
|
2782
2782
|
return { tables: f };
|
|
2783
|
-
}),
|
|
2783
|
+
}), Fi = (e) => {
|
|
2784
2784
|
switch (e.toUpperCase().replace(/_/g, " ")) {
|
|
2785
2785
|
case "CASCADE": return "cascade";
|
|
2786
2786
|
case "SET NULL": return "setNull";
|
|
2787
2787
|
case "SET DEFAULT": return "noAction";
|
|
2788
2788
|
default: return "noAction";
|
|
2789
2789
|
}
|
|
2790
|
-
},
|
|
2790
|
+
}, Ii = (e) => {
|
|
2791
2791
|
let t = e.trim();
|
|
2792
2792
|
for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
|
|
2793
2793
|
return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
|
|
2794
|
-
},
|
|
2794
|
+
}, Li = /* @__PURE__ */ new Set([
|
|
2795
2795
|
"character varying",
|
|
2796
2796
|
"varchar",
|
|
2797
2797
|
"nvarchar",
|
|
2798
2798
|
"char",
|
|
2799
2799
|
"character",
|
|
2800
2800
|
"nchar"
|
|
2801
|
-
]),
|
|
2802
|
-
if (!
|
|
2801
|
+
]), Ri = (e, t) => {
|
|
2802
|
+
if (!Li.has(e.toLowerCase())) return;
|
|
2803
2803
|
let n = Number(t);
|
|
2804
2804
|
if (!(!Number.isFinite(n) || n <= 0)) return n;
|
|
2805
|
-
},
|
|
2806
|
-
mysql: () =>
|
|
2807
|
-
mssql: () =>
|
|
2808
|
-
sqlite: () =>
|
|
2809
|
-
orElse: () =>
|
|
2805
|
+
}, zi = /* @__PURE__ */ new Set([P, z]), Bi = (e) => e.onDialectOrElse({
|
|
2806
|
+
mysql: () => ki(e),
|
|
2807
|
+
mssql: () => Pi(e),
|
|
2808
|
+
sqlite: () => Mi(e),
|
|
2809
|
+
orElse: () => Ei(e)
|
|
2810
2810
|
}).pipe(A.map((e) => ({
|
|
2811
2811
|
...e,
|
|
2812
|
-
tables: e.tables.filter((e) => !
|
|
2813
|
-
}))),
|
|
2814
|
-
let t =
|
|
2815
|
-
return t === void 0 ?
|
|
2816
|
-
}),
|
|
2812
|
+
tables: e.tables.filter((e) => !zi.has(e.name))
|
|
2813
|
+
}))), Vi = (e) => /mariadb/i.test(e) ? "mariadb" : "mysql", Hi = /* @__PURE__ */ new WeakMap(), V = (e) => A.suspend(() => {
|
|
2814
|
+
let t = Hi.get(e);
|
|
2815
|
+
return t === void 0 ? Ui(e).pipe(A.tap((t) => A.sync(() => Hi.set(e, t)))) : A.succeed(t);
|
|
2816
|
+
}), Ui = (e) => e.unsafe("SELECT VERSION() AS v").pipe(A.map((e) => {
|
|
2817
2817
|
let t = e[0]?.v;
|
|
2818
|
-
return typeof t == "string" ?
|
|
2819
|
-
}), A.catchAll(() => A.succeed("mysql"))),
|
|
2818
|
+
return typeof t == "string" ? Vi(t) : "mysql";
|
|
2819
|
+
}), A.catchAll(() => A.succeed("mysql"))), Wi = (e) => {
|
|
2820
2820
|
let t = e;
|
|
2821
2821
|
for (let e = 0; e < 6 && typeof t == "object" && t; e++) {
|
|
2822
2822
|
let e = t;
|
|
2823
2823
|
if (typeof e.errno == "number") return e.errno;
|
|
2824
2824
|
t = e.cause;
|
|
2825
2825
|
}
|
|
2826
|
-
},
|
|
2826
|
+
}, Gi = (e) => {
|
|
2827
2827
|
let t = [], n = e;
|
|
2828
2828
|
for (let e = 0; e < 6 && typeof n == "object" && n; e++) {
|
|
2829
2829
|
let e = n;
|
|
2830
2830
|
typeof e.message == "string" && t.push(e.message), n = e.cause;
|
|
2831
2831
|
}
|
|
2832
2832
|
return t.join(" | ");
|
|
2833
|
-
},
|
|
2833
|
+
}, Ki = (e, t) => {
|
|
2834
2834
|
if (t.length === 0) return !1;
|
|
2835
|
-
let n =
|
|
2835
|
+
let n = Wi(e), r = Gi(e);
|
|
2836
2836
|
return t.some((e) => e.errno !== void 0 && n !== void 0 && e.errno.includes(n) || e.messageIncludes !== void 0 && e.messageIncludes.some((e) => r.includes(e)));
|
|
2837
|
-
},
|
|
2837
|
+
}, qi = {
|
|
2838
2838
|
why: "mysql has no CREATE INDEX IF NOT EXISTS; 1061 is exactly that condition",
|
|
2839
2839
|
errno: [1061]
|
|
2840
|
-
},
|
|
2840
|
+
}, Ji = {
|
|
2841
2841
|
why: "mysql has no DROP COLUMN IF EXISTS; 1091 is exactly that condition",
|
|
2842
2842
|
errno: [1091]
|
|
2843
|
-
},
|
|
2843
|
+
}, Yi = {
|
|
2844
2844
|
why: "sqlite has no DROP COLUMN IF EXISTS, and reports the absent column only in the message",
|
|
2845
2845
|
messageIncludes: ["no such column"]
|
|
2846
|
-
},
|
|
2846
|
+
}, Xi = {
|
|
2847
2847
|
why: "mysql/mariadb DROP CONSTRAINT has no portable IF EXISTS; 1091 / 3940 are exactly \"already gone\"",
|
|
2848
2848
|
errno: [1091, 3940]
|
|
2849
|
-
},
|
|
2849
|
+
}, Zi = {
|
|
2850
2850
|
why: "mysql/mariadb ADD CONSTRAINT has no IF NOT EXISTS; 1826 is exactly \"already there\"",
|
|
2851
2851
|
errno: [1826]
|
|
2852
|
-
},
|
|
2852
|
+
}, Qi = (e, t) => A.suspend(() => {
|
|
2853
2853
|
let n;
|
|
2854
2854
|
return e.withTransaction(t.pipe(A.tapErrorCause((e) => A.sync(() => {
|
|
2855
2855
|
n = e;
|
|
2856
2856
|
})))).pipe(A.catchAllCause((e) => A.failCause(n !== void 0 && !xe.equals(n, e) ? be.sequential(n, e) : e)));
|
|
2857
|
-
}),
|
|
2857
|
+
}), $i = (e, t, n) => {
|
|
2858
2858
|
let r = e.match(/'(?:''|[^'])*'|\[(?:\]\]|[^\]])*\]|\s+|[^'\[\s]+/g) ?? [];
|
|
2859
2859
|
if (r.join("") !== e || r.some((e) => !e.startsWith("'") && !e.startsWith("[") && /"|\/\*|--/.test(e))) throw Error("Cannot safely rename CHECK: unsupported catalog SQL; use an explicit migration");
|
|
2860
2860
|
let a = r.map((e, t) => ({
|
|
@@ -2870,24 +2870,24 @@ BEGIN
|
|
|
2870
2870
|
}
|
|
2871
2871
|
if (o === 0 || r.join("").length === 0) throw Error(`Cannot safely rename CHECK reference '${t}': no exact catalog column token; use an explicit migration`);
|
|
2872
2872
|
return r.join("");
|
|
2873
|
-
},
|
|
2873
|
+
}, H = (e, t) => e.onDialectOrElse({
|
|
2874
2874
|
mysql: () => A.succeed(t.replace("T", " ").replace("Z", "")),
|
|
2875
2875
|
orElse: () => A.succeed(t)
|
|
2876
|
-
}),
|
|
2877
|
-
if ((e.type !== "text" || e.maxLength === void 0) && !
|
|
2876
|
+
}), ea = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, ta = (e) => e.type === "text" && (e.hasDefault && e.defaultValue !== void 0 || e.oneOf !== void 0 && e.oneOf.length > 0), na = (e, t) => {
|
|
2877
|
+
if ((e.type !== "text" || e.maxLength === void 0) && !ta(e) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
|
|
2878
2878
|
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;
|
|
2879
2879
|
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.`);
|
|
2880
2880
|
return I(e, t);
|
|
2881
|
-
}, na = (e) => {
|
|
2882
|
-
let t = ta(e, "postgres");
|
|
2883
|
-
return t === void 0 ? ra(e) : t;
|
|
2884
2881
|
}, ra = (e) => {
|
|
2882
|
+
let t = na(e, "postgres");
|
|
2883
|
+
return t === void 0 ? ia(e) : t;
|
|
2884
|
+
}, ia = (e) => {
|
|
2885
2885
|
switch (e.type) {
|
|
2886
2886
|
case "id": return "text";
|
|
2887
2887
|
case "text": return "text";
|
|
2888
2888
|
case "integer": return "integer";
|
|
2889
2889
|
case "real": return "double precision";
|
|
2890
|
-
case "decimal": return
|
|
2890
|
+
case "decimal": return ea(e, "NUMERIC");
|
|
2891
2891
|
case "bigint": return "bigint";
|
|
2892
2892
|
case "boolean": return "boolean";
|
|
2893
2893
|
case "timestamp": return "timestamptz";
|
|
@@ -2901,15 +2901,15 @@ BEGIN
|
|
|
2901
2901
|
case "interval": return "interval";
|
|
2902
2902
|
case "raw": return e.rawDdl ?? "text";
|
|
2903
2903
|
}
|
|
2904
|
-
},
|
|
2905
|
-
let t =
|
|
2904
|
+
}, aa = (e) => {
|
|
2905
|
+
let t = na(e, "mariadb");
|
|
2906
2906
|
if (t !== void 0) return t;
|
|
2907
2907
|
switch (e.type) {
|
|
2908
2908
|
case "id": return "VARCHAR(64)";
|
|
2909
2909
|
case "text": return "LONGTEXT";
|
|
2910
2910
|
case "integer": return "INT";
|
|
2911
2911
|
case "real": return "DOUBLE";
|
|
2912
|
-
case "decimal": return
|
|
2912
|
+
case "decimal": return ea(e, "DECIMAL");
|
|
2913
2913
|
case "bigint": return "BIGINT";
|
|
2914
2914
|
case "boolean": return "TINYINT(1)";
|
|
2915
2915
|
case "timestamp": return "DATETIME(6)";
|
|
@@ -2923,72 +2923,72 @@ BEGIN
|
|
|
2923
2923
|
case "interval": return "BIGINT";
|
|
2924
2924
|
case "raw": return e.rawDdl ?? "LONGTEXT";
|
|
2925
2925
|
}
|
|
2926
|
-
},
|
|
2926
|
+
}, U = (e) => `"${e}"`, W = (e) => `\`${e.replace(/`/g, "``")}\``, oa = (e) => e === "mariadb" ? "IF NOT EXISTS " : "", sa = (e, t, n = !0) => `ALTER TABLE ${t(e.table)} DROP COLUMN ${n ? "IF EXISTS " : ""}${t(e.column)};`, ca = (e, t = "mariadb") => `ALTER TABLE ${W(e.table)} DROP COLUMN ${t === "mariadb" ? "IF EXISTS " : ""}${W(e.column)}, ALGORITHM=COPY;`, la = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, ua = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${qa(t)}`)};`, da = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${pa(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, fa = (e, t) => {
|
|
2927
2927
|
let { defaultFactory: n, ...r } = e;
|
|
2928
2928
|
return I(e, t) !== I({
|
|
2929
2929
|
...r,
|
|
2930
2930
|
hasDefault: !1
|
|
2931
2931
|
}, t);
|
|
2932
|
-
},
|
|
2932
|
+
}, pa = (e, t) => {
|
|
2933
2933
|
let n = t(e.defaultValue);
|
|
2934
2934
|
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.`);
|
|
2935
2935
|
return n;
|
|
2936
|
-
},
|
|
2937
|
-
let r =
|
|
2938
|
-
return r ?
|
|
2939
|
-
},
|
|
2936
|
+
}, G = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], ma = (e, t, n) => {
|
|
2937
|
+
let r = G(e, t, n);
|
|
2938
|
+
return r ? xr(n, r) : void 0;
|
|
2939
|
+
}, ha = (e, t, n, r) => {
|
|
2940
2940
|
let i = n ?? e.nullable, a = Ut(e, "mariadb");
|
|
2941
2941
|
return [
|
|
2942
|
-
|
|
2942
|
+
W(t),
|
|
2943
2943
|
I(e, "mariadb"),
|
|
2944
2944
|
i ? null : "NOT NULL",
|
|
2945
2945
|
a,
|
|
2946
2946
|
r === void 0 ? null : `CHECK (${r})`
|
|
2947
2947
|
].filter(Boolean).join(" ");
|
|
2948
|
-
},
|
|
2948
|
+
}, ga = /^json_valid\(`[^`]+`\)$/i, _a = (e, t) => V(e).pipe(A.flatMap((n) => n === "mariadb" ? e`
|
|
2949
2949
|
SELECT constraint_name AS n, check_clause AS c
|
|
2950
2950
|
FROM information_schema.check_constraints
|
|
2951
|
-
WHERE constraint_schema = DATABASE() AND table_name = ${t} AND level = 'Column'`.pipe(A.map((e) => new Map(e.map((e) => [String(e.n ?? ""), String(e.c ?? "")]).filter(([e, t]) => e !== "" && t !== "" && !
|
|
2951
|
+
WHERE constraint_schema = DATABASE() AND table_name = ${t} AND level = 'Column'`.pipe(A.map((e) => new Map(e.map((e) => [String(e.n ?? ""), String(e.c ?? "")]).filter(([e, t]) => e !== "" && t !== "" && !ga.test(t.trim()))))) : A.succeed(/* @__PURE__ */ new Map()))), va = (e, t, n, r, i) => A.map(_a(e, t), (e) => `ALTER TABLE ${W(t)} MODIFY COLUMN ${ha(n, r, i, e.get(r))};`), ya = (e, t) => e == null ? null : Array.isArray(e) ? ba(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" ? Gt(e, "mariadb") : null, ba = (e, t, n) => Wt(e, t ?? { type: "json" }, n), xa = (e, t) => e == null ? null : Array.isArray(e) ? ba(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" ? Gt(e, "postgres") : null, Sa = (e, t) => {
|
|
2952
2952
|
if (!e.generatedAs) return null;
|
|
2953
2953
|
let { expr: n, stored: r } = e.generatedAs;
|
|
2954
2954
|
return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
|
|
2955
|
-
},
|
|
2956
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
2957
|
-
let n =
|
|
2958
|
-
if (n) return `${
|
|
2959
|
-
let r = [
|
|
2955
|
+
}, Ca = (e, t = !1) => {
|
|
2956
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return Kt(e.name, "postgres");
|
|
2957
|
+
let n = Sa(e, "postgres");
|
|
2958
|
+
if (n) return `${U(e.name)} ${ra(e)} ${n}`;
|
|
2959
|
+
let r = [U(e.name), ra(e)];
|
|
2960
2960
|
if (e.type === "id" && !t && r.push("PRIMARY KEY"), e.nullable || r.push("NOT NULL"), e.unique && e.type !== "id" && r.push("UNIQUE"), e.hasDefault) {
|
|
2961
|
-
let t =
|
|
2961
|
+
let t = xa(e.defaultValue, e);
|
|
2962
2962
|
t && r.push(t);
|
|
2963
2963
|
}
|
|
2964
|
-
return e.references && (r.push(`REFERENCES ${
|
|
2964
|
+
return e.references && (r.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && r.push(`ON DELETE ${{
|
|
2965
2965
|
cascade: "CASCADE",
|
|
2966
2966
|
restrict: "RESTRICT",
|
|
2967
2967
|
setNull: "SET NULL",
|
|
2968
2968
|
noAction: "NO ACTION"
|
|
2969
2969
|
}[e.references.onDelete]}`)), r.join(" ");
|
|
2970
|
-
},
|
|
2971
|
-
let t = e.columns.map((t) => ` ${
|
|
2972
|
-
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(
|
|
2970
|
+
}, wa = (e) => (e.primaryKey?.length ?? 0) > 0, Ta = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", Ea = (e) => {
|
|
2971
|
+
let t = e.columns.map((t) => ` ${Ca(t, wa(e))}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${Ta(e, U)}\n)`];
|
|
2972
|
+
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(eo({
|
|
2973
2973
|
kind: "add-index",
|
|
2974
2974
|
table: e.table,
|
|
2975
2975
|
index: t
|
|
2976
2976
|
}, !1));
|
|
2977
2977
|
return n;
|
|
2978
|
-
},
|
|
2979
|
-
let t =
|
|
2978
|
+
}, Da = 191, Oa = (e) => {
|
|
2979
|
+
let t = aa(e).toUpperCase();
|
|
2980
2980
|
return t.endsWith("TEXT") || t.endsWith("BLOB");
|
|
2981
|
-
},
|
|
2982
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
2983
|
-
let n = e.charset === void 0 ?
|
|
2984
|
-
if (r) return `${
|
|
2985
|
-
let i = [
|
|
2986
|
-
if (e.type === "id" && !t && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && !
|
|
2987
|
-
let t =
|
|
2981
|
+
}, ka = (e, t = !1) => {
|
|
2982
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return Kt(e.name, "mariadb");
|
|
2983
|
+
let n = e.charset === void 0 ? aa(e) : `${aa(e)} CHARACTER SET ${e.charset}`, r = Sa(e, "mariadb");
|
|
2984
|
+
if (r) return `${W(e.name)} ${n} ${r}`;
|
|
2985
|
+
let i = [W(e.name), n];
|
|
2986
|
+
if (e.type === "id" && !t && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && !Oa(e) && i.push("UNIQUE"), e.hasDefault) {
|
|
2987
|
+
let t = ya(e.defaultValue, e);
|
|
2988
2988
|
t && i.push(t);
|
|
2989
2989
|
}
|
|
2990
2990
|
return i.join(" ");
|
|
2991
|
-
},
|
|
2991
|
+
}, Aa = (e) => e.columns.flatMap((t) => {
|
|
2992
2992
|
if (!t.references) return [];
|
|
2993
2993
|
let n = t.references.onDelete ? ` ON DELETE ${{
|
|
2994
2994
|
cascade: "CASCADE",
|
|
@@ -2996,15 +2996,15 @@ BEGIN
|
|
|
2996
2996
|
setNull: "SET NULL",
|
|
2997
2997
|
noAction: "NO ACTION"
|
|
2998
2998
|
}[t.references.onDelete]}` : "";
|
|
2999
|
-
return [` CONSTRAINT ${
|
|
3000
|
-
}),
|
|
2999
|
+
return [` CONSTRAINT ${W(`${e.table}_${t.name}_fkey`)} FOREIGN KEY (${W(t.name)}) REFERENCES ${W(t.references.table)} (${W(t.references.column)})${n}`];
|
|
3000
|
+
}), ja = (e) => {
|
|
3001
3001
|
let t = e.find((e) => e.charset !== void 0)?.charset;
|
|
3002
3002
|
return t === void 0 ? "" : ` DEFAULT CHARACTER SET ${t}`;
|
|
3003
|
-
},
|
|
3004
|
-
let r = e.foreignKeys.map((e) => `ALTER TABLE ${
|
|
3005
|
-
let i =
|
|
3003
|
+
}, Ma = (e, t, n = /* @__PURE__ */ new Map()) => {
|
|
3004
|
+
let r = e.foreignKeys.map((e) => `ALTER TABLE ${W(e.table)} DROP FOREIGN KEY ${W(e.name)}`), i = e.columns.map((r) => {
|
|
3005
|
+
let i = G(t, e.table, r), a = ma(t, e.table, r);
|
|
3006
3006
|
if (i === void 0 || a === void 0) throw Error(`convert-charset: no declared column '${e.table}.${r}' to render MODIFY COLUMN from; it was not in ctx.declared.`);
|
|
3007
|
-
let o =
|
|
3007
|
+
let o = Sa(a, "mariadb"), s = `${W(r)} ${I(i, "mariadb")} CHARACTER SET ${e.charset}`, c = n.get(r), l = c === void 0 ? null : `CHECK (${c})`;
|
|
3008
3008
|
if (o) return `MODIFY COLUMN ${[
|
|
3009
3009
|
s,
|
|
3010
3010
|
o,
|
|
@@ -3020,30 +3020,30 @@ BEGIN
|
|
|
3020
3020
|
});
|
|
3021
3021
|
return {
|
|
3022
3022
|
drops: r,
|
|
3023
|
-
rewrite: `ALTER TABLE ${
|
|
3024
|
-
restores: e.foreignKeys.filter((e) => e.restore === "here").map((e) => `ALTER TABLE ${
|
|
3023
|
+
rewrite: `ALTER TABLE ${W(e.table)} ${[...i, `DEFAULT CHARACTER SET ${e.charset}`].join(", ")}`,
|
|
3024
|
+
restores: e.foreignKeys.filter((e) => e.restore === "here").map((e) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} FOREIGN KEY (${W(e.column)}) REFERENCES ${W(e.targetTable)} (${W(e.targetColumn)})` + (e.onDelete ? ` ON DELETE ${Pa[e.onDelete]}` : "") + (e.onUpdate && e.onUpdate !== "noAction" ? ` ON UPDATE ${Pa[e.onUpdate]}` : ""))
|
|
3025
3025
|
};
|
|
3026
|
-
},
|
|
3027
|
-
for (let n of e.indexes)
|
|
3026
|
+
}, Na = (e, t = "mariadb") => {
|
|
3027
|
+
for (let n of e.indexes) no(n, t);
|
|
3028
3028
|
let n = new Map(e.columns.map((e) => [e.name, e])), r = (e) => {
|
|
3029
|
-
let t =
|
|
3030
|
-
return t === void 0 ?
|
|
3031
|
-
}, i = e.columns.map((t) => ` ${
|
|
3032
|
-
for (let n of e.columns) n.unique && n.type !== "id" &&
|
|
3033
|
-
for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${
|
|
3029
|
+
let t = Xa(n.get(e));
|
|
3030
|
+
return t === void 0 ? W(e) : `${W(e)}(${t})`;
|
|
3031
|
+
}, i = e.columns.map((t) => ` ${ka(t, wa(e))}`).join(",\n"), a = Aa(e), o = a.length > 0 ? `${i},\n${a.join(",\n")}` : i, s = [`CREATE TABLE IF NOT EXISTS ${W(e.table)} (\n${o}${Ta(e, r)}\n)${ja(e.columns)}`];
|
|
3032
|
+
for (let n of e.columns) n.unique && n.type !== "id" && Oa(n) && s.push(`CREATE UNIQUE INDEX ${oa(t)}${W(`${e.table}_${n.name}_key`)} ON ${W(e.table)} (${r(n.name)})`);
|
|
3033
|
+
for (let n of e.indexes) n.name !== `${e.table}_pkey` && s.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${oa(t)}${W(n.name)} ON ${W(e.table)} (${n.columns.map(r).join(", ")})`);
|
|
3034
3034
|
return s;
|
|
3035
|
-
},
|
|
3035
|
+
}, Pa = {
|
|
3036
3036
|
cascade: "CASCADE",
|
|
3037
3037
|
restrict: "RESTRICT",
|
|
3038
3038
|
setNull: "SET NULL",
|
|
3039
3039
|
noAction: "NO ACTION"
|
|
3040
|
-
},
|
|
3040
|
+
}, Fa = {
|
|
3041
3041
|
cascade: "CASCADE",
|
|
3042
3042
|
restrict: "NO ACTION",
|
|
3043
3043
|
setNull: "SET NULL",
|
|
3044
3044
|
noAction: "NO ACTION"
|
|
3045
|
-
},
|
|
3046
|
-
let t =
|
|
3045
|
+
}, Ia = (e) => {
|
|
3046
|
+
let t = na(e, "sqlite");
|
|
3047
3047
|
if (t !== void 0) return t;
|
|
3048
3048
|
switch (e.type) {
|
|
3049
3049
|
case "integer":
|
|
@@ -3055,61 +3055,61 @@ BEGIN
|
|
|
3055
3055
|
case "bytes": return "BLOB";
|
|
3056
3056
|
default: return "TEXT";
|
|
3057
3057
|
}
|
|
3058
|
-
},
|
|
3059
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
3060
|
-
let n =
|
|
3061
|
-
if (n) return `${
|
|
3062
|
-
let r = [
|
|
3058
|
+
}, La = (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" ? Gt(e, "sqlite") : null, Ra = (e, t = !1) => {
|
|
3059
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return Kt(e.name, "sqlite");
|
|
3060
|
+
let n = Sa(e, "sqlite");
|
|
3061
|
+
if (n) return `${U(e.name)} ${Ia(e)} ${n}`;
|
|
3062
|
+
let r = [U(e.name), Ia(e)];
|
|
3063
3063
|
if (e.type === "id" && !t && r.push("PRIMARY KEY"), e.nullable || r.push("NOT NULL"), e.unique && e.type !== "id" && r.push("UNIQUE"), e.hasDefault) {
|
|
3064
|
-
let t =
|
|
3064
|
+
let t = La(e.defaultValue, "CURRENT_TIMESTAMP");
|
|
3065
3065
|
t && r.push(t);
|
|
3066
3066
|
}
|
|
3067
|
-
if (e.references && (r.push(`REFERENCES ${
|
|
3067
|
+
if (e.references && (r.push(`REFERENCES ${U(e.references.table)} (${U(e.references.column)})`), e.references.onDelete && r.push(`ON DELETE ${Pa[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
|
|
3068
3068
|
let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
|
|
3069
|
-
r.push(`CHECK (${
|
|
3069
|
+
r.push(`CHECK (${U(e.name)} IN (${t}))`);
|
|
3070
3070
|
}
|
|
3071
3071
|
return r.join(" ");
|
|
3072
|
-
},
|
|
3073
|
-
let t = e.columns.map((t) => ` ${
|
|
3074
|
-
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${
|
|
3072
|
+
}, za = (e) => {
|
|
3073
|
+
let t = e.columns.map((t) => ` ${Ra(t, wa(e))}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${U(e.table)} (\n${t}${Ta(e, U)}\n)`];
|
|
3074
|
+
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(t.name)} ON ${U(e.table)} (${t.columns.map(U).join(", ")})${$a(t)}`);
|
|
3075
3075
|
return n;
|
|
3076
|
-
},
|
|
3076
|
+
}, Ba = (e, t) => {
|
|
3077
3077
|
let n = t.find((t) => t.tableName === e);
|
|
3078
|
-
return n ?
|
|
3079
|
-
},
|
|
3080
|
-
let t = e.name, n = `${t}__voltro_rebuild`, r = e.columns.map((e) =>
|
|
3081
|
-
...
|
|
3078
|
+
return n ? Va(Tr([n], "sqlite").tables[0]) : [];
|
|
3079
|
+
}, Va = (e) => {
|
|
3080
|
+
let t = e.name, n = `${t}__voltro_rebuild`, r = e.columns.map((e) => U(e.name)).join(", "), i = [
|
|
3081
|
+
...za({
|
|
3082
3082
|
kind: "create-table",
|
|
3083
3083
|
table: n,
|
|
3084
3084
|
columns: e.columns,
|
|
3085
3085
|
indexes: [],
|
|
3086
3086
|
...e.primaryKey ? { primaryKey: e.primaryKey } : {}
|
|
3087
3087
|
}),
|
|
3088
|
-
`INSERT INTO ${
|
|
3089
|
-
`DROP TABLE ${
|
|
3090
|
-
`ALTER TABLE ${
|
|
3088
|
+
`INSERT INTO ${U(n)} (${r}) SELECT ${r} FROM ${U(t)}`,
|
|
3089
|
+
`DROP TABLE ${U(t)}`,
|
|
3090
|
+
`ALTER TABLE ${U(n)} RENAME TO ${U(t)}`
|
|
3091
3091
|
];
|
|
3092
|
-
for (let n of e.indexes) n.name !== `${t}_pkey` && i.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${
|
|
3092
|
+
for (let n of e.indexes) n.name !== `${t}_pkey` && i.push(`CREATE ${n.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${U(n.name)} ON ${U(t)} (${n.columns.map(U).join(", ")})${$a(n)}`);
|
|
3093
3093
|
return i;
|
|
3094
|
-
},
|
|
3094
|
+
}, Ha = (e, t, n, r) => {
|
|
3095
3095
|
let i = r ?? e.nullable;
|
|
3096
|
-
return `ALTER TABLE ${
|
|
3097
|
-
},
|
|
3098
|
-
let n = `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 ${
|
|
3096
|
+
return `ALTER TABLE ${K(n)} ALTER COLUMN ${K(t)} ${I(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
|
|
3097
|
+
}, Ua = (e, t) => {
|
|
3098
|
+
let n = `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 ${K(e.table)} DROP CONSTRAINT [' + @dc + ']');` + (t ? ` ${t}` : "");
|
|
3099
3099
|
if (!e.hasDefault) return n;
|
|
3100
|
-
let r =
|
|
3100
|
+
let r = La(e.defaultValue, "SYSUTCDATETIME()");
|
|
3101
3101
|
if (!r) return n;
|
|
3102
3102
|
let i = r.replace(/^DEFAULT\s+/i, "");
|
|
3103
|
-
return `${n} ALTER TABLE ${
|
|
3104
|
-
},
|
|
3105
|
-
let t =
|
|
3103
|
+
return `${n} ALTER TABLE ${K(e.table)} ADD DEFAULT ${i} FOR ${K(e.column)};`;
|
|
3104
|
+
}, K = (e) => `[${e.replace(/]/g, "]]")}]`, Wa = (e) => {
|
|
3105
|
+
let t = na(e, "mssql");
|
|
3106
3106
|
if (t !== void 0) return t;
|
|
3107
3107
|
switch (e.type) {
|
|
3108
3108
|
case "id": return "NVARCHAR(64)";
|
|
3109
3109
|
case "reference": return e.referenceStorage === "numeric" ? "BIGINT" : "NVARCHAR(64)";
|
|
3110
3110
|
case "integer": return "INT";
|
|
3111
3111
|
case "real": return "FLOAT";
|
|
3112
|
-
case "decimal": return
|
|
3112
|
+
case "decimal": return ea(e, "DECIMAL");
|
|
3113
3113
|
case "bigint": return "BIGINT";
|
|
3114
3114
|
case "boolean": return "BIT";
|
|
3115
3115
|
case "timestamp": return "DATETIME2(6)";
|
|
@@ -3117,53 +3117,53 @@ BEGIN
|
|
|
3117
3117
|
case "bytes": return "VARBINARY(MAX)";
|
|
3118
3118
|
default: return "NVARCHAR(MAX)";
|
|
3119
3119
|
}
|
|
3120
|
-
},
|
|
3121
|
-
if (e.type === "id" && e.idScheme?.kind === "numeric") return
|
|
3122
|
-
let r = e.type === "text" && t?.has(e.name) ? `NVARCHAR(${Math.min(e.maxLength ?? 450, 450)})` :
|
|
3123
|
-
if (i) return `${
|
|
3124
|
-
let a = [
|
|
3125
|
-
if (e.type === "json" && a.push(`CHECK ${kt(
|
|
3126
|
-
let t =
|
|
3120
|
+
}, Ga = (e, t, n = !1) => {
|
|
3121
|
+
if (e.type === "id" && e.idScheme?.kind === "numeric") return Kt(e.name, "mssql");
|
|
3122
|
+
let r = e.type === "text" && t?.has(e.name) ? `NVARCHAR(${Math.min(e.maxLength ?? 450, 450)})` : Wa(e), i = Sa(e, "mssql");
|
|
3123
|
+
if (i) return `${K(e.name)} ${i}`;
|
|
3124
|
+
let a = [K(e.name), r];
|
|
3125
|
+
if (e.type === "json" && a.push(`CHECK ${kt(K(e.name))}`), e.type === "array" && a.push(`CHECK (${K(e.name)} IS NULL OR ISJSON(${K(e.name)}) = 1)`), e.type === "id" && !n && a.push("PRIMARY KEY"), e.nullable || a.push("NOT NULL"), e.unique && e.type !== "id" && a.push("UNIQUE"), e.hasDefault) {
|
|
3126
|
+
let t = La(e.defaultValue, "SYSUTCDATETIME()");
|
|
3127
3127
|
t && a.push(t);
|
|
3128
3128
|
}
|
|
3129
|
-
return e.references && (a.push(`REFERENCES ${
|
|
3130
|
-
},
|
|
3131
|
-
let t = (e) => e.replace(/'/g, "''"), n = /* @__PURE__ */ new Set([...e.indexes.flatMap((e) => e.columns), ...e.columns.filter((e) => e.unique).map((e) => e.name)]), r = e.columns.map((t) => ` ${
|
|
3129
|
+
return e.references && (a.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && a.push(`ON DELETE ${Fa[e.references.onDelete]}`)), a.join(" ");
|
|
3130
|
+
}, Ka = (e) => {
|
|
3131
|
+
let t = (e) => e.replace(/'/g, "''"), n = /* @__PURE__ */ new Set([...e.indexes.flatMap((e) => e.columns), ...e.columns.filter((e) => e.unique).map((e) => e.name)]), r = e.columns.map((t) => ` ${Ga(t, n, wa(e))}`).join(",\n"), i = `CREATE TABLE ${K(e.table)} (\n${r}${Ta(e, K)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
|
|
3132
3132
|
for (let n of e.indexes) {
|
|
3133
3133
|
if (n.name === `${e.table}_pkey`) continue;
|
|
3134
|
-
let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${
|
|
3134
|
+
let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${K(n.name)} ON ${K(e.table)} (${n.columns.map(K).join(", ")})${$a(n)}`;
|
|
3135
3135
|
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)}')`);
|
|
3136
3136
|
}
|
|
3137
3137
|
return a;
|
|
3138
|
-
},
|
|
3139
|
-
let r = `${e.table}${
|
|
3138
|
+
}, qa = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Ja = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, Ya = (e, t, n) => {
|
|
3139
|
+
let r = `${e.table}${qa(t)}`;
|
|
3140
3140
|
return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
|
|
3141
|
-
},
|
|
3142
|
-
if (e === void 0 || !
|
|
3141
|
+
}, Xa = (e) => {
|
|
3142
|
+
if (e === void 0 || !Oa(e)) return;
|
|
3143
3143
|
let t = typeof e.maxLength == "number" && e.maxLength > 0 ? e.maxLength : void 0;
|
|
3144
|
-
return t === void 0 ?
|
|
3145
|
-
},
|
|
3146
|
-
let r =
|
|
3147
|
-
return r === void 0 ?
|
|
3148
|
-
},
|
|
3149
|
-
let n = Ne(e.index.kind, e.index.kindOptions), r = e.index.columns.map(
|
|
3144
|
+
return t === void 0 ? Da : Math.min(Da, t);
|
|
3145
|
+
}, Za = (e, t, n) => {
|
|
3146
|
+
let r = Xa(ma(e, t, n));
|
|
3147
|
+
return r === void 0 ? W(n) : `${W(n)}(${r})`;
|
|
3148
|
+
}, Qa = (e) => e.startsWith("(") ? e : U(e), $a = (e) => e.where === void 0 ? "" : ` WHERE ${e.where}`, eo = (e, t) => {
|
|
3149
|
+
let n = Ne(e.index.kind, e.index.kindOptions), r = e.index.columns.map(Qa);
|
|
3150
3150
|
if (n.opclass !== void 0) {
|
|
3151
3151
|
if (r.length !== 1) throw Error("HNSW index requires exactly one column");
|
|
3152
3152
|
r[0] = `${r[0]} ${n.opclass}`;
|
|
3153
3153
|
}
|
|
3154
|
-
return `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${
|
|
3155
|
-
},
|
|
3154
|
+
return `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${U(e.index.name)} ON ${U(e.table)}${n.using} (${r.join(", ")})${n.withSuffix}${$a(e.index)};`;
|
|
3155
|
+
}, to = (e, t, n = "mariadb") => (no(e.index, n), `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${oa(n)}${W(e.index.name)} ON ${W(e.table)} (${e.index.columns.map((n) => Za(t, e.table, n)).join(", ")});`), no = (e, t) => {
|
|
3156
3156
|
if (e.where !== void 0) throw Error(`Partial index '${e.name}' is not supported by ${t}; uniqueActive must be lowered before applying the plan.`);
|
|
3157
|
-
},
|
|
3157
|
+
}, ro = (e) => `DROP INDEX IF EXISTS ${U(e.index)};`, io = (e) => `DROP INDEX ${W(e.index)} ON ${W(e.table)};`, ao = (e) => `DROP INDEX IF EXISTS ${K(e.index)} ON ${K(e.table)};`, oo = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, so = (e) => {
|
|
3158
3158
|
let t = (e) => e.replace(/'/g, "''");
|
|
3159
3159
|
return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
|
|
3160
|
-
},
|
|
3160
|
+
}, co = (e) => `ALTER INDEX ${U(e.from)} RENAME TO ${U(e.to)};`, lo = (e) => `ALTER TABLE ${W(e.table)} RENAME INDEX ${W(e.from)} TO ${W(e.to)};`, uo = (e) => {
|
|
3161
3161
|
let t = (e) => e.replace(/'/g, "''");
|
|
3162
3162
|
return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
|
|
3163
|
-
},
|
|
3164
|
-
let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${
|
|
3163
|
+
}, fo = (e) => {
|
|
3164
|
+
let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map(K).join(", ")})${$a(e.index)}`;
|
|
3165
3165
|
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)}');`;
|
|
3166
|
-
},
|
|
3166
|
+
}, po = (e, t, n) => {
|
|
3167
3167
|
let r = n.find((t) => t.tableName === e);
|
|
3168
3168
|
if (!r) return [];
|
|
3169
3169
|
let i = [];
|
|
@@ -3171,17 +3171,17 @@ BEGIN
|
|
|
3171
3171
|
let t = r.fields[n];
|
|
3172
3172
|
if (t && t.type === "text" && !t.generatedAs) {
|
|
3173
3173
|
let r = Math.min(t.maxLength ?? 450, 450);
|
|
3174
|
-
i.push(`ALTER TABLE ${
|
|
3174
|
+
i.push(`ALTER TABLE ${K(e)} ALTER COLUMN ${K(n)} NVARCHAR(${r}) ${t.nullable ? "NULL" : "NOT NULL"};`);
|
|
3175
3175
|
}
|
|
3176
3176
|
}
|
|
3177
3177
|
return i;
|
|
3178
|
-
},
|
|
3179
|
-
let t = e.fields.map((e) =>
|
|
3180
|
-
return `ALTER TABLE ${
|
|
3181
|
-
},
|
|
3182
|
-
let n = e.fields.map((n) =>
|
|
3183
|
-
return `ALTER TABLE ${
|
|
3184
|
-
},
|
|
3178
|
+
}, mo = (e) => `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(`${e.table}_${e.column}_key`)} UNIQUE (${U(e.column)});`, ho = (e, t) => `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(`${e.table}_${e.column}_key`)} UNIQUE (${Za(t, e.table, e.column)});`, go = (e) => {
|
|
3179
|
+
let t = e.fields.map((e) => U(e)).join(", ");
|
|
3180
|
+
return `ALTER TABLE ${U(e.table)} ADD CONSTRAINT ${U(e.name)} UNIQUE (${t});`;
|
|
3181
|
+
}, _o = (e, t) => {
|
|
3182
|
+
let n = e.fields.map((n) => Za(t, e.table, n)).join(", ");
|
|
3183
|
+
return `ALTER TABLE ${W(e.table)} ADD CONSTRAINT ${W(e.name)} UNIQUE (${n});`;
|
|
3184
|
+
}, vo = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(e.name)};`, yo = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(e.name)};`, bo = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_key`)};`, xo = (e) => `ALTER TABLE ${W(e.table)} DROP INDEX ${W(`${e.table}_${e.column}_key`)};`, So = (e, t, n = Pa) => {
|
|
3185
3185
|
let r = [], i = t(e.table), a = t(e.column), o = t(e.targetTable), s = t(e.targetColumn);
|
|
3186
3186
|
if (e.orphanPolicy) {
|
|
3187
3187
|
let t = `${a} IS NOT NULL AND ${a} NOT IN (SELECT ${s} FROM ${o})`;
|
|
@@ -3194,10 +3194,10 @@ BEGIN
|
|
|
3194
3194
|
`REFERENCES ${o} (${s})`
|
|
3195
3195
|
];
|
|
3196
3196
|
return e.onDelete && c.push(`ON DELETE ${n[e.onDelete]}`), r.push(c.join(" ") + ";"), r;
|
|
3197
|
-
},
|
|
3197
|
+
}, Co = (e) => e.name ?? `${e.table}_${e.column}_fkey`, wo = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(Co(e))};`, To = (e) => `ALTER TABLE ${W(e.table)} DROP FOREIGN KEY ${W(Co(e))};`, Eo = (e, t) => {
|
|
3198
3198
|
let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
|
|
3199
3199
|
return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
|
|
3200
|
-
},
|
|
3200
|
+
}, Do = (e) => `ALTER TABLE ${U(e.table)} DROP CONSTRAINT IF EXISTS ${U(`${e.table}_${e.column}_check`)};`, Oo = (e, t) => A.gen(function* () {
|
|
3201
3201
|
let n = yield* e`
|
|
3202
3202
|
SELECT cc.constraint_name AS n, cc.check_clause AS c
|
|
3203
3203
|
FROM information_schema.check_constraints cc
|
|
@@ -3210,18 +3210,18 @@ BEGIN
|
|
|
3210
3210
|
WHERE tc.table_schema = DATABASE() AND tc.table_name = ${t.table}`), A.orElseSucceed(() => []));
|
|
3211
3211
|
for (let e of n) {
|
|
3212
3212
|
let n = String(e.n ?? "");
|
|
3213
|
-
if (n !== "" &&
|
|
3213
|
+
if (n !== "" && hi(String(e.c ?? ""))?.column === t.column) return n;
|
|
3214
3214
|
}
|
|
3215
|
-
}),
|
|
3216
|
-
let r = yield*
|
|
3217
|
-
r !== void 0 && (yield*
|
|
3218
|
-
let i = yield*
|
|
3215
|
+
}), ko = (e, t, n) => A.gen(function* () {
|
|
3216
|
+
let r = yield* Oo(e, t);
|
|
3217
|
+
r !== void 0 && (yield* q(e, `ALTER TABLE ${W(t.table)} DROP CONSTRAINT ${W(r)};`, t.kind, [Xi]));
|
|
3218
|
+
let i = yield* Oo(e, t);
|
|
3219
3219
|
if (i === void 0) return;
|
|
3220
|
-
let a =
|
|
3220
|
+
let a = G(n, t.table, t.column);
|
|
3221
3221
|
if (!a) return yield* A.die(/* @__PURE__ */ Error(`applier: cannot drop the CHECK on '${t.table}.${t.column}' — it is column-level (catalog name '${i}'), which this family removes only by redefining the column, and the declared column is not available to redefine it from.`));
|
|
3222
|
-
yield*
|
|
3223
|
-
}),
|
|
3224
|
-
let i = e.column, a = r === "mariadb", o = a ?
|
|
3222
|
+
yield* q(e, `ALTER TABLE ${W(t.table)} MODIFY COLUMN ${ha(a, t.column)};`, t.kind);
|
|
3223
|
+
}), Ao = (e, t, n, r) => {
|
|
3224
|
+
let i = e.column, a = r === "mariadb", o = a ? W : r === "mssql" ? K : U, s = a ? aa(i) : r === "mssql" ? Wa(i) : r === "sqlite" ? Ia(i) : ra(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = r === "mssql" ? i.type === "json" ? ` CHECK ${kt(o(i.name))}` : i.type === "array" ? ` CHECK (${o(i.name)} IS NULL OR ISJSON(${o(i.name)}) = 1)` : "" : "", u = (e) => a ? ya(e, i) : r === "mssql" ? La(e, "SYSUTCDATETIME()") : r === "sqlite" ? La(e, "CURRENT_TIMESTAMP") : xa(e, i), d = Sa(i, r);
|
|
3225
3225
|
if (d) {
|
|
3226
3226
|
let t = r === "mssql" ? `${o(i.name)} ${d}` : `${o(i.name)} ${s} ${d}`;
|
|
3227
3227
|
return {
|
|
@@ -3250,7 +3250,7 @@ BEGIN
|
|
|
3250
3250
|
post: p ? [p] : []
|
|
3251
3251
|
};
|
|
3252
3252
|
return i.unique && i.type !== "id" && (m.uniquePending = !0), f?.sql && (m.backfillKind = "sql", m.backfillSql = f.sql), f?.js && (m.backfillKind = "js", m.backfillJs = f.js), f?.batchSize !== void 0 && (m.batchSize = f.batchSize), f?.sleepMs !== void 0 && (m.sleepMs = f.sleepMs), m;
|
|
3253
|
-
},
|
|
3253
|
+
}, jo = /* @__PURE__ */ new Set([
|
|
3254
3254
|
"drop-index",
|
|
3255
3255
|
"drop-check",
|
|
3256
3256
|
"drop-unique",
|
|
@@ -3258,7 +3258,7 @@ BEGIN
|
|
|
3258
3258
|
"drop-foreign-key",
|
|
3259
3259
|
"drop-column",
|
|
3260
3260
|
"drop-table"
|
|
3261
|
-
]),
|
|
3261
|
+
]), Mo = (e) => {
|
|
3262
3262
|
let t = new Map(e.map((e) => [e.tableName, e]));
|
|
3263
3263
|
return (e, n) => {
|
|
3264
3264
|
let r = t.get(e);
|
|
@@ -3278,12 +3278,12 @@ BEGIN
|
|
|
3278
3278
|
...o
|
|
3279
3279
|
};
|
|
3280
3280
|
};
|
|
3281
|
-
},
|
|
3281
|
+
}, q = (e, t, n, r = []) => e.unsafe(t).pipe(A.catchIf((e) => Ki(e, r), () => A.void), A.tapError((e) => A.sync(() => {
|
|
3282
3282
|
process.stderr.write(Pe(`applier: statement failed (op=${n})`, t, e, 400));
|
|
3283
3283
|
})), A.mapError((e) => {
|
|
3284
3284
|
let r = Pe(`applier: statement failed (op=${n})`, t, e, 400).trim();
|
|
3285
3285
|
return Object.assign(e, { message: r });
|
|
3286
|
-
}), A.map(() => void 0)),
|
|
3286
|
+
}), A.map(() => void 0)), J = (e, t, n, r) => No(e, t, Ba(t, n), r), No = (e, t, n, r) => {
|
|
3287
3287
|
if (n.length === 0) return A.void;
|
|
3288
3288
|
let i = (e) => (n) => {
|
|
3289
3289
|
let i = Pe(`applier: statement failed (op=${r}, sqlite rebuild of ${t})`, e, n, 400).trim();
|
|
@@ -3300,7 +3300,7 @@ BEGIN
|
|
|
3300
3300
|
}
|
|
3301
3301
|
}), A.ignore(a("PRAGMA foreign_keys = ON")));
|
|
3302
3302
|
}));
|
|
3303
|
-
},
|
|
3303
|
+
}, Po = (e, t) => A.gen(function* () {
|
|
3304
3304
|
let n = (yield* e`
|
|
3305
3305
|
SELECT ck.name, ck.definition, ck.is_disabled AS disabled,
|
|
3306
3306
|
ck.is_not_trusted AS untrusted, ck.is_not_for_replication AS notForReplication
|
|
@@ -3312,18 +3312,18 @@ BEGIN
|
|
|
3312
3312
|
) ORDER BY ck.name
|
|
3313
3313
|
`).map((e) => ({
|
|
3314
3314
|
...e,
|
|
3315
|
-
definition:
|
|
3315
|
+
definition: $i(e.definition, t.from, t.to)
|
|
3316
3316
|
})), r = (e) => i(e, "mssql"), a = (e) => e.replace(/'/g, "''");
|
|
3317
|
-
return yield*
|
|
3317
|
+
return yield* Y(e, [
|
|
3318
3318
|
...n.map((e) => `ALTER TABLE ${r(t.table)} DROP CONSTRAINT ${r(e.name)}`),
|
|
3319
3319
|
`EXEC sp_rename N'${a(`${r(t.table)}.${r(t.from)}`)}', N'${a(t.to)}', 'COLUMN';`,
|
|
3320
3320
|
...n.flatMap((e) => [`ALTER TABLE ${r(t.table)} WITH ${e.untrusted ? "NOCHECK" : "CHECK"} ADD CONSTRAINT ${r(e.name)} CHECK ${e.notForReplication ? "NOT FOR REPLICATION " : ""}${e.definition}`, ...e.disabled ? [`ALTER TABLE ${r(t.table)} NOCHECK CONSTRAINT ${r(e.name)}`] : []])
|
|
3321
3321
|
], t.kind);
|
|
3322
|
-
}),
|
|
3322
|
+
}), Fo = (e, t, n) => e == null ? e : t.type === "json" ? JSON.stringify(e) : (t.type === "array" || t.type === "vector") && n !== "postgres" ? typeof e == "string" ? e : JSON.stringify(e) : e, Y = (e, t, n) => A.forEach(t, (t) => q(e, t, n), { discard: !0 }), Io = (e, t) => {
|
|
3323
3323
|
let n = Math.max(1, Math.floor(Number.isFinite(t) ? t : 1));
|
|
3324
3324
|
return e.literal(N(e) === "mssql" ? `OFFSET 0 ROWS FETCH NEXT ${n} ROWS ONLY` : `LIMIT ${n}`);
|
|
3325
|
-
},
|
|
3326
|
-
let i =
|
|
3325
|
+
}, Lo = (e, t, n, r) => e.unsafe(`SELECT ${r === void 0 ? "*" : i(r, t)} FROM ${i(n, t)} WHERE 1=0`).pipe(A.as(!0), A.catchAll(() => A.succeed(!1))), Ro = (e, t) => Ho(e, t, vt, P), zo = (e, t) => Ho(e, t, de, "_voltro_migration_plans"), Bo = (e, t) => Ho(e, t, li, z), Vo = (e, t) => Ho(e, t, fe, he), Ho = (e, t, n, r) => A.gen(function* () {
|
|
3326
|
+
let i = Tr([n], t).tables[0];
|
|
3327
3327
|
if (!i) return yield* A.die(/* @__PURE__ */ Error(`migration applier: the ${r} table descriptor produced no snapshot. This is a framework bug.`));
|
|
3328
3328
|
let a = {
|
|
3329
3329
|
kind: "create-table",
|
|
@@ -3331,18 +3331,18 @@ BEGIN
|
|
|
3331
3331
|
columns: i.columns,
|
|
3332
3332
|
indexes: []
|
|
3333
3333
|
}, o = yield* e.onDialectOrElse({
|
|
3334
|
-
mysql: () =>
|
|
3335
|
-
mssql: () => A.succeed(
|
|
3336
|
-
sqlite: () => A.succeed(
|
|
3337
|
-
orElse: () => A.succeed(
|
|
3334
|
+
mysql: () => V(e).pipe(A.map((e) => Na(a, e))),
|
|
3335
|
+
mssql: () => A.succeed(Ka(a)),
|
|
3336
|
+
sqlite: () => A.succeed(za(a)),
|
|
3337
|
+
orElse: () => A.succeed(Ea(a))
|
|
3338
3338
|
});
|
|
3339
|
-
yield* A.forEach(o, (t) =>
|
|
3340
|
-
}),
|
|
3339
|
+
yield* A.forEach(o, (t) => q(e, t, "resume-ledger-bootstrap"), { discard: !0 });
|
|
3340
|
+
}), Uo = (e) => e`
|
|
3341
3341
|
SELECT ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
|
|
3342
3342
|
${e("status")}, ${e("payload")}
|
|
3343
3343
|
FROM ${e(P)}
|
|
3344
|
-
`,
|
|
3345
|
-
let i = yield*
|
|
3344
|
+
`, Wo = (e, t, n, r) => A.gen(function* () {
|
|
3345
|
+
let i = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
|
|
3346
3346
|
yield* A.forEach(r, ({ index: r, planned: a }) => e`
|
|
3347
3347
|
INSERT INTO ${e(P)}
|
|
3348
3348
|
(${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")},
|
|
@@ -3353,8 +3353,8 @@ BEGIN
|
|
|
3353
3353
|
${a.op.kind}, ${bt(a.op)}, ${"pending"},
|
|
3354
3354
|
${JSON.stringify(a)}, ${i})
|
|
3355
3355
|
`, { discard: !0 });
|
|
3356
|
-
}),
|
|
3357
|
-
let a = yield*
|
|
3356
|
+
}), Go = (e, t, n, r, i) => A.gen(function* () {
|
|
3357
|
+
let a = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
|
|
3358
3358
|
if (r === "applied") {
|
|
3359
3359
|
yield* e`
|
|
3360
3360
|
UPDATE ${e(P)}
|
|
@@ -3369,8 +3369,8 @@ BEGIN
|
|
|
3369
3369
|
SET ${e("status")} = ${r}, ${e("startedAt")} = ${a}
|
|
3370
3370
|
WHERE ${e("runId")} = ${t} AND ${e("opIndex")} = ${n}
|
|
3371
3371
|
`;
|
|
3372
|
-
}),
|
|
3373
|
-
let i = yield*
|
|
3372
|
+
}), Ko = (e, t, n, r) => A.gen(function* () {
|
|
3373
|
+
let i = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
|
|
3374
3374
|
r.length > 0 && (yield* e`
|
|
3375
3375
|
UPDATE ${e(P)}
|
|
3376
3376
|
SET ${e("status")} = ${"applied"}, ${e("appliedAt")} = ${i}
|
|
@@ -3380,149 +3380,149 @@ BEGIN
|
|
|
3380
3380
|
SET ${e("status")} = ${"pending"}
|
|
3381
3381
|
WHERE ${e("runId")} = ${t} AND ${e("opIndex")} IN ${e.in(n)}
|
|
3382
3382
|
`);
|
|
3383
|
-
}),
|
|
3383
|
+
}), qo = (e, t) => t === void 0 ? e`DELETE FROM ${e(P)}`.pipe(A.asVoid) : e`DELETE FROM ${e(P)} WHERE ${e("runId")} = ${t}`.pipe(A.asVoid), Jo = (e) => Uo(e).pipe(A.map((e) => e.filter((e) => e.status === "started" || e.status === "added" || e.status === "applied").map((e) => JSON.parse(e.payload))), A.catchAll(() => A.succeed([]))), Yo = (e) => qo(e).pipe(A.catchAll(() => A.void)), Xo = (e, t, n) => A.gen(function* () {
|
|
3384
3384
|
if (Ot(n.op, n.classification, t) !== "artefact-repair") return "clean";
|
|
3385
3385
|
let r = n.op, a = (e) => i(e, t);
|
|
3386
3386
|
if (t === "sqlite" || t === "turso") {
|
|
3387
3387
|
if (!("table" in r)) return "clean";
|
|
3388
3388
|
let n = `${r.table}${Ct}`;
|
|
3389
|
-
return (yield*
|
|
3389
|
+
return (yield* Lo(e, t, n)) ? ((yield* Lo(e, t, r.table)) ? yield* q(e, `DROP TABLE ${a(n)}`, "resume-repair") : yield* q(e, `ALTER TABLE ${a(n)} RENAME TO ${a(r.table)}`, "resume-repair"), yield* A.logWarning(`migration resume: reconciled an interrupted sqlite table rebuild on '${r.table}' — replaying the operation`).pipe(A.annotateLogs({ scope: "voltro:migrate" })), "outstanding") : "clean";
|
|
3390
3390
|
}
|
|
3391
3391
|
if (r.kind !== "alter-column-type") return "clean";
|
|
3392
|
-
let o = `${r.column}${wt}`, s = `${r.column}${Tt}`, c = yield*
|
|
3393
|
-
return !l && !u ? "clean" : c && l && !u ? (yield*
|
|
3394
|
-
}),
|
|
3395
|
-
let o = process.hrtime.bigint(), s =
|
|
3392
|
+
let o = `${r.column}${wt}`, s = `${r.column}${Tt}`, c = yield* Lo(e, t, r.table, r.column), l = yield* Lo(e, t, r.table, o), u = yield* Lo(e, t, r.table, s), d = (e) => A.logWarning(`migration resume: ${e}`).pipe(A.annotateLogs({ scope: "voltro:migrate" }));
|
|
3393
|
+
return !l && !u ? "clean" : c && l && !u ? (yield* q(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(o)}`, "resume-repair"), yield* d(`dropped a half-populated shadow column '${r.table}.${o}' — replaying the type change`), "outstanding") : !c && l && u ? (yield* q(e, `ALTER TABLE ${a(r.table)} RENAME COLUMN ${a(o)} TO ${a(r.column)}`, "resume-repair"), yield* q(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`completed an interrupted shadow swap on '${r.table}.${r.column}'`), "applied") : c && !l && u ? (yield* q(e, `ALTER TABLE ${a(r.table)} DROP COLUMN ${a(s)}`, "resume-repair"), yield* d(`dropped the leftover pre-swap column '${r.table}.${s}'`), "applied") : yield* A.die(/* @__PURE__ */ Error(`applyPlan: an interrupted online type change on '${r.table}.${r.column}' left a shadow-swap state this resume cannot classify (column=${c}, ${o}=${l}, ${s}=${u}).\nNothing was changed. Inspect those three columns and reconcile them by hand — the data is in whichever of them is populated — then re-run the migration.`));
|
|
3394
|
+
}), Zo = (e, t, n, r = "fresh", a) => A.gen(function* () {
|
|
3395
|
+
let o = process.hrtime.bigint(), s = Mo(n.declared), c = t.op, l = N(e);
|
|
3396
3396
|
switch (c.kind) {
|
|
3397
3397
|
case "create-table": {
|
|
3398
3398
|
let t = yield* e.onDialectOrElse({
|
|
3399
|
-
mysql: () =>
|
|
3400
|
-
mssql: () => A.succeed(
|
|
3401
|
-
sqlite: () => A.succeed(
|
|
3402
|
-
orElse: () => A.succeed(
|
|
3399
|
+
mysql: () => V(e).pipe(A.map((e) => Na(c, e))),
|
|
3400
|
+
mssql: () => A.succeed(Ka(c)),
|
|
3401
|
+
sqlite: () => A.succeed(za(c)),
|
|
3402
|
+
orElse: () => A.succeed(Ea(c))
|
|
3403
3403
|
}), n = yield* e.onDialectOrElse({
|
|
3404
|
-
mysql: () => A.succeed([
|
|
3404
|
+
mysql: () => A.succeed([qi]),
|
|
3405
3405
|
orElse: () => A.succeed([])
|
|
3406
3406
|
});
|
|
3407
|
-
for (let r of t) yield*
|
|
3407
|
+
for (let r of t) yield* q(e, r, c.kind, n);
|
|
3408
3408
|
break;
|
|
3409
3409
|
}
|
|
3410
3410
|
case "drop-table": {
|
|
3411
|
-
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ?
|
|
3411
|
+
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? Ya(c, n, e) : Ja(c, e);
|
|
3412
3412
|
yield* e.onDialectOrElse({
|
|
3413
|
-
mysql: () =>
|
|
3414
|
-
orElse: () =>
|
|
3413
|
+
mysql: () => q(e, r(W), c.kind),
|
|
3414
|
+
orElse: () => q(e, r(U), c.kind)
|
|
3415
3415
|
});
|
|
3416
3416
|
break;
|
|
3417
3417
|
}
|
|
3418
3418
|
case "drop-column": {
|
|
3419
3419
|
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
|
|
3420
3420
|
yield* e.onDialectOrElse({
|
|
3421
|
-
mysql: () =>
|
|
3422
|
-
sqlite: () =>
|
|
3423
|
-
orElse: () =>
|
|
3421
|
+
mysql: () => V(e).pipe(A.flatMap((r) => q(e, t ? ua(c, n, W) : ca(c, r), c.kind, t ? [] : [Ji]))),
|
|
3422
|
+
sqlite: () => q(e, t ? ua(c, n, U) : sa(c, U, !1), c.kind, t ? [] : [Yi]),
|
|
3423
|
+
orElse: () => q(e, t ? ua(c, n, U) : sa(c, U), c.kind)
|
|
3424
3424
|
});
|
|
3425
3425
|
break;
|
|
3426
3426
|
}
|
|
3427
3427
|
case "rename-column":
|
|
3428
3428
|
yield* e.onDialectOrElse({
|
|
3429
|
-
mysql: () =>
|
|
3430
|
-
mssql: () =>
|
|
3431
|
-
orElse: () =>
|
|
3429
|
+
mysql: () => q(e, la(c, W), c.kind),
|
|
3430
|
+
mssql: () => Po(e, c),
|
|
3431
|
+
orElse: () => q(e, la(c, U), c.kind)
|
|
3432
3432
|
});
|
|
3433
3433
|
break;
|
|
3434
3434
|
case "add-index":
|
|
3435
3435
|
yield* e.onDialectOrElse({
|
|
3436
|
-
sqlite: () =>
|
|
3437
|
-
mysql: () =>
|
|
3438
|
-
mssql: () =>
|
|
3439
|
-
orElse: () =>
|
|
3436
|
+
sqlite: () => q(e, eo(c, !1), c.kind),
|
|
3437
|
+
mysql: () => V(e).pipe(A.flatMap((t) => q(e, to(c, n.declared, t), c.kind, [qi]))),
|
|
3438
|
+
mssql: () => Y(e, [...po(c.table, c.index.columns, n.declared), fo(c)], c.kind),
|
|
3439
|
+
orElse: () => q(e, eo(c, t.classification === "online-required"), c.kind)
|
|
3440
3440
|
});
|
|
3441
3441
|
break;
|
|
3442
3442
|
case "drop-index":
|
|
3443
3443
|
yield* e.onDialectOrElse({
|
|
3444
|
-
mysql: () =>
|
|
3445
|
-
mssql: () =>
|
|
3446
|
-
orElse: () =>
|
|
3444
|
+
mysql: () => q(e, io(c), c.kind),
|
|
3445
|
+
mssql: () => q(e, ao(c), c.kind),
|
|
3446
|
+
orElse: () => q(e, ro(c), c.kind)
|
|
3447
3447
|
});
|
|
3448
3448
|
break;
|
|
3449
3449
|
case "rename-table":
|
|
3450
3450
|
yield* e.onDialectOrElse({
|
|
3451
|
-
mysql: () =>
|
|
3452
|
-
mssql: () =>
|
|
3453
|
-
orElse: () =>
|
|
3451
|
+
mysql: () => q(e, oo(c, W), c.kind),
|
|
3452
|
+
mssql: () => q(e, so(c), c.kind),
|
|
3453
|
+
orElse: () => q(e, oo(c, U), c.kind)
|
|
3454
3454
|
});
|
|
3455
3455
|
break;
|
|
3456
3456
|
case "rename-index":
|
|
3457
3457
|
yield* e.onDialectOrElse({
|
|
3458
|
-
mysql: () =>
|
|
3459
|
-
mssql: () =>
|
|
3460
|
-
orElse: () =>
|
|
3458
|
+
mysql: () => q(e, lo(c), c.kind),
|
|
3459
|
+
mssql: () => q(e, uo(c), c.kind),
|
|
3460
|
+
orElse: () => q(e, co(c), c.kind)
|
|
3461
3461
|
});
|
|
3462
3462
|
break;
|
|
3463
3463
|
case "add-unique":
|
|
3464
3464
|
yield* e.onDialectOrElse({
|
|
3465
|
-
mysql: () =>
|
|
3466
|
-
sqlite: () =>
|
|
3467
|
-
mssql: () =>
|
|
3468
|
-
orElse: () =>
|
|
3465
|
+
mysql: () => q(e, ho(c, n.declared), c.kind),
|
|
3466
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3467
|
+
mssql: () => Y(e, [...po(c.table, [c.column], n.declared), mo(c)], c.kind),
|
|
3468
|
+
orElse: () => q(e, mo(c), c.kind)
|
|
3469
3469
|
});
|
|
3470
3470
|
break;
|
|
3471
3471
|
case "drop-unique":
|
|
3472
3472
|
yield* e.onDialectOrElse({
|
|
3473
|
-
mysql: () =>
|
|
3474
|
-
sqlite: () =>
|
|
3475
|
-
orElse: () =>
|
|
3473
|
+
mysql: () => q(e, xo(c), c.kind),
|
|
3474
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3475
|
+
orElse: () => q(e, bo(c), c.kind)
|
|
3476
3476
|
});
|
|
3477
3477
|
break;
|
|
3478
3478
|
case "add-enum-value":
|
|
3479
3479
|
yield* e.onDialectOrElse({
|
|
3480
|
-
pg: () => c.enumName === void 0 ? A.die(/* @__PURE__ */ Error(`add-enum-value on postgres needs the type name for ${c.table}.${c.column}; the plan carries none.`)) :
|
|
3480
|
+
pg: () => c.enumName === void 0 ? A.die(/* @__PURE__ */ Error(`add-enum-value on postgres needs the type name for ${c.table}.${c.column}; the plan carries none.`)) : q(e, `ALTER TYPE ${i(c.enumName, "postgres")} ADD VALUE IF NOT EXISTS '${c.value.replace(/'/g, "''")}'`, c.kind),
|
|
3481
3481
|
mysql: () => {
|
|
3482
|
-
let t =
|
|
3483
|
-
return t === void 0 || t.enumValues === void 0 || t.enumValues.length === 0 ? A.die(/* @__PURE__ */ Error(`add-enum-value on the mysql family needs the declared column ${c.table}.${c.column} and its labels; the declaration carries none.`)) : A.flatMap(
|
|
3482
|
+
let t = G(n.declared, c.table, c.column);
|
|
3483
|
+
return t === void 0 || t.enumValues === void 0 || t.enumValues.length === 0 ? A.die(/* @__PURE__ */ Error(`add-enum-value on the mysql family needs the declared column ${c.table}.${c.column} and its labels; the declaration carries none.`)) : A.flatMap(va(e, c.table, t, c.column), (t) => q(e, t, c.kind));
|
|
3484
3484
|
},
|
|
3485
3485
|
orElse: () => A.void
|
|
3486
3486
|
});
|
|
3487
3487
|
break;
|
|
3488
3488
|
case "add-unique-composite":
|
|
3489
3489
|
yield* e.onDialectOrElse({
|
|
3490
|
-
mysql: () =>
|
|
3491
|
-
sqlite: () =>
|
|
3492
|
-
mssql: () =>
|
|
3493
|
-
orElse: () =>
|
|
3490
|
+
mysql: () => q(e, _o(c, n.declared), c.kind),
|
|
3491
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3492
|
+
mssql: () => Y(e, [...po(c.table, c.fields, n.declared), go(c)], c.kind),
|
|
3493
|
+
orElse: () => q(e, go(c), c.kind)
|
|
3494
3494
|
});
|
|
3495
3495
|
break;
|
|
3496
3496
|
case "drop-unique-composite":
|
|
3497
3497
|
yield* e.onDialectOrElse({
|
|
3498
|
-
mysql: () =>
|
|
3499
|
-
sqlite: () =>
|
|
3500
|
-
orElse: () =>
|
|
3498
|
+
mysql: () => q(e, yo(c), c.kind),
|
|
3499
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3500
|
+
orElse: () => q(e, vo(c), c.kind)
|
|
3501
3501
|
});
|
|
3502
3502
|
break;
|
|
3503
3503
|
case "add-foreign-key":
|
|
3504
3504
|
yield* e.onDialectOrElse({
|
|
3505
|
-
mysql: () =>
|
|
3506
|
-
sqlite: () =>
|
|
3507
|
-
mssql: () =>
|
|
3508
|
-
orElse: () =>
|
|
3505
|
+
mysql: () => Y(e, So(c, W), c.kind),
|
|
3506
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3507
|
+
mssql: () => Y(e, So(c, K, Fa), c.kind),
|
|
3508
|
+
orElse: () => Y(e, So(c, U), c.kind)
|
|
3509
3509
|
});
|
|
3510
3510
|
break;
|
|
3511
3511
|
case "add-column": {
|
|
3512
|
-
let i =
|
|
3512
|
+
let i = Ao(c, t, s, yield* e.onDialectOrElse({
|
|
3513
3513
|
mysql: () => A.succeed("mariadb"),
|
|
3514
3514
|
mssql: () => A.succeed("mssql"),
|
|
3515
3515
|
sqlite: () => A.succeed("sqlite"),
|
|
3516
3516
|
orElse: () => A.succeed("postgres")
|
|
3517
3517
|
}));
|
|
3518
|
-
if (!(r === "resume" && (yield*
|
|
3518
|
+
if (!(r === "resume" && (yield* Lo(e, N(e), c.table, c.column.name)))) for (let t of i.pre) yield* q(e, t, c.kind);
|
|
3519
3519
|
let u = t.classification === "online-required" || i.batchSize !== void 0 || i.sleepMs !== void 0, d = A.gen(function* () {
|
|
3520
3520
|
if (i.backfillKind === "sql" && i.backfillSql) {
|
|
3521
3521
|
if (t.classification !== "online-required" && i.batchSize === void 0) yield* e`UPDATE ${e(c.table)} SET ${e(c.column.name)} = ${i.backfillSql}`;
|
|
3522
3522
|
else {
|
|
3523
3523
|
let t = i.batchSize ?? 5e3, n = i.sleepMs ?? 0, r, a = 0;
|
|
3524
3524
|
for (;;) {
|
|
3525
|
-
let o = r === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL ORDER BY ${e("id")} ${
|
|
3525
|
+
let o = r === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL ORDER BY ${e("id")} ${Io(e, t)}` : yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL AND ${e("id")} > ${r} ORDER BY ${e("id")} ${Io(e, t)}`;
|
|
3526
3526
|
if (o.length === 0) break;
|
|
3527
3527
|
let s = o.map((e) => e.id);
|
|
3528
3528
|
yield* e`UPDATE ${e(c.table)} SET ${e(c.column.name)} = ${i.backfillSql} WHERE ${e("id")} IN ${e.in(s)}`, a += o.length, yield* A.logInfo(`backfill ${c.table}.${c.column.name}: ${a} rows`).pipe(A.annotateLogs({
|
|
@@ -3534,7 +3534,7 @@ BEGIN
|
|
|
3534
3534
|
} else if (i.backfillKind === "js" && i.backfillJs) {
|
|
3535
3535
|
let t = i.batchSize ?? 1e3, r = i.sleepMs ?? 0, a = n.declared.find((e) => e.tableName === c.table), o, s = 0;
|
|
3536
3536
|
for (;;) {
|
|
3537
|
-
let n = o === void 0 ? yield* e`SELECT * FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL ORDER BY ${e("id")} ${
|
|
3537
|
+
let n = o === void 0 ? yield* e`SELECT * FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL ORDER BY ${e("id")} ${Io(e, t)}` : yield* e`SELECT * FROM ${e(c.table)} WHERE ${e(c.column.name)} IS NULL AND ${e("id")} > ${o} ORDER BY ${e("id")} ${Io(e, t)}`;
|
|
3538
3538
|
if (n.length === 0) break;
|
|
3539
3539
|
let u = a === void 0 ? n : p(n, a, l);
|
|
3540
3540
|
for (let t of u) {
|
|
@@ -3542,7 +3542,7 @@ BEGIN
|
|
|
3542
3542
|
try: () => Promise.resolve(i.backfillJs(t)),
|
|
3543
3543
|
catch: (e) => e
|
|
3544
3544
|
}).pipe(A.orDie);
|
|
3545
|
-
yield* e`UPDATE ${e(c.table)} SET ${e(c.column.name)} = ${
|
|
3545
|
+
yield* e`UPDATE ${e(c.table)} SET ${e(c.column.name)} = ${Fo(n, c.column, l)} WHERE ${e("id")} = ${t.id}`;
|
|
3546
3546
|
}
|
|
3547
3547
|
s += u.length, yield* A.logInfo(`backfill ${c.table}.${c.column.name}: ${s} rows processed`).pipe(A.annotateLogs({
|
|
3548
3548
|
scope: "voltro:migrate",
|
|
@@ -3552,8 +3552,8 @@ BEGIN
|
|
|
3552
3552
|
}
|
|
3553
3553
|
}
|
|
3554
3554
|
}), f = A.gen(function* () {
|
|
3555
|
-
for (let t of i.post) yield*
|
|
3556
|
-
if (
|
|
3555
|
+
for (let t of i.post) yield* q(e, t, c.kind);
|
|
3556
|
+
if (O(l) && (i.uniquePending === !0 || i.backfillKind !== void 0 && !c.column.nullable)) yield* J(e, c.table, n.declared, c.kind);
|
|
3557
3557
|
else if (i.uniquePending === !0) {
|
|
3558
3558
|
let t = {
|
|
3559
3559
|
kind: "add-unique",
|
|
@@ -3561,9 +3561,9 @@ BEGIN
|
|
|
3561
3561
|
column: c.column.name
|
|
3562
3562
|
};
|
|
3563
3563
|
yield* e.onDialectOrElse({
|
|
3564
|
-
mysql: () =>
|
|
3565
|
-
mssql: () =>
|
|
3566
|
-
orElse: () =>
|
|
3564
|
+
mysql: () => q(e, ho(t, n.declared), c.kind),
|
|
3565
|
+
mssql: () => Y(e, [...po(c.table, [c.column.name], n.declared), mo(t)], c.kind),
|
|
3566
|
+
orElse: () => q(e, mo(t), c.kind)
|
|
3567
3567
|
});
|
|
3568
3568
|
}
|
|
3569
3569
|
});
|
|
@@ -3584,47 +3584,47 @@ BEGIN
|
|
|
3584
3584
|
case "alter-column-nullability":
|
|
3585
3585
|
yield* e.onDialectOrElse({
|
|
3586
3586
|
mysql: () => {
|
|
3587
|
-
let t =
|
|
3588
|
-
return t ? A.flatMap(
|
|
3587
|
+
let t = G(n.declared, c.table, c.column);
|
|
3588
|
+
return t ? A.flatMap(va(e, c.table, t, c.column, c.toNullable), (t) => q(e, t, c.kind)) : A.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${c.table}.${c.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
|
|
3589
3589
|
},
|
|
3590
3590
|
mssql: () => {
|
|
3591
|
-
let t =
|
|
3592
|
-
return t ?
|
|
3591
|
+
let t = G(n.declared, c.table, c.column);
|
|
3592
|
+
return t ? q(e, Ha(t, c.column, c.table, c.toNullable), c.kind) : A.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${c.table}.${c.column}'.`));
|
|
3593
3593
|
},
|
|
3594
|
-
sqlite: () =>
|
|
3595
|
-
orElse: () =>
|
|
3594
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3595
|
+
orElse: () => q(e, `ALTER TABLE ${U(c.table)} ALTER COLUMN ${U(c.column)} ${c.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, c.kind)
|
|
3596
3596
|
});
|
|
3597
3597
|
break;
|
|
3598
3598
|
case "alter-column-default": {
|
|
3599
|
-
let t =
|
|
3599
|
+
let t = ma(n.declared, c.table, c.column), r = G(n.declared, c.table, c.column), i = (e) => c.hasDefault && r !== void 0 && fa(r, e) ? r : void 0;
|
|
3600
3600
|
yield* e.onDialectOrElse({
|
|
3601
3601
|
mysql: () => {
|
|
3602
3602
|
let n = i("mariadb");
|
|
3603
|
-
return A.flatMap(n ?
|
|
3603
|
+
return A.flatMap(n ? va(e, c.table, n, c.column) : A.succeed(da(c, W, (e) => ya(e, t))), (t) => q(e, t, c.kind));
|
|
3604
3604
|
},
|
|
3605
3605
|
mssql: () => {
|
|
3606
3606
|
let t = i("mssql");
|
|
3607
|
-
return
|
|
3607
|
+
return q(e, Ua(c, t ? Ha(t, c.column, c.table) : void 0), c.kind);
|
|
3608
3608
|
},
|
|
3609
|
-
sqlite: () =>
|
|
3610
|
-
orElse: () =>
|
|
3609
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3610
|
+
orElse: () => q(e, da(c, U, (e) => xa(e, t)), c.kind)
|
|
3611
3611
|
});
|
|
3612
3612
|
break;
|
|
3613
3613
|
}
|
|
3614
3614
|
case "alter-column-type": {
|
|
3615
|
-
let r =
|
|
3615
|
+
let r = ra(ma(n.declared, c.table, c.column) ?? { type: c.to }), i = c.using ? ` USING ${c.using}` : "";
|
|
3616
3616
|
if (t.classification !== "online-required") {
|
|
3617
3617
|
yield* e.onDialectOrElse({
|
|
3618
3618
|
mysql: () => {
|
|
3619
|
-
let t =
|
|
3620
|
-
return t ? A.flatMap(
|
|
3619
|
+
let t = G(n.declared, c.table, c.column);
|
|
3620
|
+
return t ? A.flatMap(va(e, c.table, t, c.column), (t) => q(e, t, c.kind)) : A.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${c.table}.${c.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
|
|
3621
3621
|
},
|
|
3622
3622
|
mssql: () => {
|
|
3623
|
-
let t =
|
|
3624
|
-
return t ?
|
|
3623
|
+
let t = G(n.declared, c.table, c.column);
|
|
3624
|
+
return t ? q(e, Ha(t, c.column, c.table), c.kind) : A.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${c.table}.${c.column}'.`));
|
|
3625
3625
|
},
|
|
3626
|
-
sqlite: () =>
|
|
3627
|
-
orElse: () =>
|
|
3626
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3627
|
+
orElse: () => q(e, `ALTER TABLE ${U(c.table)} ALTER COLUMN ${U(c.column)} TYPE ${r}${i};`, c.kind)
|
|
3628
3628
|
});
|
|
3629
3629
|
break;
|
|
3630
3630
|
}
|
|
@@ -3633,53 +3633,53 @@ BEGIN
|
|
|
3633
3633
|
orElse: () => A.void
|
|
3634
3634
|
});
|
|
3635
3635
|
let a = `${c.column}__shadow`, o = `${c.column}__old`;
|
|
3636
|
-
yield* e.unsafe(`ALTER TABLE ${
|
|
3637
|
-
let s = c.using ??
|
|
3636
|
+
yield* e.unsafe(`ALTER TABLE ${U(c.table)} ADD COLUMN ${U(a)} ${r}`);
|
|
3637
|
+
let s = c.using ?? U(c.column), l;
|
|
3638
3638
|
for (;;) {
|
|
3639
|
-
let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(a)} IS NULL ORDER BY ${e("id")} ${
|
|
3639
|
+
let t = l === void 0 ? yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(a)} IS NULL ORDER BY ${e("id")} ${Io(e, 5e3)}` : yield* e`SELECT ${e("id")} FROM ${e(c.table)} WHERE ${e(a)} IS NULL AND ${e("id")} > ${l} ORDER BY ${e("id")} ${Io(e, 5e3)}`;
|
|
3640
3640
|
if (t.length === 0) break;
|
|
3641
|
-
yield* e.unsafe(`UPDATE ${
|
|
3641
|
+
yield* e.unsafe(`UPDATE ${U(c.table)} SET ${U(a)} = ${s} WHERE ${U(c.column)} IS NOT NULL AND ${U(a)} IS NULL AND ${U("id")} IN (${t.map((e) => `'${e.id.replace(/'/g, "''")}'`).join(",")})`), l = t[t.length - 1].id;
|
|
3642
3642
|
}
|
|
3643
|
-
yield* A.logInfo(`alter-column-type shadow ${c.table}.${c.column}: shadow populated`).pipe(A.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${
|
|
3643
|
+
yield* A.logInfo(`alter-column-type shadow ${c.table}.${c.column}: shadow populated`).pipe(A.annotateLogs({ scope: "voltro:migrate" })), yield* e.unsafe(`ALTER TABLE ${U(c.table)} RENAME COLUMN ${U(c.column)} TO ${U(o)}`), yield* e.unsafe(`ALTER TABLE ${U(c.table)} RENAME COLUMN ${U(a)} TO ${U(c.column)}`), yield* e.unsafe(`ALTER TABLE ${U(c.table)} DROP COLUMN ${U(o)}`);
|
|
3644
3644
|
break;
|
|
3645
3645
|
}
|
|
3646
3646
|
case "drop-foreign-key":
|
|
3647
3647
|
yield* e.onDialectOrElse({
|
|
3648
|
-
mysql: () =>
|
|
3649
|
-
sqlite: () =>
|
|
3650
|
-
orElse: () =>
|
|
3648
|
+
mysql: () => q(e, To(c), c.kind),
|
|
3649
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3650
|
+
orElse: () => q(e, wo(c), c.kind)
|
|
3651
3651
|
});
|
|
3652
3652
|
break;
|
|
3653
3653
|
case "add-check":
|
|
3654
3654
|
yield* e.onDialectOrElse({
|
|
3655
|
-
mysql: () =>
|
|
3656
|
-
sqlite: () =>
|
|
3657
|
-
orElse: () =>
|
|
3655
|
+
mysql: () => q(e, Eo(c, W), c.kind),
|
|
3656
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3657
|
+
orElse: () => q(e, Eo(c, U), c.kind)
|
|
3658
3658
|
});
|
|
3659
3659
|
break;
|
|
3660
3660
|
case "convert-charset":
|
|
3661
3661
|
yield* e.onDialectOrElse({
|
|
3662
3662
|
mysql: () => A.gen(function* () {
|
|
3663
|
-
let { drops: t, rewrite: r, restores: i } =
|
|
3664
|
-
for (let n of t) yield*
|
|
3665
|
-
yield*
|
|
3666
|
-
for (let t of i) yield*
|
|
3663
|
+
let { drops: t, rewrite: r, restores: i } = Ma(c, n.declared, yield* _a(e, c.table));
|
|
3664
|
+
for (let n of t) yield* q(e, n, c.kind, [Xi]);
|
|
3665
|
+
yield* q(e, r, c.kind);
|
|
3666
|
+
for (let t of i) yield* q(e, t, c.kind, [Zi]);
|
|
3667
3667
|
}),
|
|
3668
3668
|
orElse: () => A.dieMessage("convert-charset requires MySQL or MariaDB")
|
|
3669
3669
|
});
|
|
3670
3670
|
break;
|
|
3671
3671
|
case "reconcile-json-check": {
|
|
3672
|
-
let t =
|
|
3672
|
+
let t = K(c.column), n = c.validation === "value" ? kt(t) : `(${t} IS NULL OR ISJSON(${t}) = 1)`;
|
|
3673
3673
|
yield* e.onDialectOrElse({
|
|
3674
|
-
mssql: () =>
|
|
3674
|
+
mssql: () => Y(e, [...c.dropConstraints.map((e) => `ALTER TABLE ${K(c.table)} DROP CONSTRAINT ${K(e)}`), `ALTER TABLE ${K(c.table)} WITH CHECK ADD CHECK ${n}`], c.kind),
|
|
3675
3675
|
orElse: () => A.dieMessage("reconcile-json-check requires SQL Server")
|
|
3676
3676
|
});
|
|
3677
3677
|
break;
|
|
3678
3678
|
}
|
|
3679
3679
|
case "drop-check": yield* e.onDialectOrElse({
|
|
3680
|
-
mysql: () =>
|
|
3681
|
-
sqlite: () =>
|
|
3682
|
-
orElse: () =>
|
|
3680
|
+
mysql: () => ko(e, c, n.declared),
|
|
3681
|
+
sqlite: () => J(e, c.table, n.declared, c.kind),
|
|
3682
|
+
orElse: () => q(e, Do(c), c.kind)
|
|
3683
3683
|
});
|
|
3684
3684
|
}
|
|
3685
3685
|
return {
|
|
@@ -3687,7 +3687,7 @@ BEGIN
|
|
|
3687
3687
|
status: "applied",
|
|
3688
3688
|
durationMs: Number((process.hrtime.bigint() - o) / 1000000n)
|
|
3689
3689
|
};
|
|
3690
|
-
}),
|
|
3690
|
+
}), Qo = (e, t, n, r) => A.gen(function* () {
|
|
3691
3691
|
let i = [...new Set(r.map((e) => e.runId))];
|
|
3692
3692
|
if (i.length > 1) return yield* A.die(/* @__PURE__ */ Error(`applyPlan: the resume ledger holds ${i.length} unfinished runs (${i.join(", ")}). Only one migration may be in flight at a time — the advisory lock enforces it — so this means a run was interrupted and a LATER one wrote over it without clearing.\nNothing was changed. Inspect \`${P}\`, reconcile the schema by hand, and delete the rows of the run you have finished.`));
|
|
3693
3693
|
let a = i[0], o = [...r].map((e) => ({
|
|
@@ -3702,7 +3702,7 @@ BEGIN
|
|
|
3702
3702
|
runId: a,
|
|
3703
3703
|
why: "no operation had started — no DDL ran"
|
|
3704
3704
|
};
|
|
3705
|
-
let u = s ? yield*
|
|
3705
|
+
let u = s ? yield* Xo(e, t, s.planned) : "clean", d = r[0].planFingerprint;
|
|
3706
3706
|
if (d !== n.toFingerprint) return {
|
|
3707
3707
|
kind: "discard",
|
|
3708
3708
|
runId: a,
|
|
@@ -3713,7 +3713,7 @@ BEGIN
|
|
|
3713
3713
|
kind: "discard",
|
|
3714
3714
|
runId: a,
|
|
3715
3715
|
why: "every recorded operation had already taken effect"
|
|
3716
|
-
} : (yield*
|
|
3716
|
+
} : (yield* Ko(e, a, p.map((e) => e.index), m.map((e) => e.index)), yield* A.logWarning(`migration resume: continuing run ${a} — replaying ${p.length} operation(s), ${o.length - p.length} already applied`).pipe(A.annotateLogs({ scope: "voltro:migrate" })), {
|
|
3717
3717
|
kind: "resume",
|
|
3718
3718
|
runId: a,
|
|
3719
3719
|
ops: p.map((e) => ({
|
|
@@ -3721,7 +3721,7 @@ BEGIN
|
|
|
3721
3721
|
planned: e.planned
|
|
3722
3722
|
}))
|
|
3723
3723
|
});
|
|
3724
|
-
}),
|
|
3724
|
+
}), $o = (e, t, n) => A.gen(function* () {
|
|
3725
3725
|
for (let r of t.operations) {
|
|
3726
3726
|
let a = r.op;
|
|
3727
3727
|
if (a.kind !== "add-index" || !a.index.unique || a.index.where === void 0 || t.operations.some((e) => e.op.kind === "rename-table" ? e.op.to === a.table : e.op.table === a.table && [
|
|
@@ -3732,7 +3732,7 @@ BEGIN
|
|
|
3732
3732
|
let o = a.index.columns.map((e) => e.startsWith("(") ? e : i(e, n)), s = n === "mssql" ? "" : o.map((e) => ` AND ${e} IS NOT NULL`).join(""), c = n === "mssql" ? "SELECT TOP (1) 1" : "SELECT 1", l = n === "mssql" ? "" : " LIMIT 1";
|
|
3733
3733
|
if ((yield* e.unsafe(`${c} FROM ${i(a.table, n)} WHERE (${a.index.where})${s} GROUP BY ${o.join(", ")} HAVING COUNT(*) > 1${l}`)).length > 0) return yield* A.die(/* @__PURE__ */ Error(`applyPlan: partial unique index '${a.index.name}' on '${a.table}' conflicts with existing qualifying rows. No schema or row changes were applied. Resolve the conflicting data explicitly before retrying.`));
|
|
3734
3734
|
}
|
|
3735
|
-
}),
|
|
3735
|
+
}), es = (e) => {
|
|
3736
3736
|
let t = e.op, n = (e) => typeof t[e] == "string" ? t[e] : "";
|
|
3737
3737
|
return [
|
|
3738
3738
|
t.kind,
|
|
@@ -3741,13 +3741,13 @@ BEGIN
|
|
|
3741
3741
|
n("name"),
|
|
3742
3742
|
n("to")
|
|
3743
3743
|
].join("\0");
|
|
3744
|
-
},
|
|
3744
|
+
}, ts = (e, t, n) => A.acquireUseRelease(ft(e, { schema: n.lockSchema }), () => ns(e, t, n), (e) => e.release.pipe(A.orDie)), ns = (e, t, n) => A.gen(function* () {
|
|
3745
3745
|
let r = t.operations.filter((e) => e.blocked);
|
|
3746
3746
|
if (r.length > 0) return yield* A.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
|
|
3747
|
-
let i = Date.now(), a = [], o = N(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) =>
|
|
3747
|
+
let i = Date.now(), a = [], o = N(e), s = yield* n.replan(e), c = new Set(t.operations.filter((e) => !e.blocked).map((e) => es(e))), l = {
|
|
3748
3748
|
...s,
|
|
3749
3749
|
operations: s.operations.map((e) => {
|
|
3750
|
-
if (!e.blocked || !c.has(
|
|
3750
|
+
if (!e.blocked || !c.has(es(e))) return e;
|
|
3751
3751
|
let { blocked: t, ...n } = e;
|
|
3752
3752
|
return n;
|
|
3753
3753
|
})
|
|
@@ -3755,54 +3755,54 @@ BEGIN
|
|
|
3755
3755
|
(l.operations.length !== t.operations.length || l.toFingerprint !== t.toFingerprint) && (yield* A.logInfo(`migration: re-planned under the lock — ${t.operations.length} operation(s) became ${l.operations.length}. Another writer changed the schema while this plan waited.`).pipe(A.annotateLogs({ scope: "voltro:migrate" })));
|
|
3756
3756
|
let u = l.operations.filter((e) => e.blocked);
|
|
3757
3757
|
if (u.length > 0) return yield* A.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — re-planning under the migration lock found ${u.length} blocked operation(s). Run \`voltro db plan\` to see the fixes.`));
|
|
3758
|
-
let d =
|
|
3759
|
-
d && (yield*
|
|
3760
|
-
let f =
|
|
3761
|
-
f && (yield*
|
|
3762
|
-
let p =
|
|
3763
|
-
p && (yield*
|
|
3758
|
+
let d = un(n.declared, o);
|
|
3759
|
+
d && (yield* q(e, d, "extensions"));
|
|
3760
|
+
let f = _n(n.declared, o);
|
|
3761
|
+
f && (yield* q(e, f, "enum-types"));
|
|
3762
|
+
let p = gn(n.declared, o);
|
|
3763
|
+
p && (yield* q(e, p, "enum-types"));
|
|
3764
3764
|
let m = _t(o) === "plan-transactional", g = m ? l.operations.filter((e) => e.classification !== "online-required") : [], _ = m ? l.operations.filter((e) => e.classification === "online-required") : l.operations, v = `plan_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`, y = _.map((e, t) => ({
|
|
3765
3765
|
index: t,
|
|
3766
3766
|
planned: e
|
|
3767
3767
|
})), b = "fresh";
|
|
3768
|
-
yield*
|
|
3769
|
-
let x = yield*
|
|
3768
|
+
yield* $o(e, l, o), yield* Ro(e, o);
|
|
3769
|
+
let x = yield* Uo(e);
|
|
3770
3770
|
if (x.length > 0) {
|
|
3771
|
-
let t = yield*
|
|
3772
|
-
t.kind === "resume" ? (v = t.runId, y = t.ops, b = "resume") : (yield* A.logWarning(`migration resume: discarding the ledger of run ${t.runId} — ${t.why}`).pipe(A.annotateLogs({ scope: "voltro:migrate" })), yield*
|
|
3771
|
+
let t = yield* Qo(e, o, l, x);
|
|
3772
|
+
t.kind === "resume" ? (v = t.runId, y = t.ops, b = "resume") : (yield* A.logWarning(`migration resume: discarding the ledger of run ${t.runId} — ${t.why}`).pipe(A.annotateLogs({ scope: "voltro:migrate" })), yield* qo(e, t.runId));
|
|
3773
3773
|
}
|
|
3774
|
-
b === "fresh" && y.length > 0 && (yield*
|
|
3774
|
+
b === "fresh" && y.length > 0 && (yield* Wo(e, v, l.toFingerprint, y)), g.length > 0 && (yield* Qi(e, A.gen(function* () {
|
|
3775
3775
|
let e = yield* j.SqlClient, t = [], r = () => A.gen(function* () {
|
|
3776
3776
|
for (let e of t.splice(0)) yield* e.data, yield* e.after;
|
|
3777
3777
|
});
|
|
3778
|
-
for (let i of g)
|
|
3778
|
+
for (let i of g) jo.has(i.op.kind) && t.length > 0 && (yield* r()), a.push(yield* Zo(e, i, n, "fresh", (e) => t.push(e)));
|
|
3779
3779
|
yield* r();
|
|
3780
3780
|
})));
|
|
3781
3781
|
let S = [], C = () => A.gen(function* () {
|
|
3782
3782
|
let t = S.splice(0);
|
|
3783
3783
|
if (t.length !== 0) {
|
|
3784
|
-
yield*
|
|
3784
|
+
yield* Qi(e, A.gen(function* () {
|
|
3785
3785
|
for (let e of t) yield* e.data;
|
|
3786
3786
|
}));
|
|
3787
3787
|
for (let n of t) yield* n.after, a.push({
|
|
3788
3788
|
op: n.op,
|
|
3789
3789
|
status: "applied",
|
|
3790
3790
|
durationMs: Number(process.hrtime.bigint() - n.startedAt) / 1e6
|
|
3791
|
-
}), yield*
|
|
3791
|
+
}), yield* Go(e, v, n.index, "applied", Number(process.hrtime.bigint() - n.startedAt) / 1e6);
|
|
3792
3792
|
}
|
|
3793
3793
|
});
|
|
3794
3794
|
for (let { index: t, planned: r } of y) {
|
|
3795
|
-
|
|
3796
|
-
let i = a.length, o = process.hrtime.bigint(), s = yield*
|
|
3795
|
+
jo.has(r.op.kind) && S.length > 0 && (yield* C()), yield* Go(e, v, t, "started");
|
|
3796
|
+
let i = a.length, o = process.hrtime.bigint(), s = yield* Zo(e, r, n, b, (e) => S.push({
|
|
3797
3797
|
...e,
|
|
3798
3798
|
index: t,
|
|
3799
3799
|
startedAt: o
|
|
3800
3800
|
})).pipe(A.mapError((e) => Object.assign(e, { message: `${String(e?.message ?? e)}\n\n progress: ${i} of ${y.length + g.length} operation(s) applied before this one${g.length > 0 ? ` (${g.length} of them in a transaction)` : ""}.\n` + (m ? " This dialect applies a plan atomically, so the run is rolled back.\n" : ` This dialect does NOT apply a plan atomically: those ${i} are COMMITTED and there is no rollback.\n The ledger records how far it got (operation ${t} was in flight).\n`) })));
|
|
3801
3801
|
if (s.deferred === !0) {
|
|
3802
|
-
yield*
|
|
3802
|
+
yield* Go(e, v, t, "added");
|
|
3803
3803
|
continue;
|
|
3804
3804
|
}
|
|
3805
|
-
a.push(s), yield*
|
|
3805
|
+
a.push(s), yield* Go(e, v, t, "applied", s.durationMs);
|
|
3806
3806
|
}
|
|
3807
3807
|
yield* C();
|
|
3808
3808
|
let w = yield* n.replan(e);
|
|
@@ -3810,23 +3810,23 @@ BEGIN
|
|
|
3810
3810
|
let e = (e) => "column" in e ? typeof e.column == "string" ? `.${e.column}` : `.${String(e.column.name ?? "")}` : "", t = w.operations.slice(0, 10).map((t) => ` - ${t.op.kind} ${"table" in t.op ? t.op.table : ""}${e(t.op)}`).join("\n"), n = a.filter((e) => e.status === "applied"), r = n.slice(0, 10).map((t) => ` - ${t.op.kind} ${"table" in t.op ? t.op.table : ""}${e(t.op)}`).join("\n") + (n.length > 10 ? `\n … and ${n.length - 10} more` : "");
|
|
3811
3811
|
return yield* A.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${l.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${w.operations.length}:\n${t}${w.operations.length > 10 ? `\n … and ${w.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.\n` + (m ? " This dialect applies a plan atomically, so the run is rolled back and the schema IS unchanged.\n" : ` This dialect does NOT apply a plan atomically. The ${n.length} operation(s) below are COMMITTED\n and there is no rollback — the schema is PART-APPLIED, not unchanged:\n${r}\n Re-running plans from where the database now is, which is a different plan from the one that failed.\n`) + "Two causes look identical from here, so read the list before assuming either:\n - the DDL for those operations is a no-op (it succeeded and changed nothing), or\n - the planner cannot see what the DDL did, so it proposes the same work again — which is what an\n operation naming an object a PREVIOUS operation created or renamed usually means.\nReport the operation kinds above with the column types involved."));
|
|
3812
3812
|
}
|
|
3813
|
-
let T = a.filter((e) => e.status === "applied").length, E = Date.now() - i, D = v,
|
|
3813
|
+
let T = a.filter((e) => e.status === "applied").length, E = Date.now() - i, D = v, ee = (/* @__PURE__ */ new Date()).toISOString(), te = yield* H(e, ee), O = [...g, ...y.map((e) => e.planned)];
|
|
3814
3814
|
yield* e`
|
|
3815
3815
|
INSERT INTO ${e("_voltro_migration_plans")}
|
|
3816
3816
|
(${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
|
|
3817
3817
|
${e("appliedBy")}, ${e("environment")}, ${e("source")},
|
|
3818
3818
|
${e("durationMs")}, ${e("appliedAt")}, ${e("notes")})
|
|
3819
3819
|
VALUES
|
|
3820
|
-
(${D}, ${l.toFingerprint}, ${w.fromFingerprint}, ${JSON.stringify(
|
|
3820
|
+
(${D}, ${l.toFingerprint}, ${w.fromFingerprint}, ${JSON.stringify(O)},
|
|
3821
3821
|
${n.appliedBy}, ${n.environment}, ${n.source},
|
|
3822
|
-
${E}, ${
|
|
3823
|
-
`, yield*
|
|
3824
|
-
let
|
|
3825
|
-
return yield* A.promise(() => h({ changedTables:
|
|
3822
|
+
${E}, ${te}, ${n.notes ?? null})
|
|
3823
|
+
`, yield* qo(e, v);
|
|
3824
|
+
let ne = [...new Set(O.flatMap((e) => e.op.kind === "rename-table" ? [e.op.to] : [e.op.table]))];
|
|
3825
|
+
return yield* A.promise(() => h({ changedTables: ne }).catch(() => {})), {
|
|
3826
3826
|
id: D,
|
|
3827
|
-
appliedAt:
|
|
3827
|
+
appliedAt: ee,
|
|
3828
3828
|
fingerprint: l.toFingerprint,
|
|
3829
|
-
operations:
|
|
3829
|
+
operations: O,
|
|
3830
3830
|
appliedBy: n.appliedBy,
|
|
3831
3831
|
environment: n.environment,
|
|
3832
3832
|
durationMs: E,
|
|
@@ -3834,7 +3834,7 @@ BEGIN
|
|
|
3834
3834
|
source: n.source,
|
|
3835
3835
|
...n.notes ? { notes: n.notes } : {}
|
|
3836
3836
|
};
|
|
3837
|
-
}),
|
|
3837
|
+
}), rs = (e, t) => {
|
|
3838
3838
|
switch (t.kind) {
|
|
3839
3839
|
case "drop-foreign-key": return {
|
|
3840
3840
|
...e,
|
|
@@ -3866,38 +3866,38 @@ BEGIN
|
|
|
3866
3866
|
...e.primaryKey === void 0 ? {} : { primaryKey: e.primaryKey.map((e) => e === t.from ? t.to : e) }
|
|
3867
3867
|
};
|
|
3868
3868
|
}
|
|
3869
|
-
},
|
|
3870
|
-
let r = n.tables.find((e) => e.name === t.table), i = () => r === void 0 ? A.void :
|
|
3869
|
+
}, X = (e, t, n) => {
|
|
3870
|
+
let r = n.tables.find((e) => e.name === t.table), i = () => r === void 0 ? A.void : No(e, t.table, Va(rs(r, t)), t.kind);
|
|
3871
3871
|
switch (t.kind) {
|
|
3872
3872
|
case "drop-foreign-key": return e.onDialectOrElse({
|
|
3873
|
-
mysql: () =>
|
|
3873
|
+
mysql: () => q(e, To(t), t.kind),
|
|
3874
3874
|
sqlite: i,
|
|
3875
|
-
orElse: () =>
|
|
3875
|
+
orElse: () => q(e, wo(t), t.kind)
|
|
3876
3876
|
});
|
|
3877
3877
|
case "drop-index": return e.onDialectOrElse({
|
|
3878
|
-
mysql: () =>
|
|
3879
|
-
mssql: () =>
|
|
3880
|
-
orElse: () =>
|
|
3878
|
+
mysql: () => q(e, io(t), t.kind),
|
|
3879
|
+
mssql: () => q(e, ao(t), t.kind),
|
|
3880
|
+
orElse: () => q(e, ro(t), t.kind)
|
|
3881
3881
|
});
|
|
3882
3882
|
case "drop-column": return e.onDialectOrElse({
|
|
3883
|
-
mysql: () =>
|
|
3883
|
+
mysql: () => V(e).pipe(A.flatMap((n) => q(e, ca(t, n), t.kind, [Ji]))),
|
|
3884
3884
|
sqlite: i,
|
|
3885
|
-
orElse: () =>
|
|
3885
|
+
orElse: () => q(e, sa(t, U), t.kind)
|
|
3886
3886
|
});
|
|
3887
3887
|
case "rename-column": return e.onDialectOrElse({
|
|
3888
|
-
mysql: () =>
|
|
3889
|
-
mssql: () =>
|
|
3890
|
-
orElse: () =>
|
|
3888
|
+
mysql: () => q(e, la(t, W), t.kind),
|
|
3889
|
+
mssql: () => Po(e, t),
|
|
3890
|
+
orElse: () => q(e, la(t, U), t.kind)
|
|
3891
3891
|
});
|
|
3892
3892
|
}
|
|
3893
|
-
},
|
|
3893
|
+
}, is = (e, t, n) => Zo(e, t, { declared: n }), as = (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"), os = (e) => e`
|
|
3894
3894
|
SELECT fingerprint
|
|
3895
3895
|
FROM _voltro_migration_plans
|
|
3896
3896
|
ORDER BY ${e("appliedAt")} DESC
|
|
3897
3897
|
LIMIT 1
|
|
3898
|
-
`.pipe(A.map((e) => e.length > 0 ? e[0].fingerprint : void 0), A.catchAll(() => A.succeed(void 0))),
|
|
3899
|
-
if ((yield*
|
|
3900
|
-
let r = `plan_${Date.now().toString(36)}`, i = yield*
|
|
3898
|
+
`.pipe(A.map((e) => e.length > 0 ? e[0].fingerprint : void 0), A.catchAll(() => A.succeed(void 0))), ss = (e, t, n) => A.gen(function* () {
|
|
3899
|
+
if ((yield* os(e)) === t.toFingerprint) return "already-current";
|
|
3900
|
+
let r = `plan_${Date.now().toString(36)}`, i = yield* H(e, (/* @__PURE__ */ new Date()).toISOString());
|
|
3901
3901
|
return yield* e`
|
|
3902
3902
|
INSERT INTO ${e("_voltro_migration_plans")}
|
|
3903
3903
|
(${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
|
|
@@ -3908,8 +3908,8 @@ BEGIN
|
|
|
3908
3908
|
${n.appliedBy}, ${n.environment}, ${n.source},
|
|
3909
3909
|
${0}, ${i}, ${"no DDL — the declared schema already matched the database"})
|
|
3910
3910
|
`, "recorded";
|
|
3911
|
-
}).pipe(A.catchAll(() => A.succeed("already-current"))),
|
|
3912
|
-
let r =
|
|
3911
|
+
}).pipe(A.catchAll(() => A.succeed("already-current"))), cs = (e, t, n) => A.gen(function* () {
|
|
3912
|
+
let r = L(Tr(t, N(e), { charset: n.charset })), i = yield* os(e);
|
|
3913
3913
|
return i === r ? {
|
|
3914
3914
|
kind: "up-to-date",
|
|
3915
3915
|
fingerprint: r
|
|
@@ -3918,23 +3918,23 @@ BEGIN
|
|
|
3918
3918
|
expected: r,
|
|
3919
3919
|
...i === void 0 ? {} : { actual: i }
|
|
3920
3920
|
};
|
|
3921
|
-
}),
|
|
3921
|
+
}), ls = [
|
|
3922
3922
|
"pgeagertest_",
|
|
3923
3923
|
"mig_e2e_",
|
|
3924
3924
|
"mig_test_",
|
|
3925
3925
|
"mysqleagertest_",
|
|
3926
3926
|
"mssqleagertest_",
|
|
3927
3927
|
"sqliteeagertest_"
|
|
3928
|
-
],
|
|
3928
|
+
], us = (e) => ls.some((t) => e.startsWith(t)), ds = (e, t) => A.gen(function* () {
|
|
3929
3929
|
if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
|
|
3930
|
-
let n = t.filter((e) =>
|
|
3930
|
+
let n = t.filter((e) => us(e.name)).map((e) => e.name);
|
|
3931
3931
|
if (n.length === 0) return [];
|
|
3932
3932
|
for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(A.catchAll(() => A.void));
|
|
3933
3933
|
return n;
|
|
3934
|
-
}),
|
|
3934
|
+
}), fs = () => {
|
|
3935
3935
|
let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
|
|
3936
3936
|
return e.length > 0 ? { ignoreTables: e } : {};
|
|
3937
|
-
},
|
|
3937
|
+
}, ps = (e) => {
|
|
3938
3938
|
if (e === void 0) return;
|
|
3939
3939
|
let t = e.trim();
|
|
3940
3940
|
if (t === "") return;
|
|
@@ -3944,56 +3944,56 @@ BEGIN
|
|
|
3944
3944
|
kind: "tables",
|
|
3945
3945
|
tables: new Set(n)
|
|
3946
3946
|
} : void 0;
|
|
3947
|
-
},
|
|
3947
|
+
}, ms = (e) => typeof e.table == "string" ? e.table : void 0, hs = (e, t = { kind: "all" }) => ({
|
|
3948
3948
|
...e,
|
|
3949
3949
|
operations: e.operations.map((e) => {
|
|
3950
3950
|
if (!e.blocked || e.classification !== "lossy") return e;
|
|
3951
3951
|
if (t?.kind === "tables") {
|
|
3952
|
-
let n =
|
|
3952
|
+
let n = ms(e.op);
|
|
3953
3953
|
if (n === void 0 || !t.tables.has(n)) return e;
|
|
3954
3954
|
}
|
|
3955
3955
|
let { blocked: n, ...r } = e;
|
|
3956
3956
|
return r;
|
|
3957
3957
|
})
|
|
3958
|
-
}),
|
|
3959
|
-
let t =
|
|
3958
|
+
}), gs = (e, t, n) => t === "postgres" ? Dr(e, n).pipe(A.flatMap((e) => {
|
|
3959
|
+
let t = Or(e);
|
|
3960
3960
|
return t === void 0 ? A.void : A.logWarning(`auto-migrate: ${t}`).pipe(A.annotateLogs({ scope: "voltro:migrate" }));
|
|
3961
|
-
}), A.catchAll(() => A.void)) : A.void,
|
|
3961
|
+
}), A.catchAll(() => A.void)) : A.void, _s = (e, t, n) => A.gen(function* () {
|
|
3962
3962
|
let i = N(e), a = t;
|
|
3963
3963
|
if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
|
|
3964
|
-
let t =
|
|
3965
|
-
if ((yield*
|
|
3964
|
+
let t = L(Tr(a, i, { charset: n.charset }));
|
|
3965
|
+
if ((yield* os(e)) === t) return yield* gs(e, i, a), {
|
|
3966
3966
|
kind: "up-to-date",
|
|
3967
3967
|
fingerprint: t
|
|
3968
3968
|
};
|
|
3969
3969
|
}
|
|
3970
|
-
let s = yield*
|
|
3970
|
+
let s = yield* Bi(e), c = yield* ds(e, s.tables);
|
|
3971
3971
|
c.length > 0 && (yield* A.logInfo(`auto-migrate: reaped ${c.length} test-fixture leftover(s)`).pipe(A.annotateLogs({
|
|
3972
3972
|
scope: "voltro:migrate",
|
|
3973
3973
|
count: c.length
|
|
3974
|
-
})), s = yield*
|
|
3974
|
+
})), s = yield* Bi(e));
|
|
3975
3975
|
{
|
|
3976
|
-
let e = n.softDropRetentionDays ?? 7, t =
|
|
3976
|
+
let e = n.softDropRetentionDays ?? 7, t = te(s, { retentionDays: e });
|
|
3977
3977
|
t.length > 0 && (yield* A.logWarning(`auto-migrate: ${r(t, e)}`).pipe(A.annotateLogs({
|
|
3978
3978
|
scope: "voltro:migrate",
|
|
3979
3979
|
snapshots: t.map((e) => e.name)
|
|
3980
3980
|
})));
|
|
3981
3981
|
}
|
|
3982
|
-
let l = new Set(t.map((e) => e.tableName)), u = (e) => o(e, l), d =
|
|
3982
|
+
let l = new Set(t.map((e) => e.tableName)), u = (e) => o(e, l), d = ci({
|
|
3983
3983
|
declared: a,
|
|
3984
3984
|
live: { tables: u(s.tables) },
|
|
3985
3985
|
dialect: i,
|
|
3986
3986
|
charset: n.charset,
|
|
3987
|
-
...
|
|
3987
|
+
...fs()
|
|
3988
3988
|
});
|
|
3989
3989
|
if (d.summary.blocked > 0) {
|
|
3990
|
-
let e = d.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t =
|
|
3991
|
-
if (t === void 0 || !e || (d =
|
|
3990
|
+
let e = d.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = ps(process.env.VOLTRO_DESTRUCTIVE_OK);
|
|
3991
|
+
if (t === void 0 || !e || (d = hs(d, t), d.operations.some((e) => e.blocked))) return {
|
|
3992
3992
|
kind: "refused-blocked",
|
|
3993
3993
|
plan: d
|
|
3994
3994
|
};
|
|
3995
3995
|
}
|
|
3996
|
-
return d.operations.length === 0 ? (yield*
|
|
3996
|
+
return d.operations.length === 0 ? (yield* ss(e, d, {
|
|
3997
3997
|
appliedBy: n.appliedBy,
|
|
3998
3998
|
environment: n.environment === "prod" ? "dev" : n.environment,
|
|
3999
3999
|
source: "auto-diff"
|
|
@@ -4002,38 +4002,38 @@ BEGIN
|
|
|
4002
4002
|
fingerprint: d.toFingerprint
|
|
4003
4003
|
}) : {
|
|
4004
4004
|
kind: "applied",
|
|
4005
|
-
applied: yield*
|
|
4005
|
+
applied: yield* ts(e, d, {
|
|
4006
4006
|
declared: t,
|
|
4007
4007
|
appliedBy: n.appliedBy,
|
|
4008
4008
|
environment: n.environment === "prod" ? "dev" : n.environment,
|
|
4009
4009
|
source: "auto-diff",
|
|
4010
4010
|
replan: (e) => A.gen(function* () {
|
|
4011
|
-
let t = yield*
|
|
4012
|
-
return
|
|
4011
|
+
let t = yield* Bi(e);
|
|
4012
|
+
return ci({
|
|
4013
4013
|
declared: a,
|
|
4014
4014
|
live: { tables: u(t.tables) },
|
|
4015
4015
|
dialect: i,
|
|
4016
4016
|
charset: n.charset,
|
|
4017
|
-
...
|
|
4017
|
+
...fs()
|
|
4018
4018
|
});
|
|
4019
4019
|
})
|
|
4020
4020
|
}),
|
|
4021
4021
|
plan: d
|
|
4022
4022
|
};
|
|
4023
|
-
}),
|
|
4023
|
+
}), vs = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? A.succeed({
|
|
4024
4024
|
kind: "skipped",
|
|
4025
4025
|
reason: "VOLTRO_AUTO_MIGRATE=0"
|
|
4026
|
-
}) : n.environment === "prod" ?
|
|
4026
|
+
}) : n.environment === "prod" ? cs(e, t, n) : _s(e, t, n), ys = (e, t) => {
|
|
4027
4027
|
switch (e.kind) {
|
|
4028
4028
|
case "skipped": return `auto-migrate: skipped (${e.reason})`;
|
|
4029
|
-
case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${
|
|
4029
|
+
case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${ur(e.fingerprint)})`;
|
|
4030
4030
|
case "applied": {
|
|
4031
4031
|
let t = e.plan.summary;
|
|
4032
|
-
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=${
|
|
4032
|
+
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=${ur(e.applied.fingerprint)}`;
|
|
4033
4033
|
}
|
|
4034
|
-
case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${
|
|
4034
|
+
case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${ur(e.expected)}` + (e.actual ? ` live=${ur(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
|
|
4035
4035
|
case "refused-blocked": {
|
|
4036
|
-
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 === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` +
|
|
4036
|
+
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 === "drop-table").map((e) => "table" in e.op ? e.op.table : "").filter(Boolean), i = t.filter((e) => e.op.kind === "add-column").length, a = t.filter((e) => e.op.kind === "drop-column").length, o = t.filter((e) => e.classification === "needs-rename-annotation").length, s = `auto-migrate: REFUSED — ${e.plan.summary.blocked} blocked operation(s):\n` + as(e.plan), c = [""];
|
|
4037
4037
|
if (n > 0 && c.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=${r.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.", ` → Set \`VOLTRO_DESTRUCTIVE_OK=${r.join(",")}\` for ONE run — it acknowledges`, " the data loss for THOSE tables only; every other lossy op in this plan stays blocked.", " (`VOLTRO_DESTRUCTIVE_OK=1` acknowledges all of them, which is rarely what you mean.)", " There is deliberately no `dropped()` marker for a TABLE, unlike for a column: a", " dropped column leaves a slot worth documenting in the declaration, a dropped table", " leaves nothing — the marker would be a dead entry you must remember to delete.", " 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`)."), i > 0 && c.push(`${i} 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."), a > 0) {
|
|
4038
4038
|
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
4039
4039
|
for (let r of e.plan.operations) {
|
|
@@ -4050,13 +4050,13 @@ BEGIN
|
|
|
4050
4050
|
return o > 0 && c.push(`${o} 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."), c.push("", "See `voltro db plan` for the full machine-readable diff."), s + "\n" + c.join("\n");
|
|
4051
4051
|
}
|
|
4052
4052
|
}
|
|
4053
|
-
},
|
|
4053
|
+
}, bs = (e) => typeof e.__definition == "function" ? u({ c: e }).c : e, xs = (e) => {
|
|
4054
4054
|
if (typeof e != "string") return e;
|
|
4055
4055
|
let t = e.trim().replace(/::[a-zA-Z0-9_ "]+$/, "").trim();
|
|
4056
4056
|
if (/^current_timestamp(\(\d*\))?$/i.test(t) || /^now\(\)$/i.test(t)) return "now";
|
|
4057
4057
|
let n = /^'(.*)'$/s.exec(t);
|
|
4058
4058
|
return n === null ? e : n[1].replace(/''/g, "'");
|
|
4059
|
-
},
|
|
4059
|
+
}, Z = (e, t = /* @__PURE__ */ new Map()) => {
|
|
4060
4060
|
let n = {};
|
|
4061
4061
|
for (let r of e.columns) {
|
|
4062
4062
|
let e = r.references, i = e === void 0 ? void 0 : t.get(e.table);
|
|
@@ -4065,7 +4065,7 @@ BEGIN
|
|
|
4065
4065
|
nullable: r.nullable,
|
|
4066
4066
|
unique: r.unique,
|
|
4067
4067
|
hasDefault: r.hasDefault,
|
|
4068
|
-
...r.hasDefault ? { defaultValue:
|
|
4068
|
+
...r.hasDefault ? { defaultValue: xs(r.defaultValue) } : {},
|
|
4069
4069
|
...r.maxLength === void 0 ? {} : { maxLength: r.maxLength },
|
|
4070
4070
|
...r.precision === void 0 ? {} : { precision: r.precision },
|
|
4071
4071
|
...r.scale === void 0 ? {} : { scale: r.scale },
|
|
@@ -4080,7 +4080,7 @@ BEGIN
|
|
|
4080
4080
|
references: () => i === void 0 ? {
|
|
4081
4081
|
tableName: e.table,
|
|
4082
4082
|
fields: {}
|
|
4083
|
-
} :
|
|
4083
|
+
} : Z(i),
|
|
4084
4084
|
referenceColumn: e.column,
|
|
4085
4085
|
...e.onDelete === void 0 ? {} : { onDelete: e.onDelete },
|
|
4086
4086
|
...e.onUpdate === void 0 ? {} : { refOnUpdate: e.onUpdate },
|
|
@@ -4107,31 +4107,31 @@ BEGIN
|
|
|
4107
4107
|
})),
|
|
4108
4108
|
...e.primaryKey === void 0 ? {} : { appliedPrimaryKey: e.primaryKey }
|
|
4109
4109
|
};
|
|
4110
|
-
},
|
|
4110
|
+
}, Ss = (e) => {
|
|
4111
4111
|
let t = new Map(e.tables.map((e) => [e.name, e]));
|
|
4112
|
-
return e.tables.map((e) =>
|
|
4113
|
-
},
|
|
4112
|
+
return e.tables.map((e) => Z(e, t));
|
|
4113
|
+
}, Cs = (e, t = "safe") => ({
|
|
4114
4114
|
op: e,
|
|
4115
4115
|
classification: t,
|
|
4116
4116
|
reason: "file migration schema operation"
|
|
4117
|
-
}),
|
|
4117
|
+
}), Q = "this context was built over an in-memory store without a `sql` client, and this needs a live connection. Run the migration against a database (the runner supplies the client), or keep a database-free test to `each`, `rewrite`, `expect`, `skipUnless`, `store`, `log`, `schema.tableExists`, `schema.columnExists` and a Promise body under `transactional`.", ws = {
|
|
4118
4118
|
snapshot: "the in-memory store holds rows, not a catalog — it has no column types, defaults, indexes or constraints to report. `schema.tableExists` and `schema.columnExists` answer from the rows it holds; a body that needs the whole shape needs a database.",
|
|
4119
4119
|
indexExists: "the in-memory store has no indexes — every read of it is a scan — so there is no honest answer to give, and `false` would claim an index is absent from a store that could never have had one. Run this migration against a database, or guard on `schema.tableExists` / `schema.columnExists`, which the store can answer.",
|
|
4120
4120
|
foreignKeyExists: "the in-memory store has no constraints, so there is no honest answer to give, and `false` would claim a foreign key is absent from a store that could never have had one. Run this migration against a database, or guard on `schema.tableExists` / `schema.columnExists`, which the store can answer.",
|
|
4121
|
-
evolve:
|
|
4122
|
-
createTable:
|
|
4123
|
-
dropTable:
|
|
4124
|
-
renameTable:
|
|
4125
|
-
addColumn:
|
|
4126
|
-
alterColumn:
|
|
4127
|
-
addIndex:
|
|
4128
|
-
addForeignKey:
|
|
4129
|
-
dropForeignKey:
|
|
4130
|
-
dropIndex:
|
|
4131
|
-
dropColumn:
|
|
4132
|
-
renameColumn:
|
|
4133
|
-
truncate:
|
|
4134
|
-
},
|
|
4121
|
+
evolve: Q,
|
|
4122
|
+
createTable: Q,
|
|
4123
|
+
dropTable: Q,
|
|
4124
|
+
renameTable: Q,
|
|
4125
|
+
addColumn: Q,
|
|
4126
|
+
alterColumn: Q,
|
|
4127
|
+
addIndex: Q,
|
|
4128
|
+
addForeignKey: Q,
|
|
4129
|
+
dropForeignKey: Q,
|
|
4130
|
+
dropIndex: Q,
|
|
4131
|
+
dropColumn: Q,
|
|
4132
|
+
renameColumn: Q,
|
|
4133
|
+
truncate: Q
|
|
4134
|
+
}, Ts = "this context was built over a store that cannot report the tables it holds (`DataStore.storedTables` is not implemented), so the question has no honest answer here. Use the in-memory store `@voltro/runtime` ships, or run the migration against a database.", Es = (e, t) => {
|
|
4135
4135
|
let n = () => {
|
|
4136
4136
|
let e = t.storedTables;
|
|
4137
4137
|
if (e !== void 0) return new Map(e.call(t).map((e) => [e.table, e]));
|
|
@@ -4139,23 +4139,23 @@ BEGIN
|
|
|
4139
4139
|
return {
|
|
4140
4140
|
tableExists: (e) => A.suspend(() => {
|
|
4141
4141
|
let t = n();
|
|
4142
|
-
return t === void 0 ? r("schema.tableExists()",
|
|
4142
|
+
return t === void 0 ? r("schema.tableExists()", Ts) : A.succeed(t.has(e));
|
|
4143
4143
|
}),
|
|
4144
4144
|
columnExists: (e, t) => A.suspend(() => {
|
|
4145
4145
|
let i = n();
|
|
4146
|
-
if (i === void 0) return r("schema.columnExists()",
|
|
4146
|
+
if (i === void 0) return r("schema.columnExists()", Ts);
|
|
4147
4147
|
let a = i.get(e);
|
|
4148
4148
|
return a === void 0 ? A.succeed(!1) : a.rowCount === 0 ? r(`schema.columnExists(${JSON.stringify(e)}, ${JSON.stringify(t)})`, `${e} is in this store and holds no rows, and a column exists in a store without a catalog only as a key on a row — so "no such column" and "no row has said yet" are the same observation, and answering either would be a guess. Seed ${e} with a row carrying the columns this migration guards on, or run the migration against a database.`) : A.succeed(a.columns.includes(t));
|
|
4149
4149
|
})
|
|
4150
4150
|
};
|
|
4151
|
-
},
|
|
4152
|
-
let n = { ...
|
|
4153
|
-
for (let [t, r] of Object.entries(
|
|
4151
|
+
}, Ds = (e, t) => {
|
|
4152
|
+
let n = { ...Es(e, t) };
|
|
4153
|
+
for (let [t, r] of Object.entries(ws)) n[t] = () => A.fail(new S(e, `schema.${t}()`, r));
|
|
4154
4154
|
return n;
|
|
4155
|
-
},
|
|
4155
|
+
}, Os = (e) => typeof e == "function" && typeof e.onDialectOrElse == "function", ks = (e) => A.isEffect(e) ? e : A.tryPromise({
|
|
4156
4156
|
try: () => e,
|
|
4157
4157
|
catch: (e) => e
|
|
4158
|
-
}),
|
|
4158
|
+
}), As = (e, t, n) => t.run === void 0 ? Promise.reject(new S(e, "transactional() with an Effect body", "an Effect returned from `transactional` runs ON the transaction's connection, and this store has none. Return a Promise body that uses the transaction's `store`, or run the migration against a database.")) : t.run(n), js = (e, t) => {
|
|
4159
4159
|
let n = e.run;
|
|
4160
4160
|
if (n === void 0) return t;
|
|
4161
4161
|
let r = {};
|
|
@@ -4167,20 +4167,20 @@ BEGIN
|
|
|
4167
4167
|
});
|
|
4168
4168
|
}
|
|
4169
4169
|
return r;
|
|
4170
|
-
},
|
|
4171
|
-
let r = () =>
|
|
4170
|
+
}, Ms = (e, t, n) => {
|
|
4171
|
+
let r = () => Bi(e), i = (e, t) => e.tables.find((e) => e.name === t), a = (e, t, n) => i(e, t)?.columns.find((e) => e.name === n), o = (e) => A.succeed(e), s = (e) => new Map(e.tables.map((e) => [e.name, e])), c = (e, t) => {
|
|
4172
4172
|
let n = i(e, t);
|
|
4173
4173
|
if (n === void 0) throw Error(`schema: table ${t} does not exist`);
|
|
4174
4174
|
return n;
|
|
4175
4175
|
}, l = (n) => A.gen(function* () {
|
|
4176
|
-
let i = () => r().pipe(A.map((e) => ({ tables: e.tables.filter((e) => e.name === n.tableName) }))), a =
|
|
4176
|
+
let i = () => r().pipe(A.map((e) => ({ tables: e.tables.filter((e) => e.name === n.tableName) }))), a = hs(ci({
|
|
4177
4177
|
declared: [n],
|
|
4178
4178
|
live: yield* i(),
|
|
4179
4179
|
dialect: t
|
|
4180
4180
|
})), o = a.operations.filter((e) => e.blocked !== void 0);
|
|
4181
4181
|
if (o.length > 0) return yield* A.fail(/* @__PURE__ */ Error(`evolve(${n.tableName}): ${o.length} operation(s) cannot be planned:\n` + o.map((e) => ` - ${e.op.kind}: ${e.blocked?.fix ?? e.reason}`).join("\n")));
|
|
4182
|
-
for (let t of a.operations) yield*
|
|
4183
|
-
let s =
|
|
4182
|
+
for (let t of a.operations) yield* is(e, t, [n]);
|
|
4183
|
+
let s = ci({
|
|
4184
4184
|
declared: [n],
|
|
4185
4185
|
live: yield* i(),
|
|
4186
4186
|
dialect: t
|
|
@@ -4194,28 +4194,28 @@ BEGIN
|
|
|
4194
4194
|
return (yield* r()).tables.some((t) => t.name === e.tableName) ? yield* o("already-present") : (yield* l(e), "applied");
|
|
4195
4195
|
}),
|
|
4196
4196
|
dropTable: (t) => A.gen(function* () {
|
|
4197
|
-
return (yield* r()).tables.some((e) => e.name === t) ? (yield*
|
|
4197
|
+
return (yield* r()).tables.some((e) => e.name === t) ? (yield* is(e, Cs({
|
|
4198
4198
|
kind: "drop-table",
|
|
4199
4199
|
table: t
|
|
4200
4200
|
}, "lossy"), []), "applied") : yield* o("already-absent");
|
|
4201
4201
|
}),
|
|
4202
4202
|
renameTable: (t, n) => A.gen(function* () {
|
|
4203
4203
|
let a = yield* r(), s = i(a, t) !== void 0, l = i(a, n) !== void 0;
|
|
4204
|
-
return !s && l ? yield* o("already-present") : s ? l ? yield* A.fail(/* @__PURE__ */ Error(`renameTable: ${n} already exists beside ${t}`)) : (yield*
|
|
4204
|
+
return !s && l ? yield* o("already-present") : s ? l ? yield* A.fail(/* @__PURE__ */ Error(`renameTable: ${n} already exists beside ${t}`)) : (yield* is(e, Cs({
|
|
4205
4205
|
kind: "rename-table",
|
|
4206
4206
|
from: t,
|
|
4207
4207
|
to: n
|
|
4208
|
-
}), [
|
|
4208
|
+
}), [Z(c(a, t))]), "applied") : yield* A.fail(/* @__PURE__ */ Error(`renameTable: ${t} does not exist`));
|
|
4209
4209
|
}),
|
|
4210
4210
|
addColumn: (t, n, i) => A.gen(function* () {
|
|
4211
4211
|
let a = yield* r(), u = c(a, t);
|
|
4212
4212
|
if (u.columns.some((e) => e.name === n)) return yield* o("already-present");
|
|
4213
|
-
let d =
|
|
4213
|
+
let d = bs(i);
|
|
4214
4214
|
if (!d.nullable && !d.hasDefault && d.backfill === void 0) {
|
|
4215
4215
|
let r = yield* e`SELECT COUNT(*) AS n FROM ${e(t)}`;
|
|
4216
4216
|
if (Number(r[0]?.n ?? 0) > 0) return yield* A.fail(/* @__PURE__ */ Error(`addColumn(${t}.${n}): a NOT NULL column without a default cannot be added to a table with rows on any dialect. Add it nullable or with a default, fill it (rewrite), then alterColumn(${JSON.stringify(t)}, ${JSON.stringify(n)}, { nullable: false }).`));
|
|
4217
4217
|
}
|
|
4218
|
-
let f =
|
|
4218
|
+
let f = Z(u, s(a));
|
|
4219
4219
|
return yield* l({
|
|
4220
4220
|
...f,
|
|
4221
4221
|
fields: {
|
|
@@ -4240,7 +4240,7 @@ BEGIN
|
|
|
4240
4240
|
defaultValue: n.default
|
|
4241
4241
|
}
|
|
4242
4242
|
};
|
|
4243
|
-
return yield* l(
|
|
4243
|
+
return yield* l(Z({
|
|
4244
4244
|
...a,
|
|
4245
4245
|
columns: a.columns.map((e) => e.name === t ? f : e)
|
|
4246
4246
|
}, s(i))), "applied";
|
|
@@ -4249,7 +4249,7 @@ BEGIN
|
|
|
4249
4249
|
let i = yield* r(), a = c(i, e), u = n.unique === !0;
|
|
4250
4250
|
if (u && t.length === 1) {
|
|
4251
4251
|
let n = a.columns.find((e) => e.name === t[0]);
|
|
4252
|
-
return n === void 0 ? yield* A.fail(/* @__PURE__ */ Error(`addIndex: ${e}.${t[0]} does not exist`)) : n.unique ? yield* o("already-present") : (yield* l(
|
|
4252
|
+
return n === void 0 ? yield* A.fail(/* @__PURE__ */ Error(`addIndex: ${e}.${t[0]} does not exist`)) : n.unique ? yield* o("already-present") : (yield* l(Z({
|
|
4253
4253
|
...a,
|
|
4254
4254
|
columns: a.columns.map((e) => e.name === n.name ? {
|
|
4255
4255
|
...e,
|
|
@@ -4265,7 +4265,7 @@ BEGIN
|
|
|
4265
4265
|
columns: t,
|
|
4266
4266
|
unique: u
|
|
4267
4267
|
};
|
|
4268
|
-
return yield* l(
|
|
4268
|
+
return yield* l(Z({
|
|
4269
4269
|
...a,
|
|
4270
4270
|
indexes: [...a.indexes, f]
|
|
4271
4271
|
}, s(i))), "applied";
|
|
@@ -4287,7 +4287,7 @@ BEGIN
|
|
|
4287
4287
|
onUpdate: u.onUpdate ?? "noAction"
|
|
4288
4288
|
}
|
|
4289
4289
|
};
|
|
4290
|
-
return yield* l(
|
|
4290
|
+
return yield* l(Z({
|
|
4291
4291
|
...f,
|
|
4292
4292
|
columns: f.columns.map((e) => e.name === n ? h : e)
|
|
4293
4293
|
}, s(d))), "applied";
|
|
@@ -4301,7 +4301,7 @@ BEGIN
|
|
|
4301
4301
|
foreignKeyExists: (e, t) => r().pipe(A.map((n) => a(n, e, t)?.references !== void 0)),
|
|
4302
4302
|
dropForeignKey: (t, n) => A.gen(function* () {
|
|
4303
4303
|
let i = yield* r(), s = a(i, t, n);
|
|
4304
|
-
return s?.references === void 0 ? yield* o("already-absent") : (yield*
|
|
4304
|
+
return s?.references === void 0 ? yield* o("already-absent") : (yield* X(e, {
|
|
4305
4305
|
kind: "drop-foreign-key",
|
|
4306
4306
|
table: t,
|
|
4307
4307
|
column: n,
|
|
@@ -4310,7 +4310,7 @@ BEGIN
|
|
|
4310
4310
|
}),
|
|
4311
4311
|
dropIndex: (t, n) => A.gen(function* () {
|
|
4312
4312
|
let a = yield* r();
|
|
4313
|
-
return i(a, t)?.indexes.some((e) => e.name === n) ?? !1 ? (yield*
|
|
4313
|
+
return i(a, t)?.indexes.some((e) => e.name === n) ?? !1 ? (yield* X(e, {
|
|
4314
4314
|
kind: "drop-index",
|
|
4315
4315
|
table: t,
|
|
4316
4316
|
index: n
|
|
@@ -4319,18 +4319,18 @@ BEGIN
|
|
|
4319
4319
|
dropColumn: (t, n) => A.gen(function* () {
|
|
4320
4320
|
let s = yield* r(), c = a(s, t, n);
|
|
4321
4321
|
if (c === void 0) return yield* o("already-absent");
|
|
4322
|
-
c.references !== void 0 && (yield*
|
|
4322
|
+
c.references !== void 0 && (yield* X(e, {
|
|
4323
4323
|
kind: "drop-foreign-key",
|
|
4324
4324
|
table: t,
|
|
4325
4325
|
column: n,
|
|
4326
4326
|
...c.references.constraintName === void 0 ? {} : { name: c.references.constraintName }
|
|
4327
4327
|
}, s), s = yield* r());
|
|
4328
|
-
for (let r of i(s, t)?.indexes ?? []) r.columns.includes(n) && r.name !== `${t}_pkey` && (yield*
|
|
4328
|
+
for (let r of i(s, t)?.indexes ?? []) r.columns.includes(n) && r.name !== `${t}_pkey` && (yield* X(e, {
|
|
4329
4329
|
kind: "drop-index",
|
|
4330
4330
|
table: t,
|
|
4331
4331
|
index: r.name
|
|
4332
4332
|
}, s));
|
|
4333
|
-
return i(s, t)?.indexes.some((e) => e.columns.includes(n) && e.name !== `${t}_pkey`) && (s = yield* r()), yield*
|
|
4333
|
+
return i(s, t)?.indexes.some((e) => e.columns.includes(n) && e.name !== `${t}_pkey`) && (s = yield* r()), yield* X(e, {
|
|
4334
4334
|
kind: "drop-column",
|
|
4335
4335
|
table: t,
|
|
4336
4336
|
column: n
|
|
@@ -4338,7 +4338,7 @@ BEGIN
|
|
|
4338
4338
|
}),
|
|
4339
4339
|
renameColumn: (t, n, i) => A.gen(function* () {
|
|
4340
4340
|
let s = yield* r(), c = a(s, t, n) !== void 0, l = a(s, t, i) !== void 0;
|
|
4341
|
-
return !c && l ? yield* o("already-present") : c ? l ? yield* A.fail(/* @__PURE__ */ Error(`renameColumn: ${t}.${i} already exists beside ${n} — a rename cannot merge two columns`)) : (yield*
|
|
4341
|
+
return !c && l ? yield* o("already-present") : c ? l ? yield* A.fail(/* @__PURE__ */ Error(`renameColumn: ${t}.${i} already exists beside ${n} — a rename cannot merge two columns`)) : (yield* X(e, {
|
|
4342
4342
|
kind: "rename-column",
|
|
4343
4343
|
table: t,
|
|
4344
4344
|
from: n,
|
|
@@ -4346,7 +4346,7 @@ BEGIN
|
|
|
4346
4346
|
}, s), "applied") : yield* A.fail(/* @__PURE__ */ Error(`renameColumn: ${t}.${n} does not exist`));
|
|
4347
4347
|
})
|
|
4348
4348
|
};
|
|
4349
|
-
},
|
|
4349
|
+
}, Ns = (e, t, n, r) => {
|
|
4350
4350
|
let i;
|
|
4351
4351
|
return (async function* () {
|
|
4352
4352
|
for (;;) {
|
|
@@ -4368,8 +4368,8 @@ BEGIN
|
|
|
4368
4368
|
if (i = s, yield o, o.length < n) return;
|
|
4369
4369
|
}
|
|
4370
4370
|
})();
|
|
4371
|
-
},
|
|
4372
|
-
let i = r.batchSize ?? 1e3, a = 0, o = 0, s =
|
|
4371
|
+
}, Ps = (e) => e > 0 ? A.sleep(`${e} millis`) : A.void, Fs = (e) => (t, n, r = {}) => A.gen(function* () {
|
|
4372
|
+
let i = r.batchSize ?? 1e3, a = 0, o = 0, s = Ns(e, t, i);
|
|
4373
4373
|
for (;;) {
|
|
4374
4374
|
let e = yield* A.tryPromise({
|
|
4375
4375
|
try: () => s.next(),
|
|
@@ -4377,16 +4377,16 @@ BEGIN
|
|
|
4377
4377
|
});
|
|
4378
4378
|
if (e.done) break;
|
|
4379
4379
|
o++;
|
|
4380
|
-
for (let t of e.value) yield*
|
|
4381
|
-
yield*
|
|
4380
|
+
for (let t of e.value) yield* ks(n(t)), a++;
|
|
4381
|
+
yield* Ps(r.sleepMs ?? 0);
|
|
4382
4382
|
}
|
|
4383
4383
|
return {
|
|
4384
4384
|
scanned: a,
|
|
4385
4385
|
pages: o
|
|
4386
4386
|
};
|
|
4387
|
-
}),
|
|
4387
|
+
}), Is = (e, t) => t == null ? oe(e) : se(e, t), Ls = (e) => typeof e != "object" || !e || e instanceof Date, Rs = (e, t) => A.gen(function* () {
|
|
4388
4388
|
if (e === void 0) return [];
|
|
4389
|
-
let n = (yield*
|
|
4389
|
+
let n = (yield* Bi(e)).tables.find((e) => e.name === t)?.columns ?? [], r = new Set(n.map((e) => e.name)), i = ce(t)?.fields;
|
|
4390
4390
|
return n.filter((e) => e.type === "timestamp" || e.type === "date" || i?.[e.name]?.type === "timestamp" || i?.[e.name]?.type === "date").map((e, t) => {
|
|
4391
4391
|
let n = `__voltro_rewrite_guard_${t}`;
|
|
4392
4392
|
for (; r.has(n);) n += "_";
|
|
@@ -4395,14 +4395,14 @@ BEGIN
|
|
|
4395
4395
|
alias: n
|
|
4396
4396
|
};
|
|
4397
4397
|
});
|
|
4398
|
-
}),
|
|
4399
|
-
let s = o.batchSize ?? 1e3, c = o.maxPasses ?? 10, l = o.guard ?? [], u = yield*
|
|
4398
|
+
}), zs = (e, t, n, r) => (i, a, o = {}) => A.gen(function* () {
|
|
4399
|
+
let s = o.batchSize ?? 1e3, c = o.maxPasses ?? 10, l = o.guard ?? [], u = yield* Rs(n, i), f = /* @__PURE__ */ new WeakMap(), p = u.length === 0 || n === void 0 ? t : { query: async (a) => {
|
|
4400
4400
|
let o = _e(a, n), s = u.map(({ column: e, alias: t }) => n`${n.onDialectOrElse({
|
|
4401
4401
|
mysql: () => n`CAST(${n(e)} AS CHAR)`,
|
|
4402
4402
|
mssql: () => n`CONVERT(VARCHAR(40), ${n(e)}, 127)`,
|
|
4403
4403
|
orElse: () => n`CAST(${n(e)} AS TEXT)`
|
|
4404
4404
|
})} AS ${n(t)}`);
|
|
4405
|
-
return (await
|
|
4405
|
+
return (await As(e, t, n`SELECT *, ${n.csv(s)} FROM (${o}) AS ${n("__voltro_rewrite_rows")} ORDER BY ${n("id")} ASC`)).map((e) => {
|
|
4406
4406
|
let t = { ...e }, n = /* @__PURE__ */ new Map();
|
|
4407
4407
|
for (let { column: e, alias: r } of u) n.set(e, t[r]), delete t[r];
|
|
4408
4408
|
let a = _([t], i, r)[0];
|
|
@@ -4415,7 +4415,7 @@ BEGIN
|
|
|
4415
4415
|
contended: 0
|
|
4416
4416
|
}, h = m;
|
|
4417
4417
|
for (let e = 1; e <= c; e++) {
|
|
4418
|
-
let n = 0, r = 0, c = 0, u =
|
|
4418
|
+
let n = 0, r = 0, c = 0, u = Ns(p, i, s);
|
|
4419
4419
|
for (;;) {
|
|
4420
4420
|
let e = yield* A.tryPromise({
|
|
4421
4421
|
try: () => u.next(),
|
|
@@ -4432,14 +4432,14 @@ BEGIN
|
|
|
4432
4432
|
let s = Object.entries(e).filter(([e, t]) => !Object.is(o[e], t));
|
|
4433
4433
|
if (s.length === 0) continue;
|
|
4434
4434
|
let u = [se("id", o.id)], d = (e) => f.get(o)?.has(e) ? f.get(o).get(e) : o[e];
|
|
4435
|
-
for (let [e] of s)
|
|
4436
|
-
for (let e of l) u.push(
|
|
4435
|
+
for (let [e] of s) Ls(o[e]) && u.push(Is(e, d(e)));
|
|
4436
|
+
for (let e of l) u.push(Is(e, d(e)));
|
|
4437
4437
|
(yield* A.tryPromise({
|
|
4438
4438
|
try: () => t.updateMany(i, Object.fromEntries(s), { where: v(...u) }),
|
|
4439
4439
|
catch: (e) => e
|
|
4440
4440
|
})) === 1 ? r++ : c++;
|
|
4441
4441
|
}
|
|
4442
|
-
yield*
|
|
4442
|
+
yield* Ps(o.sleepMs ?? 0);
|
|
4443
4443
|
}
|
|
4444
4444
|
if (h = {
|
|
4445
4445
|
passes: e,
|
|
@@ -4454,13 +4454,13 @@ BEGIN
|
|
|
4454
4454
|
}, r === 0 && c === 0) return m;
|
|
4455
4455
|
}
|
|
4456
4456
|
return yield* A.fail(new d(i, h));
|
|
4457
|
-
}),
|
|
4457
|
+
}), Bs = (e) => {
|
|
4458
4458
|
let { migrationId: t } = e, n = `migrations:file:${t}`;
|
|
4459
|
-
if (e.sql !== void 0 && !
|
|
4459
|
+
if (e.sql !== void 0 && !Os(e.sql)) throw new S(t, "makeFileMigrationContext()", `\`sql\` is not an @effect/sql client (got ${typeof e.sql}). Pass the client the store executes on, or omit \`sql\` to drive the body over an in-memory store.`);
|
|
4460
4460
|
if (e.sql === void 0 && e.store.run !== void 0) throw new S(t, "makeFileMigrationContext()", "a SQL-backed store was given without `sql`. Its migration context runs `raw()`, `schema` and the guarded rewrite on the client the store executes on; pass that client, or use an in-memory store for a database-free test.");
|
|
4461
4461
|
let r = e.sql, i = [], a = (e) => {
|
|
4462
4462
|
if (typeof e != "string" || e.trim().length < 12) throw Error(`raw(reason): say why this migration needs raw SQL — the reason is what a reviewer and \`voltro doctor\` read (got ${JSON.stringify(e)})`);
|
|
4463
|
-
if (r === void 0) throw new S(t, `raw(${JSON.stringify(e)})`,
|
|
4463
|
+
if (r === void 0) throw new S(t, `raw(${JSON.stringify(e)})`, Q);
|
|
4464
4464
|
return r;
|
|
4465
4465
|
};
|
|
4466
4466
|
return {
|
|
@@ -4480,9 +4480,9 @@ BEGIN
|
|
|
4480
4480
|
...t ?? {}
|
|
4481
4481
|
}))
|
|
4482
4482
|
},
|
|
4483
|
-
schema: r === void 0 ?
|
|
4484
|
-
each:
|
|
4485
|
-
rewrite:
|
|
4483
|
+
schema: r === void 0 ? Ds(t, o) : js(o, Ms(r, e.dialect, o)),
|
|
4484
|
+
each: Fs(o),
|
|
4485
|
+
rewrite: zs(t, o, r, e.dialect),
|
|
4486
4486
|
expect: (e, t) => {
|
|
4487
4487
|
i.push({
|
|
4488
4488
|
description: e,
|
|
@@ -4490,7 +4490,7 @@ BEGIN
|
|
|
4490
4490
|
});
|
|
4491
4491
|
},
|
|
4492
4492
|
skipUnless: (e, t) => A.gen(function* () {
|
|
4493
|
-
if (!(typeof e == "boolean" ? e : yield*
|
|
4493
|
+
if (!(typeof e == "boolean" ? e : yield* ks(e))) return yield* A.fail(new T(t));
|
|
4494
4494
|
})
|
|
4495
4495
|
}))(e.store),
|
|
4496
4496
|
transactional: (n) => A.tryPromise({
|
|
@@ -4499,19 +4499,19 @@ BEGIN
|
|
|
4499
4499
|
store: e,
|
|
4500
4500
|
raw: a
|
|
4501
4501
|
});
|
|
4502
|
-
return A.isEffect(r) ?
|
|
4502
|
+
return A.isEffect(r) ? As(t, e, r) : r;
|
|
4503
4503
|
}),
|
|
4504
4504
|
catch: (e) => e
|
|
4505
4505
|
})
|
|
4506
4506
|
},
|
|
4507
4507
|
expectations: i
|
|
4508
4508
|
};
|
|
4509
|
-
},
|
|
4509
|
+
}, Vs = (e) => A.gen(function* () {
|
|
4510
4510
|
let t = [];
|
|
4511
|
-
for (let { description: n, check: r } of e) (yield*
|
|
4511
|
+
for (let { description: n, check: r } of e) (yield* ks(r())) || t.push(n);
|
|
4512
4512
|
return t;
|
|
4513
|
-
}),
|
|
4514
|
-
let t = [], n = (e) => (n) => (!n && !t.some((t) =>
|
|
4513
|
+
}), Hs = (e) => e.kind === "table" ? e.table : `${e.table}.${e.name}`, Us = (e, t) => e.kind === t.kind && e.table === t.table && Hs(e) === Hs(t), Ws = (e) => {
|
|
4514
|
+
let t = [], n = (e) => (n) => (!n && !t.some((t) => Us(t, e)) && t.push(e), n), r = (e, t) => (...r) => e(...r).pipe(A.map(n(t(...r)))), i = {
|
|
4515
4515
|
tableExists: r(e.schema.tableExists, (e) => ({
|
|
4516
4516
|
kind: "table",
|
|
4517
4517
|
table: e
|
|
@@ -4542,9 +4542,9 @@ BEGIN
|
|
|
4542
4542
|
},
|
|
4543
4543
|
absent: () => t.slice()
|
|
4544
4544
|
};
|
|
4545
|
-
},
|
|
4545
|
+
}, Gs = (e) => {
|
|
4546
4546
|
let t = [], n = (e) => {
|
|
4547
|
-
t.some((t) =>
|
|
4547
|
+
t.some((t) => Us(t, e)) || t.push(e);
|
|
4548
4548
|
};
|
|
4549
4549
|
for (let t of e.operations) {
|
|
4550
4550
|
let e = t.op;
|
|
@@ -4587,17 +4587,17 @@ BEGIN
|
|
|
4587
4587
|
}
|
|
4588
4588
|
}
|
|
4589
4589
|
return t;
|
|
4590
|
-
},
|
|
4591
|
-
let n =
|
|
4590
|
+
}, Ks = (e, t) => {
|
|
4591
|
+
let n = Gs(t);
|
|
4592
4592
|
return n.length === 0 ? [] : e.flatMap((e) => {
|
|
4593
|
-
let t = e.absent.filter((e) => n.some((t) =>
|
|
4593
|
+
let t = e.absent.filter((e) => n.some((t) => Us(t, e)));
|
|
4594
4594
|
return t.length === 0 ? [] : [{
|
|
4595
4595
|
id: e.id,
|
|
4596
4596
|
reason: e.reason,
|
|
4597
4597
|
created: t
|
|
4598
4598
|
}];
|
|
4599
4599
|
});
|
|
4600
|
-
},
|
|
4600
|
+
}, qs = Ee({ scope: "voltro:migrate" }), Js = (e) => Te("sha256").update(e).digest("hex").slice(0, 16), Ys = /* @__PURE__ */ new Set([
|
|
4601
4601
|
"node_modules",
|
|
4602
4602
|
"dist",
|
|
4603
4603
|
"build",
|
|
@@ -4606,11 +4606,11 @@ BEGIN
|
|
|
4606
4606
|
".next",
|
|
4607
4607
|
".git",
|
|
4608
4608
|
".framework"
|
|
4609
|
-
]),
|
|
4609
|
+
]), Xs = async (e) => {
|
|
4610
4610
|
let t = [], n = async (e) => {
|
|
4611
4611
|
let r = await De.readdir(e, { withFileTypes: !0 }).catch(() => []);
|
|
4612
4612
|
for (let i of r) {
|
|
4613
|
-
if (
|
|
4613
|
+
if (Ys.has(i.name)) continue;
|
|
4614
4614
|
let r = Oe(e, i.name);
|
|
4615
4615
|
i.isDirectory() ? await n(r) : i.isFile() && ue.test(i.name) && t.push(r);
|
|
4616
4616
|
}
|
|
@@ -4619,45 +4619,45 @@ BEGIN
|
|
|
4619
4619
|
let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
|
|
4620
4620
|
return n.localeCompare(r);
|
|
4621
4621
|
});
|
|
4622
|
-
},
|
|
4622
|
+
}, Zs = async (e) => await import(ke(e).href), Qs = async (e, t = Zs) => {
|
|
4623
4623
|
let n = [];
|
|
4624
4624
|
for (let r of e) {
|
|
4625
4625
|
let e = (await t(r)).default;
|
|
4626
4626
|
if (!ye(e)) {
|
|
4627
|
-
|
|
4627
|
+
qs.warn("migration file has no default-exported `migration(...)` — skipped", { file: r });
|
|
4628
4628
|
continue;
|
|
4629
4629
|
}
|
|
4630
4630
|
let i = await De.readFile(r, "utf8").catch(() => "");
|
|
4631
4631
|
n.push({
|
|
4632
4632
|
file: r,
|
|
4633
4633
|
migration: e,
|
|
4634
|
-
hash:
|
|
4634
|
+
hash: Js(i)
|
|
4635
4635
|
});
|
|
4636
4636
|
}
|
|
4637
4637
|
return n;
|
|
4638
|
-
},
|
|
4638
|
+
}, $s = "_voltro_migration_plans", ec = (e) => {
|
|
4639
4639
|
let t = N(e);
|
|
4640
|
-
return (t === "sqlite" ? e`SELECT COUNT(*) AS n FROM sqlite_master WHERE type = 'table' AND name = ${
|
|
4641
|
-
},
|
|
4640
|
+
return (t === "sqlite" ? e`SELECT COUNT(*) AS n FROM sqlite_master WHERE type = 'table' AND name = ${$s}` : t === "mysql" ? e`SELECT COUNT(*) AS n FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ${$s}` : t === "mssql" ? e`SELECT COUNT(*) AS n FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = ${$s}` : e`SELECT COUNT(*) AS n FROM information_schema.tables WHERE table_schema = current_schema() AND table_name = ${$s}`).pipe(A.map((e) => Number(e[0]?.n ?? 0) > 0));
|
|
4641
|
+
}, tc = (e) => nc(e).pipe(A.map((e) => e.map((e) => e.id))), nc = (e) => ec(e).pipe(A.flatMap((t) => t ? e`
|
|
4642
4642
|
SELECT ${e("id")}, ${e("fingerprint")}
|
|
4643
|
-
FROM ${e(
|
|
4643
|
+
FROM ${e($s)}
|
|
4644
4644
|
WHERE ${e("source")} = 'file'
|
|
4645
4645
|
`.pipe(A.map((e) => e.map((e) => ({
|
|
4646
4646
|
id: e.id,
|
|
4647
4647
|
hash: e.fingerprint ?? ""
|
|
4648
|
-
})))) : A.succeed([]))),
|
|
4648
|
+
})))) : A.succeed([]))), rc = (e, t) => t.filter((t) => {
|
|
4649
4649
|
let n = e.get(t.migration.id);
|
|
4650
4650
|
return n !== void 0 && n !== "" && n !== t.hash;
|
|
4651
|
-
}).map((e) => e.migration.id),
|
|
4651
|
+
}).map((e) => e.migration.id), ic = (e) => y(ae(e))?.kind === "unique", ac = class extends Error {
|
|
4652
4652
|
migrationId;
|
|
4653
4653
|
file;
|
|
4654
4654
|
cause;
|
|
4655
4655
|
_tag = "FileMigrationLedgerError";
|
|
4656
4656
|
constructor(e, t, n) {
|
|
4657
|
-
super(
|
|
4657
|
+
super(ic(n) ? `migration ${e}: up() SUCCEEDED here, and ANOTHER process had already recorded the same migration.\n The body has run TWICE. The ledger row is correct — do not delete it; the next run will not apply ${t} again.\n Two processes applied it without being serialised by the migration lock: check that both reach the same database and lock schema.\n Cause: ${n instanceof Error ? n.message : String(n)}` : `migration ${e}: up() SUCCEEDED but the ledger row could not be written.\n The change IS in the database. It is NOT recorded, so the next run would apply it AGAIN.\n Do not re-run ${t} until this is resolved.\n Cause: ${n instanceof Error ? n.message : String(n)}`), this.migrationId = e, this.file = t, this.cause = n, this.name = "FileMigrationLedgerError";
|
|
4658
4658
|
}
|
|
4659
|
-
},
|
|
4660
|
-
let r = yield*
|
|
4659
|
+
}, oc = (e, t, n) => A.gen(function* () {
|
|
4660
|
+
let r = yield* H(e, n.appliedAtIso);
|
|
4661
4661
|
yield* e`
|
|
4662
4662
|
INSERT INTO ${e("_voltro_migration_plans")}
|
|
4663
4663
|
(${e("id")}, ${e("fingerprint")}, ${e("operations")},
|
|
@@ -4671,19 +4671,19 @@ BEGIN
|
|
|
4671
4671
|
}])},
|
|
4672
4672
|
${n.appliedBy}, ${n.env}, ${"file"},
|
|
4673
4673
|
${n.durationMs}, ${r}, ${n.notes})
|
|
4674
|
-
`.pipe(A.mapError((e) => new
|
|
4675
|
-
}),
|
|
4674
|
+
`.pipe(A.mapError((e) => new ac(t.migration.id, t.file, e)));
|
|
4675
|
+
}), sc = (e) => {
|
|
4676
4676
|
for (let t of m(e)) if (t instanceof T) return t.reason;
|
|
4677
|
-
},
|
|
4678
|
-
let r =
|
|
4677
|
+
}, cc = (e, t, n) => A.gen(function* () {
|
|
4678
|
+
let r = Ws(t), i = r.ctx, a = e.migration.up(i), o = !A.isEffect(a), s = yield* (A.isEffect(a) ? a : A.tryPromise({
|
|
4679
4679
|
try: () => a,
|
|
4680
4680
|
catch: (e) => e
|
|
4681
4681
|
})).pipe(A.as(void 0), A.catchAll((e) => {
|
|
4682
|
-
let t =
|
|
4682
|
+
let t = sc(e);
|
|
4683
4683
|
return t === void 0 ? A.fail(e) : A.succeed(t);
|
|
4684
4684
|
}));
|
|
4685
4685
|
if (s === void 0) {
|
|
4686
|
-
let t = yield*
|
|
4686
|
+
let t = yield* Vs(n);
|
|
4687
4687
|
if (t.length > 0) return yield* A.fail(new x(e.migration.id, t));
|
|
4688
4688
|
}
|
|
4689
4689
|
return {
|
|
@@ -4691,7 +4691,7 @@ BEGIN
|
|
|
4691
4691
|
promiseForm: o,
|
|
4692
4692
|
absent: r.absent()
|
|
4693
4693
|
};
|
|
4694
|
-
}),
|
|
4694
|
+
}), lc = (e, t, n, r, i, a) => A.gen(function* () {
|
|
4695
4695
|
let o = Date.now(), s = (/* @__PURE__ */ new Date()).toISOString(), c = N(e), l = `migrations:file:${n.migration.id}`, u = (e) => ({
|
|
4696
4696
|
durationMs: Date.now() - o,
|
|
4697
4697
|
notes: e.skipped === void 0 ? n.migration.description : `skipped: ${e.skipped}`
|
|
@@ -4699,19 +4699,19 @@ BEGIN
|
|
|
4699
4699
|
if (n.migration.transactional !== !1 && !a) {
|
|
4700
4700
|
if (t.run === void 0) return yield* A.fail(/* @__PURE__ */ Error(`migration ${n.migration.id}: transactional: true needs a SQL-backed store`));
|
|
4701
4701
|
let a = c === "mysql" || c === "mariadb", o = `probe_${n.migration.id}_${Date.now().toString(36)}`;
|
|
4702
|
-
a && (yield*
|
|
4702
|
+
a && (yield* Ro(e, c));
|
|
4703
4703
|
let d = () => e`SELECT COUNT(*) AS n FROM ${e(P)} WHERE ${e("runId")} = ${o}`.pipe(A.map((e) => Number(e[0]?.n ?? 0) > 0)), f = yield* A.tryPromise({
|
|
4704
4704
|
try: () => t.transactional(async (t) => {
|
|
4705
4705
|
a && await t.run(e`INSERT INTO ${e(P)} (${e("id")}, ${e("runId")}, ${e("planFingerprint")}, ${e("opIndex")}, ${e("status")}, ${e("opKind")}, ${e("opTarget")}, ${e("payload")})
|
|
4706
4706
|
VALUES (${`mop_${o}`}, ${o}, ${""}, ${0}, ${"pending"}, ${"probe"}, ${""}, ${"{}"})`);
|
|
4707
|
-
let { ctx: l, expectations: f } =
|
|
4707
|
+
let { ctx: l, expectations: f } = Bs({
|
|
4708
4708
|
sql: e,
|
|
4709
4709
|
store: t,
|
|
4710
4710
|
dialect: c,
|
|
4711
4711
|
migrationId: n.migration.id,
|
|
4712
4712
|
appliedAt: s
|
|
4713
|
-
}), p = await t.run(
|
|
4714
|
-
return await t.run(
|
|
4713
|
+
}), p = await t.run(cc(n, l, f)), m = a && await A.runPromise(d().pipe(A.provideService(j.SqlClient, e))), { durationMs: h, notes: g } = u(p);
|
|
4714
|
+
return await t.run(oc(e, n, {
|
|
4715
4715
|
env: r,
|
|
4716
4716
|
appliedBy: i,
|
|
4717
4717
|
durationMs: h,
|
|
@@ -4734,14 +4734,14 @@ BEGIN
|
|
|
4734
4734
|
}
|
|
4735
4735
|
});
|
|
4736
4736
|
}
|
|
4737
|
-
let { ctx: d, expectations: f } =
|
|
4737
|
+
let { ctx: d, expectations: f } = Bs({
|
|
4738
4738
|
sql: e,
|
|
4739
4739
|
store: t,
|
|
4740
4740
|
dialect: c,
|
|
4741
4741
|
migrationId: n.migration.id,
|
|
4742
4742
|
appliedAt: s
|
|
4743
|
-
}), p = yield*
|
|
4744
|
-
return p.promiseForm && p.skipped === void 0 && m < 2 && (yield* A.logWarning(`migration ${n.migration.id}: up() resolved in ${m}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(A.annotateLogs({ scope: l }))), p.skipped !== void 0 && (yield* A.logInfo(`migration ${n.migration.id} skipped: ${p.skipped}`).pipe(A.annotateLogs({ scope: l }))), yield*
|
|
4743
|
+
}), p = yield* cc(n, d, f), { durationMs: m, notes: h } = u(p);
|
|
4744
|
+
return p.promiseForm && p.skipped === void 0 && m < 2 && (yield* A.logWarning(`migration ${n.migration.id}: up() resolved in ${m}ms — did the body \`await\` an \`@effect/sql\` Effect by accident? \`sql.unsafe(...)\` returns an Effect, not a Promise; \`await\` on it is a silent no-op. Switch the body to \`Effect.gen(function* () { yield* sql.unsafe(...) })\` form.`).pipe(A.annotateLogs({ scope: l }))), p.skipped !== void 0 && (yield* A.logInfo(`migration ${n.migration.id} skipped: ${p.skipped}`).pipe(A.annotateLogs({ scope: l }))), yield* oc(e, n, {
|
|
4745
4745
|
env: r,
|
|
4746
4746
|
appliedBy: i,
|
|
4747
4747
|
durationMs: m,
|
|
@@ -4755,9 +4755,9 @@ BEGIN
|
|
|
4755
4755
|
absent: p.absent
|
|
4756
4756
|
}
|
|
4757
4757
|
};
|
|
4758
|
-
}),
|
|
4758
|
+
}), uc = (e, t, n, r) => A.gen(function* () {
|
|
4759
4759
|
let i = yield* A.tryPromise({
|
|
4760
|
-
try: () =>
|
|
4760
|
+
try: () => Xs(Oe(t, "migrations")),
|
|
4761
4761
|
catch: (e) => e
|
|
4762
4762
|
});
|
|
4763
4763
|
if (i.length === 0) return {
|
|
@@ -4766,7 +4766,7 @@ BEGIN
|
|
|
4766
4766
|
drifted: []
|
|
4767
4767
|
};
|
|
4768
4768
|
let a = yield* A.tryPromise({
|
|
4769
|
-
try: () =>
|
|
4769
|
+
try: () => Qs(i, r),
|
|
4770
4770
|
catch: (e) => e
|
|
4771
4771
|
});
|
|
4772
4772
|
if (a.length === 0) return {
|
|
@@ -4774,8 +4774,8 @@ BEGIN
|
|
|
4774
4774
|
alreadyApplied: [],
|
|
4775
4775
|
drifted: []
|
|
4776
4776
|
};
|
|
4777
|
-
let o = new Map((yield*
|
|
4778
|
-
for (let e of s)
|
|
4777
|
+
let o = new Map((yield* nc(e)).map((e) => [e.id, e.hash])), s = rc(o, a);
|
|
4778
|
+
for (let e of s) qs.warn("file migration: the body on disk is not the one that was applied — the file no longer describes this database", {
|
|
4779
4779
|
id: e,
|
|
4780
4780
|
file: a.find((t) => t.migration.id === e)?.file
|
|
4781
4781
|
});
|
|
@@ -4785,11 +4785,11 @@ BEGIN
|
|
|
4785
4785
|
alreadyApplied: c.filter((e) => o.has(e.migration.id)),
|
|
4786
4786
|
drifted: s
|
|
4787
4787
|
};
|
|
4788
|
-
}),
|
|
4788
|
+
}), dc = (e, t, n, r) => uc(e, t, n, r).pipe(A.map((e) => e.pending.map((e) => e.migration.id))), fc = (e, t, n) => uc(e, t, n).pipe(A.map((e) => e.pending.map((e) => ({
|
|
4789
4789
|
id: e.migration.id,
|
|
4790
4790
|
phase: e.migration.phase,
|
|
4791
4791
|
irreversible: D(e.migration.down)
|
|
4792
|
-
})))),
|
|
4792
|
+
})))), pc = (e, t) => uc(e, t).pipe(A.map((e) => {
|
|
4793
4793
|
let t = new Set(e.drifted);
|
|
4794
4794
|
return [...e.alreadyApplied.map((e) => ({
|
|
4795
4795
|
id: e.migration.id,
|
|
@@ -4802,16 +4802,16 @@ BEGIN
|
|
|
4802
4802
|
applied: !1,
|
|
4803
4803
|
bodyChanged: !1
|
|
4804
4804
|
}))].sort((e, t) => e.id < t.id ? -1 : 1);
|
|
4805
|
-
})),
|
|
4806
|
-
let { pending: n, alreadyApplied: r } = yield*
|
|
4805
|
+
})), mc = (e, t) => A.gen(function* () {
|
|
4806
|
+
let { pending: n, alreadyApplied: r } = yield* uc(e, t.projectRoot, t.phase), i = r.map((e) => e.migration.id);
|
|
4807
4807
|
if (n.length === 0) return {
|
|
4808
4808
|
applied: [],
|
|
4809
4809
|
skipped: i,
|
|
4810
4810
|
skips: []
|
|
4811
4811
|
};
|
|
4812
|
-
yield*
|
|
4812
|
+
yield* zo(e, N(e));
|
|
4813
4813
|
let a = yield* A.acquireUseRelease(ft(e, { schema: t.lockSchema }), () => A.gen(function* () {
|
|
4814
|
-
let r = new Set((yield*
|
|
4814
|
+
let r = new Set((yield* nc(e)).map((e) => e.id)), i = n.filter((e) => !r.has(e.migration.id));
|
|
4815
4815
|
i.length < n.length && (yield* A.logInfo("file-based migrations applied by another process while this one waited for the migration lock").pipe(A.annotateLogs({
|
|
4816
4816
|
scope: "voltro:migrate",
|
|
4817
4817
|
ids: n.filter((e) => r.has(e.migration.id)).map((e) => e.migration.id).join(",")
|
|
@@ -4824,7 +4824,7 @@ BEGIN
|
|
|
4824
4824
|
file: n.file,
|
|
4825
4825
|
phase: n.migration.phase
|
|
4826
4826
|
}));
|
|
4827
|
-
let { durationMs: r, skip: i } = yield*
|
|
4827
|
+
let { durationMs: r, skip: i } = yield* lc(e, t.store, n, t.env, t.appliedBy, t.enclosed === !0);
|
|
4828
4828
|
a.push({
|
|
4829
4829
|
id: n.migration.id,
|
|
4830
4830
|
durationMs: r
|
|
@@ -4845,24 +4845,24 @@ BEGIN
|
|
|
4845
4845
|
skipped: i,
|
|
4846
4846
|
skips: a.skips
|
|
4847
4847
|
};
|
|
4848
|
-
}),
|
|
4848
|
+
}), hc = (e, t) => e`
|
|
4849
4849
|
SELECT ${e("id")}
|
|
4850
4850
|
FROM ${e("_voltro_migration_plans")}
|
|
4851
4851
|
WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
|
|
4852
|
-
`,
|
|
4853
|
-
if (!(yield*
|
|
4852
|
+
`, gc = (t, n) => A.gen(function* () {
|
|
4853
|
+
if (!(yield* hc(t, n.id))[0]) return yield* A.fail(/* @__PURE__ */ Error(`rollback: ${n.id} not found in _voltro_migration_plans (file source)`));
|
|
4854
4854
|
let r = yield* A.tryPromise({
|
|
4855
|
-
try: () =>
|
|
4855
|
+
try: () => Xs(Oe(n.projectRoot, "migrations")),
|
|
4856
4856
|
catch: (e) => e
|
|
4857
4857
|
}), i = (yield* A.tryPromise({
|
|
4858
|
-
try: () =>
|
|
4858
|
+
try: () => Qs(r),
|
|
4859
4859
|
catch: (e) => e
|
|
4860
4860
|
})).find((e) => e.migration.id === n.id);
|
|
4861
4861
|
if (!i) return yield* A.fail(/* @__PURE__ */ Error(`rollback: file for migration ${n.id} not found on disk under ${n.projectRoot}/migrations/`));
|
|
4862
4862
|
let a = D(i.migration.down);
|
|
4863
4863
|
return a === void 0 ? yield* A.acquireUseRelease(ft(t, { schema: n.lockSchema }), () => A.gen(function* () {
|
|
4864
|
-
if ((yield*
|
|
4865
|
-
let e = Date.now(), { ctx: r } =
|
|
4864
|
+
if ((yield* hc(t, n.id))[0] === void 0) return yield* A.fail(/* @__PURE__ */ Error(`rollback: ${n.id} was rolled back by another process while this one waited for the migration lock — nothing to do`));
|
|
4865
|
+
let e = Date.now(), { ctx: r } = Bs({
|
|
4866
4866
|
sql: t,
|
|
4867
4867
|
store: n.store,
|
|
4868
4868
|
dialect: N(t),
|
|
@@ -4879,7 +4879,7 @@ BEGIN
|
|
|
4879
4879
|
durationMs: o
|
|
4880
4880
|
};
|
|
4881
4881
|
}), (e) => e.release.pipe(A.orDie)) : yield* A.fail(new e(n.id, a));
|
|
4882
|
-
}),
|
|
4882
|
+
}), _c = (e) => A.gen(function* () {
|
|
4883
4883
|
let t = yield* j.SqlClient, n = yield* t`
|
|
4884
4884
|
SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
|
|
4885
4885
|
WHERE source = 'auto-diff'
|
|
@@ -4924,8 +4924,8 @@ BEGIN
|
|
|
4924
4924
|
snapshotFingerprint: e.fingerprint,
|
|
4925
4925
|
snapshotId: i
|
|
4926
4926
|
};
|
|
4927
|
-
}),
|
|
4928
|
-
if (
|
|
4927
|
+
}), vc = (e) => new Set(e.flatMap((e) => e.op.kind === "create-table" ? [e.op.table] : [])), yc = (e, t) => t !== void 0 && "table" in e && t.createdTables.has(e.table), $ = { safe: !0 }, bc = (e, t) => {
|
|
4928
|
+
if (yc(e, t)) return $;
|
|
4929
4929
|
switch (e.kind) {
|
|
4930
4930
|
case "add-enum-value": return { safe: !0 };
|
|
4931
4931
|
case "drop-column": return {
|
|
@@ -4957,7 +4957,7 @@ BEGIN
|
|
|
4957
4957
|
reason: `instances on the previous release read/write "${e.table}"."${e.column}" as ${e.from}; the new ${e.to} type can reject their writes or fail to decode their reads`,
|
|
4958
4958
|
remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
|
|
4959
4959
|
};
|
|
4960
|
-
case "alter-column-nullability": return e.toNullable ?
|
|
4960
|
+
case "alter-column-nullability": return e.toNullable ? $ : {
|
|
4961
4961
|
safe: !1,
|
|
4962
4962
|
reason: `instances on the previous release may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
|
|
4963
4963
|
remedy: `make code always write "${e.column}" and deploy that first; add NOT NULL in a LATER deploy (with a default to cover the gap)`
|
|
@@ -4968,12 +4968,12 @@ BEGIN
|
|
|
4968
4968
|
reason: `instances on the previous release still write "${e.table}" without honouring the new uniqueness; a colliding insert now fails mid-rollout`,
|
|
4969
4969
|
remedy: "make code enforce uniqueness first and deploy that; add the constraint in a LATER deploy once no old writer remains"
|
|
4970
4970
|
};
|
|
4971
|
-
case "reconcile-json-check": return e.previousValidation === "container" && e.validation === "value" ?
|
|
4971
|
+
case "reconcile-json-check": return e.previousValidation === "container" && e.validation === "value" ? $ : {
|
|
4972
4972
|
safe: !1,
|
|
4973
4973
|
reason: `instances on the previous release write "${e.table}"."${e.column}" without the new JSON validation, which now rejects them`,
|
|
4974
4974
|
remedy: "ensure all writers supply valid JSON in the required domain before enabling this check"
|
|
4975
4975
|
};
|
|
4976
|
-
case "add-check": return e.table.startsWith("_voltro_") ?
|
|
4976
|
+
case "add-check": return e.table.startsWith("_voltro_") ? $ : {
|
|
4977
4977
|
safe: !1,
|
|
4978
4978
|
reason: `instances on the previous release may write values to "${e.table}" the new CHECK rejects`,
|
|
4979
4979
|
remedy: "make code satisfy the constraint first and deploy that; add the CHECK in a LATER deploy"
|
|
@@ -4983,7 +4983,7 @@ BEGIN
|
|
|
4983
4983
|
reason: `instances on the previous release may write "${e.table}"."${e.column}" values with no matching parent row, which the new FK rejects`,
|
|
4984
4984
|
remedy: "make code guarantee the referent first and deploy that; add the FK in a LATER deploy"
|
|
4985
4985
|
};
|
|
4986
|
-
case "convert-charset": return e.charset === "utf8mb4" ?
|
|
4986
|
+
case "convert-charset": return e.charset === "utf8mb4" ? $ : {
|
|
4987
4987
|
safe: !1,
|
|
4988
4988
|
reason: `instances on the previous release may write 4-byte characters into "${e.table}", which utf8mb3 rejects with errno 1366`,
|
|
4989
4989
|
remedy: "keep utf8mb4 while any writer on the previous release remains; narrow in a LATER deploy, after every writer refuses such input itself"
|
|
@@ -4997,10 +4997,10 @@ BEGIN
|
|
|
4997
4997
|
case "drop-unique":
|
|
4998
4998
|
case "drop-unique-composite":
|
|
4999
4999
|
case "drop-foreign-key":
|
|
5000
|
-
case "drop-check": return
|
|
5000
|
+
case "drop-check": return $;
|
|
5001
5001
|
}
|
|
5002
5002
|
}, xc = (e) => {
|
|
5003
|
-
let t = [], n = { createdTables:
|
|
5003
|
+
let t = [], n = { createdTables: vc(e) };
|
|
5004
5004
|
for (let r of e) {
|
|
5005
5005
|
let e = bc(r.op, n);
|
|
5006
5006
|
e.safe || t.push({
|
|
@@ -5059,7 +5059,7 @@ BEGIN
|
|
|
5059
5059
|
infidelity: Tc(o)
|
|
5060
5060
|
};
|
|
5061
5061
|
else {
|
|
5062
|
-
let i = await e.plan(), o = Tc(i), s = o.filter((e) => e.classification === "lossy"), c =
|
|
5062
|
+
let i = await e.plan(), o = Tc(i), s = o.filter((e) => e.classification === "lossy"), c = hs(i), l = c.operations.filter((e) => e.blocked !== void 0).map(wc);
|
|
5063
5063
|
if (l.length > 0) a = {
|
|
5064
5064
|
...n,
|
|
5065
5065
|
outcome: "blocked",
|
|
@@ -5172,7 +5172,7 @@ BEGIN
|
|
|
5172
5172
|
}, r = s.get(e.table_name) ?? [];
|
|
5173
5173
|
r.push(n), s.set(e.table_name, r);
|
|
5174
5174
|
}
|
|
5175
|
-
let c =
|
|
5175
|
+
let c = vr({
|
|
5176
5176
|
live: { tables: [...s].map(([e, t]) => ({
|
|
5177
5177
|
name: e,
|
|
5178
5178
|
columns: t,
|
|
@@ -5193,4 +5193,4 @@ BEGIN
|
|
|
5193
5193
|
values: [...t]
|
|
5194
5194
|
}), Pc = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
|
|
5195
5195
|
//#endregion
|
|
5196
|
-
export { Nt as DEFAULT_CDC_CHANNEL,
|
|
5196
|
+
export { Nt as DEFAULT_CDC_CHANNEL, z as DEPLOY_LEDGER_TABLE, ue as FILE_MIGRATION_PATTERN, ac as FileMigrationLedgerError, e as IrreversibleMigrationError, gt as MIGRATION_ATOMICITY, pt as MIGRATION_NEEDS_TWO_CONNECTIONS, le as MIGRATION_PHASES, dr as MYSQL_CHARSETS, x as MigrationExpectationFailed, S as MigrationNeedsSqlClient, T as MigrationSkipped, Pt as REACTIVE_TRIGGER_PREFIX, d as RewriteUnstableError, br as STORE_CHARSET_REMEDY, g as TransactionBrokenByBodyError, Ke as VOLTRO_MIGRATION_LOCK_KEY, li as _voltroDeploysTable, ft as acquireMigrationLock, Ao as addColumnDdl, H as appliedAtValue, tc as appliedFileMigrationIds, nc as appliedFileMigrations, Jo as appliedLedgerOperations, Nn as applyNamespacedSchema, ts as applyPlan, Cn as applySchema, Sc as assessRollingDeployGate, Dc as branchRehearsalExitCode, hr as charsetColumnsOf, Ti as chunkTables, bc as classifyRollingDeploySafety, Yo as clearResumeLedger, di as closeDeploy, pr as columnTakesCharset, vc as createdTablesOf, Tr as declaredSnapshot, Wt as defaultArrayClause, Ut as defaultClause, Gt as defaultJsonClause, ys as describeOutcome, Hs as describeProbe, yr as describeStoreCharsetFinding, ps as destructiveScope, Dr as detectReactiveTriggerDrift, to as emitAddIndexMysql, Ma as emitConvertCharsetMysql, Ka as emitCreateTableMssql, Na as emitCreateTableMysql, Ea as emitCreateTablePg, za as emitCreateTableSqlite, sa as emitDropColumnDdl, ca as emitDropColumnDdlMysql, Sn as emitFrameworkBootstrapSql, bn as emitNamespaceProvisionDdl, xn as emitNamespacedSchemaSql, yn as emitSchemaSql, Vi as engineFromVersion, Bo as ensureDeployLedgerTable, Ro as ensureLedgerTable, zo as ensurePlanLedgerTable, Vo as ensureReplaceMarkerTable, _n as enumRenameBlocks, gn as enumTypeBlocks, un as extensionBlocks, fi as failDeploy, Vs as failedExpectations, pc as fileMigrationStatus, L as fingerprintSchema, Qe as fnv1a64, kc as formatBranchRehearsal, Or as formatReactiveTriggerDrift, fs as ignoreTablesFromEnv, Bi as introspectSchema, b as irreversible, D as irreversibleReason, Ki as isAlreadySatisfied, ye as isFileMigration, fr as isMysqlCharset, Pc as isRawSqlFragment, Tn as isReRunSafeDdl, Bs as makeFileMigrationContext, gi as mapPgType, Ss as materialiseSnapshot, t as migration, _t as migrationAtomicityFor, Js as migrationBodyHash, $e as migrationLockKeyForSchema, et as migrationLockNameForSchema, Xa as mysqlIndexPrefixFor, zt as notifyFunctionName, Kt as numericIdSql, ui as openDeploy, hi as parseEnumCheck, dc as pendingFileMigrationIds, fc as pendingFileMigrationSummary, Ks as permanentSkips, ci as planMigrations, o as plannableLiveTables, Gs as plannedCreations, Pn as provisionTenantNamespace, Ft as reactiveTriggerName, ln as reactiveTriggerRepairSql, ss as recordUpToDate, Ue as registerSqlPoolCapacity, Ec as rehearseMigrationOnBranch, wc as rehearsedOperation, ka as renderColumnMysql, Ca as renderColumnPg, Je as resolveMigrationLockSchema, V as resolveMysqlEngine, gc as rollbackFileBasedMigration, xc as rollingDeployUnsafeOps, mc as runFileBasedMigrations, Fn as runFrameworkBootstrap, Mn as runMigrate, is as runMigrationOp, vs as runPlannedMigrations, X as runSchemaOp, ur as shortFingerprint, xr as snapshotColumn, Nc as sql, We as sqlPoolCapacity, I as sqlType, _c as squashMigrationPlans, mr as stampDeclaredCharset, vr as storeCharsetFindings, Mc as tenantNamespaceCharsetFindings, hs as unblockLossy, pi as unfinishedDeploys, Xs as walkMigrationFiles, ht as withMigrationLock, Ws as withSchemaProbeRecorder };
|