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