okmodel 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/dist/adapters/pg/bunsql-extra.d.ts +5 -5
- package/dist/adapters/pg/bunsql.d.ts +6 -2
- package/dist/adapters/pg/nodepostgres.d.ts +16 -1
- package/dist/adapters/pg/postgres-extra.d.ts +3 -17
- package/dist/adapters/pg/postgresjs.d.ts +2 -1
- package/dist/contracts/driver.d.ts +3 -2
- package/dist/contracts/error.d.ts +1 -1
- package/dist/dialects/pg/errors.d.ts +2 -0
- package/dist/dialects/pg/ext/fuzzystrmatch.js +1 -1
- package/dist/dialects/pg/ext/hstore.js +1 -1
- package/dist/dialects/pg/ext/ltree.js +1 -1
- package/dist/dialects/pg/ext/pgcrypto.js +1 -1
- package/dist/dialects/pg/ext/unaccent.js +1 -1
- package/dist/dialects/pg/filters.d.ts +2 -2
- package/dist/dialects/pg/fn/index.js +1 -1
- package/dist/dialects/pg/index.js +3 -3
- package/dist/dialects/pg/introspect.d.ts +12 -0
- package/dist/dialects/pg/view/index.js +2 -2
- package/dist/runtime/param-limit.d.ts +20 -0
- package/dist/runtime/pg/bun.js +3 -3
- package/dist/runtime/pg/neon.js +3 -3
- package/dist/runtime/pg/pg.js +3 -3
- package/dist/runtime/pg/pglite.js +2 -2
- package/dist/runtime/pg/postgresjs.js +10 -10
- package/dist/runtime/tenancy/index.js +1 -1
- package/dist/runtime/traits/index.js +2 -2
- package/dist/runtime/validate/index.js +2 -2
- package/dist/runtime/write.d.ts +1 -1
- package/dist/shared/{5kyb3tqx.js → 1h5h1rf5.js} +1 -1
- package/dist/shared/{4vbf83xx.js → 2vcnpf0n.js} +1 -1
- package/dist/shared/{8n688yjg.js → 3ap5hxvj.js} +2 -1
- package/dist/shared/{wvtjg5m3.js → 3d7a80fq.js} +1 -1
- package/dist/shared/{bphrgwz9.js → 3dr444ny.js} +57 -78
- package/dist/shared/{yvabyg9k.js → 3vvpcphd.js} +7 -6
- package/dist/shared/{760ppr76.js → 4a3mmhhe.js} +2 -2
- package/dist/shared/{90sg0w5a.js → 4pkz5nvw.js} +65 -10
- package/dist/shared/{mazpbcdj.js → 4te76xc5.js} +1 -1
- package/dist/shared/{xwhdcrm4.js → 60y4ahmw.js} +1 -1
- package/dist/shared/{9dtgn1z2.js → 63qjmhnp.js} +100 -17
- package/dist/shared/{s7he5e5d.js → 67w3kn71.js} +1 -1
- package/dist/shared/{n306gqkd.js → 6vfvsdkt.js} +9 -7
- package/dist/shared/{jpybhf98.js → 6xqvesa5.js} +1 -1
- package/dist/shared/{n5whk3mt.js → 8gdbty5v.js} +8 -8
- package/dist/shared/{ccsmhv9r.js → 8ma6drzr.js} +194 -31
- package/dist/shared/{3456242y.js → 8p2bgye0.js} +110 -18
- package/dist/shared/{ebhz8vh6.js → 8qwqrxed.js} +11 -3
- package/dist/shared/{ss2kv2rs.js → 8v7vzpgt.js} +10 -7
- package/dist/shared/{8qzkd9f3.js → ak61ye1f.js} +3 -3
- package/dist/shared/{6nae0spm.js → bdekbvmt.js} +69 -7
- package/dist/shared/{tw1nvvfj.js → bxjq6xqv.js} +2 -2
- package/dist/shared/{rbxt795q.js → c7dqd3gk.js} +81 -41
- package/dist/shared/ddh72ym5.js +20 -0
- package/dist/shared/e1c55v04.js +10 -0
- package/dist/shared/{8jesqsrk.js → ekhq3ytz.js} +1 -1
- package/dist/shared/{7ba5h6pb.js → esy4dyxe.js} +5 -5
- package/dist/shared/{gcefca6p.js → f9t9g54z.js} +22 -9
- package/dist/shared/fkjne6gx.js +8 -0
- package/dist/shared/{ds229x4r.js → fne90dvz.js} +4 -1
- package/dist/shared/{cexb7z6b.js → gr9sn4za.js} +1 -1
- package/dist/shared/{mvmm3xpb.js → gzgfsspx.js} +1 -1
- package/dist/shared/{fdsz3w80.js → hgt69zjf.js} +2 -2
- package/dist/shared/{dd5pmnky.js → jvxcp1qk.js} +70 -86
- package/dist/shared/{yybhre6n.js → k73e8n9d.js} +3 -3
- package/dist/shared/{mgaq2sd3.js → kzgrcy8s.js} +8 -7
- package/dist/shared/{myk8fswx.js → mz48rs74.js} +14 -3
- package/dist/shared/{62b603gr.js → n6je5b28.js} +10 -23
- package/dist/shared/{2szgv6yj.js → ns35jqz0.js} +71 -45
- package/dist/shared/{xtsydxjg.js → nstwgzn8.js} +1 -1
- package/dist/shared/{stfa9xcw.js → py2zrrm6.js} +7 -6
- package/dist/shared/{9dr2qnx7.js → qqm3ze6q.js} +1 -1
- package/dist/shared/{cf8zdz5p.js → rcjm0yn7.js} +27 -34
- package/dist/shared/{ckz05z15.js → rged92v6.js} +7 -4
- package/dist/shared/{qvwwp1mp.js → rw4tpcd0.js} +30 -21
- package/dist/shared/{bsek72fg.js → s5qe47a6.js} +3 -0
- package/dist/shared/{1d9q9cv2.js → smxzjz60.js} +2 -2
- package/dist/shared/{c3mvnq7a.js → th5rnaxw.js} +1 -1
- package/dist/shared/{1mxm04fy.js → tyqapcgk.js} +71 -8
- package/dist/shared/{zdqf8k5d.js → vsna85qf.js} +1 -1
- package/dist/shared/{63qtkrca.js → vy47ryqa.js} +55 -5
- package/dist/shared/{xv8qj97g.js → wbdh9qbg.js} +3 -1
- package/dist/shared/{2zdxkt7b.js → wp7y8q3y.js} +41 -9
- package/dist/shared/{pg4ezgyf.js → xbd9xs6p.js} +2 -2
- package/dist/shared/{npdftanb.js → xbvz446k.js} +16 -13
- package/dist/shared/{aksb89mn.js → y6tfjk9q.js} +2 -2
- package/dist/shared/{3bb7wsqt.js → ycnft340.js} +1 -1
- package/dist/shared/{z7s6fpxv.js → ymenf259.js} +1 -1
- package/dist/shared/{71n0jmhc.js → ysdw2fg3.js} +10 -2
- package/dist/shared/{xqacq37x.js → zecrwdk9.js} +1 -1
- package/dist/shared/{3t6kw83m.js → zm2rzqba.js} +2 -1
- package/dist/tooling/cli.js +122 -44
- package/dist/tooling/driver-run.js +107 -24
- package/dist/tooling/github/comment.d.ts +8 -2
- package/dist/tooling/migrate/apply.d.ts +17 -2
- package/dist/tooling/migrate/drift.d.ts +12 -0
- package/dist/tooling/migrate/driver-url.d.ts +17 -0
- package/dist/tooling/migrate/index.js +9 -7
- package/dist/tooling/migrate/policy.d.ts +17 -5
- package/dist/tooling/migrate/pooler-probe.d.ts +23 -0
- package/dist/tooling/migrate/pull.d.ts +3 -0
- package/dist/tooling/migrate/runner.d.ts +24 -1
- package/dist/tooling/shared/{0j0jtse1.js → 09a6vsys.js} +1 -1
- package/dist/tooling/shared/{68tf18v4.js → 0v9ptnxp.js} +8 -8
- package/dist/tooling/shared/{qartgazh.js → 0wtzps9p.js} +6 -6
- package/dist/tooling/shared/{1800eymw.js → 0yhf1db4.js} +6 -6
- package/dist/tooling/shared/{s6qha57m.js → 19msgrsc.js} +2 -2
- package/dist/tooling/shared/{3yn79q5m.js → 1fwfm5m3.js} +1 -1
- package/dist/tooling/shared/{hfq3n3bd.js → 2jdn09e2.js} +55 -5
- package/dist/tooling/shared/{v6j1ep6w.js → 2qrte2ct.js} +5 -5
- package/dist/tooling/shared/{yb4kd19s.js → 2v4nwnkb.js} +1 -1
- package/dist/tooling/shared/{ezqn88nj.js → 33z39trp.js} +106 -23
- package/dist/tooling/shared/{0r05zhyq.js → 353vnw9z.js} +5 -5
- package/dist/tooling/shared/{m4hhb8aa.js → 390kry9g.js} +2 -2
- package/dist/tooling/shared/{rcywj2w8.js → 3f6etb9z.js} +18 -31
- package/dist/tooling/shared/{9wsnsvbf.js → 3t2cqmsx.js} +1 -1
- package/dist/tooling/shared/{5zrzffnk.js → 4dzvjtpy.js} +1 -1
- package/dist/tooling/shared/{am04v8na.js → 4ec0nxvw.js} +10 -10
- package/dist/tooling/shared/{04svnxxj.js → 4tg2bn41.js} +59 -78
- package/dist/tooling/shared/{829fjxyw.js → 5rah55z0.js} +2 -2
- package/dist/tooling/shared/{c0xevn1h.js → 804w1t69.js} +4 -4
- package/dist/tooling/shared/{dhatassp.js → 8g0m0rvd.js} +6 -6
- package/dist/tooling/shared/{zx3v9phv.js → 8msbtw5s.js} +1 -1
- package/dist/tooling/shared/{7pxncnzs.js → 8t22h3h7.js} +2 -2
- package/dist/tooling/shared/{wbwq1jsa.js → 91c59b7b.js} +2 -2
- package/dist/tooling/shared/{a2xe04bm.js → adk9k6va.js} +1 -1
- package/dist/tooling/shared/{w17sj05d.js → ajjd5cwz.js} +2 -2
- package/dist/tooling/shared/{35zemrmf.js → angjck01.js} +1 -1
- package/dist/tooling/shared/{jsjjz875.js → asnnc3v5.js} +1 -1
- package/dist/tooling/shared/{5bmksndh.js → bj1kyqc8.js} +2 -2
- package/dist/tooling/shared/{kbqnrs1x.js → bt3tjemb.js} +11 -3
- package/dist/tooling/shared/{vwr2y833.js → chk2bh4f.js} +2 -2
- package/dist/tooling/shared/{ybdew6j7.js → ckq4z5ax.js} +5 -2
- package/dist/tooling/shared/{3rmaz3pq.js → d3rhb24q.js} +1 -1
- package/dist/tooling/shared/{mw5npye0.js → d8q00vxg.js} +4 -4
- package/dist/tooling/shared/{j664qjrt.js → dx188rxs.js} +2 -2
- package/dist/tooling/shared/{8yr7ges1.js → efq6p9df.js} +35 -42
- package/dist/tooling/shared/{yhp829bx.js → en6rwzq0.js} +3 -3
- package/dist/tooling/shared/{f77nnfqy.js → f2r5g0fs.js} +2 -2
- package/dist/tooling/shared/{zs9aymcp.js → f4gep0nk.js} +1 -1
- package/dist/tooling/shared/{kz715295.js → f8a010fm.js} +13 -11
- package/dist/tooling/shared/{w5d89rb4.js → fdsek6pa.js} +1 -1
- package/dist/tooling/shared/fvmrxsd1.js +8 -0
- package/dist/tooling/shared/{jpgmjsx3.js → g3xybeqf.js} +4 -3
- package/dist/tooling/shared/{wezxf3h8.js → gefmpwsa.js} +1 -1
- package/dist/tooling/shared/{jr2nmr81.js → gjj71hfh.js} +23 -20
- package/dist/tooling/shared/{9sfbtwsk.js → jgzt69pa.js} +5 -5
- package/dist/tooling/shared/{a4pzghha.js → jm30k2ca.js} +10 -8
- package/dist/tooling/shared/{shjs0379.js → kayqzpbk.js} +6 -3
- package/dist/tooling/shared/{tcwpjvxe.js → kvw1672d.js} +1 -1
- package/dist/tooling/shared/{stebqyyd.js → mr1kcgpw.js} +3 -3
- package/dist/tooling/shared/{tpssp7ac.js → mwbdf409.js} +1 -1
- package/dist/tooling/shared/{fh07z1dt.js → ns9207v3.js} +1 -1
- package/dist/tooling/shared/{5p8km5jb.js → p6tjv97k.js} +3 -3
- package/dist/tooling/shared/{ytk1tjs0.js → p73evwf0.js} +1 -1
- package/dist/tooling/shared/{8m5znpdt.js → phc1nc4g.js} +1 -1
- package/dist/tooling/shared/{asgr07mp.js → ppybjw50.js} +79 -16
- package/dist/tooling/shared/{t4xveemq.js → qdrn8ghn.js} +5 -4
- package/dist/tooling/shared/rd8h01ta.js +20 -0
- package/dist/tooling/shared/{7aews1zg.js → rwg8y90m.js} +3 -3
- package/dist/tooling/shared/{5x3pf400.js → ry2f3w8p.js} +3 -3
- package/dist/tooling/shared/{m3xt8b1h.js → ryc5sa58.js} +8 -8
- package/dist/tooling/shared/{57btdkgm.js → ss87qxwv.js} +2 -2
- package/dist/tooling/shared/{6vk28rjp.js → vg68k11z.js} +3 -3
- package/dist/tooling/shared/{62fxpc1p.js → vms9dta5.js} +73 -89
- package/dist/tooling/shared/{gqwevek4.js → xchpnbdv.js} +1 -1
- package/dist/tooling/shared/{t6zjeake.js → xn6p01fh.js} +5 -5
- package/dist/tooling/shared/{7b3xp9gc.js → xwr6q618.js} +3 -3
- package/dist/tooling/shared/{yfedr1zb.js → xx3gmq94.js} +1 -1
- package/dist/tooling/shared/{9qr9rkbh.js → y2bd7yfx.js} +21 -13
- package/dist/tooling/shared/{nxq95eb6.js → y4gq9rbe.js} +11 -11
- package/dist/tooling/shared/{76pv6qff.js → y4vwft92.js} +2 -2
- package/dist/tooling/shared/{sjwkt1pg.js → yz68xcmc.js} +1 -1
- package/dist/tooling/testing/factories.d.ts +1 -3
- package/dist/tooling/testing/index.js +1 -1
- package/package.json +2 -1
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
viewGlobalReason,
|
|
6
6
|
viewMentions
|
|
7
|
-
} from "./
|
|
7
|
+
} from "./4a3mmhhe.js";
|
|
8
8
|
import {
|
|
9
9
|
createClient
|
|
10
|
-
} from "./
|
|
10
|
+
} from "./xbvz446k.js";
|
|
11
11
|
import {
|
|
12
12
|
OkmError2
|
|
13
13
|
} from "./52szzakm.js";
|
|
@@ -189,29 +189,30 @@ function bindFactories(host, definitions) {
|
|
|
189
189
|
}
|
|
190
190
|
return bound;
|
|
191
191
|
}
|
|
192
|
-
async function insertRow(host, table, overrides, children, inherited) {
|
|
193
|
-
|
|
192
|
+
async function insertRow(host, table, overrides, children, inherited, creating) {
|
|
193
|
+
const inflight = creating ?? new Set;
|
|
194
|
+
if (inflight.has(table)) {
|
|
194
195
|
throw new OkmError2("invalid", `Factory cycle at ${table}.`, {
|
|
195
196
|
fix: { summary: "A ref() points back at a row that is still being created." }
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
|
-
|
|
199
|
+
inflight.add(table);
|
|
199
200
|
try {
|
|
200
|
-
return await insertPrepared(host, table, overrides, children, inherited);
|
|
201
|
+
return await insertPrepared(host, table, overrides, children, inherited, inflight);
|
|
201
202
|
} finally {
|
|
202
|
-
|
|
203
|
+
inflight.delete(table);
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
|
-
async function insertPrepared(host, table, overrides, children, inherited) {
|
|
206
|
+
async function insertPrepared(host, table, overrides, children, inherited, creating) {
|
|
206
207
|
const facts = requireTable(host, table);
|
|
207
208
|
const defined = host.definitions.get(table)?.(context(host)) ?? {};
|
|
208
209
|
const merged = { ...defined, ...overrides };
|
|
209
|
-
const
|
|
210
|
-
const taken = takeTenant(merged, facts.tenant ?
|
|
210
|
+
const keys = tenantKeyNames(host);
|
|
211
|
+
const taken = takeTenant(merged, facts.tenant ? keys : []);
|
|
211
212
|
const requested = taken.tenant ?? inherited;
|
|
212
213
|
const tenant = facts.tenant ? requested ?? host.rng.uuid() : undefined;
|
|
213
|
-
const resolved = await resolveRefs(host, taken.rest, tenant);
|
|
214
|
-
await fillRequired(host, facts, resolved, tenant);
|
|
214
|
+
const resolved = await resolveRefs(host, taken.rest, tenant, creating);
|
|
215
|
+
await fillRequired(host, facts, resolved, tenant, creating);
|
|
215
216
|
const row = await writeRow(host, facts, resolved, tenant);
|
|
216
217
|
host.cache.set(cacheKey(table, facts.tenant ? tenant : undefined), row);
|
|
217
218
|
host.created.set(table, (host.created.get(table) ?? 0) + 1);
|
|
@@ -227,7 +228,7 @@ async function insertPrepared(host, table, overrides, children, inherited) {
|
|
|
227
228
|
}
|
|
228
229
|
const link = linkFields(host, facts, requireTable(host, child), row);
|
|
229
230
|
for (let index = 0;index < count; index += 1) {
|
|
230
|
-
await insertRow(host, child, link, undefined, tenant);
|
|
231
|
+
await insertRow(host, child, link, undefined, tenant, creating);
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
}
|
|
@@ -276,20 +277,26 @@ function context(host) {
|
|
|
276
277
|
}
|
|
277
278
|
};
|
|
278
279
|
}
|
|
279
|
-
function takeTenant(row,
|
|
280
|
-
if (
|
|
280
|
+
function takeTenant(row, keys) {
|
|
281
|
+
if (keys.length === 0)
|
|
281
282
|
return { tenant: undefined, rest: row };
|
|
282
|
-
const value = row[key];
|
|
283
283
|
const rest = { ...row };
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
284
|
+
let tenant;
|
|
285
|
+
for (const key of keys) {
|
|
286
|
+
if (!Object.hasOwn(rest, key))
|
|
287
|
+
continue;
|
|
288
|
+
const value = rest[key];
|
|
289
|
+
delete rest[key];
|
|
290
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
291
|
+
throw new OkmError2("invalid", `${key} must be a uuid string.`, {
|
|
292
|
+
fix: { summary: `Pass create({ ${key} }) the tenant uuid.` }
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
tenant ??= value;
|
|
289
296
|
}
|
|
290
|
-
return { tenant
|
|
297
|
+
return { tenant, rest };
|
|
291
298
|
}
|
|
292
|
-
async function resolveRefs(host, row, tenant) {
|
|
299
|
+
async function resolveRefs(host, row, tenant, creating) {
|
|
293
300
|
const resolved = {};
|
|
294
301
|
for (const field of Object.keys(row)) {
|
|
295
302
|
const value = row[field];
|
|
@@ -298,18 +305,18 @@ async function resolveRefs(host, row, tenant) {
|
|
|
298
305
|
resolved[field] = value;
|
|
299
306
|
continue;
|
|
300
307
|
}
|
|
301
|
-
resolved[field] = primaryValue(await referenced(host, target, tenant), requireTable(host, target), host
|
|
308
|
+
resolved[field] = primaryValue(await referenced(host, target, tenant, creating), requireTable(host, target), tenantKeyNames(host));
|
|
302
309
|
}
|
|
303
310
|
return resolved;
|
|
304
311
|
}
|
|
305
|
-
async function fillRequired(host, facts, row, tenant) {
|
|
312
|
+
async function fillRequired(host, facts, row, tenant, creating) {
|
|
306
313
|
for (const column of facts.columns) {
|
|
307
314
|
if (!isRequired(column) || Object.hasOwn(row, column.field))
|
|
308
315
|
continue;
|
|
309
316
|
const foreign = facts.foreignKeys.find((key) => key.columns.includes(column.sql));
|
|
310
317
|
if (foreign !== undefined) {
|
|
311
318
|
const target = factsBySql(host, foreign.target);
|
|
312
|
-
const parent = await referenced(host, target.name, tenant);
|
|
319
|
+
const parent = await referenced(host, target.name, tenant, creating);
|
|
313
320
|
assignForeign(host, facts, foreign, parent, row);
|
|
314
321
|
if (Object.hasOwn(row, column.field))
|
|
315
322
|
continue;
|
|
@@ -319,7 +326,7 @@ async function fillRequired(host, facts, row, tenant) {
|
|
|
319
326
|
}
|
|
320
327
|
function assignForeign(host, child, foreign, parent, row) {
|
|
321
328
|
const target = factsBySql(host, foreign.target);
|
|
322
|
-
const
|
|
329
|
+
const keys = new Set(tenantKeyNames(host));
|
|
323
330
|
for (let index = 0;index < foreign.columns.length; index += 1) {
|
|
324
331
|
const childSql = foreign.columns[index];
|
|
325
332
|
const parentSql = foreign.targetColumns[index];
|
|
@@ -327,25 +334,36 @@ function assignForeign(host, child, foreign, parent, row) {
|
|
|
327
334
|
continue;
|
|
328
335
|
const field = fieldOf(child, childSql);
|
|
329
336
|
const source = fieldOf(target, parentSql);
|
|
330
|
-
if (field === undefined || source === undefined || field
|
|
337
|
+
if (field === undefined || source === undefined || keys.has(field))
|
|
331
338
|
continue;
|
|
332
339
|
if (!Object.hasOwn(row, field))
|
|
333
340
|
row[field] = parent[source];
|
|
334
341
|
}
|
|
335
342
|
}
|
|
336
|
-
async function referenced(host, table, tenant) {
|
|
343
|
+
async function referenced(host, table, tenant, creating) {
|
|
337
344
|
const facts = requireTable(host, table);
|
|
338
345
|
const scope = facts.tenant ? tenant : undefined;
|
|
339
346
|
const cached = host.cache.get(cacheKey(table, scope));
|
|
340
347
|
if (cached !== undefined)
|
|
341
348
|
return cached;
|
|
342
|
-
return insertRow(host, table, scope === undefined ? undefined : tenantOverride(host, scope), undefined, scope);
|
|
349
|
+
return insertRow(host, table, scope === undefined ? undefined : tenantOverride(host, scope), undefined, scope, creating);
|
|
343
350
|
}
|
|
344
351
|
function tenantOverride(host, tenant) {
|
|
345
|
-
const
|
|
346
|
-
if (
|
|
352
|
+
const keys = tenantKeyNames(host);
|
|
353
|
+
if (keys.length === 0)
|
|
347
354
|
return;
|
|
348
|
-
|
|
355
|
+
const overrides = {};
|
|
356
|
+
for (const key of keys)
|
|
357
|
+
overrides[key] = tenant;
|
|
358
|
+
return overrides;
|
|
359
|
+
}
|
|
360
|
+
function tenantKeyNames(host) {
|
|
361
|
+
const tenancy = host.schema.tenancy;
|
|
362
|
+
if (tenancy === undefined)
|
|
363
|
+
return [];
|
|
364
|
+
if (tenancy.keys !== undefined && tenancy.keys.length > 0)
|
|
365
|
+
return tenancy.keys;
|
|
366
|
+
return [tenancy.key];
|
|
349
367
|
}
|
|
350
368
|
function linkFields(host, parent, child, row) {
|
|
351
369
|
const many = parent.relations.find((relation) => relation.kind === "many" && relation.table === child.name);
|
|
@@ -366,7 +384,7 @@ function linkFields(host, parent, child, row) {
|
|
|
366
384
|
});
|
|
367
385
|
}
|
|
368
386
|
function paired(host, child, parent, childSql, parentSql, row) {
|
|
369
|
-
const
|
|
387
|
+
const keys = new Set(tenantKeyNames(host));
|
|
370
388
|
const linked = {};
|
|
371
389
|
for (let index = 0;index < childSql.length; index += 1) {
|
|
372
390
|
const childName = childSql[index];
|
|
@@ -375,7 +393,7 @@ function paired(host, child, parent, childSql, parentSql, row) {
|
|
|
375
393
|
continue;
|
|
376
394
|
const field = fieldOf(child, childName);
|
|
377
395
|
const source = fieldOf(parent, parentName);
|
|
378
|
-
if (field === undefined || source === undefined || field
|
|
396
|
+
if (field === undefined || source === undefined || keys.has(field))
|
|
379
397
|
continue;
|
|
380
398
|
linked[field] = row[source];
|
|
381
399
|
}
|
|
@@ -463,8 +481,9 @@ function enumLabels(catalog, dataType) {
|
|
|
463
481
|
}
|
|
464
482
|
return;
|
|
465
483
|
}
|
|
466
|
-
function primaryValue(row, facts,
|
|
467
|
-
const
|
|
484
|
+
function primaryValue(row, facts, tenantKeys) {
|
|
485
|
+
const skip = new Set(tenantKeys);
|
|
486
|
+
const fields = facts.primary.filter((field) => !skip.has(field));
|
|
468
487
|
if (fields.length !== 1) {
|
|
469
488
|
throw new OkmError2("invalid", `ref(${facts.name}) needs a single primary key.`, {
|
|
470
489
|
fix: { summary: "Set the foreign-key columns in the factory." }
|
|
@@ -590,16 +609,18 @@ async function isolation(host) {
|
|
|
590
609
|
}
|
|
591
610
|
}
|
|
592
611
|
async function checkTable(host, facts, tenantA, tenantB) {
|
|
593
|
-
const key = host.schema.tenancy?.key;
|
|
594
|
-
if (key === undefined)
|
|
595
|
-
return;
|
|
596
612
|
const keys = tenantKeys(host);
|
|
613
|
+
if (keys.length === 0)
|
|
614
|
+
return;
|
|
597
615
|
if (host.definitions.size > 0 && !host.definitions.has(facts.name)) {
|
|
598
616
|
throw new OkmError2("invalid", `Factory ${facts.name} is missing.`, {
|
|
599
617
|
fix: { summary: `Add ${facts.name} to factories().` }
|
|
600
618
|
});
|
|
601
619
|
}
|
|
602
|
-
const
|
|
620
|
+
const overrides = {};
|
|
621
|
+
for (const key of keys)
|
|
622
|
+
overrides[key] = tenantB;
|
|
623
|
+
const row = await insertRow(host, facts.name, overrides, undefined, tenantB);
|
|
603
624
|
const where = primaryWhere(facts, row, keys);
|
|
604
625
|
const client = openTenant(host, tenantA);
|
|
605
626
|
const handle = tableHandle2(client, facts.name);
|
|
@@ -762,7 +783,14 @@ async function checkFlips(host, facts, keys, tenantA, tenantB) {
|
|
|
762
783
|
continue;
|
|
763
784
|
values[flipped] = tenantB;
|
|
764
785
|
const client = openTenant(host, values);
|
|
765
|
-
|
|
786
|
+
let stored;
|
|
787
|
+
try {
|
|
788
|
+
stored = await tableHandle2(client, facts.name).insert(data);
|
|
789
|
+
} catch (error) {
|
|
790
|
+
if (error instanceof OkmError2 && error.kind === "foreign_key")
|
|
791
|
+
continue;
|
|
792
|
+
throw error;
|
|
793
|
+
}
|
|
766
794
|
if (!isRow2(stored))
|
|
767
795
|
continue;
|
|
768
796
|
const where = primaryWhere(facts, stored, keys);
|
|
@@ -863,9 +891,8 @@ async function checkView(host, view, keys, tenantA, tenantB) {
|
|
|
863
891
|
for (const tenant of [tenantA, tenantB]) {
|
|
864
892
|
for (const name of sources) {
|
|
865
893
|
const facts = requireFacts(host, name);
|
|
866
|
-
const key = keys[0];
|
|
867
894
|
const overrides = markerFor(view, facts, keys, tenant);
|
|
868
|
-
|
|
895
|
+
for (const key of keys)
|
|
869
896
|
overrides[key] = tenant;
|
|
870
897
|
const row = await insertRow(host, name, overrides, undefined, tenant);
|
|
871
898
|
if (tenant === tenantB)
|
|
@@ -1317,7 +1344,6 @@ async function testing2(schema, options) {
|
|
|
1317
1344
|
facts,
|
|
1318
1345
|
rng: rng(seed),
|
|
1319
1346
|
cache: new Map,
|
|
1320
|
-
creating: new Set,
|
|
1321
1347
|
created: new Map,
|
|
1322
1348
|
definitions: new Map
|
|
1323
1349
|
};
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./jvxcp1qk.js";
|
|
4
4
|
import"./12z7aznj.js";
|
|
5
5
|
import"./n442h54c.js";
|
|
6
6
|
import"./fk9vef30.js";
|
|
7
7
|
import {
|
|
8
8
|
openProject
|
|
9
|
-
} from "./
|
|
9
|
+
} from "./wp7y8q3y.js";
|
|
10
10
|
import {
|
|
11
|
+
driverUrl,
|
|
11
12
|
sessionFailure,
|
|
12
13
|
finishQuiet,
|
|
13
14
|
assertTargetPolicy,
|
|
14
15
|
selectTarget
|
|
15
|
-
} from "./
|
|
16
|
+
} from "./bdekbvmt.js";
|
|
16
17
|
import {
|
|
17
18
|
isExactVersion,
|
|
18
19
|
compareExtensionVersions
|
|
@@ -41,7 +42,7 @@ var TYPES = `
|
|
|
41
42
|
where e.extname = $1
|
|
42
43
|
and d.deptype = 'e'
|
|
43
44
|
and d.classid = 'pg_type'::regclass
|
|
44
|
-
and t.typtype in ('b', 'e', 'd')
|
|
45
|
+
and t.typtype in ('b', 'e', 'd', 'c')
|
|
45
46
|
order by t.typname
|
|
46
47
|
`;
|
|
47
48
|
var FUNCTIONS = `
|
|
@@ -312,7 +313,7 @@ async function extProject(cwd, command, flags) {
|
|
|
312
313
|
const opened = await openProject(cwd);
|
|
313
314
|
const target = selectTarget(opened.config, flags.target);
|
|
314
315
|
assertTargetPolicy(target, "check", flags.allowProtected);
|
|
315
|
-
const pool = open2({ url: target.url, max: 1 });
|
|
316
|
+
const pool = open2({ url: driverUrl(target.url), max: 1 });
|
|
316
317
|
try {
|
|
317
318
|
if (command === "list")
|
|
318
319
|
return formatList(await readExtensions(pool));
|
|
@@ -424,7 +425,7 @@ async function withServer(cwd, flags, body) {
|
|
|
424
425
|
const opened = await openProject(cwd);
|
|
425
426
|
const target = selectTarget(opened.config, flags.target);
|
|
426
427
|
assertTargetPolicy(target, "check", flags.allowProtected);
|
|
427
|
-
const pool = open2({ url: target.url, max: 1 });
|
|
428
|
+
const pool = open2({ url: driverUrl(target.url), max: 1 });
|
|
428
429
|
try {
|
|
429
430
|
return await body(pool);
|
|
430
431
|
} catch (error) {
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
send2,
|
|
6
6
|
reserve,
|
|
7
|
-
|
|
8
|
-
} from "./
|
|
7
|
+
releaseReserved
|
|
8
|
+
} from "./n6je5b28.js";
|
|
9
9
|
import {
|
|
10
10
|
resetSession2,
|
|
11
11
|
refuseWhenLost2
|
|
@@ -62,19 +62,13 @@ function lostQuery(error) {
|
|
|
62
62
|
function socketClosed(error) {
|
|
63
63
|
if (!(error instanceof Error))
|
|
64
64
|
return false;
|
|
65
|
-
if (error.message
|
|
65
|
+
if (bunClosed(error.message))
|
|
66
66
|
return true;
|
|
67
|
-
return error.cause instanceof Error && error.cause.message
|
|
67
|
+
return error.cause instanceof Error && bunClosed(error.cause.message);
|
|
68
68
|
}
|
|
69
|
-
async function listen(sql,
|
|
69
|
+
async function listen(sql, closed, channel, onNotify) {
|
|
70
70
|
if (closed)
|
|
71
71
|
return rejectClosed();
|
|
72
|
-
const pending = parked.splice(0);
|
|
73
|
-
for (const reserved of pending) {
|
|
74
|
-
const done = reserved.release();
|
|
75
|
-
if (done instanceof Promise)
|
|
76
|
-
await done;
|
|
77
|
-
}
|
|
78
72
|
const subscription = await sql.listen(channel, onNotify);
|
|
79
73
|
return async () => {
|
|
80
74
|
await subscription.unlisten();
|
|
@@ -84,7 +78,7 @@ async function checkout(held) {
|
|
|
84
78
|
const { counters, isClosed } = held;
|
|
85
79
|
if (isClosed())
|
|
86
80
|
return rejectClosed();
|
|
87
|
-
const reserved = await
|
|
81
|
+
const reserved = await reserve(held.sql, held.acquireMs, counters);
|
|
88
82
|
counters.reserved += 1;
|
|
89
83
|
const session = new WireSession((text, params) => send2(reserved, text, params), held.notices, isClosed, false, () => {
|
|
90
84
|
counters.reservedBusy += 1;
|
|
@@ -140,20 +134,33 @@ async function checkout(held) {
|
|
|
140
134
|
try {
|
|
141
135
|
if (!lost.on)
|
|
142
136
|
await reset(session, reserved);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
137
|
+
else if (session.depth() > 0 && !reportsClosed(reserved)) {
|
|
138
|
+
await reserved.unsafe("ROLLBACK").catch(() => {
|
|
139
|
+
return;
|
|
140
|
+
});
|
|
141
|
+
session.abandon();
|
|
142
|
+
}
|
|
143
|
+
} catch {
|
|
144
|
+
lost.on = true;
|
|
148
145
|
} finally {
|
|
149
146
|
counters.reserved = Math.max(0, counters.reserved - 1);
|
|
150
147
|
if (lost.on) {
|
|
151
148
|
try {
|
|
152
149
|
reserved.release();
|
|
153
150
|
} catch {}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
151
|
+
if (counters.reserved === 0)
|
|
152
|
+
await flushClosed(held.sql);
|
|
153
|
+
} else {
|
|
154
|
+
try {
|
|
155
|
+
await releaseReserved(reserved);
|
|
156
|
+
} catch {
|
|
157
|
+
try {
|
|
158
|
+
reserved.release();
|
|
159
|
+
} catch {}
|
|
160
|
+
if (counters.reserved === 0)
|
|
161
|
+
await flushClosed(held.sql);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
157
164
|
}
|
|
158
165
|
}
|
|
159
166
|
};
|
|
@@ -161,20 +168,6 @@ async function checkout(held) {
|
|
|
161
168
|
function reportsClosed(reserved) {
|
|
162
169
|
return Reflect.get(reserved, "closed") === true;
|
|
163
170
|
}
|
|
164
|
-
async function takeOpen(held) {
|
|
165
|
-
while (held.parked.length > 0) {
|
|
166
|
-
const next = held.parked.pop();
|
|
167
|
-
if (next === undefined)
|
|
168
|
-
return;
|
|
169
|
-
if (!reportsClosed(next))
|
|
170
|
-
return next;
|
|
171
|
-
try {
|
|
172
|
-
next.release();
|
|
173
|
-
} catch {}
|
|
174
|
-
await flushClosed(held.sql);
|
|
175
|
-
}
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
171
|
async function flushClosed(sql) {
|
|
179
172
|
for (let attempt = 0;attempt < 3; attempt += 1) {
|
|
180
173
|
try {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
assertAuthorDrift2,
|
|
3
|
+
sealDomainChecks2,
|
|
3
4
|
catalogQuery2,
|
|
4
5
|
managedRoleOptions2
|
|
5
|
-
} from "./
|
|
6
|
-
import"./
|
|
7
|
-
import"./
|
|
6
|
+
} from "./4pkz5nvw.js";
|
|
7
|
+
import"./e1c55v04.js";
|
|
8
|
+
import"./mz48rs74.js";
|
|
9
|
+
import"./bdekbvmt.js";
|
|
8
10
|
import"./fk9vef30.js";
|
|
9
11
|
import"./12z7aznj.js";
|
|
10
12
|
export {
|
|
11
13
|
assertAuthorDrift2 as assertAuthorDrift,
|
|
12
14
|
catalogQuery2 as catalogQuery,
|
|
13
|
-
managedRoleOptions2 as managedRoleOptions
|
|
15
|
+
managedRoleOptions2 as managedRoleOptions,
|
|
16
|
+
sealDomainChecks2 as sealDomainChecks
|
|
14
17
|
};
|
|
@@ -6,31 +6,35 @@ import {
|
|
|
6
6
|
} from "./fk9vef30.js";
|
|
7
7
|
import"./n442h54c.js";
|
|
8
8
|
import"./cm3w0ywp.js";
|
|
9
|
-
import"./
|
|
9
|
+
import"./jvxcp1qk.js";
|
|
10
10
|
import {
|
|
11
11
|
watchReserved2
|
|
12
|
-
} from "./
|
|
13
|
-
import {
|
|
14
|
-
ensureMigrationTables2
|
|
15
|
-
} from "./ccsmhv9r.js";
|
|
12
|
+
} from "./3dr444ny.js";
|
|
16
13
|
import {
|
|
17
14
|
sealViews,
|
|
18
15
|
catalogQuery2,
|
|
19
16
|
managedRoleOptions2
|
|
20
|
-
} from "./
|
|
17
|
+
} from "./4pkz5nvw.js";
|
|
18
|
+
import {
|
|
19
|
+
ensureMigrationTables2
|
|
20
|
+
} from "./8ma6drzr.js";
|
|
21
21
|
import {
|
|
22
22
|
assumeRole,
|
|
23
23
|
grantSchema,
|
|
24
|
+
ownSchema,
|
|
24
25
|
assertSchemaUsageLanded,
|
|
25
26
|
catalogsEqual,
|
|
26
27
|
snapshotDifference
|
|
27
|
-
} from "./
|
|
28
|
+
} from "./8p2bgye0.js";
|
|
28
29
|
import {
|
|
29
30
|
roleExists
|
|
30
|
-
} from "./
|
|
31
|
+
} from "./6xqvesa5.js";
|
|
32
|
+
import {
|
|
33
|
+
probeStableBackend
|
|
34
|
+
} from "./e1c55v04.js";
|
|
31
35
|
import {
|
|
32
36
|
introspectSchema
|
|
33
|
-
} from "./
|
|
37
|
+
} from "./mz48rs74.js";
|
|
34
38
|
import {
|
|
35
39
|
projectPath,
|
|
36
40
|
loadSnapshots,
|
|
@@ -44,22 +48,23 @@ import {
|
|
|
44
48
|
hasError,
|
|
45
49
|
lintRefusal,
|
|
46
50
|
openProject
|
|
47
|
-
} from "./
|
|
51
|
+
} from "./wp7y8q3y.js";
|
|
48
52
|
import {
|
|
53
|
+
driverUrl,
|
|
49
54
|
sqlStatements,
|
|
50
55
|
transactionControl,
|
|
51
56
|
canonicalTypeName,
|
|
52
57
|
createdRoleName,
|
|
53
58
|
createRoleOnce,
|
|
59
|
+
changesRole,
|
|
54
60
|
classOf,
|
|
55
61
|
strictestClass,
|
|
56
62
|
planMigration,
|
|
57
63
|
sessionFailure,
|
|
58
64
|
finishQuiet,
|
|
59
65
|
assertDirectConnection,
|
|
60
|
-
assertStableBackend,
|
|
61
66
|
selectTarget
|
|
62
|
-
} from "./
|
|
67
|
+
} from "./bdekbvmt.js";
|
|
63
68
|
import {
|
|
64
69
|
isConnectionLost
|
|
65
70
|
} from "./cnkky55j.js";
|
|
@@ -154,7 +159,7 @@ function retargetSteps(steps, schema, source = "public") {
|
|
|
154
159
|
}));
|
|
155
160
|
}
|
|
156
161
|
async function inCheckTransaction(url, scratch, config, allowPooler, run) {
|
|
157
|
-
const sql = postgres(url, {
|
|
162
|
+
const sql = postgres(driverUrl(url), {
|
|
158
163
|
max: 1,
|
|
159
164
|
connect_timeout: 5,
|
|
160
165
|
idle_timeout: 1,
|
|
@@ -174,7 +179,7 @@ async function inCheckTransaction(url, scratch, config, allowPooler, run) {
|
|
|
174
179
|
let rolledBack = false;
|
|
175
180
|
let xid = "";
|
|
176
181
|
try {
|
|
177
|
-
await
|
|
182
|
+
await probeStableBackend(url, async () => {
|
|
178
183
|
const rows = await reserved.unsafe("select pg_backend_pid()::text as pid");
|
|
179
184
|
const pid = cell(rows[0], "pid");
|
|
180
185
|
return pid ?? "";
|
|
@@ -273,7 +278,7 @@ function closedError() {
|
|
|
273
278
|
return Object.assign(new Error("CONNECTION_CLOSED"), { code: "CONNECTION_CLOSED" });
|
|
274
279
|
}
|
|
275
280
|
async function dropScratch(url, scratch) {
|
|
276
|
-
const sql = postgres(url, {
|
|
281
|
+
const sql = postgres(driverUrl(url), {
|
|
277
282
|
max: 1,
|
|
278
283
|
connect_timeout: 5,
|
|
279
284
|
idle_timeout: 1,
|
|
@@ -322,6 +327,9 @@ async function runSteps(sql, connection, scratch, migrationRole, migration, sess
|
|
|
322
327
|
if (prepared.sql.length === 0)
|
|
323
328
|
continue;
|
|
324
329
|
try {
|
|
330
|
+
if (migrationRole !== undefined && !changesRole(step.sql) && session.setRole !== migrationRole && await roleExists(connection, migrationRole)) {
|
|
331
|
+
await assumeRole(connection, migrationRole, session);
|
|
332
|
+
}
|
|
325
333
|
const created = createdRoleName(step.sql);
|
|
326
334
|
const existed = created !== undefined && await roleExists(connection, created);
|
|
327
335
|
if (step.backfill !== undefined) {
|
|
@@ -332,17 +340,18 @@ async function runSteps(sql, connection, scratch, migrationRole, migration, sess
|
|
|
332
340
|
} else if (!existed) {
|
|
333
341
|
await sql.unsafe(createRoleOnce(prepared.sql.replace(/;\s*$/, "")));
|
|
334
342
|
}
|
|
335
|
-
if (created !== undefined && created === migrationRole) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
await assumeRole(connection, created, session);
|
|
343
|
+
if (created !== undefined && created === migrationRole && !existed) {
|
|
344
|
+
await grantSchema(connection, scratch, created);
|
|
345
|
+
await ownSchema(connection, scratch, created);
|
|
346
|
+
await connection.execute(`grant select, insert, update on okm_meta, okm_history, okm_backfill to ${quoteIdent2(created)}`);
|
|
341
347
|
}
|
|
342
348
|
} catch (error) {
|
|
343
349
|
throw failStep(migration.id, index, error);
|
|
344
350
|
}
|
|
345
351
|
}
|
|
352
|
+
if (migrationRole !== undefined && session.setRole !== migrationRole && await roleExists(connection, migrationRole)) {
|
|
353
|
+
await assumeRole(connection, migrationRole, session);
|
|
354
|
+
}
|
|
346
355
|
}
|
|
347
356
|
function prepareCheckSql(sql) {
|
|
348
357
|
const parts = sqlStatements(sql);
|
|
@@ -54,6 +54,9 @@ function scanLiteral(literal, state) {
|
|
|
54
54
|
for (let index = 0;index < literal.length; index += 1) {
|
|
55
55
|
const char = literal[index] ?? "";
|
|
56
56
|
const code = literal.charCodeAt(index);
|
|
57
|
+
if (char === "\\") {
|
|
58
|
+
fragmentError("A fragment cannot include a backslash.", "Pass the value as an interpolation.");
|
|
59
|
+
}
|
|
57
60
|
if (state.quote !== undefined) {
|
|
58
61
|
if (char !== state.quote)
|
|
59
62
|
continue;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
emitSqlSelect,
|
|
3
3
|
decodeSqlNumber
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./ycnft340.js";
|
|
5
5
|
import {
|
|
6
6
|
refusePrototypeKey
|
|
7
7
|
} from "./a62rb2da.js";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./9a4ae4p8.js";
|
|
11
11
|
import {
|
|
12
12
|
readSelectFragment
|
|
13
|
-
} from "./
|
|
13
|
+
} from "./s5qe47a6.js";
|
|
14
14
|
import {
|
|
15
15
|
emitWhere,
|
|
16
16
|
emitOrder,
|