@voltro/database 0.32.0 → 0.33.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 +205 -0
- package/dist/sql.js +249 -248
- package/package.json +4 -3
package/dist/sql.js
CHANGED
|
@@ -1085,27 +1085,28 @@ BEGIN
|
|
|
1085
1085
|
let t = Tt(e, n);
|
|
1086
1086
|
t && s.push(t);
|
|
1087
1087
|
}
|
|
1088
|
-
|
|
1088
|
+
return JSON.stringify(bt(n.references)) !== JSON.stringify(bt(r.references)) && (r.references && s.push(R({
|
|
1089
1089
|
kind: "drop-foreign-key",
|
|
1090
1090
|
table: e,
|
|
1091
1091
|
column: n.name
|
|
1092
|
-
}, "safe", `drop FK on ${e}.${n.name} (→ ${r.references.table})`)), n
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
},
|
|
1092
|
+
}, "safe", `drop FK on ${e}.${n.name} (→ ${r.references.table})`)), s.push(...Rt(e, n))), s;
|
|
1093
|
+
}, Rt = (e, t) => {
|
|
1094
|
+
let n = [];
|
|
1095
|
+
if (!t.references) return n;
|
|
1096
|
+
let r = t.references.table, i = t.references.orphanPolicy ?? "fail", a = {
|
|
1097
|
+
kind: "add-foreign-key",
|
|
1098
|
+
table: e,
|
|
1099
|
+
column: t.name,
|
|
1100
|
+
targetTable: r,
|
|
1101
|
+
targetColumn: t.references.column,
|
|
1102
|
+
...t.references.onDelete ? { onDelete: t.references.onDelete } : {},
|
|
1103
|
+
...t.references.onUpdate ? { onUpdate: t.references.onUpdate } : {}
|
|
1104
|
+
};
|
|
1105
|
+
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({
|
|
1106
|
+
...a,
|
|
1107
|
+
orphanPolicy: i
|
|
1108
|
+
}, "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;
|
|
1109
|
+
}, zt = (e, t, n) => {
|
|
1109
1110
|
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));
|
|
1110
1111
|
for (let [n, c] of Object.entries(t)) {
|
|
1111
1112
|
let t = c.renamedFrom;
|
|
@@ -1121,22 +1122,22 @@ BEGIN
|
|
|
1121
1122
|
consumedAddedNames: i,
|
|
1122
1123
|
consumedRemovedNames: a
|
|
1123
1124
|
};
|
|
1124
|
-
},
|
|
1125
|
+
}, Bt = /* @__PURE__ */ new Set([
|
|
1125
1126
|
"postgres",
|
|
1126
1127
|
"mysql",
|
|
1127
1128
|
"mariadb",
|
|
1128
1129
|
"mssql"
|
|
1129
|
-
]),
|
|
1130
|
+
]), Vt = {
|
|
1130
1131
|
ops: [],
|
|
1131
1132
|
consumedAddedNames: /* @__PURE__ */ new Set(),
|
|
1132
1133
|
consumedRemovedNames: /* @__PURE__ */ new Set()
|
|
1133
|
-
},
|
|
1134
|
-
if (i === void 0 || !
|
|
1135
|
-
let a = t.added.filter((e) =>
|
|
1136
|
-
if (a.length === 0) return
|
|
1134
|
+
}, Ht = (e) => !e.unique && !e.expression, Ut = (e, t, n, r, i) => {
|
|
1135
|
+
if (i === void 0 || !Bt.has(i)) return Vt;
|
|
1136
|
+
let a = t.added.filter((e) => Ht(e) && !r.has(e.name));
|
|
1137
|
+
if (a.length === 0) return Vt;
|
|
1137
1138
|
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();
|
|
1138
1139
|
for (let n of t.removed) {
|
|
1139
|
-
if (!
|
|
1140
|
+
if (!Ht(n)) continue;
|
|
1140
1141
|
let t = o(n), r = a.filter((e) => !l.has(e.name) && s(e) === t);
|
|
1141
1142
|
if (r.length !== 1) continue;
|
|
1142
1143
|
let i = r[0];
|
|
@@ -1152,7 +1153,7 @@ BEGIN
|
|
|
1152
1153
|
consumedAddedNames: l,
|
|
1153
1154
|
consumedRemovedNames: u
|
|
1154
1155
|
};
|
|
1155
|
-
},
|
|
1156
|
+
}, Wt = (e, t, n) => {
|
|
1156
1157
|
let r = [], i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
|
|
1157
1158
|
for (let t of e.tables) t.renamedFrom !== void 0 && (s.set(t.renamedFrom, (s.get(t.renamedFrom) ?? 0) + 1), c.add(t.renamedFrom));
|
|
1158
1159
|
for (let c of e.tables) {
|
|
@@ -1192,12 +1193,12 @@ BEGIN
|
|
|
1192
1193
|
claimedOldNames: c,
|
|
1193
1194
|
refusals: o
|
|
1194
1195
|
};
|
|
1195
|
-
},
|
|
1196
|
+
}, Gt = (e, t, n, r) => {
|
|
1196
1197
|
if (t === void 0) return {
|
|
1197
1198
|
live: e,
|
|
1198
1199
|
ops: []
|
|
1199
1200
|
};
|
|
1200
|
-
let i = r !== void 0 &&
|
|
1201
|
+
let i = r !== void 0 && Bt.has(r), a = [], o = e.indexes.map((e) => {
|
|
1201
1202
|
if (!e.name.startsWith(t)) return e;
|
|
1202
1203
|
let r = `${n}${e.name.slice(t.length)}`;
|
|
1203
1204
|
return r === e.name ? e : e.name === `${t}_pkey` ? {
|
|
@@ -1223,7 +1224,7 @@ BEGIN
|
|
|
1223
1224
|
},
|
|
1224
1225
|
ops: a
|
|
1225
1226
|
};
|
|
1226
|
-
},
|
|
1227
|
+
}, Kt = (e) => {
|
|
1227
1228
|
let t = {
|
|
1228
1229
|
safe: 0,
|
|
1229
1230
|
needsDefault: 0,
|
|
@@ -1258,8 +1259,8 @@ BEGIN
|
|
|
1258
1259
|
break;
|
|
1259
1260
|
}
|
|
1260
1261
|
return t;
|
|
1261
|
-
},
|
|
1262
|
-
let t = I(e.declared, e.dialect), n = _t(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Nt, a = [], o =
|
|
1262
|
+
}, qt = (e) => {
|
|
1263
|
+
let t = I(e.declared, e.dialect), n = _t(e.declared, t), r = new Map(e.live.tables.map((e) => [e.name, e])), i = e.onlineAfter ?? Nt, a = [], o = Wt(t, r, n);
|
|
1263
1264
|
a.push(...o.ops);
|
|
1264
1265
|
for (let e of t.tables) if (!o.renamedInto.has(e.name) && !r.has(e.name)) {
|
|
1265
1266
|
a.push(jt(e.name, e.columns, e.indexes, e.primaryKey, o.refusals.get(e.name)));
|
|
@@ -1273,9 +1274,9 @@ BEGIN
|
|
|
1273
1274
|
for (let s of t.tables) {
|
|
1274
1275
|
let t = o.renamedInto.get(s.name), c = r.get(s.name) ?? (t === void 0 ? void 0 : r.get(t));
|
|
1275
1276
|
if (!c) continue;
|
|
1276
|
-
let l =
|
|
1277
|
+
let l = Gt(c, t, s.name, e.dialect);
|
|
1277
1278
|
a.push(...l.ops);
|
|
1278
|
-
let d = l.live, f = n.get(s.name), p = Dt(s, d, e.dialect), m = Ot(s, d), h =
|
|
1279
|
+
let d = l.live, f = n.get(s.name), p = Dt(s, d, e.dialect), m = Ot(s, d), h = zt(f.table, f.columnDefs, p);
|
|
1279
1280
|
a.push(...h.ops);
|
|
1280
1281
|
for (let e of p.removed) {
|
|
1281
1282
|
if (h.consumedRemovedNames.has(e.name) || u(e.name)) continue;
|
|
@@ -1287,9 +1288,9 @@ BEGIN
|
|
|
1287
1288
|
let t = f.columnDefs[e.name];
|
|
1288
1289
|
a.push(kt(s.name, e, t));
|
|
1289
1290
|
let n = Tt(s.name, e);
|
|
1290
|
-
n && a.push(n);
|
|
1291
|
+
n && a.push(n), a.push(...Rt(s.name, e));
|
|
1291
1292
|
}
|
|
1292
|
-
let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ =
|
|
1293
|
+
let g = new Map(h.ops.flatMap((e) => e.op.kind === "rename-column" ? [[e.op.from, e.op.to]] : [])), _ = Ut(s.name, m, g, new Set(d.indexes.map((e) => e.name)), e.dialect);
|
|
1293
1294
|
a.push(..._.ops);
|
|
1294
1295
|
for (let e of m.added) _.consumedAddedNames.has(e.name) || a.push(Pt(s.name, e, d.rowCount, i));
|
|
1295
1296
|
for (let e of m.removed) _.consumedRemovedNames.has(e.name) || a.push(Ft(s.name, e));
|
|
@@ -1376,9 +1377,9 @@ BEGIN
|
|
|
1376
1377
|
operations: S,
|
|
1377
1378
|
fromFingerprint: P(e.live),
|
|
1378
1379
|
toFingerprint: P(t),
|
|
1379
|
-
summary:
|
|
1380
|
+
summary: Kt(S)
|
|
1380
1381
|
};
|
|
1381
|
-
},
|
|
1382
|
+
}, Jt = (e) => {
|
|
1382
1383
|
let t = /[`"[]?([A-Za-z_][A-Za-z0-9_]*)[`"\]]?\s*(?:in\b|=)/i.exec(e);
|
|
1383
1384
|
if (!t) return null;
|
|
1384
1385
|
let n = [...e.matchAll(/'((?:[^']|'')*)'/g)].map((e) => e[1].replace(/''/g, "'"));
|
|
@@ -1386,7 +1387,7 @@ BEGIN
|
|
|
1386
1387
|
column: t[1],
|
|
1387
1388
|
values: n
|
|
1388
1389
|
};
|
|
1389
|
-
},
|
|
1390
|
+
}, Yt = (e, t) => {
|
|
1390
1391
|
if (t === "vector") return "vector";
|
|
1391
1392
|
switch (e) {
|
|
1392
1393
|
case "text":
|
|
@@ -1421,25 +1422,25 @@ BEGIN
|
|
|
1421
1422
|
case "SET DEFAULT": return "noAction";
|
|
1422
1423
|
default: return "noAction";
|
|
1423
1424
|
}
|
|
1424
|
-
},
|
|
1425
|
+
}, Xt = (e, t) => {
|
|
1425
1426
|
let n = e !== void 0 && e !== "" ? Number(e) : NaN;
|
|
1426
1427
|
return Number.isInteger(n) && n > 0 ? n : t;
|
|
1427
|
-
},
|
|
1428
|
+
}, Zt = () => Xt(process.env.VOLTRO_INTROSPECT_BATCH, 20), Qt = 300, $t = () => {
|
|
1428
1429
|
let e = process.env.VOLTRO_INTROSPECT_TIMEOUT_MS;
|
|
1429
|
-
return e !== void 0 && e.trim() === "0" ? 0 :
|
|
1430
|
-
},
|
|
1430
|
+
return e !== void 0 && e.trim() === "0" ? 0 : Xt(e, 3e4);
|
|
1431
|
+
}, en = (e, t) => {
|
|
1431
1432
|
let n = Number.isFinite(t) && t >= 1 ? Math.floor(t) : 1, r = [];
|
|
1432
1433
|
for (let t = 0; t < e.length; t += n) r.push(e.slice(t, t + n));
|
|
1433
1434
|
return r;
|
|
1434
|
-
},
|
|
1435
|
-
let t =
|
|
1435
|
+
}, tn = (e) => {
|
|
1436
|
+
let t = $t(), n = p.gen(function* () {
|
|
1436
1437
|
t > 0 && (yield* e.unsafe(`SET LOCAL statement_timeout = ${t}`));
|
|
1437
|
-
let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i =
|
|
1438
|
+
let n = (t) => e.unsafe("(" + t.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ") + ")"), r = (t) => e.unsafe(String(Math.max(0, Math.trunc(t)))), i = Zt(), a = (e, t) => p.gen(function* () {
|
|
1438
1439
|
let r = [];
|
|
1439
|
-
for (let a of
|
|
1440
|
+
for (let a of en(e, i)) a.length !== 0 && r.push(...yield* t(n(a)));
|
|
1440
1441
|
return r;
|
|
1441
1442
|
}), o = [];
|
|
1442
|
-
for (let t = 0;; t +=
|
|
1443
|
+
for (let t = 0;; t += Qt) {
|
|
1443
1444
|
let n = yield* e`
|
|
1444
1445
|
SELECT c.relname AS table_name,
|
|
1445
1446
|
COALESCE(c.reltuples::bigint, 0) AS row_count
|
|
@@ -1447,9 +1448,9 @@ BEGIN
|
|
|
1447
1448
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
1448
1449
|
WHERE n.nspname = current_schema() AND c.relkind = 'r'
|
|
1449
1450
|
ORDER BY c.relname
|
|
1450
|
-
LIMIT ${r(
|
|
1451
|
+
LIMIT ${r(Qt)} OFFSET ${r(t)}
|
|
1451
1452
|
`;
|
|
1452
|
-
if (o.push(...n), n.length <
|
|
1453
|
+
if (o.push(...n), n.length < Qt) break;
|
|
1453
1454
|
}
|
|
1454
1455
|
let s = /* @__PURE__ */ new Set(), c = [];
|
|
1455
1456
|
for (let e of o) s.has(e.table_name) || (s.add(e.table_name), c.push(e));
|
|
@@ -1583,7 +1584,7 @@ BEGIN
|
|
|
1583
1584
|
let w = [];
|
|
1584
1585
|
for (let e of c) {
|
|
1585
1586
|
let t = /* @__PURE__ */ new Set(), n = (v.get(e.table_name) ?? []).filter((e) => t.has(e.column_name) ? !1 : (t.add(e.column_name), !0)), r = y.get(e.table_name) ?? /* @__PURE__ */ new Set(), i = b.get(e.table_name) ?? /* @__PURE__ */ new Set(), a = S.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) => {
|
|
1586
|
-
let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" :
|
|
1587
|
+
let n = r.has(t.column_name) && r.size === 1, a = o.get(t.column_name), s = a ? "reference" : n && t.column_name === "id" ? "id" : Yt(t.data_type, t.udt_name), c = a ? {
|
|
1587
1588
|
table: a.target_table,
|
|
1588
1589
|
column: a.target_column,
|
|
1589
1590
|
onDelete: z(a.delete_rule),
|
|
@@ -1637,7 +1638,7 @@ BEGIN
|
|
|
1637
1638
|
let n = `${String(e)} ${String(e.cause ?? "")}`.toLowerCase();
|
|
1638
1639
|
return n.includes("statement timeout") || n.includes("57014") ? p.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.`)) : p.fail(e);
|
|
1639
1640
|
}));
|
|
1640
|
-
},
|
|
1641
|
+
}, nn = (e, t) => {
|
|
1641
1642
|
switch (e.toLowerCase()) {
|
|
1642
1643
|
case "varchar":
|
|
1643
1644
|
case "char":
|
|
@@ -1673,7 +1674,7 @@ BEGIN
|
|
|
1673
1674
|
let t = e, n = {};
|
|
1674
1675
|
for (let e of Object.keys(t)) n[e.toLowerCase()] = t[e];
|
|
1675
1676
|
return n;
|
|
1676
|
-
}),
|
|
1677
|
+
}), rn = (e) => p.gen(function* () {
|
|
1677
1678
|
let t = B(yield* e`
|
|
1678
1679
|
SELECT table_name, COALESCE(table_rows, 0) AS table_rows
|
|
1679
1680
|
FROM information_schema.tables
|
|
@@ -1707,7 +1708,7 @@ BEGIN
|
|
|
1707
1708
|
o.add(`${e.table_name}.${t[1]}`);
|
|
1708
1709
|
continue;
|
|
1709
1710
|
}
|
|
1710
|
-
let n =
|
|
1711
|
+
let n = Jt(e.check_clause);
|
|
1711
1712
|
n && s.set(`${e.table_name}.${n.column}`, n.values);
|
|
1712
1713
|
}
|
|
1713
1714
|
let c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
|
|
@@ -1730,7 +1731,7 @@ BEGIN
|
|
|
1730
1731
|
let t = c.get(e.table_name) ?? [], n = l.get(e.table_name) ?? [], r = new Map(n.map((e) => [e.source_column, e])), i = t.filter((e) => e.column_key === "PRI").map((e) => e.column_name), a = /* @__PURE__ */ new Set(), f = u.get(e.table_name);
|
|
1731
1732
|
if (f) for (let e of f.values()) e.length === 1 && e[0].non_unique === 0 && a.add(e[0].column_name);
|
|
1732
1733
|
let p = t.map((t) => {
|
|
1733
|
-
let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" :
|
|
1734
|
+
let n = i.includes(t.column_name) && i.length === 1, c = r.get(t.column_name), l = c ? "reference" : n && t.column_name === "id" ? "id" : o.has(`${e.table_name}.${t.column_name}`) ? "json" : nn(t.data_type, t.column_type), u = c ? {
|
|
1734
1735
|
table: c.target_table,
|
|
1735
1736
|
column: c.target_column,
|
|
1736
1737
|
onDelete: z(c.delete_rule),
|
|
@@ -1772,10 +1773,10 @@ BEGIN
|
|
|
1772
1773
|
});
|
|
1773
1774
|
}
|
|
1774
1775
|
return { tables: d };
|
|
1775
|
-
}),
|
|
1776
|
+
}), an = (e) => {
|
|
1776
1777
|
let t = e.toUpperCase();
|
|
1777
1778
|
return t.includes("INT") ? "integer" : t.includes("REAL") || t.includes("FLOA") || t.includes("DOUB") ? "real" : t.includes("BLOB") ? "bytes" : "text";
|
|
1778
|
-
},
|
|
1779
|
+
}, on = (e) => p.gen(function* () {
|
|
1779
1780
|
let t = yield* e`
|
|
1780
1781
|
SELECT name, sql FROM sqlite_master
|
|
1781
1782
|
WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
|
|
@@ -1792,7 +1793,7 @@ BEGIN
|
|
|
1792
1793
|
d.set(t.name, r), t.unique === 1 && r.length === 1 && f.add(r[0]);
|
|
1793
1794
|
}
|
|
1794
1795
|
let p = o.map((e) => {
|
|
1795
|
-
let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" :
|
|
1796
|
+
let n = u.length === 1 && u[0] === e.name, r = l.get(e.name), i = r ? "reference" : n && e.name === "id" ? "id" : an(e.type), a = r ? {
|
|
1796
1797
|
table: r.table,
|
|
1797
1798
|
column: r.to,
|
|
1798
1799
|
onDelete: z(r.on_delete),
|
|
@@ -1831,7 +1832,7 @@ BEGIN
|
|
|
1831
1832
|
});
|
|
1832
1833
|
}
|
|
1833
1834
|
return { tables: r };
|
|
1834
|
-
}),
|
|
1835
|
+
}), sn = (e) => {
|
|
1835
1836
|
switch (e.toLowerCase()) {
|
|
1836
1837
|
case "int":
|
|
1837
1838
|
case "smallint":
|
|
@@ -1853,7 +1854,7 @@ BEGIN
|
|
|
1853
1854
|
case "image": return "bytes";
|
|
1854
1855
|
default: return "text";
|
|
1855
1856
|
}
|
|
1856
|
-
}, V = (e) => e === !0 || e === 1,
|
|
1857
|
+
}, V = (e) => e === !0 || e === 1, cn = (e) => p.gen(function* () {
|
|
1857
1858
|
let t = yield* e`
|
|
1858
1859
|
SELECT TABLE_NAME AS table_name FROM INFORMATION_SCHEMA.TABLES
|
|
1859
1860
|
WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_NAME`, n = yield* e`
|
|
@@ -1914,12 +1915,12 @@ BEGIN
|
|
|
1914
1915
|
else V(t[0].is_unique) && t.length === 1 && f.add(t[0].column_name);
|
|
1915
1916
|
}
|
|
1916
1917
|
let p = t.map((t) => {
|
|
1917
|
-
let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" :
|
|
1918
|
+
let n = d.length === 1 && d[0] === t.column_name, i = r.get(t.column_name), a = i ? "reference" : n && t.column_name === "id" ? "id" : sn(t.data_type), s = i ? {
|
|
1918
1919
|
table: i.target_table,
|
|
1919
1920
|
column: i.target_column,
|
|
1920
|
-
onDelete:
|
|
1921
|
-
onUpdate:
|
|
1922
|
-
} : void 0, c = t.column_default === null ? null :
|
|
1921
|
+
onDelete: ln(i.delete_rule),
|
|
1922
|
+
onUpdate: ln(i.update_rule)
|
|
1923
|
+
} : void 0, c = t.column_default === null ? null : un(t.column_default), l = o.get(`${e}.${t.column_name}`);
|
|
1923
1924
|
return {
|
|
1924
1925
|
name: t.column_name,
|
|
1925
1926
|
type: a,
|
|
@@ -1953,18 +1954,18 @@ BEGIN
|
|
|
1953
1954
|
});
|
|
1954
1955
|
}
|
|
1955
1956
|
return { tables: u };
|
|
1956
|
-
}),
|
|
1957
|
+
}), ln = (e) => {
|
|
1957
1958
|
switch (e.toUpperCase().replace(/_/g, " ")) {
|
|
1958
1959
|
case "CASCADE": return "cascade";
|
|
1959
1960
|
case "SET NULL": return "setNull";
|
|
1960
1961
|
case "SET DEFAULT": return "noAction";
|
|
1961
1962
|
default: return "noAction";
|
|
1962
1963
|
}
|
|
1963
|
-
},
|
|
1964
|
+
}, un = (e) => {
|
|
1964
1965
|
let t = e.trim();
|
|
1965
1966
|
for (; t.startsWith("(") && t.endsWith(")");) t = t.slice(1, -1).trim();
|
|
1966
1967
|
return t.startsWith("N'") && t.endsWith("'") ? t = t.slice(2, -1) : t.startsWith("'") && t.endsWith("'") && (t = t.slice(1, -1)), t;
|
|
1967
|
-
},
|
|
1968
|
+
}, dn = /* @__PURE__ */ new Set([
|
|
1968
1969
|
"character varying",
|
|
1969
1970
|
"varchar",
|
|
1970
1971
|
"nvarchar",
|
|
@@ -1972,32 +1973,32 @@ BEGIN
|
|
|
1972
1973
|
"character",
|
|
1973
1974
|
"nchar"
|
|
1974
1975
|
]), H = (e, t) => {
|
|
1975
|
-
if (!
|
|
1976
|
+
if (!dn.has(e.toLowerCase())) return;
|
|
1976
1977
|
let n = Number(t);
|
|
1977
1978
|
if (!(!Number.isFinite(n) || n <= 0)) return n;
|
|
1978
1979
|
}, U = (e) => e.onDialectOrElse({
|
|
1979
|
-
mysql: () =>
|
|
1980
|
-
mssql: () =>
|
|
1981
|
-
sqlite: () =>
|
|
1982
|
-
orElse: () =>
|
|
1983
|
-
}),
|
|
1980
|
+
mysql: () => rn(e),
|
|
1981
|
+
mssql: () => cn(e),
|
|
1982
|
+
sqlite: () => on(e),
|
|
1983
|
+
orElse: () => tn(e)
|
|
1984
|
+
}), fn = (e, t) => e.onDialectOrElse({
|
|
1984
1985
|
mysql: () => p.succeed(t.replace("T", " ").replace("Z", "")),
|
|
1985
1986
|
orElse: () => p.succeed(t)
|
|
1986
|
-
}),
|
|
1987
|
+
}), pn = (e, t) => `${t}(${e.precision ?? 38}, ${e.scale ?? 0})`, W = (e, t) => {
|
|
1987
1988
|
if (!(e.type === "text" && e.maxLength !== void 0) && !e.spatial && e.type !== "vector" && e.type !== "array" && e.type !== "enum") return;
|
|
1988
1989
|
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;
|
|
1989
1990
|
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.`);
|
|
1990
1991
|
return j(e, t);
|
|
1991
|
-
}, pn = (e) => {
|
|
1992
|
-
let t = W(e, "postgres");
|
|
1993
|
-
return t === void 0 ? mn(e) : t;
|
|
1994
1992
|
}, mn = (e) => {
|
|
1993
|
+
let t = W(e, "postgres");
|
|
1994
|
+
return t === void 0 ? hn(e) : t;
|
|
1995
|
+
}, hn = (e) => {
|
|
1995
1996
|
switch (e.type) {
|
|
1996
1997
|
case "id": return "text";
|
|
1997
1998
|
case "text": return "text";
|
|
1998
1999
|
case "integer": return "integer";
|
|
1999
2000
|
case "real": return "double precision";
|
|
2000
|
-
case "decimal": return
|
|
2001
|
+
case "decimal": return pn(e, "NUMERIC");
|
|
2001
2002
|
case "bigint": return "bigint";
|
|
2002
2003
|
case "boolean": return "boolean";
|
|
2003
2004
|
case "timestamp": return "timestamptz";
|
|
@@ -2011,7 +2012,7 @@ BEGIN
|
|
|
2011
2012
|
case "interval": return "interval";
|
|
2012
2013
|
case "raw": return e.rawDdl ?? "text";
|
|
2013
2014
|
}
|
|
2014
|
-
},
|
|
2015
|
+
}, gn = (e) => {
|
|
2015
2016
|
let t = W(e, "mariadb");
|
|
2016
2017
|
if (t !== void 0) return t;
|
|
2017
2018
|
switch (e.type) {
|
|
@@ -2019,7 +2020,7 @@ BEGIN
|
|
|
2019
2020
|
case "text": return e.hasDefault && e.defaultValue !== void 0 || e.oneOf && e.oneOf.length > 0 ? "VARCHAR(255)" : "LONGTEXT";
|
|
2020
2021
|
case "integer": return "INT";
|
|
2021
2022
|
case "real": return "DOUBLE";
|
|
2022
|
-
case "decimal": return
|
|
2023
|
+
case "decimal": return pn(e, "DECIMAL");
|
|
2023
2024
|
case "bigint": return "BIGINT";
|
|
2024
2025
|
case "boolean": return "TINYINT(1)";
|
|
2025
2026
|
case "timestamp": return "DATETIME(6)";
|
|
@@ -2033,14 +2034,14 @@ BEGIN
|
|
|
2033
2034
|
case "interval": return "BIGINT";
|
|
2034
2035
|
case "raw": return e.rawDdl ?? "LONGTEXT";
|
|
2035
2036
|
}
|
|
2036
|
-
}, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``,
|
|
2037
|
+
}, G = (e) => `"${e}"`, K = (e) => `\`${e.replace(/`/g, "``")}\``, _n = (e, t) => `ALTER TABLE ${t(e.table)} DROP COLUMN IF EXISTS ${t(e.column)};`, vn = (e) => `ALTER TABLE ${K(e.table)} DROP COLUMN IF EXISTS ${K(e.column)}, ALGORITHM=COPY;`, yn = (e, t) => `ALTER TABLE ${t(e.table)} RENAME COLUMN ${t(e.from)} TO ${t(e.to)};`, bn = (e, t, n) => `ALTER TABLE ${n(e.table)} RENAME COLUMN ${n(e.column)} TO ${n(`${e.column}${Gn(t)}`)};`, xn = (e, t, n) => e.hasDefault && e.defaultValue !== void 0 ? `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} SET ${Sn(e, n)};` : `ALTER TABLE ${t(e.table)} ALTER COLUMN ${t(e.column)} DROP DEFAULT;`, Sn = (e, t) => {
|
|
2037
2038
|
let n = t(e.defaultValue);
|
|
2038
2039
|
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.`);
|
|
2039
2040
|
return n;
|
|
2040
|
-
}, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n],
|
|
2041
|
+
}, q = (e, t, n) => e.find((e) => e.tableName === t)?.fields[n], Cn = (e, t, n) => {
|
|
2041
2042
|
let r = q(e, t, n);
|
|
2042
2043
|
return r ? ct(n, r) : void 0;
|
|
2043
|
-
},
|
|
2044
|
+
}, wn = (e, t, n) => {
|
|
2044
2045
|
let r = n ?? e.nullable, i = be(e, "mariadb");
|
|
2045
2046
|
return [
|
|
2046
2047
|
K(t),
|
|
@@ -2048,17 +2049,17 @@ BEGIN
|
|
|
2048
2049
|
r ? null : "NOT NULL",
|
|
2049
2050
|
i
|
|
2050
2051
|
].filter(Boolean).join(" ");
|
|
2051
|
-
},
|
|
2052
|
+
}, Tn = (e, t) => e == null ? null : Array.isArray(e) ? En(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" ? M(e, "mariadb") : null, En = (e, t, n) => xe(e, t ?? { type: "json" }, n), Dn = (e, t) => e == null ? null : Array.isArray(e) ? En(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" ? M(e, "postgres") : null, J = (e, t) => {
|
|
2052
2053
|
if (!e.generatedAs) return null;
|
|
2053
2054
|
let { expr: n, stored: r } = e.generatedAs;
|
|
2054
2055
|
return t === "postgres" ? `GENERATED ALWAYS AS (${n}) STORED` : t === "mssql" ? `AS (${n})${r ? " PERSISTED" : ""}` : `GENERATED ALWAYS AS (${n}) ${r ? "STORED" : "VIRTUAL"}`;
|
|
2055
|
-
},
|
|
2056
|
+
}, On = (e) => {
|
|
2056
2057
|
if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "postgres");
|
|
2057
2058
|
let t = J(e, "postgres");
|
|
2058
|
-
if (t) return `${G(e.name)} ${
|
|
2059
|
-
let n = [G(e.name),
|
|
2059
|
+
if (t) return `${G(e.name)} ${mn(e)} ${t}`;
|
|
2060
|
+
let n = [G(e.name), mn(e)];
|
|
2060
2061
|
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
|
|
2061
|
-
let t =
|
|
2062
|
+
let t = Dn(e.defaultValue, e);
|
|
2062
2063
|
t && n.push(t);
|
|
2063
2064
|
}
|
|
2064
2065
|
return e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
|
|
@@ -2067,20 +2068,20 @@ BEGIN
|
|
|
2067
2068
|
setNull: "SET NULL",
|
|
2068
2069
|
noAction: "NO ACTION"
|
|
2069
2070
|
}[e.references.onDelete]}`)), n.join(" ");
|
|
2070
|
-
},
|
|
2071
|
-
let t = e.columns.map((e) => ` ${
|
|
2072
|
-
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(
|
|
2071
|
+
}, kn = (e, t) => e.primaryKey && e.primaryKey.length > 0 ? `,\n PRIMARY KEY (${e.primaryKey.map(t).join(", ")})` : "", An = (e) => {
|
|
2072
|
+
let t = e.columns.map((e) => ` ${On(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${kn(e, G)}\n)`];
|
|
2073
|
+
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(Xn).join(", ")})`);
|
|
2073
2074
|
return n;
|
|
2074
|
-
},
|
|
2075
|
-
let t =
|
|
2075
|
+
}, jn = 191, Mn = (e) => {
|
|
2076
|
+
let t = gn(e).toUpperCase();
|
|
2076
2077
|
return t.endsWith("TEXT") || t.endsWith("BLOB");
|
|
2077
|
-
},
|
|
2078
|
+
}, Nn = (e) => {
|
|
2078
2079
|
if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mariadb");
|
|
2079
2080
|
let t = J(e, "mariadb");
|
|
2080
|
-
if (t) return `${K(e.name)} ${
|
|
2081
|
-
let n = [K(e.name),
|
|
2082
|
-
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !
|
|
2083
|
-
let t =
|
|
2081
|
+
if (t) return `${K(e.name)} ${gn(e)} ${t}`;
|
|
2082
|
+
let n = [K(e.name), gn(e)];
|
|
2083
|
+
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && !Mn(e) && n.push("UNIQUE"), e.hasDefault) {
|
|
2084
|
+
let t = Tn(e.defaultValue, e);
|
|
2084
2085
|
t && n.push(t);
|
|
2085
2086
|
}
|
|
2086
2087
|
return e.references && (n.push(`REFERENCES ${K(e.references.table)} (${K(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${{
|
|
@@ -2089,25 +2090,25 @@ BEGIN
|
|
|
2089
2090
|
setNull: "SET NULL",
|
|
2090
2091
|
noAction: "NO ACTION"
|
|
2091
2092
|
}[e.references.onDelete]}`)), n.join(" ");
|
|
2092
|
-
},
|
|
2093
|
+
}, Pn = (e) => {
|
|
2093
2094
|
let t = new Map(e.columns.map((e) => [e.name, e])), n = (e) => {
|
|
2094
2095
|
let n = t.get(e);
|
|
2095
|
-
return n &&
|
|
2096
|
-
}, r = e.columns.map((e) => ` ${
|
|
2097
|
-
for (let t of e.columns) t.unique && t.type !== "id" &&
|
|
2096
|
+
return n && Mn(n) ? `${K(e)}(${jn})` : K(e);
|
|
2097
|
+
}, r = e.columns.map((e) => ` ${Nn(e)}`).join(",\n"), i = [`CREATE TABLE IF NOT EXISTS ${K(e.table)} (\n${r}${kn(e, n)}\n)`];
|
|
2098
|
+
for (let t of e.columns) t.unique && t.type !== "id" && Mn(t) && i.push(`CREATE UNIQUE INDEX IF NOT EXISTS ${K(`${e.table}_${t.name}_key`)} ON ${K(e.table)} (${n(t.name)})`);
|
|
2098
2099
|
for (let t of e.indexes) t.name !== `${e.table}_pkey` && i.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(t.name)} ON ${K(e.table)} (${t.columns.map(n).join(", ")})`);
|
|
2099
2100
|
return i;
|
|
2100
|
-
},
|
|
2101
|
+
}, Fn = {
|
|
2101
2102
|
cascade: "CASCADE",
|
|
2102
2103
|
restrict: "RESTRICT",
|
|
2103
2104
|
setNull: "SET NULL",
|
|
2104
2105
|
noAction: "NO ACTION"
|
|
2105
|
-
},
|
|
2106
|
+
}, In = {
|
|
2106
2107
|
cascade: "CASCADE",
|
|
2107
2108
|
restrict: "NO ACTION",
|
|
2108
2109
|
setNull: "SET NULL",
|
|
2109
2110
|
noAction: "NO ACTION"
|
|
2110
|
-
},
|
|
2111
|
+
}, Ln = (e) => {
|
|
2111
2112
|
let t = W(e, "sqlite");
|
|
2112
2113
|
if (t !== void 0) return t;
|
|
2113
2114
|
switch (e.type) {
|
|
@@ -2119,29 +2120,29 @@ BEGIN
|
|
|
2119
2120
|
case "bytes": return "BLOB";
|
|
2120
2121
|
default: return "TEXT";
|
|
2121
2122
|
}
|
|
2122
|
-
}, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null,
|
|
2123
|
+
}, Y = (e, t) => e == null ? null : e === "now" ? `DEFAULT ${t}` : typeof e == "boolean" ? `DEFAULT ${+!!e}` : typeof e == "number" ? `DEFAULT ${e}` : typeof e == "string" ? /[()]|^'/.test(e) ? `DEFAULT ${e}` : `DEFAULT '${e.replace(/'/g, "''")}'` : typeof e == "object" ? M(e, "sqlite") : null, Rn = (e) => {
|
|
2123
2124
|
if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "sqlite");
|
|
2124
2125
|
let t = J(e, "sqlite");
|
|
2125
|
-
if (t) return `${G(e.name)} ${
|
|
2126
|
-
let n = [G(e.name),
|
|
2126
|
+
if (t) return `${G(e.name)} ${Ln(e)} ${t}`;
|
|
2127
|
+
let n = [G(e.name), Ln(e)];
|
|
2127
2128
|
if (e.type === "id" && n.push("PRIMARY KEY"), e.nullable || n.push("NOT NULL"), e.unique && e.type !== "id" && n.push("UNIQUE"), e.hasDefault) {
|
|
2128
2129
|
let t = Y(e.defaultValue, "CURRENT_TIMESTAMP");
|
|
2129
2130
|
t && n.push(t);
|
|
2130
2131
|
}
|
|
2131
|
-
if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${
|
|
2132
|
+
if (e.references && (n.push(`REFERENCES ${G(e.references.table)} (${G(e.references.column)})`), e.references.onDelete && n.push(`ON DELETE ${Fn[e.references.onDelete]}`)), e.oneOf && e.oneOf.length > 0) {
|
|
2132
2133
|
let t = e.oneOf.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
|
|
2133
2134
|
n.push(`CHECK (${G(e.name)} IN (${t}))`);
|
|
2134
2135
|
}
|
|
2135
2136
|
return n.join(" ");
|
|
2136
|
-
},
|
|
2137
|
-
let t = e.columns.map((e) => ` ${
|
|
2137
|
+
}, zn = (e) => {
|
|
2138
|
+
let t = e.columns.map((e) => ` ${Rn(e)}`).join(",\n"), n = [`CREATE TABLE IF NOT EXISTS ${G(e.table)} (\n${t}${kn(e, G)}\n)`];
|
|
2138
2139
|
for (let t of e.indexes) t.name !== `${e.table}_pkey` && n.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e.table)} (${t.columns.map(G).join(", ")})`);
|
|
2139
2140
|
return n;
|
|
2140
2141
|
}, X = (e, t) => {
|
|
2141
2142
|
let n = t.find((t) => t.tableName === e);
|
|
2142
2143
|
if (!n) return [];
|
|
2143
2144
|
let r = I([n]).tables[0], i = `${e}__voltro_rebuild`, a = r.columns.map((e) => G(e.name)).join(", "), o = [
|
|
2144
|
-
...
|
|
2145
|
+
...zn({
|
|
2145
2146
|
kind: "create-table",
|
|
2146
2147
|
table: i,
|
|
2147
2148
|
columns: r.columns,
|
|
@@ -2154,17 +2155,17 @@ BEGIN
|
|
|
2154
2155
|
];
|
|
2155
2156
|
for (let t of r.indexes) t.name !== `${e}_pkey` && o.push(`CREATE ${t.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${G(t.name)} ON ${G(e)} (${t.columns.map(G).join(", ")})`);
|
|
2156
2157
|
return o;
|
|
2157
|
-
},
|
|
2158
|
+
}, Bn = (e, t, n, r) => {
|
|
2158
2159
|
let i = r ?? e.nullable;
|
|
2159
2160
|
return `ALTER TABLE ${Z(n)} ALTER COLUMN ${Z(t)} ${j(e, "mssql")} ${i ? "NULL" : "NOT NULL"};`;
|
|
2160
|
-
},
|
|
2161
|
+
}, Vn = (e) => {
|
|
2161
2162
|
let t = `DECLARE @dc sysname; SELECT @dc = dc.name FROM sys.default_constraints dc JOIN sys.columns col ON col.object_id = dc.parent_object_id AND col.column_id = dc.parent_column_id WHERE dc.parent_object_id = OBJECT_ID(N'${e.table.replace(/'/g, "''")}') AND col.name = N'${e.column.replace(/'/g, "''")}'; IF @dc IS NOT NULL EXEC(N'ALTER TABLE ${Z(e.table)} DROP CONSTRAINT [' + @dc + ']');`;
|
|
2162
2163
|
if (!e.hasDefault) return t;
|
|
2163
2164
|
let n = Y(e.defaultValue, "SYSUTCDATETIME()");
|
|
2164
2165
|
if (!n) return t;
|
|
2165
2166
|
let r = n.replace(/^DEFAULT\s+/i, "");
|
|
2166
2167
|
return `${t} ALTER TABLE ${Z(e.table)} ADD DEFAULT ${r} FOR ${Z(e.column)};`;
|
|
2167
|
-
}, Z = (e) => `[${e.replace(/]/g, "]]")}]`,
|
|
2168
|
+
}, Z = (e) => `[${e.replace(/]/g, "]]")}]`, Hn = (e) => {
|
|
2168
2169
|
let t = W(e, "mssql");
|
|
2169
2170
|
if (t !== void 0) return t;
|
|
2170
2171
|
switch (e.type) {
|
|
@@ -2172,7 +2173,7 @@ BEGIN
|
|
|
2172
2173
|
case "reference": return "NVARCHAR(64)";
|
|
2173
2174
|
case "integer": return "INT";
|
|
2174
2175
|
case "real": return "FLOAT";
|
|
2175
|
-
case "decimal": return
|
|
2176
|
+
case "decimal": return pn(e, "DECIMAL");
|
|
2176
2177
|
case "bigint": return "BIGINT";
|
|
2177
2178
|
case "boolean": return "BIT";
|
|
2178
2179
|
case "timestamp": return "DATETIME2(6)";
|
|
@@ -2180,40 +2181,40 @@ BEGIN
|
|
|
2180
2181
|
case "bytes": return "VARBINARY(MAX)";
|
|
2181
2182
|
default: return "NVARCHAR(MAX)";
|
|
2182
2183
|
}
|
|
2183
|
-
},
|
|
2184
|
+
}, Un = (e, t) => {
|
|
2184
2185
|
if (e.type === "id" && e.idScheme?.kind === "numeric") return N(e.name, "mssql");
|
|
2185
|
-
let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" :
|
|
2186
|
+
let n = e.type === "text" && t?.has(e.name) ? "NVARCHAR(450)" : Hn(e), r = J(e, "mssql");
|
|
2186
2187
|
if (r) return `${Z(e.name)} ${r}`;
|
|
2187
2188
|
let i = [Z(e.name), n];
|
|
2188
2189
|
if (e.type === "id" && i.push("PRIMARY KEY"), e.nullable || i.push("NOT NULL"), e.unique && e.type !== "id" && i.push("UNIQUE"), e.hasDefault) {
|
|
2189
2190
|
let t = Y(e.defaultValue, "SYSUTCDATETIME()");
|
|
2190
2191
|
t && i.push(t);
|
|
2191
2192
|
}
|
|
2192
|
-
return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${
|
|
2193
|
-
},
|
|
2194
|
-
let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${
|
|
2193
|
+
return e.references && (i.push(`REFERENCES ${Z(e.references.table)} (${Z(e.references.column)})`), e.references.onDelete && i.push(`ON DELETE ${In[e.references.onDelete]}`)), i.join(" ");
|
|
2194
|
+
}, Wn = (e) => {
|
|
2195
|
+
let t = (e) => e.replace(/'/g, "''"), n = new Set(e.indexes.flatMap((e) => e.columns)), r = e.columns.map((e) => ` ${Un(e, n)}`).join(",\n"), i = `CREATE TABLE ${Z(e.table)} (\n${r}${kn(e, Z)}\n)`, a = [`IF OBJECT_ID(N'${t(e.table)}', N'U') IS NULL EXEC(N'${t(i)}')`];
|
|
2195
2196
|
for (let n of e.indexes) {
|
|
2196
2197
|
if (n.name === `${e.table}_pkey`) continue;
|
|
2197
2198
|
let r = `CREATE ${n.unique ? "UNIQUE " : ""}INDEX ${Z(n.name)} ON ${Z(e.table)} (${n.columns.map(Z).join(", ")})`;
|
|
2198
2199
|
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)}')`);
|
|
2199
2200
|
}
|
|
2200
2201
|
return a;
|
|
2201
|
-
},
|
|
2202
|
-
let r = `${e.table}${
|
|
2202
|
+
}, Gn = (e) => `__dropped_${e.replace(/[-:T.Z]/g, "").slice(0, 14)}`, Kn = (e, t) => `DROP TABLE IF EXISTS ${t(e.table)};`, qn = (e, t, n) => {
|
|
2203
|
+
let r = `${e.table}${Gn(t)}`;
|
|
2203
2204
|
return `ALTER TABLE ${n(e.table)} RENAME TO ${n(r)};`;
|
|
2204
|
-
},
|
|
2205
|
+
}, Jn = (e, t, n) => {
|
|
2205
2206
|
let r = q(e, t, n);
|
|
2206
|
-
return r ?
|
|
2207
|
-
},
|
|
2207
|
+
return r ? Mn({ type: r.type }) : !1;
|
|
2208
|
+
}, Yn = (e, t, n) => Jn(e, t, n) ? `${K(n)}(${jn})` : K(n), Xn = (e) => e.startsWith("(") ? e : G(e), Zn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${t ? "CONCURRENTLY " : ""}IF NOT EXISTS ${G(e.index.name)} ON ${G(e.table)} (${e.index.columns.map(Xn).join(", ")});`, Qn = (e, t) => `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS ${K(e.index.name)} ON ${K(e.table)} (${e.index.columns.map((n) => Yn(t, e.table, n)).join(", ")});`, $n = (e) => `DROP INDEX IF EXISTS ${G(e.index)};`, er = (e) => `DROP INDEX ${K(e.index)} ON ${K(e.table)};`, tr = (e) => `DROP INDEX IF EXISTS ${Z(e.index)} ON ${Z(e.table)};`, nr = (e, t) => `ALTER TABLE ${t(e.from)} RENAME TO ${t(e.to)};`, rr = (e) => {
|
|
2208
2209
|
let t = (e) => e.replace(/'/g, "''");
|
|
2209
2210
|
return `EXEC sp_rename N'${t(e.from)}', N'${t(e.to)}';`;
|
|
2210
|
-
},
|
|
2211
|
+
}, ir = (e) => `ALTER INDEX ${G(e.from)} RENAME TO ${G(e.to)};`, ar = (e) => `ALTER TABLE ${K(e.table)} RENAME INDEX ${K(e.from)} TO ${K(e.to)};`, or = (e) => {
|
|
2211
2212
|
let t = (e) => e.replace(/'/g, "''");
|
|
2212
2213
|
return `EXEC sp_rename N'${t(e.table)}.${t(e.from)}', N'${t(e.to)}', N'INDEX';`;
|
|
2213
|
-
},
|
|
2214
|
+
}, sr = (e) => {
|
|
2214
2215
|
let t = (e) => e.replace(/'/g, "''"), n = `CREATE ${e.index.unique ? "UNIQUE " : ""}INDEX ${Z(e.index.name)} ON ${Z(e.table)} (${e.index.columns.map(Z).join(", ")})`;
|
|
2215
2216
|
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)}');`;
|
|
2216
|
-
},
|
|
2217
|
+
}, cr = (e, t, n) => {
|
|
2217
2218
|
let r = n.find((t) => t.tableName === e);
|
|
2218
2219
|
if (!r) return [];
|
|
2219
2220
|
let i = [];
|
|
@@ -2222,13 +2223,13 @@ BEGIN
|
|
|
2222
2223
|
t && t.type === "text" && !t.generatedAs && i.push(`ALTER TABLE ${Z(e)} ALTER COLUMN ${Z(n)} NVARCHAR(450) ${t.nullable ? "NULL" : "NOT NULL"};`);
|
|
2223
2224
|
}
|
|
2224
2225
|
return i;
|
|
2225
|
-
},
|
|
2226
|
+
}, lr = (e) => `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(`${e.table}_${e.column}_key`)} UNIQUE (${G(e.column)});`, ur = (e, t) => `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(`${e.table}_${e.column}_key`)} UNIQUE (${Yn(t, e.table, e.column)});`, dr = (e) => {
|
|
2226
2227
|
let t = e.fields.map((e) => G(e)).join(", ");
|
|
2227
2228
|
return `ALTER TABLE ${G(e.table)} ADD CONSTRAINT ${G(e.name)} UNIQUE (${t});`;
|
|
2228
|
-
},
|
|
2229
|
-
let n = e.fields.map((n) =>
|
|
2229
|
+
}, fr = (e, t) => {
|
|
2230
|
+
let n = e.fields.map((n) => Yn(t, e.table, n)).join(", ");
|
|
2230
2231
|
return `ALTER TABLE ${K(e.table)} ADD CONSTRAINT ${K(e.name)} UNIQUE (${n});`;
|
|
2231
|
-
},
|
|
2232
|
+
}, pr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(e.name)};`, mr = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(e.name)};`, hr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_key`)};`, gr = (e) => `ALTER TABLE ${K(e.table)} DROP INDEX ${K(`${e.table}_${e.column}_key`)};`, _r = (e, t) => {
|
|
2232
2233
|
let n = [], r = t(e.table), i = t(e.column), a = t(e.targetTable), o = t(e.targetColumn);
|
|
2233
2234
|
if (e.orphanPolicy) {
|
|
2234
2235
|
let t = `${i} IS NOT NULL AND ${i} NOT IN (SELECT ${o} FROM ${a})`;
|
|
@@ -2246,11 +2247,11 @@ BEGIN
|
|
|
2246
2247
|
setNull: "SET NULL",
|
|
2247
2248
|
noAction: "NO ACTION"
|
|
2248
2249
|
}[e.onDelete]}`), n.push(s.join(" ") + ";"), n;
|
|
2249
|
-
},
|
|
2250
|
+
}, vr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_fkey`)};`, yr = (e) => `ALTER TABLE ${K(e.table)} DROP FOREIGN KEY ${K(`${e.table}_${e.column}_fkey`)};`, br = (e, t) => {
|
|
2250
2251
|
let n = e.values.map((e) => `'${e.replace(/'/g, "''")}'`).join(", ");
|
|
2251
2252
|
return `ALTER TABLE ${t(e.table)} ADD CONSTRAINT ${t(`${e.table}_${e.column}_check`)} CHECK (${t(e.column)} IN (${n}));`;
|
|
2252
|
-
},
|
|
2253
|
-
let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ?
|
|
2253
|
+
}, xr = (e) => `ALTER TABLE ${G(e.table)} DROP CONSTRAINT IF EXISTS ${G(`${e.table}_${e.column}_check`)};`, Sr = (e) => `ALTER TABLE ${K(e.table)} DROP CHECK ${K(`${e.table}_${e.column}_check`)};`, Cr = (e, t, n, r) => {
|
|
2254
|
+
let i = e.column, a = r === "mariadb", o = a ? K : r === "mssql" ? Z : G, s = a ? gn(i) : r === "mssql" ? Hn(i) : r === "sqlite" ? Ln(i) : mn(i), c = r === "mssql" ? "ADD" : "ADD COLUMN", l = (e) => a ? Tn(e, i) : r === "mssql" ? Y(e, "SYSUTCDATETIME()") : r === "sqlite" ? Y(e, "CURRENT_TIMESTAMP") : Dn(e, i), u = J(i, r);
|
|
2254
2255
|
if (u) {
|
|
2255
2256
|
let t = r === "mssql" ? `${o(i.name)} ${u}` : `${o(i.name)} ${s} ${u}`;
|
|
2256
2257
|
return {
|
|
@@ -2278,7 +2279,7 @@ BEGIN
|
|
|
2278
2279
|
post: f ? [f] : []
|
|
2279
2280
|
};
|
|
2280
2281
|
return d?.sql && (p.backfillKind = "sql", p.backfillSql = d.sql), d?.js && (p.backfillKind = "js", p.backfillJs = d.js), d?.batchSize !== void 0 && (p.batchSize = d.batchSize), d?.sleepMs !== void 0 && (p.sleepMs = d.sleepMs), p;
|
|
2281
|
-
},
|
|
2282
|
+
}, wr = (e) => {
|
|
2282
2283
|
let t = new Map(e.map((e) => [e.tableName, e]));
|
|
2283
2284
|
return (e, n) => {
|
|
2284
2285
|
let r = t.get(e);
|
|
@@ -2303,21 +2304,21 @@ BEGIN
|
|
|
2303
2304
|
})), p.mapError((e) => {
|
|
2304
2305
|
let r = b(`applier: statement failed (op=${n})`, t, e, 400).trim();
|
|
2305
2306
|
return Object.assign(e, { message: r });
|
|
2306
|
-
}), p.map(() => void 0)), $ = (e, t, n) => p.forEach(t, (t) => Q(e, t, n), { discard: !0 }),
|
|
2307
|
-
let r = process.hrtime.bigint(), i =
|
|
2307
|
+
}), p.map(() => void 0)), $ = (e, t, n) => p.forEach(t, (t) => Q(e, t, n), { discard: !0 }), Tr = (e, t, n) => p.gen(function* () {
|
|
2308
|
+
let r = process.hrtime.bigint(), i = wr(n.declared), a = t.op;
|
|
2308
2309
|
switch (a.kind) {
|
|
2309
2310
|
case "create-table": {
|
|
2310
2311
|
let t = yield* e.onDialectOrElse({
|
|
2311
|
-
mysql: () => p.succeed(
|
|
2312
|
-
mssql: () => p.succeed(
|
|
2313
|
-
sqlite: () => p.succeed(
|
|
2314
|
-
orElse: () => p.succeed(
|
|
2312
|
+
mysql: () => p.succeed(Pn(a)),
|
|
2313
|
+
mssql: () => p.succeed(Wn(a)),
|
|
2314
|
+
sqlite: () => p.succeed(zn(a)),
|
|
2315
|
+
orElse: () => p.succeed(An(a))
|
|
2315
2316
|
});
|
|
2316
2317
|
for (let n of t) yield* Q(e, n, a.kind);
|
|
2317
2318
|
break;
|
|
2318
2319
|
}
|
|
2319
2320
|
case "drop-table": {
|
|
2320
|
-
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ?
|
|
2321
|
+
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString(), r = (e) => t ? qn(a, n, e) : Kn(a, e);
|
|
2321
2322
|
yield* e.onDialectOrElse({
|
|
2322
2323
|
mysql: () => Q(e, r(K), a.kind),
|
|
2323
2324
|
orElse: () => Q(e, r(G), a.kind)
|
|
@@ -2327,85 +2328,85 @@ BEGIN
|
|
|
2327
2328
|
case "drop-column": {
|
|
2328
2329
|
let t = process.env.VOLTRO_SOFT_DROP === "1", n = (/* @__PURE__ */ new Date()).toISOString();
|
|
2329
2330
|
yield* e.onDialectOrElse({
|
|
2330
|
-
mysql: () => Q(e, t ?
|
|
2331
|
-
orElse: () => Q(e, t ?
|
|
2331
|
+
mysql: () => Q(e, t ? bn(a, n, K) : vn(a), a.kind),
|
|
2332
|
+
orElse: () => Q(e, t ? bn(a, n, G) : _n(a, G), a.kind)
|
|
2332
2333
|
});
|
|
2333
2334
|
break;
|
|
2334
2335
|
}
|
|
2335
2336
|
case "rename-column":
|
|
2336
2337
|
yield* e.onDialectOrElse({
|
|
2337
|
-
mysql: () => Q(e,
|
|
2338
|
+
mysql: () => Q(e, yn(a, K), a.kind),
|
|
2338
2339
|
mssql: () => Q(e, `EXEC sp_rename N'${a.table.replace(/'/g, "''")}.${a.from.replace(/'/g, "''")}', N'${a.to.replace(/'/g, "''")}', 'COLUMN';`, a.kind),
|
|
2339
|
-
orElse: () => Q(e,
|
|
2340
|
+
orElse: () => Q(e, yn(a, G), a.kind)
|
|
2340
2341
|
});
|
|
2341
2342
|
break;
|
|
2342
2343
|
case "add-index":
|
|
2343
2344
|
yield* e.onDialectOrElse({
|
|
2344
|
-
mysql: () => Q(e,
|
|
2345
|
-
mssql: () => $(e, [...
|
|
2346
|
-
orElse: () => Q(e,
|
|
2345
|
+
mysql: () => Q(e, Qn(a, n.declared), a.kind),
|
|
2346
|
+
mssql: () => $(e, [...cr(a.table, a.index.columns, n.declared), sr(a)], a.kind),
|
|
2347
|
+
orElse: () => Q(e, Zn(a, t.classification === "online-required"), a.kind)
|
|
2347
2348
|
});
|
|
2348
2349
|
break;
|
|
2349
2350
|
case "drop-index":
|
|
2350
2351
|
yield* e.onDialectOrElse({
|
|
2351
|
-
mysql: () => Q(e,
|
|
2352
|
-
mssql: () => Q(e,
|
|
2353
|
-
orElse: () => Q(e,
|
|
2352
|
+
mysql: () => Q(e, er(a), a.kind),
|
|
2353
|
+
mssql: () => Q(e, tr(a), a.kind),
|
|
2354
|
+
orElse: () => Q(e, $n(a), a.kind)
|
|
2354
2355
|
});
|
|
2355
2356
|
break;
|
|
2356
2357
|
case "rename-table":
|
|
2357
2358
|
yield* e.onDialectOrElse({
|
|
2358
|
-
mysql: () => Q(e,
|
|
2359
|
-
mssql: () => Q(e,
|
|
2360
|
-
orElse: () => Q(e,
|
|
2359
|
+
mysql: () => Q(e, nr(a, K), a.kind),
|
|
2360
|
+
mssql: () => Q(e, rr(a), a.kind),
|
|
2361
|
+
orElse: () => Q(e, nr(a, G), a.kind)
|
|
2361
2362
|
});
|
|
2362
2363
|
break;
|
|
2363
2364
|
case "rename-index":
|
|
2364
2365
|
yield* e.onDialectOrElse({
|
|
2365
|
-
mysql: () => Q(e,
|
|
2366
|
-
mssql: () => Q(e,
|
|
2367
|
-
orElse: () => Q(e,
|
|
2366
|
+
mysql: () => Q(e, ar(a), a.kind),
|
|
2367
|
+
mssql: () => Q(e, or(a), a.kind),
|
|
2368
|
+
orElse: () => Q(e, ir(a), a.kind)
|
|
2368
2369
|
});
|
|
2369
2370
|
break;
|
|
2370
2371
|
case "add-unique":
|
|
2371
2372
|
yield* e.onDialectOrElse({
|
|
2372
|
-
mysql: () => Q(e,
|
|
2373
|
+
mysql: () => Q(e, ur(a, n.declared), a.kind),
|
|
2373
2374
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2374
|
-
mssql: () => $(e, [...
|
|
2375
|
-
orElse: () => Q(e,
|
|
2375
|
+
mssql: () => $(e, [...cr(a.table, [a.column], n.declared), lr(a)], a.kind),
|
|
2376
|
+
orElse: () => Q(e, lr(a), a.kind)
|
|
2376
2377
|
});
|
|
2377
2378
|
break;
|
|
2378
2379
|
case "drop-unique":
|
|
2379
2380
|
yield* e.onDialectOrElse({
|
|
2380
|
-
mysql: () => Q(e,
|
|
2381
|
+
mysql: () => Q(e, gr(a), a.kind),
|
|
2381
2382
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2382
|
-
orElse: () => Q(e,
|
|
2383
|
+
orElse: () => Q(e, hr(a), a.kind)
|
|
2383
2384
|
});
|
|
2384
2385
|
break;
|
|
2385
2386
|
case "add-unique-composite":
|
|
2386
2387
|
yield* e.onDialectOrElse({
|
|
2387
|
-
mysql: () => Q(e,
|
|
2388
|
+
mysql: () => Q(e, fr(a, n.declared), a.kind),
|
|
2388
2389
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2389
|
-
mssql: () => $(e, [...
|
|
2390
|
-
orElse: () => Q(e,
|
|
2390
|
+
mssql: () => $(e, [...cr(a.table, a.fields, n.declared), dr(a)], a.kind),
|
|
2391
|
+
orElse: () => Q(e, dr(a), a.kind)
|
|
2391
2392
|
});
|
|
2392
2393
|
break;
|
|
2393
2394
|
case "drop-unique-composite":
|
|
2394
2395
|
yield* e.onDialectOrElse({
|
|
2395
|
-
mysql: () => Q(e,
|
|
2396
|
+
mysql: () => Q(e, mr(a), a.kind),
|
|
2396
2397
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2397
|
-
orElse: () => Q(e,
|
|
2398
|
+
orElse: () => Q(e, pr(a), a.kind)
|
|
2398
2399
|
});
|
|
2399
2400
|
break;
|
|
2400
2401
|
case "add-foreign-key":
|
|
2401
2402
|
yield* e.onDialectOrElse({
|
|
2402
|
-
mysql: () => $(e,
|
|
2403
|
+
mysql: () => $(e, _r(a, K), a.kind),
|
|
2403
2404
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2404
|
-
orElse: () => $(e,
|
|
2405
|
+
orElse: () => $(e, _r(a, G), a.kind)
|
|
2405
2406
|
});
|
|
2406
2407
|
break;
|
|
2407
2408
|
case "add-column": {
|
|
2408
|
-
let n =
|
|
2409
|
+
let n = Cr(a, t, i, yield* e.onDialectOrElse({
|
|
2409
2410
|
mysql: () => p.succeed("mariadb"),
|
|
2410
2411
|
mssql: () => p.succeed("mssql"),
|
|
2411
2412
|
sqlite: () => p.succeed("sqlite"),
|
|
@@ -2451,37 +2452,37 @@ BEGIN
|
|
|
2451
2452
|
yield* e.onDialectOrElse({
|
|
2452
2453
|
mysql: () => {
|
|
2453
2454
|
let t = q(n.declared, a.table, a.column);
|
|
2454
|
-
return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${
|
|
2455
|
+
return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${wn(t, a.column, a.toNullable)};`, a.kind) : p.die(/* @__PURE__ */ Error(`alter-column-nullability on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
|
|
2455
2456
|
},
|
|
2456
2457
|
mssql: () => {
|
|
2457
2458
|
let t = q(n.declared, a.table, a.column);
|
|
2458
|
-
return t ? Q(e,
|
|
2459
|
+
return t ? Q(e, Bn(t, a.column, a.table, a.toNullable), a.kind) : p.die(/* @__PURE__ */ Error(`alter-column-nullability on mssql needs the declared column '${a.table}.${a.column}'.`));
|
|
2459
2460
|
},
|
|
2460
2461
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2461
2462
|
orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} ${a.toNullable ? "DROP NOT NULL" : "SET NOT NULL"};`, a.kind)
|
|
2462
2463
|
});
|
|
2463
2464
|
break;
|
|
2464
2465
|
case "alter-column-default": {
|
|
2465
|
-
let t =
|
|
2466
|
+
let t = Cn(n.declared, a.table, a.column);
|
|
2466
2467
|
yield* e.onDialectOrElse({
|
|
2467
|
-
mysql: () => Q(e,
|
|
2468
|
-
mssql: () => Q(e,
|
|
2468
|
+
mysql: () => Q(e, xn(a, K, (e) => Tn(e, t)), a.kind),
|
|
2469
|
+
mssql: () => Q(e, Vn(a), a.kind),
|
|
2469
2470
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2470
|
-
orElse: () => Q(e,
|
|
2471
|
+
orElse: () => Q(e, xn(a, G, (e) => Dn(e, t)), a.kind)
|
|
2471
2472
|
});
|
|
2472
2473
|
break;
|
|
2473
2474
|
}
|
|
2474
2475
|
case "alter-column-type": {
|
|
2475
|
-
let r =
|
|
2476
|
+
let r = mn(Cn(n.declared, a.table, a.column) ?? { type: a.to }), i = a.using ? ` USING ${a.using}` : "";
|
|
2476
2477
|
if (t.classification !== "online-required") {
|
|
2477
2478
|
yield* e.onDialectOrElse({
|
|
2478
2479
|
mysql: () => {
|
|
2479
2480
|
let t = q(n.declared, a.table, a.column);
|
|
2480
|
-
return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${
|
|
2481
|
+
return t ? Q(e, `ALTER TABLE ${K(a.table)} MODIFY COLUMN ${wn(t, a.column)};`, a.kind) : p.die(/* @__PURE__ */ Error(`alter-column-type on mariadb needs the declared column '${a.table}.${a.column}' (to render MODIFY COLUMN); it was not in ctx.declared.`));
|
|
2481
2482
|
},
|
|
2482
2483
|
mssql: () => {
|
|
2483
2484
|
let t = q(n.declared, a.table, a.column);
|
|
2484
|
-
return t ? Q(e,
|
|
2485
|
+
return t ? Q(e, Bn(t, a.column, a.table), a.kind) : p.die(/* @__PURE__ */ Error(`alter-column-type on mssql needs the declared column '${a.table}.${a.column}'.`));
|
|
2485
2486
|
},
|
|
2486
2487
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2487
2488
|
orElse: () => Q(e, `ALTER TABLE ${G(a.table)} ALTER COLUMN ${G(a.column)} TYPE ${r}${i};`, a.kind)
|
|
@@ -2505,23 +2506,23 @@ BEGIN
|
|
|
2505
2506
|
}
|
|
2506
2507
|
case "drop-foreign-key":
|
|
2507
2508
|
yield* e.onDialectOrElse({
|
|
2508
|
-
mysql: () => Q(e,
|
|
2509
|
+
mysql: () => Q(e, yr(a), a.kind),
|
|
2509
2510
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2510
|
-
orElse: () => Q(e,
|
|
2511
|
+
orElse: () => Q(e, vr(a), a.kind)
|
|
2511
2512
|
});
|
|
2512
2513
|
break;
|
|
2513
2514
|
case "add-check":
|
|
2514
2515
|
yield* e.onDialectOrElse({
|
|
2515
|
-
mysql: () => Q(e,
|
|
2516
|
+
mysql: () => Q(e, br(a, K), a.kind),
|
|
2516
2517
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2517
|
-
orElse: () => Q(e,
|
|
2518
|
+
orElse: () => Q(e, br(a, G), a.kind)
|
|
2518
2519
|
});
|
|
2519
2520
|
break;
|
|
2520
2521
|
case "drop-check":
|
|
2521
2522
|
yield* e.onDialectOrElse({
|
|
2522
|
-
mysql: () => Q(e,
|
|
2523
|
+
mysql: () => Q(e, Sr(a), a.kind),
|
|
2523
2524
|
sqlite: () => $(e, X(a.table, n.declared), a.kind),
|
|
2524
|
-
orElse: () => Q(e,
|
|
2525
|
+
orElse: () => Q(e, xr(a), a.kind)
|
|
2525
2526
|
});
|
|
2526
2527
|
break;
|
|
2527
2528
|
}
|
|
@@ -2530,7 +2531,7 @@ BEGIN
|
|
|
2530
2531
|
status: "applied",
|
|
2531
2532
|
durationMs: Number((process.hrtime.bigint() - r) / 1000000n)
|
|
2532
2533
|
};
|
|
2533
|
-
}),
|
|
2534
|
+
}), Er = (e, t, n) => p.gen(function* () {
|
|
2534
2535
|
let r = t.operations.filter((e) => e.blocked);
|
|
2535
2536
|
if (r.length > 0) return yield* p.die(/* @__PURE__ */ Error(`applyPlan: refusing to execute — ${r.length} blocked operations. Run \`voltro db plan\` to see the fixes.`));
|
|
2536
2537
|
yield* E(e);
|
|
@@ -2543,9 +2544,9 @@ BEGIN
|
|
|
2543
2544
|
}), i = r ? t.operations.filter((e) => e.classification !== "online-required") : [], o = r ? t.operations.filter((e) => e.classification === "online-required") : t.operations;
|
|
2544
2545
|
i.length > 0 && (yield* e.withTransaction(p.gen(function* () {
|
|
2545
2546
|
let e = yield* h.SqlClient;
|
|
2546
|
-
for (let t of i) a.push(yield*
|
|
2547
|
+
for (let t of i) a.push(yield* Tr(e, t, n));
|
|
2547
2548
|
})));
|
|
2548
|
-
for (let t of o) a.push(yield*
|
|
2549
|
+
for (let t of o) a.push(yield* Tr(e, t, n));
|
|
2549
2550
|
} finally {
|
|
2550
2551
|
yield* D(e).pipe(p.orDie);
|
|
2551
2552
|
}
|
|
@@ -2554,7 +2555,7 @@ BEGIN
|
|
|
2554
2555
|
let e = o.operations.slice(0, 10).map((e) => ` - ${e.op.kind} ${"table" in e.op ? e.op.table : ""}${"column" in e.op ? `.${String(e.op.column)}` : ""}`).join("\n");
|
|
2555
2556
|
return yield* p.die(/* @__PURE__ */ Error(`applyPlan: the migration did not converge. ${t.operations.length} operation(s) were executed without error, but re-planning against the live schema still finds ${o.operations.length}:\n${e}${o.operations.length > 10 ? `\n … and ${o.operations.length - 10} more` : ""}\nNo fingerprint was recorded — recording one would make the next boot report "schema up to date" for a schema that was never applied. This is a framework bug; the schema is unchanged and safe.\nTwo 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.`));
|
|
2556
2557
|
}
|
|
2557
|
-
let s = a.filter((e) => e.status === "applied").length, c = Date.now() - i, l = `plan_${Date.now().toString(36)}`, u = (/* @__PURE__ */ new Date()).toISOString(), d = yield*
|
|
2558
|
+
let s = a.filter((e) => e.status === "applied").length, c = Date.now() - i, l = `plan_${Date.now().toString(36)}`, u = (/* @__PURE__ */ new Date()).toISOString(), d = yield* fn(e, u);
|
|
2558
2559
|
return yield* e`
|
|
2559
2560
|
INSERT INTO ${e("_voltro_migration_plans")}
|
|
2560
2561
|
(${e("id")}, ${e("fingerprint")}, ${e("liveFingerprint")}, ${e("operations")},
|
|
@@ -2576,19 +2577,19 @@ BEGIN
|
|
|
2576
2577
|
source: n.source,
|
|
2577
2578
|
...n.notes ? { notes: n.notes } : {}
|
|
2578
2579
|
};
|
|
2579
|
-
}),
|
|
2580
|
+
}), Dr = (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"), Or = (e) => e`
|
|
2580
2581
|
SELECT fingerprint
|
|
2581
2582
|
FROM _voltro_migration_plans
|
|
2582
2583
|
ORDER BY ${e("appliedAt")} DESC
|
|
2583
2584
|
LIMIT 1
|
|
2584
|
-
`.pipe(p.map((e) => e.length > 0 ? e[0].fingerprint : void 0), p.catchAll(() => p.succeed(void 0))),
|
|
2585
|
+
`.pipe(p.map((e) => e.length > 0 ? e[0].fingerprint : void 0), p.catchAll(() => p.succeed(void 0))), kr = (e) => e.onDialectOrElse({
|
|
2585
2586
|
pg: () => "postgres",
|
|
2586
2587
|
mysql: () => "mysql",
|
|
2587
2588
|
mssql: () => "mssql",
|
|
2588
2589
|
sqlite: () => "sqlite",
|
|
2589
2590
|
orElse: () => "sqlite"
|
|
2590
|
-
}),
|
|
2591
|
-
let n = P(I(t,
|
|
2591
|
+
}), Ar = (e, t) => p.gen(function* () {
|
|
2592
|
+
let n = P(I(t, kr(e))), r = yield* Or(e);
|
|
2592
2593
|
return r === n ? {
|
|
2593
2594
|
kind: "up-to-date",
|
|
2594
2595
|
fingerprint: n
|
|
@@ -2597,23 +2598,23 @@ BEGIN
|
|
|
2597
2598
|
expected: n,
|
|
2598
2599
|
...r === void 0 ? {} : { actual: r }
|
|
2599
2600
|
};
|
|
2600
|
-
}),
|
|
2601
|
+
}), jr = [
|
|
2601
2602
|
"pgeagertest_",
|
|
2602
2603
|
"mig_e2e_",
|
|
2603
2604
|
"mig_test_",
|
|
2604
2605
|
"mysqleagertest_",
|
|
2605
2606
|
"mssqleagertest_",
|
|
2606
2607
|
"sqliteeagertest_"
|
|
2607
|
-
],
|
|
2608
|
+
], Mr = (e) => jr.some((t) => e.startsWith(t)), Nr = (e, t) => p.gen(function* () {
|
|
2608
2609
|
if (process.env.VOLTRO_TEST_FIXTURE_GC === "off") return [];
|
|
2609
|
-
let n = t.filter((e) =>
|
|
2610
|
+
let n = t.filter((e) => Mr(e.name)).map((e) => e.name);
|
|
2610
2611
|
if (n.length === 0) return [];
|
|
2611
2612
|
for (let t of n) yield* e.unsafe(`DROP TABLE IF EXISTS "${t}" CASCADE`).pipe(p.catchAll(() => p.void));
|
|
2612
2613
|
return n;
|
|
2613
|
-
}),
|
|
2614
|
+
}), Pr = () => {
|
|
2614
2615
|
let e = (process.env.VOLTRO_DB_IGNORE_TABLES ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
|
|
2615
2616
|
return e.length > 0 ? { ignoreTables: e } : {};
|
|
2616
|
-
},
|
|
2617
|
+
}, Fr = (e) => {
|
|
2617
2618
|
if (e === void 0) return;
|
|
2618
2619
|
let t = e.trim();
|
|
2619
2620
|
if (t === "") return;
|
|
@@ -2623,43 +2624,43 @@ BEGIN
|
|
|
2623
2624
|
kind: "tables",
|
|
2624
2625
|
tables: new Set(n)
|
|
2625
2626
|
} : void 0;
|
|
2626
|
-
},
|
|
2627
|
+
}, Ir = (e) => typeof e.table == "string" ? e.table : void 0, Lr = (e, t = { kind: "all" }) => ({
|
|
2627
2628
|
...e,
|
|
2628
2629
|
operations: e.operations.map((e) => {
|
|
2629
2630
|
if (!e.blocked || e.classification !== "lossy") return e;
|
|
2630
2631
|
if (t?.kind === "tables") {
|
|
2631
|
-
let n =
|
|
2632
|
+
let n = Ir(e.op);
|
|
2632
2633
|
if (n === void 0 || !t.tables.has(n)) return e;
|
|
2633
2634
|
}
|
|
2634
2635
|
let { blocked: n, ...r } = e;
|
|
2635
2636
|
return r;
|
|
2636
2637
|
})
|
|
2637
|
-
}),
|
|
2638
|
+
}), Rr = (e, t, n) => t === "postgres" ? ft(e, n).pipe(p.flatMap((e) => {
|
|
2638
2639
|
let t = pt(e);
|
|
2639
2640
|
return t === void 0 ? p.void : p.logWarning(`auto-migrate: ${t}`).pipe(p.annotateLogs({ scope: "voltro:migrate" }));
|
|
2640
|
-
}), p.catchAll(() => p.void)) : p.void,
|
|
2641
|
-
let r =
|
|
2641
|
+
}), p.catchAll(() => p.void)) : p.void, zr = (e, t, n) => p.gen(function* () {
|
|
2642
|
+
let r = kr(e), i = t;
|
|
2642
2643
|
if (process.env.VOLTRO_MIGRATE_FORCE !== "1") {
|
|
2643
2644
|
let t = P(I(i, r));
|
|
2644
|
-
if ((yield*
|
|
2645
|
+
if ((yield* Or(e)) === t) return yield* Rr(e, r, i), {
|
|
2645
2646
|
kind: "up-to-date",
|
|
2646
2647
|
fingerprint: t
|
|
2647
2648
|
};
|
|
2648
2649
|
}
|
|
2649
|
-
let a = yield* U(e), o = yield*
|
|
2650
|
+
let a = yield* U(e), o = yield* Nr(e, a.tables);
|
|
2650
2651
|
o.length > 0 && (yield* p.logInfo(`auto-migrate: reaped ${o.length} test-fixture leftover(s)`).pipe(p.annotateLogs({
|
|
2651
2652
|
scope: "voltro:migrate",
|
|
2652
2653
|
count: o.length
|
|
2653
2654
|
})), a = yield* U(e));
|
|
2654
|
-
let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !s(e.name) || c.has(e.name)), u =
|
|
2655
|
+
let c = new Set(t.map((e) => e.tableName)), l = (e) => e.filter((e) => !s(e.name) || c.has(e.name)), u = qt({
|
|
2655
2656
|
declared: i,
|
|
2656
2657
|
live: { tables: l(a.tables) },
|
|
2657
2658
|
dialect: r,
|
|
2658
|
-
...
|
|
2659
|
+
...Pr()
|
|
2659
2660
|
});
|
|
2660
2661
|
if (u.summary.blocked > 0) {
|
|
2661
|
-
let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t =
|
|
2662
|
-
if (t === void 0 || !e || (u =
|
|
2662
|
+
let e = u.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy"), t = Fr(process.env.VOLTRO_DESTRUCTIVE_OK);
|
|
2663
|
+
if (t === void 0 || !e || (u = Lr(u, t), u.operations.some((e) => e.blocked))) return {
|
|
2663
2664
|
kind: "refused-blocked",
|
|
2664
2665
|
plan: u
|
|
2665
2666
|
};
|
|
@@ -2669,27 +2670,27 @@ BEGIN
|
|
|
2669
2670
|
fingerprint: u.toFingerprint
|
|
2670
2671
|
} : {
|
|
2671
2672
|
kind: "applied",
|
|
2672
|
-
applied: yield*
|
|
2673
|
+
applied: yield* Er(e, u, {
|
|
2673
2674
|
declared: t,
|
|
2674
2675
|
appliedBy: n.appliedBy,
|
|
2675
2676
|
environment: n.environment === "prod" ? "dev" : n.environment,
|
|
2676
2677
|
source: "auto-diff",
|
|
2677
2678
|
replan: (e) => p.gen(function* () {
|
|
2678
2679
|
let t = yield* U(e);
|
|
2679
|
-
return
|
|
2680
|
+
return qt({
|
|
2680
2681
|
declared: i,
|
|
2681
2682
|
live: { tables: l(t.tables) },
|
|
2682
2683
|
dialect: r,
|
|
2683
|
-
...
|
|
2684
|
+
...Pr()
|
|
2684
2685
|
});
|
|
2685
2686
|
})
|
|
2686
2687
|
}),
|
|
2687
2688
|
plan: u
|
|
2688
2689
|
};
|
|
2689
|
-
}),
|
|
2690
|
+
}), Br = (e, t, n) => process.env.VOLTRO_AUTO_MIGRATE === "0" ? p.succeed({
|
|
2690
2691
|
kind: "skipped",
|
|
2691
2692
|
reason: "VOLTRO_AUTO_MIGRATE=0"
|
|
2692
|
-
}) : n.environment === "prod" ?
|
|
2693
|
+
}) : n.environment === "prod" ? Ar(e, t) : zr(e, t, n), Vr = (e, t) => {
|
|
2693
2694
|
switch (e.kind) {
|
|
2694
2695
|
case "skipped": return `auto-migrate: skipped (${e.reason})`;
|
|
2695
2696
|
case "up-to-date": return `auto-migrate: schema up to date (${t}, fingerprint=${F(e.fingerprint)})`;
|
|
@@ -2699,7 +2700,7 @@ BEGIN
|
|
|
2699
2700
|
}
|
|
2700
2701
|
case "prod-mismatch": return `auto-migrate: SCHEMA FINGERPRINT MISMATCH — declared=${F(e.expected)}` + (e.actual ? ` live=${F(e.actual)}` : " live=<no _voltro_migration_plans row>") + ". Run `voltro db apply --plan plan.json` from the deploy pipeline before serving.";
|
|
2701
2702
|
case "refused-blocked": {
|
|
2702
|
-
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` +
|
|
2703
|
+
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` + Dr(e.plan), c = [""];
|
|
2703
2704
|
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) {
|
|
2704
2705
|
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
|
|
2705
2706
|
for (let r of e.plan.operations) {
|
|
@@ -2716,7 +2717,7 @@ BEGIN
|
|
|
2716
2717
|
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");
|
|
2717
2718
|
}
|
|
2718
2719
|
}
|
|
2719
|
-
},
|
|
2720
|
+
}, Hr = /* @__PURE__ */ new Set([
|
|
2720
2721
|
"node_modules",
|
|
2721
2722
|
"dist",
|
|
2722
2723
|
"build",
|
|
@@ -2725,11 +2726,11 @@ BEGIN
|
|
|
2725
2726
|
".next",
|
|
2726
2727
|
".git",
|
|
2727
2728
|
".framework"
|
|
2728
|
-
]),
|
|
2729
|
+
]), Ur = async (e) => {
|
|
2729
2730
|
let t = [], n = async (e) => {
|
|
2730
2731
|
let r = await _.readdir(e, { withFileTypes: !0 }).catch(() => []);
|
|
2731
2732
|
for (let i of r) {
|
|
2732
|
-
if (
|
|
2733
|
+
if (Hr.has(i.name)) continue;
|
|
2733
2734
|
let r = v(e, i.name);
|
|
2734
2735
|
i.isDirectory() ? await n(r) : i.isFile() && o.test(i.name) && t.push(r);
|
|
2735
2736
|
}
|
|
@@ -2738,7 +2739,7 @@ BEGIN
|
|
|
2738
2739
|
let n = e.split("/").pop() ?? e, r = t.split("/").pop() ?? t;
|
|
2739
2740
|
return n.localeCompare(r);
|
|
2740
2741
|
});
|
|
2741
|
-
},
|
|
2742
|
+
}, Wr = async (e) => {
|
|
2742
2743
|
let t = [];
|
|
2743
2744
|
for (let n of e) {
|
|
2744
2745
|
let e = (await import(y(n).href)).default;
|
|
@@ -2752,11 +2753,11 @@ BEGIN
|
|
|
2752
2753
|
});
|
|
2753
2754
|
}
|
|
2754
2755
|
return t;
|
|
2755
|
-
},
|
|
2756
|
+
}, Gr = (e) => e`
|
|
2756
2757
|
SELECT ${e("id")}
|
|
2757
2758
|
FROM ${e("_voltro_migration_plans")}
|
|
2758
2759
|
WHERE ${e("source")} = 'file'
|
|
2759
|
-
`.pipe(p.map((e) => e.map((e) => e.id)), p.catchAll(() => p.succeed([]))),
|
|
2760
|
+
`.pipe(p.map((e) => e.map((e) => e.id)), p.catchAll(() => p.succeed([]))), Kr = class extends Error {
|
|
2760
2761
|
migrationId;
|
|
2761
2762
|
file;
|
|
2762
2763
|
cause;
|
|
@@ -2764,7 +2765,7 @@ BEGIN
|
|
|
2764
2765
|
constructor(e, t, n) {
|
|
2765
2766
|
super(`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";
|
|
2766
2767
|
}
|
|
2767
|
-
},
|
|
2768
|
+
}, qr = (e, t, n, r) => p.gen(function* () {
|
|
2768
2769
|
let i = Date.now(), a = (/* @__PURE__ */ new Date()).toISOString(), o = {
|
|
2769
2770
|
sql: e,
|
|
2770
2771
|
log: {
|
|
@@ -2785,7 +2786,7 @@ BEGIN
|
|
|
2785
2786
|
});
|
|
2786
2787
|
let c = Date.now() - i;
|
|
2787
2788
|
!p.isEffect(s) && c < 2 && (yield* p.logWarning(`migration ${t.migration.id}: up() resolved in ${c}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(p.annotateLogs({ scope: `migrations:file:${t.migration.id}` })));
|
|
2788
|
-
let l = yield*
|
|
2789
|
+
let l = yield* fn(e, a);
|
|
2789
2790
|
return yield* e`
|
|
2790
2791
|
INSERT INTO ${e("_voltro_migration_plans")}
|
|
2791
2792
|
(${e("id")}, ${e("fingerprint")}, ${e("operations")},
|
|
@@ -2798,10 +2799,10 @@ BEGIN
|
|
|
2798
2799
|
}])},
|
|
2799
2800
|
${r}, ${n}, ${"file"},
|
|
2800
2801
|
${c}, ${l}, ${t.migration.description})
|
|
2801
|
-
`.pipe(p.mapError((e) => new
|
|
2802
|
-
}),
|
|
2802
|
+
`.pipe(p.mapError((e) => new Kr(t.migration.id, t.file, e))), { durationMs: c };
|
|
2803
|
+
}), Jr = (e, t) => p.gen(function* () {
|
|
2803
2804
|
let n = yield* p.tryPromise({
|
|
2804
|
-
try: () =>
|
|
2805
|
+
try: () => Ur(v(t, "migrations")),
|
|
2805
2806
|
catch: (e) => e
|
|
2806
2807
|
});
|
|
2807
2808
|
if (n.length === 0) return {
|
|
@@ -2809,20 +2810,20 @@ BEGIN
|
|
|
2809
2810
|
skipped: []
|
|
2810
2811
|
};
|
|
2811
2812
|
let r = yield* p.tryPromise({
|
|
2812
|
-
try: () =>
|
|
2813
|
+
try: () => Wr(n),
|
|
2813
2814
|
catch: (e) => e
|
|
2814
2815
|
});
|
|
2815
2816
|
if (r.length === 0) return {
|
|
2816
2817
|
pending: [],
|
|
2817
2818
|
skipped: []
|
|
2818
2819
|
};
|
|
2819
|
-
let i = new Set(yield*
|
|
2820
|
+
let i = new Set(yield* Gr(e));
|
|
2820
2821
|
return {
|
|
2821
2822
|
pending: r.filter((e) => !i.has(e.migration.id)),
|
|
2822
2823
|
skipped: r.filter((e) => i.has(e.migration.id)).map((e) => e.migration.id)
|
|
2823
2824
|
};
|
|
2824
|
-
}),
|
|
2825
|
-
let { pending: n, skipped: r } = yield*
|
|
2825
|
+
}), Yr = (e, t) => Jr(e, t).pipe(p.map((e) => e.pending.map((e) => e.migration.id))), Xr = (e, t) => p.gen(function* () {
|
|
2826
|
+
let { pending: n, skipped: r } = yield* Jr(e, t.projectRoot);
|
|
2826
2827
|
if (n.length === 0) return {
|
|
2827
2828
|
applied: [],
|
|
2828
2829
|
skipped: r
|
|
@@ -2836,7 +2837,7 @@ BEGIN
|
|
|
2836
2837
|
id: r.migration.id,
|
|
2837
2838
|
file: r.file
|
|
2838
2839
|
}));
|
|
2839
|
-
let { durationMs: n } = yield*
|
|
2840
|
+
let { durationMs: n } = yield* qr(e, r, t.env, t.appliedBy);
|
|
2840
2841
|
i.push({
|
|
2841
2842
|
id: r.migration.id,
|
|
2842
2843
|
durationMs: n
|
|
@@ -2853,18 +2854,18 @@ BEGIN
|
|
|
2853
2854
|
applied: i,
|
|
2854
2855
|
skipped: r
|
|
2855
2856
|
};
|
|
2856
|
-
}),
|
|
2857
|
+
}), Zr = (e, t) => e`
|
|
2857
2858
|
SELECT ${e("id")}
|
|
2858
2859
|
FROM ${e("_voltro_migration_plans")}
|
|
2859
2860
|
WHERE ${e("id")} = ${t} AND ${e("source")} = 'file'
|
|
2860
2861
|
LIMIT 1
|
|
2861
|
-
`,
|
|
2862
|
-
if (!(yield*
|
|
2862
|
+
`, Qr = (e, t) => p.gen(function* () {
|
|
2863
|
+
if (!(yield* Zr(e, t.id))[0]) return yield* p.fail(/* @__PURE__ */ Error(`rollback: ${t.id} not found in _voltro_migration_plans (file source)`));
|
|
2863
2864
|
let n = yield* p.tryPromise({
|
|
2864
|
-
try: () =>
|
|
2865
|
+
try: () => Ur(v(t.projectRoot, "migrations")),
|
|
2865
2866
|
catch: (e) => e
|
|
2866
2867
|
}), r = (yield* p.tryPromise({
|
|
2867
|
-
try: () =>
|
|
2868
|
+
try: () => Wr(n),
|
|
2868
2869
|
catch: (e) => e
|
|
2869
2870
|
})).find((e) => e.migration.id === t.id);
|
|
2870
2871
|
if (!r) return yield* p.fail(/* @__PURE__ */ Error(`rollback: file for migration ${t.id} not found on disk under ${t.projectRoot}/migrations/`));
|
|
@@ -2897,7 +2898,7 @@ BEGIN
|
|
|
2897
2898
|
} finally {
|
|
2898
2899
|
yield* D(e).pipe(p.orDie);
|
|
2899
2900
|
}
|
|
2900
|
-
}),
|
|
2901
|
+
}), $r = (e) => p.gen(function* () {
|
|
2901
2902
|
let t = yield* h.SqlClient, n = yield* t`
|
|
2902
2903
|
SELECT id, fingerprint, appliedAt FROM _voltro_migration_plans
|
|
2903
2904
|
WHERE source = 'auto-diff'
|
|
@@ -2942,7 +2943,7 @@ BEGIN
|
|
|
2942
2943
|
snapshotFingerprint: e.fingerprint,
|
|
2943
2944
|
snapshotId: i
|
|
2944
2945
|
};
|
|
2945
|
-
}),
|
|
2946
|
+
}), ei = { safe: !0 }, ti = (e) => {
|
|
2946
2947
|
switch (e.kind) {
|
|
2947
2948
|
case "drop-column": return {
|
|
2948
2949
|
safe: !1,
|
|
@@ -2969,7 +2970,7 @@ BEGIN
|
|
|
2969
2970
|
reason: `old instances read/write "${e.table}"."${e.column}" as ${e.from}; the new ${e.to} type can reject their writes or fail to decode their reads`,
|
|
2970
2971
|
remedy: "add a new column of the target type + backfill + dual-write, cut code over, then drop the old column in a LATER deploy"
|
|
2971
2972
|
};
|
|
2972
|
-
case "alter-column-nullability": return e.toNullable ?
|
|
2973
|
+
case "alter-column-nullability": return e.toNullable ? ei : {
|
|
2973
2974
|
safe: !1,
|
|
2974
2975
|
reason: `old instances may INSERT "${e.table}" without (or with NULL in) "${e.column}", which the new NOT NULL rejects`,
|
|
2975
2976
|
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)`
|
|
@@ -2999,12 +3000,12 @@ BEGIN
|
|
|
2999
3000
|
case "drop-unique":
|
|
3000
3001
|
case "drop-unique-composite":
|
|
3001
3002
|
case "drop-foreign-key":
|
|
3002
|
-
case "drop-check": return
|
|
3003
|
+
case "drop-check": return ei;
|
|
3003
3004
|
}
|
|
3004
|
-
},
|
|
3005
|
+
}, ni = (e) => {
|
|
3005
3006
|
let t = [];
|
|
3006
3007
|
for (let n of e) {
|
|
3007
|
-
let e =
|
|
3008
|
+
let e = ti(n.op);
|
|
3008
3009
|
e.safe || t.push({
|
|
3009
3010
|
op: n,
|
|
3010
3011
|
reason: e.reason,
|
|
@@ -3012,7 +3013,7 @@ BEGIN
|
|
|
3012
3013
|
});
|
|
3013
3014
|
}
|
|
3014
3015
|
return t;
|
|
3015
|
-
},
|
|
3016
|
+
}, ri = (e) => {
|
|
3016
3017
|
if (!e.enabled || e.unsafeCount === 0) return {
|
|
3017
3018
|
refuse: !1,
|
|
3018
3019
|
warnForced: !1,
|
|
@@ -3028,10 +3029,10 @@ BEGIN
|
|
|
3028
3029
|
warnForced: !1,
|
|
3029
3030
|
message: `${t}. Old instances would break against the new schema mid-rollout. Split into expand → deploy → contract (see the ⚠ list above), deploy with no overlap (maintenance window / scale-to-zero), or pass --force to override.`
|
|
3030
3031
|
};
|
|
3031
|
-
},
|
|
3032
|
+
}, ii = (e, ...t) => ({
|
|
3032
3033
|
_tag: "RawSqlFragment",
|
|
3033
3034
|
strings: [...e],
|
|
3034
3035
|
values: [...t]
|
|
3035
|
-
}),
|
|
3036
|
+
}), ai = (e) => typeof e == "object" && !!e && e._tag === "RawSqlFragment";
|
|
3036
3037
|
//#endregion
|
|
3037
|
-
export { O as DEFAULT_CDC_CHANNEL, o as FILE_MIGRATION_PATTERN,
|
|
3038
|
+
export { O as DEFAULT_CDC_CHANNEL, o as FILE_MIGRATION_PATTERN, Kr as FileMigrationLedgerError, k as REACTIVE_TRIGGER_PREFIX, ne as VOLTRO_MIGRATION_LOCK_KEY, E as acquireMigrationLock, et as applyNamespacedSchema, Er as applyPlan, Je as applySchema, ri as assessRollingDeployGate, en as chunkTables, ti as classifyRollingDeploySafety, I as declaredSnapshot, xe as defaultArrayClause, be as defaultClause, M as defaultJsonClause, Vr as describeOutcome, Fr as destructiveScope, ft as detectReactiveTriggerDrift, _n as emitDropColumnDdl, vn as emitDropColumnDdlMysql, qe as emitFrameworkBootstrapSql, Ge as emitNamespaceProvisionDdl, Ke as emitNamespacedSchemaSql, We as emitSchemaSql, P as fingerprintSchema, pt as formatReactiveTriggerDrift, Pr as ignoreTablesFromEnv, U as introspectSchema, r as isFileMigration, ai as isRawSqlFragment, Yt as mapPgType, c as migration, N as numericIdSql, Jt as parseEnumCheck, Yr as pendingFileMigrationIds, qt as planMigrations, tt as provisionTenantNamespace, Fe as reactiveTriggerRepairSql, D as releaseMigrationLock, Nn as renderColumnMysql, On as renderColumnPg, Qr as rollbackFileBasedMigration, ni as rollingDeployUnsafeOps, Xr as runFileBasedMigrations, nt as runFrameworkBootstrap, $e as runMigrate, Br as runPlannedMigrations, F as shortFingerprint, ct as snapshotColumn, ii as sql, j as sqlType, $r as squashMigrationPlans, Lr as unblockLossy, ge as withMigrationLock };
|