okmodel 0.7.0 → 0.8.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/dist/adapters/capabilities.d.ts +32 -0
- package/dist/adapters/failure.d.ts +1 -1
- package/dist/adapters/pg/bun-sql.d.ts +53 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +1 -1
- package/dist/adapters/pg/bunsql.d.ts +1 -1
- package/dist/adapters/pg/neon-extra.d.ts +18 -0
- package/dist/adapters/pg/neon.d.ts +104 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +1 -1
- package/dist/contracts/error.d.ts +1 -1
- package/dist/dialects/pg/fn/index.d.ts +39 -1
- package/dist/dialects/pg/fn/index.js +118 -26
- package/dist/dialects/pg/index.d.ts +2 -0
- package/dist/dialects/pg/index.js +393 -18
- package/dist/dialects/pg/introspect.d.ts +11 -0
- package/dist/dialects/pg/operators.d.ts +1 -1
- package/dist/dialects/pg/ops/fragment.d.ts +119 -0
- package/dist/dialects/pg/ops/lane.d.ts +49 -0
- package/dist/dialects/pg/view/client.d.ts +14 -6
- package/dist/dialects/pg/view/index.d.ts +73 -1
- package/dist/dialects/pg/view/index.js +156 -5
- package/dist/dialects/pg/view/scratch.d.ts +8 -5
- package/dist/runtime/otel.d.ts +105 -0
- package/dist/runtime/otel.js +97 -0
- package/dist/runtime/pg/bun.js +4 -4
- package/dist/runtime/pg/neon.d.ts +38 -0
- package/dist/runtime/pg/neon.js +64 -0
- package/dist/runtime/pg/pg.js +4 -4
- package/dist/runtime/pg/pglite.js +4 -4
- package/dist/runtime/pg/postgresjs.js +4 -4
- package/dist/runtime/plan.d.ts +1 -1
- package/dist/runtime/sql-fragment.d.ts +43 -0
- package/dist/runtime/tenancy/index.js +10 -10
- package/dist/runtime/topology.d.ts +1 -1
- package/dist/runtime/traits/index.js +15 -16
- package/dist/runtime/types.d.ts +15 -1
- package/dist/runtime/validate/index.js +4 -4
- package/dist/shared/{mtaszv5a.js → 0wrea3jq.js} +102 -4
- package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
- package/dist/shared/{w79hsckn.js → 14x60fbf.js} +5 -5
- package/dist/shared/{ek2wt2dz.js → 16kvjebh.js} +4 -4
- package/dist/shared/{svncdeh5.js → 195pzzzz.js} +8 -8
- package/dist/shared/{gzaveazc.js → 1d9q9cv2.js} +29 -2
- package/dist/shared/{jvd0mqag.js → 3449rcae.js} +5 -5
- package/dist/shared/{14vx95q4.js → 35q0n9tz.js} +7 -7
- package/dist/shared/3bb7wsqt.js +99 -0
- package/dist/shared/{y6njgyda.js → 3t6kw83m.js} +2 -2
- package/dist/shared/{81ebdx9p.js → 4m6hskg8.js} +4 -4
- package/dist/shared/{xhfsfkgk.js → 4vbf83xx.js} +9 -2
- package/dist/shared/{bg3rym3g.js → 63f4ksbz.js} +2 -2
- package/dist/shared/{pt94kz7f.js → 6m78c8ss.js} +1 -1
- package/dist/shared/{5e3tf63j.js → 760ppr76.js} +14 -6
- package/dist/shared/{zm0ptry0.js → 7ghwamrf.js} +1 -1
- package/dist/shared/{xnxsed62.js → 9dr2qnx7.js} +14 -14
- package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
- package/dist/shared/{q5c6ngn3.js → a62rb2da.js} +1 -1
- package/dist/shared/{kb2sdhfb.js → ae4j5f42.js} +17 -1
- package/dist/shared/agsfb86s.js +233 -0
- package/dist/shared/{7k9grvf6.js → b6d6p0zc.js} +5 -5
- package/dist/shared/{tbrvgw6z.js → bah9nbg3.js} +17 -16
- package/dist/shared/{5fe3kbsh.js → bnby0esn.js} +1 -1
- package/dist/shared/bsek72fg.js +225 -0
- package/dist/shared/{1w508jbr.js → bxas03mq.js} +21 -17
- package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
- package/dist/shared/{tsvww22q.js → dpc2r7rb.js} +7 -7
- package/dist/shared/{vb6qfyve.js → e8zyaqvj.js} +2 -2
- package/dist/shared/{hyh73qk6.js → ecn8mfdq.js} +5 -5
- package/dist/shared/{gs74dbj5.js → f4jy1j7x.js} +27 -14
- package/dist/shared/{ttsqgp4p.js → fjpnhqan.js} +2 -2
- package/dist/shared/{xjk7hnn5.js → g5yc06ka.js} +2 -2
- package/dist/shared/{w72kgg4q.js → hfqmpasr.js} +6 -6
- package/dist/shared/{kr0jzbw2.js → hm5f8jby.js} +7 -7
- package/dist/shared/{dkxgzaqd.js → hqpxf4a4.js} +1 -1
- package/dist/shared/{cn957f8d.js → jebgrkeq.js} +3 -3
- package/dist/shared/{wa07eas9.js → jp36k7dp.js} +11 -11
- package/dist/shared/jx2m62cs.js +96 -0
- package/dist/shared/{sfz1ksn6.js → k86n8vq3.js} +2 -2
- package/dist/shared/{67txcrcw.js → kgwp4jdd.js} +4 -4
- package/dist/shared/{8skf0cam.js → kj9d8maq.js} +1 -1
- package/dist/shared/{aytqh5y2.js → m4xff2a6.js} +2 -2
- package/dist/shared/{zp9fmend.js → mfedzr74.js} +4 -4
- package/dist/shared/{ax7qv55k.js → mkrn359n.js} +60 -11
- package/dist/shared/{m6p12kbr.js → mnvjvqyp.js} +10 -10
- package/dist/shared/{1qa0qajz.js → mtw6jz76.js} +1 -1
- package/dist/shared/{1est4ezg.js → n05z9nwz.js} +3 -3
- package/dist/shared/{pbp1ss85.js → n0jmpgj1.js} +2 -2
- package/dist/shared/{ktz42yez.js → n41w4fbz.js} +5 -5
- package/dist/shared/{n816peh1.js → n454kcnw.js} +1 -1
- package/dist/shared/n7kg8mmx.js +61 -0
- package/dist/shared/{g6evj1j3.js → needfe47.js} +1 -1
- package/dist/shared/{2shdbn8q.js → njga14v4.js} +9 -9
- package/dist/shared/{vqrjpcqn.js → nmnsgj7x.js} +1 -1
- package/dist/shared/{b5pftnn2.js → p3xbdcvt.js} +14 -18
- package/dist/shared/{te5as7z7.js → p5nh3r8q.js} +3 -3
- package/dist/shared/{p6qc5gcp.js → pan0370z.js} +6 -6
- package/dist/shared/{79dt02vc.js → q0cqt2sp.js} +1 -1
- package/dist/shared/{5v3xf80k.js → qd9hhd8f.js} +1 -1
- package/dist/shared/{bm22fvzr.js → qfw14tna.js} +2 -2
- package/dist/shared/{9s0ypp87.js → sjk86yrx.js} +1 -1
- package/dist/shared/{3v7t1yrv.js → th3be82n.js} +2 -2
- package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
- package/dist/shared/{vczs8gd4.js → v1wad97q.js} +2 -2
- package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
- package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
- package/dist/shared/{bz84tkzm.js → wcrheftc.js} +2 -2
- package/dist/shared/{ab9gmbwy.js → wvdjznah.js} +5 -5
- package/dist/shared/{7mnme5tn.js → wz2a78mp.js} +1 -1
- package/dist/shared/{9y3mmmh1.js → xfhe73sb.js} +1 -1
- package/dist/shared/{je4axnm8.js → z581d7ny.js} +2 -2
- package/dist/shared/{x933k9a3.js → zbqbmmrp.js} +10 -10
- package/dist/shared/{rs73fca9.js → zgex00fd.js} +6 -6
- package/dist/shared/{jznfax0y.js → zq1he88x.js} +4 -4
- package/dist/tooling/cli.js +26 -13
- package/dist/tooling/driver-run.js +4971 -0
- package/dist/tooling/driver-test.d.ts +36 -0
- package/dist/tooling/migrate/commands.d.ts +2 -2
- package/dist/tooling/migrate/index.js +9 -9
- package/dist/tooling/migrate/project.d.ts +3 -0
- package/dist/tooling/shared/03k6res6.js +210 -0
- package/dist/tooling/shared/08kemxjd.js +10 -0
- package/dist/tooling/shared/2revefqt.js +209 -0
- package/dist/tooling/shared/2wtvc7rw.js +1425 -0
- package/dist/tooling/shared/345tbc2k.js +16 -0
- package/dist/tooling/shared/3m1hkg7z.js +344 -0
- package/dist/tooling/shared/3rrw5w8f.js +81 -0
- package/dist/tooling/shared/3tq8pnb8.js +131 -0
- package/dist/tooling/shared/417zdsk7.js +194 -0
- package/dist/tooling/shared/4d2w25vw.js +40 -0
- package/dist/tooling/shared/54tqkxja.js +51 -0
- package/dist/tooling/shared/5bvw2nev.js +12 -0
- package/dist/tooling/shared/6nyfyw70.js +231 -0
- package/dist/tooling/shared/72fyg4zv.js +160 -0
- package/dist/tooling/shared/733a1tq3.js +38 -0
- package/dist/tooling/shared/7ae7rjmn.js +20 -0
- package/dist/tooling/shared/7kms6fvj.js +20 -0
- package/dist/tooling/shared/8sqrsw3s.js +49 -0
- package/dist/tooling/shared/96ps4g1z.js +32 -0
- package/dist/tooling/shared/9kazs5p6.js +195 -0
- package/dist/tooling/shared/9xzm7hjg.js +38 -0
- package/dist/tooling/shared/a6pp9d12.js +49 -0
- package/dist/tooling/shared/a7q7t4n3.js +22 -0
- package/dist/tooling/shared/aftb2mwr.js +18 -0
- package/dist/tooling/shared/bz2dqhab.js +311 -0
- package/dist/tooling/shared/cmptmb4f.js +12 -0
- package/dist/tooling/shared/ddjtfgnx.js +177 -0
- package/dist/tooling/shared/djydjpqt.js +261 -0
- package/dist/tooling/shared/dw08f3m8.js +9 -0
- package/dist/tooling/shared/dy672fz6.js +16 -0
- package/dist/tooling/shared/dzx85q70.js +66 -0
- package/dist/tooling/shared/ec71zqgt.js +270 -0
- package/dist/tooling/shared/ep8zh3bk.js +6 -0
- package/dist/tooling/shared/f9mphxej.js +3789 -0
- package/dist/tooling/shared/fb9k2qwd.js +89 -0
- package/dist/tooling/shared/g9ad4n80.js +211 -0
- package/dist/tooling/shared/gfvtj6d0.js +94 -0
- package/dist/tooling/shared/gmcf9cxf.js +294 -0
- package/dist/tooling/shared/htnaj77v.js +17 -0
- package/dist/tooling/shared/j9t5s12a.js +7 -0
- package/dist/tooling/shared/jne7b93p.js +42 -0
- package/dist/tooling/shared/ma2340rx.js +118 -0
- package/dist/tooling/shared/mtrqn2hn.js +505 -0
- package/dist/tooling/shared/n4jqhpqz.js +27 -0
- package/dist/tooling/shared/nf7jmhfa.js +20 -0
- package/dist/tooling/shared/p7f08ktn.js +332 -0
- package/dist/tooling/shared/ppnnnvj8.js +13 -0
- package/dist/tooling/shared/pqy21k24.js +312 -0
- package/dist/tooling/shared/pw8fgahx.js +69 -0
- package/dist/tooling/shared/pwsytxm5.js +17 -0
- package/dist/tooling/shared/rf83gr2d.js +94 -0
- package/dist/tooling/shared/rq5kk8j6.js +401 -0
- package/dist/tooling/shared/rs1jb051.js +12 -0
- package/dist/tooling/shared/smn6kz1p.js +157 -0
- package/dist/tooling/shared/spk1jg3r.js +1696 -0
- package/dist/tooling/shared/tn8gay14.js +143 -0
- package/dist/tooling/shared/vraj6d74.js +42 -0
- package/dist/tooling/shared/vs0t6qt8.js +64 -0
- package/dist/tooling/shared/vx86qjv8.js +150 -0
- package/dist/tooling/shared/w7qe8sj1.js +140 -0
- package/dist/tooling/shared/wt7j7nf6.js +15 -0
- package/dist/tooling/shared/wwnekq5n.js +6 -0
- package/dist/tooling/shared/xhrnjch9.js +185 -0
- package/dist/tooling/shared/xjs6zqtc.js +190 -0
- package/dist/tooling/shared/y031jct9.js +16 -0
- package/dist/tooling/shared/y5656f0e.js +233 -0
- package/dist/tooling/shared/yfr8hzhm.js +604 -0
- package/dist/tooling/shared/yk9mp7vb.js +250 -0
- package/dist/tooling/shared/yw30vnq2.js +139 -0
- package/dist/tooling/shared/z8d7ptht.js +618 -0
- package/dist/tooling/shared/zhwnfyb2.js +9 -0
- package/dist/tooling/shared/zvnhh1n0.js +198 -0
- package/dist/tooling/testing/index.js +3 -3
- package/package.json +14 -2
- package/dist/shared/y34a8714.js +0 -150
- package/dist/shared/zy8r7qvz.js +0 -116
- package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
- package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError,
|
|
3
|
+
catalogFileText2
|
|
4
|
+
} from "./f9mphxej.js";
|
|
5
|
+
|
|
6
|
+
// src/runtime/drift.ts
|
|
7
|
+
async function assertCompatible(pool, schema, recordedHash, source, options) {
|
|
8
|
+
const code = await codeHash(schema, source);
|
|
9
|
+
if (code.hash === recordedHash)
|
|
10
|
+
return;
|
|
11
|
+
const { loadOnce } = await import("./htnaj77v.js");
|
|
12
|
+
if (code.artifact !== undefined) {
|
|
13
|
+
const artifact = code.artifact;
|
|
14
|
+
await loadOnce(`text\x00${artifact.hash}`, async () => {
|
|
15
|
+
const { loadTrustedCatalog } = await import("./5bvw2nev.js");
|
|
16
|
+
loadTrustedCatalog(artifact.text, artifact.hash);
|
|
17
|
+
});
|
|
18
|
+
} else if (code.fromFile) {
|
|
19
|
+
const dir = artifactDir(source.catalogDir);
|
|
20
|
+
await loadOnce(`file\x00${dir}\x00${code.hash}`, async () => {
|
|
21
|
+
const text = await readText(`${dir}/catalog.json`);
|
|
22
|
+
if (text === undefined) {
|
|
23
|
+
throw new OkmError("OKM1027", `${dir}/catalog.json is missing.`, {
|
|
24
|
+
fix: {
|
|
25
|
+
summary: "Run okm build so catalog.json matches catalog.hash. connect does not rebuild the catalog from the schema."
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const { loadTrustedCatalog } = await import("./5bvw2nev.js");
|
|
30
|
+
loadTrustedCatalog(text, code.hash);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const { assertDrift } = await import("./rf83gr2d.js");
|
|
34
|
+
await assertDrift(pool, code.hash, recordedHash, options);
|
|
35
|
+
}
|
|
36
|
+
async function codeHash(schema, source) {
|
|
37
|
+
if (source.catalog !== undefined) {
|
|
38
|
+
return { hash: source.catalog.hash, artifact: source.catalog, fromFile: false };
|
|
39
|
+
}
|
|
40
|
+
const listed = await readHashFile(source.catalogDir);
|
|
41
|
+
if (listed !== undefined)
|
|
42
|
+
return { hash: listed, fromFile: true };
|
|
43
|
+
const { catalogHash } = await import("./5bvw2nev.js");
|
|
44
|
+
return { hash: catalogHash(schemaCatalog(schema)), fromFile: false };
|
|
45
|
+
}
|
|
46
|
+
function schemaCatalog(schema) {
|
|
47
|
+
const value = Reflect.get(schema, "catalog");
|
|
48
|
+
if (typeof value !== "object" || value === null || !("objects" in value)) {
|
|
49
|
+
throw new OkmError("OKM1520", "The schema has no catalog to compare.", {
|
|
50
|
+
fix: {
|
|
51
|
+
summary: "Pass the schema() result to connect, or a catalog artifact from okm build."
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
async function readHashFile(catalogDir) {
|
|
58
|
+
const text = await readText(`${artifactDir(catalogDir)}/catalog.hash`);
|
|
59
|
+
if (text === undefined)
|
|
60
|
+
return;
|
|
61
|
+
const hash = catalogFileText2(text, "catalog.hash").trim();
|
|
62
|
+
return hash.length === 0 ? undefined : hash;
|
|
63
|
+
}
|
|
64
|
+
function artifactDir(catalogDir) {
|
|
65
|
+
if (catalogDir !== undefined)
|
|
66
|
+
return catalogDir.replace(/[/\\]+$/, "");
|
|
67
|
+
const cwd = globalThis.process?.cwd?.() ?? ".";
|
|
68
|
+
return `${cwd}/.okm`;
|
|
69
|
+
}
|
|
70
|
+
async function readText(path) {
|
|
71
|
+
const bun = globalThis.Bun;
|
|
72
|
+
if (bun !== undefined) {
|
|
73
|
+
const file = bun.file(path);
|
|
74
|
+
if (!await file.exists())
|
|
75
|
+
return;
|
|
76
|
+
return file.text();
|
|
77
|
+
}
|
|
78
|
+
const loader = globalThis.process?.getBuiltinModule;
|
|
79
|
+
if (loader === undefined)
|
|
80
|
+
return;
|
|
81
|
+
try {
|
|
82
|
+
return await loader("node:fs/promises").readFile(path, "utf8");
|
|
83
|
+
} catch {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export {
|
|
88
|
+
assertCompatible
|
|
89
|
+
};
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DriverError2,
|
|
3
|
+
isConnectionFailure
|
|
4
|
+
} from "./f9mphxej.js";
|
|
5
|
+
import {
|
|
6
|
+
send2,
|
|
7
|
+
reserve2,
|
|
8
|
+
park2
|
|
9
|
+
} from "./xjs6zqtc.js";
|
|
10
|
+
import {
|
|
11
|
+
resetSession2,
|
|
12
|
+
refuseWhenLost2
|
|
13
|
+
} from "./4d2w25vw.js";
|
|
14
|
+
import {
|
|
15
|
+
cursorStream
|
|
16
|
+
} from "./7kms6fvj.js";
|
|
17
|
+
import {
|
|
18
|
+
WireSession
|
|
19
|
+
} from "./yw30vnq2.js";
|
|
20
|
+
import {
|
|
21
|
+
noTimeout
|
|
22
|
+
} from "./rs1jb051.js";
|
|
23
|
+
import {
|
|
24
|
+
rejectClosed,
|
|
25
|
+
runCall
|
|
26
|
+
} from "./xhrnjch9.js";
|
|
27
|
+
|
|
28
|
+
// src/adapters/pg/bunsql-extra.ts
|
|
29
|
+
async function recover(sql, error, text, depth, clientRead, closedDuring, again) {
|
|
30
|
+
if (!lostQuery(error))
|
|
31
|
+
throw error;
|
|
32
|
+
await flushClosed(sql);
|
|
33
|
+
const alreadyDead = closedDuring || socketClosed(error);
|
|
34
|
+
if (!clientRead && !alreadyDead || depth !== 0 || !readStatement(text))
|
|
35
|
+
throw error;
|
|
36
|
+
try {
|
|
37
|
+
return await again();
|
|
38
|
+
} catch (next) {
|
|
39
|
+
if (lostQuery(next))
|
|
40
|
+
await flushClosed(sql);
|
|
41
|
+
throw next;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function drainClosed(sql) {
|
|
45
|
+
return flushClosed(sql).then(() => {
|
|
46
|
+
return;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function readStatement(text) {
|
|
50
|
+
const head = text.trimStart().toLowerCase().replace(/\s+/g, " ");
|
|
51
|
+
if (head.length === 0 || head.includes("pg_advisory"))
|
|
52
|
+
return false;
|
|
53
|
+
if (/\sfor (?:no key update|key share|update|share)\b/.test(head))
|
|
54
|
+
return false;
|
|
55
|
+
return !/^(?:insert|update|delete|refresh|with|create|alter|drop|truncate|grant|revoke|comment|vacuum|analyze|reindex|copy|begin|start|commit|rollback|savepoint|release|set|reset)\b/.test(head);
|
|
56
|
+
}
|
|
57
|
+
function lostQuery(error) {
|
|
58
|
+
return isConnectionFailure(error) || socketClosed(error);
|
|
59
|
+
}
|
|
60
|
+
function socketClosed(error) {
|
|
61
|
+
if (!(error instanceof Error))
|
|
62
|
+
return false;
|
|
63
|
+
if (error.message === "Connection closed")
|
|
64
|
+
return true;
|
|
65
|
+
return error.cause instanceof Error && error.cause.message === "Connection closed";
|
|
66
|
+
}
|
|
67
|
+
async function listen(sql, parked, closed, channel, onNotify) {
|
|
68
|
+
if (closed)
|
|
69
|
+
return rejectClosed();
|
|
70
|
+
const pending = parked.splice(0);
|
|
71
|
+
for (const reserved of pending) {
|
|
72
|
+
const done = reserved.release();
|
|
73
|
+
if (done instanceof Promise)
|
|
74
|
+
await done;
|
|
75
|
+
}
|
|
76
|
+
const subscription = await sql.listen(channel, onNotify);
|
|
77
|
+
return async () => {
|
|
78
|
+
await subscription.unlisten();
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async function checkout(held) {
|
|
82
|
+
const { counters, isClosed } = held;
|
|
83
|
+
if (isClosed())
|
|
84
|
+
return rejectClosed();
|
|
85
|
+
const reserved = await takeOpen(held) ?? await reserve2(held.sql, held.acquireMs, counters);
|
|
86
|
+
counters.reserved += 1;
|
|
87
|
+
const session = new WireSession((text, params) => send2(reserved, text, params), held.notices, isClosed, false, () => {
|
|
88
|
+
counters.reservedBusy += 1;
|
|
89
|
+
}, () => {
|
|
90
|
+
counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
|
|
91
|
+
});
|
|
92
|
+
let lost = { on: false };
|
|
93
|
+
const opened = held.closures();
|
|
94
|
+
const reconnected = () => {
|
|
95
|
+
if (held.closures() === opened)
|
|
96
|
+
return;
|
|
97
|
+
lost.on = true;
|
|
98
|
+
return Promise.reject(new DriverError2("Connection closed", { sqlstate: "08006" }));
|
|
99
|
+
};
|
|
100
|
+
const guard = (run) => refuseWhenLost2(lost, () => run().catch((error) => {
|
|
101
|
+
if (error instanceof Error && bunClosed(error.message)) {
|
|
102
|
+
throw new DriverError2(error.message, { cause: error, sqlstate: "08006" });
|
|
103
|
+
}
|
|
104
|
+
throw error;
|
|
105
|
+
}));
|
|
106
|
+
let released = false;
|
|
107
|
+
return {
|
|
108
|
+
execute: (text, params, options) => {
|
|
109
|
+
const refused = noTimeout(options);
|
|
110
|
+
if (refused !== undefined)
|
|
111
|
+
return refused;
|
|
112
|
+
const gone = reconnected();
|
|
113
|
+
if (gone !== undefined)
|
|
114
|
+
return gone;
|
|
115
|
+
return guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch)));
|
|
116
|
+
},
|
|
117
|
+
batch: (statements, options) => {
|
|
118
|
+
const refused = noTimeout(options);
|
|
119
|
+
if (refused !== undefined)
|
|
120
|
+
return refused;
|
|
121
|
+
const gone = reconnected();
|
|
122
|
+
if (gone !== undefined)
|
|
123
|
+
return gone;
|
|
124
|
+
return guard(() => runCall(isClosed(), options, async (watch) => {
|
|
125
|
+
const { runAtomicBatch } = await import("./3rrw5w8f.js");
|
|
126
|
+
return runAtomicBatch(session, statements, watch);
|
|
127
|
+
}));
|
|
128
|
+
},
|
|
129
|
+
evict() {
|
|
130
|
+
lost.on = true;
|
|
131
|
+
},
|
|
132
|
+
async release() {
|
|
133
|
+
if (released)
|
|
134
|
+
return;
|
|
135
|
+
released = true;
|
|
136
|
+
if (!lost.on && reportsClosed(reserved))
|
|
137
|
+
lost.on = true;
|
|
138
|
+
try {
|
|
139
|
+
if (!lost.on)
|
|
140
|
+
await reset(session, reserved);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (lostQuery(error) || reportsClosed(reserved))
|
|
143
|
+
lost.on = true;
|
|
144
|
+
else
|
|
145
|
+
throw error;
|
|
146
|
+
} finally {
|
|
147
|
+
counters.reserved = Math.max(0, counters.reserved - 1);
|
|
148
|
+
if (lost.on) {
|
|
149
|
+
try {
|
|
150
|
+
reserved.release();
|
|
151
|
+
} catch {}
|
|
152
|
+
await flushClosed(held.sql);
|
|
153
|
+
} else
|
|
154
|
+
await park2(held.parked, reserved);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function reportsClosed(reserved) {
|
|
160
|
+
return Reflect.get(reserved, "closed") === true;
|
|
161
|
+
}
|
|
162
|
+
async function takeOpen(held) {
|
|
163
|
+
while (held.parked.length > 0) {
|
|
164
|
+
const next = held.parked.pop();
|
|
165
|
+
if (next === undefined)
|
|
166
|
+
return;
|
|
167
|
+
if (!reportsClosed(next))
|
|
168
|
+
return next;
|
|
169
|
+
try {
|
|
170
|
+
next.release();
|
|
171
|
+
} catch {}
|
|
172
|
+
await flushClosed(held.sql);
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
async function flushClosed(sql) {
|
|
177
|
+
for (let attempt = 0;attempt < 3; attempt += 1) {
|
|
178
|
+
try {
|
|
179
|
+
await sql.unsafe("select 1");
|
|
180
|
+
return true;
|
|
181
|
+
} catch {}
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
function bunClosed(message) {
|
|
186
|
+
return message === "Connection closed" || message === "connection must be a PostgresSQLConnection";
|
|
187
|
+
}
|
|
188
|
+
async function reset(session, sql) {
|
|
189
|
+
const run = (text) => sql.unsafe(text);
|
|
190
|
+
await resetSession2(session.depth(), run);
|
|
191
|
+
}
|
|
192
|
+
function streamRows(checkout, text, params) {
|
|
193
|
+
return async function* () {
|
|
194
|
+
const connection = await checkout();
|
|
195
|
+
try {
|
|
196
|
+
yield* cursorStream((statement, values) => connection.execute(statement, values), text, params);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
connection.evict?.();
|
|
199
|
+
throw error;
|
|
200
|
+
} finally {
|
|
201
|
+
await connection.release();
|
|
202
|
+
}
|
|
203
|
+
}();
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
checkout,
|
|
207
|
+
drainClosed,
|
|
208
|
+
listen,
|
|
209
|
+
recover,
|
|
210
|
+
streamRows
|
|
211
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DriverError2,
|
|
3
|
+
isConnectionLost
|
|
4
|
+
} from "./f9mphxej.js";
|
|
5
|
+
import {
|
|
6
|
+
connectClient3,
|
|
7
|
+
send4
|
|
8
|
+
} from "./y5656f0e.js";
|
|
9
|
+
import {
|
|
10
|
+
resetSession2
|
|
11
|
+
} from "./4d2w25vw.js";
|
|
12
|
+
import {
|
|
13
|
+
WireSession
|
|
14
|
+
} from "./yw30vnq2.js";
|
|
15
|
+
import {
|
|
16
|
+
noTimeout
|
|
17
|
+
} from "./rs1jb051.js";
|
|
18
|
+
import {
|
|
19
|
+
rejectClosed,
|
|
20
|
+
runCall
|
|
21
|
+
} from "./xhrnjch9.js";
|
|
22
|
+
|
|
23
|
+
// src/adapters/pg/neon-extra.ts
|
|
24
|
+
async function checkout(held) {
|
|
25
|
+
const { pool, counters, named, isClosed } = held;
|
|
26
|
+
if (isClosed())
|
|
27
|
+
return rejectClosed();
|
|
28
|
+
const client = await connectClient3(pool, held.acquireMs, counters);
|
|
29
|
+
counters.reserved += 1;
|
|
30
|
+
let lost = false;
|
|
31
|
+
const onError = () => {
|
|
32
|
+
lost = true;
|
|
33
|
+
};
|
|
34
|
+
const events = client;
|
|
35
|
+
events.on("error", onError);
|
|
36
|
+
const local = new Set;
|
|
37
|
+
const session = new WireSession((text, params) => {
|
|
38
|
+
const pending = send4(client, text, params, named);
|
|
39
|
+
const guarded = pending.catch((error) => {
|
|
40
|
+
if (isConnectionLost(error) || lost) {
|
|
41
|
+
lost = true;
|
|
42
|
+
if (isConnectionLost(error))
|
|
43
|
+
throw error;
|
|
44
|
+
throw Object.assign(new DriverError2("CONNECTION_CLOSED", { cause: error }), {
|
|
45
|
+
code: "CONNECTION_CLOSED"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
});
|
|
50
|
+
return guarded;
|
|
51
|
+
}, held.notices, isClosed, false, () => {
|
|
52
|
+
counters.reservedBusy += 1;
|
|
53
|
+
}, () => {
|
|
54
|
+
counters.reservedBusy = Math.max(0, counters.reservedBusy - 1);
|
|
55
|
+
}, local);
|
|
56
|
+
const guard = (run) => lost ? rejectClosed() : run();
|
|
57
|
+
let released = false;
|
|
58
|
+
return {
|
|
59
|
+
execute: (text, params, options) => {
|
|
60
|
+
const refused = noTimeout(options);
|
|
61
|
+
if (refused !== undefined)
|
|
62
|
+
return refused;
|
|
63
|
+
return guard(() => runCall(isClosed(), options, (watch) => session.query(text, params, watch)));
|
|
64
|
+
},
|
|
65
|
+
batch: (statements, options) => {
|
|
66
|
+
const refused = noTimeout(options);
|
|
67
|
+
if (refused !== undefined)
|
|
68
|
+
return refused;
|
|
69
|
+
return guard(() => runCall(isClosed(), options, async (watch) => {
|
|
70
|
+
const { runAtomicBatch } = await import("./3rrw5w8f.js");
|
|
71
|
+
return runAtomicBatch(session, statements, watch);
|
|
72
|
+
}));
|
|
73
|
+
},
|
|
74
|
+
async release() {
|
|
75
|
+
if (released)
|
|
76
|
+
return;
|
|
77
|
+
released = true;
|
|
78
|
+
try {
|
|
79
|
+
if (!lost)
|
|
80
|
+
await reset(session, client);
|
|
81
|
+
} finally {
|
|
82
|
+
counters.reserved = Math.max(0, counters.reserved - 1);
|
|
83
|
+
events.removeListener("error", onError);
|
|
84
|
+
client.release(lost);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async function reset(session, client) {
|
|
90
|
+
await resetSession2(session.depth(), (text) => client.query(text));
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
checkout
|
|
94
|
+
};
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertNoControl
|
|
3
|
+
} from "./3tq8pnb8.js";
|
|
4
|
+
import {
|
|
5
|
+
OkmError,
|
|
6
|
+
throwNamed,
|
|
7
|
+
isOperator,
|
|
8
|
+
operatorName,
|
|
9
|
+
operatorValue,
|
|
10
|
+
tag,
|
|
11
|
+
refuseHidden,
|
|
12
|
+
quote,
|
|
13
|
+
list,
|
|
14
|
+
fail2
|
|
15
|
+
} from "./f9mphxej.js";
|
|
16
|
+
|
|
17
|
+
// src/dialects/pg/ops/fragment.ts
|
|
18
|
+
var IDENT = Symbol("okmodel.sql.ident");
|
|
19
|
+
var COLUMN = Symbol("okmodel.sql.column");
|
|
20
|
+
function fragmentError(message, fix) {
|
|
21
|
+
throw new OkmError("OKM1125", message, { fix: { summary: fix } });
|
|
22
|
+
}
|
|
23
|
+
function isFragmentParts(value) {
|
|
24
|
+
return Array.isArray(value) && value.every(isPart);
|
|
25
|
+
}
|
|
26
|
+
function isPart(value) {
|
|
27
|
+
if (typeof value !== "object" || value === null || !("k" in value))
|
|
28
|
+
return false;
|
|
29
|
+
const kind = value.k;
|
|
30
|
+
if (kind === "t")
|
|
31
|
+
return "s" in value && typeof value.s === "string";
|
|
32
|
+
if (kind === "p")
|
|
33
|
+
return "v" in value && typeof value.v === "string";
|
|
34
|
+
if (kind === "n" || kind === "c")
|
|
35
|
+
return true;
|
|
36
|
+
if (kind === "i")
|
|
37
|
+
return "n" in value && typeof value.n === "string";
|
|
38
|
+
if (kind === "f")
|
|
39
|
+
return "parts" in value && isFragmentParts(value.parts);
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
function readSelectFragment(value) {
|
|
43
|
+
if (!isOperator(value) || operatorName(value) !== "sql")
|
|
44
|
+
return;
|
|
45
|
+
const named = value;
|
|
46
|
+
if (typeof named.as !== "string") {
|
|
47
|
+
fragmentError("A select fragment needs as(name).", 'Call .as("len") and pass that value in select.');
|
|
48
|
+
}
|
|
49
|
+
const stored = operatorValue(value);
|
|
50
|
+
if (!isFragmentParts(stored)) {
|
|
51
|
+
fragmentError("A fragment was not created by fragment``.", "Call fragment`...`.");
|
|
52
|
+
}
|
|
53
|
+
const textual = named.text === true;
|
|
54
|
+
return textual ? { as: named.as, parts: stored, textual: true } : { as: named.as, parts: stored };
|
|
55
|
+
}
|
|
56
|
+
function scanLiteral(literal, state) {
|
|
57
|
+
for (let index = 0;index < literal.length; index += 1) {
|
|
58
|
+
const char = literal[index] ?? "";
|
|
59
|
+
const code = literal.charCodeAt(index);
|
|
60
|
+
if (state.quote !== undefined) {
|
|
61
|
+
if (char !== state.quote)
|
|
62
|
+
continue;
|
|
63
|
+
if (literal[index + 1] === state.quote) {
|
|
64
|
+
index += 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
state.quote = undefined;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (code <= 31 && code !== 9 && code !== 10 && code !== 13 || code === 127) {
|
|
71
|
+
fragmentError("A fragment literal contains a control character.", "Remove NUL and other control characters. A newline, tab, or return is allowed.");
|
|
72
|
+
}
|
|
73
|
+
if (char === "'" || char === '"') {
|
|
74
|
+
state.quote = char;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (char === "(") {
|
|
78
|
+
state.paren += 1;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (char === ")") {
|
|
82
|
+
state.paren -= 1;
|
|
83
|
+
if (state.paren < 0) {
|
|
84
|
+
fragmentError("A fragment has unbalanced SQL.", "Keep parentheses and quotes balanced. A fragment cannot close the surrounding predicate.");
|
|
85
|
+
}
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (char === ";") {
|
|
89
|
+
fragmentError("A fragment cannot include a semicolon.", "Pass the value as an interpolation. The fragment is one expression.");
|
|
90
|
+
}
|
|
91
|
+
if (char === "$") {
|
|
92
|
+
fragmentError("A fragment cannot include a dollar quote or a parameter marker.", "Interpolate the value. The planner numbers parameters.");
|
|
93
|
+
}
|
|
94
|
+
if (char === "-" && literal[index + 1] === "-" || char === "/" && literal[index + 1] === "*") {
|
|
95
|
+
fragmentError("A fragment cannot include a comment.", "Remove the comment. A comment can hide the rest of the predicate.");
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function appendText(parts, literal) {
|
|
100
|
+
if (literal.length === 0)
|
|
101
|
+
return;
|
|
102
|
+
parts.push({ k: "t", s: literal });
|
|
103
|
+
}
|
|
104
|
+
function appendValue(parts, value) {
|
|
105
|
+
if (value === null) {
|
|
106
|
+
parts.push({ k: "n" });
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (typeof value === "string") {
|
|
110
|
+
parts.push({ k: "p", v: value });
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (typeof value === "number") {
|
|
114
|
+
if (!Number.isFinite(value)) {
|
|
115
|
+
fragmentError("A fragment needs a finite number.", "Pass a finite number, or leave it out.");
|
|
116
|
+
}
|
|
117
|
+
parts.push({ k: "p", v: String(value) });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (typeof value === "boolean") {
|
|
121
|
+
parts.push({ k: "p", v: value ? "true" : "false" });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (typeof value === "bigint") {
|
|
125
|
+
parts.push({ k: "p", v: String(value) });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (typeof value === "object") {
|
|
129
|
+
if (COLUMN in value) {
|
|
130
|
+
parts.push({ k: "c" });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (IDENT in value) {
|
|
134
|
+
const name = value[IDENT];
|
|
135
|
+
if (typeof name === "string") {
|
|
136
|
+
parts.push({ k: "i", n: name });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (isOperator(value) && operatorName(value) === "sql") {
|
|
141
|
+
const nested = operatorValue(value);
|
|
142
|
+
if (!isFragmentParts(nested)) {
|
|
143
|
+
fragmentError("A fragment was not created by fragment``.", "Call fragment`...`.");
|
|
144
|
+
}
|
|
145
|
+
parts.push({ k: "f", parts: nested });
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
fragmentError("A fragment cannot interpolate that value.", "Interpolate a string, number, boolean, null, ident(name), fragment.column, or another fragment.");
|
|
150
|
+
}
|
|
151
|
+
function hasSql(parts) {
|
|
152
|
+
for (const part of parts) {
|
|
153
|
+
if (part.k === "t") {
|
|
154
|
+
if (part.s.trim().length > 0)
|
|
155
|
+
return true;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
function compile(strings, values) {
|
|
163
|
+
const state = { quote: undefined, paren: 0 };
|
|
164
|
+
const parts = [];
|
|
165
|
+
for (let index = 0;index < values.length + 1; index += 1) {
|
|
166
|
+
const literal = strings[index] ?? "";
|
|
167
|
+
scanLiteral(literal, state);
|
|
168
|
+
appendText(parts, literal);
|
|
169
|
+
if (index === values.length)
|
|
170
|
+
continue;
|
|
171
|
+
if (state.quote !== undefined) {
|
|
172
|
+
fragmentError("A fragment cannot interpolate inside quotes.", "Do not put an interpolation inside quotes. Write title = ${name}.");
|
|
173
|
+
}
|
|
174
|
+
appendValue(parts, values[index]);
|
|
175
|
+
}
|
|
176
|
+
if (state.quote !== undefined || state.paren !== 0) {
|
|
177
|
+
fragmentError("A fragment has unbalanced SQL.", "Keep parentheses and quotes balanced. A fragment cannot close the surrounding predicate.");
|
|
178
|
+
}
|
|
179
|
+
if (!hasSql(parts)) {
|
|
180
|
+
fragmentError("A fragment needs SQL text.", "Write an expression, or interpolate a value.");
|
|
181
|
+
}
|
|
182
|
+
return parts;
|
|
183
|
+
}
|
|
184
|
+
function isTemplate(value) {
|
|
185
|
+
return Array.isArray(value) && "raw" in value;
|
|
186
|
+
}
|
|
187
|
+
function bind(parts, textual = false) {
|
|
188
|
+
const tagged = tag("sql", parts);
|
|
189
|
+
return Object.assign(tagged, {
|
|
190
|
+
as(name) {
|
|
191
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
192
|
+
fragmentError("as(name) needs a result name.", 'Call .as("len") with a name that is not a column.');
|
|
193
|
+
}
|
|
194
|
+
assertNoControl(name, "fragment as");
|
|
195
|
+
const selected = Object.assign(tag("sql", parts), { as: name });
|
|
196
|
+
return textual ? Object.assign(selected, { text: true }) : selected;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function fragmentTag(strings, ...values) {
|
|
201
|
+
if (!isTemplate(strings)) {
|
|
202
|
+
fragmentError("Call fragment as a template: fragment`...`.", "Write fragment`length(${fragment.column}) > ${1}`.");
|
|
203
|
+
}
|
|
204
|
+
return bind(compile(strings, values));
|
|
205
|
+
}
|
|
206
|
+
var fragment = Object.assign(fragmentTag, {
|
|
207
|
+
column: { [COLUMN]: true }
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// src/runtime/sql-fragment.ts
|
|
211
|
+
function emitSqlValue(table, ref, value, sink) {
|
|
212
|
+
const dot = ref.indexOf(".");
|
|
213
|
+
const alias = dot < 0 ? ref : ref.slice(0, dot);
|
|
214
|
+
writeFragment(requireParts(value), sink, alias, ref, table, "where");
|
|
215
|
+
}
|
|
216
|
+
function emitSqlSelect(table, parts, sink, alias) {
|
|
217
|
+
writeFragment(parts, sink, alias, undefined, table, "select");
|
|
218
|
+
}
|
|
219
|
+
function decodeSqlNumber(wire) {
|
|
220
|
+
const parsed = Number(wire);
|
|
221
|
+
if (!Number.isFinite(parsed)) {
|
|
222
|
+
throw new OkmError("OKM1125", "A select fragment must be a number.", {
|
|
223
|
+
fix: { summary: "Use a numeric expression, such as length(title). Text stays in where." }
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return parsed;
|
|
227
|
+
}
|
|
228
|
+
function requireParts(value) {
|
|
229
|
+
if (!isFragmentParts(value)) {
|
|
230
|
+
throw new OkmError("OKM1125", "A fragment was not created by fragment``.", {
|
|
231
|
+
fix: { summary: "Call fragment`...`." }
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return value;
|
|
235
|
+
}
|
|
236
|
+
function writeFragment(parts, sink, alias, ref, table, place) {
|
|
237
|
+
sink.mark(":g");
|
|
238
|
+
sink.text("(");
|
|
239
|
+
for (const part of parts)
|
|
240
|
+
writePart(part, sink, alias, ref, table, place);
|
|
241
|
+
sink.mark(":g");
|
|
242
|
+
sink.text(")");
|
|
243
|
+
}
|
|
244
|
+
function writePart(part, sink, alias, ref, table, place) {
|
|
245
|
+
if (part.k === "t") {
|
|
246
|
+
sink.mark(`:t:${String(part.s.length)}:${part.s}`);
|
|
247
|
+
sink.text(part.s);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
if (part.k === "p") {
|
|
251
|
+
sink.mark(":p");
|
|
252
|
+
sink.param(part.v);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (part.k === "n") {
|
|
256
|
+
sink.mark(":n");
|
|
257
|
+
sink.text("null");
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (part.k === "i") {
|
|
261
|
+
writeIdent(part.n, table, sink, alias, place);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (part.k === "c") {
|
|
265
|
+
if (ref === undefined) {
|
|
266
|
+
throw new OkmError("OKM1125", "fragment.column belongs on a where field.", {
|
|
267
|
+
fix: { summary: "Use ident(name) in select, or put fragment.column on a where field." }
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
sink.mark(":c");
|
|
271
|
+
sink.text(ref);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
writeFragment(part.parts, sink, alias, ref, table, place);
|
|
275
|
+
}
|
|
276
|
+
function writeIdent(name, table, sink, alias, place) {
|
|
277
|
+
const column = table.columns.get(name);
|
|
278
|
+
if (column === undefined) {
|
|
279
|
+
throwNamed("OKM1120", name, table.names, `Field ${name} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
|
|
280
|
+
}
|
|
281
|
+
if (place === "select") {
|
|
282
|
+
if (column.hidden) {
|
|
283
|
+
fail2("OKM1120", `Field ${column.field} is hidden.`, "A select fragment cannot name a hidden field.");
|
|
284
|
+
}
|
|
285
|
+
} else {
|
|
286
|
+
refuseHidden(column);
|
|
287
|
+
}
|
|
288
|
+
sink.mark(`:i:${String(column.field.length)}:${column.field}`);
|
|
289
|
+
sink.text(alias);
|
|
290
|
+
sink.text(".");
|
|
291
|
+
sink.text(quote(column.sql));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export { readSelectFragment, emitSqlValue, emitSqlSelect, decodeSqlNumber };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/runtime/catalog-cache.ts
|
|
2
|
+
var inflight = new Map;
|
|
3
|
+
function loadOnce(key, load) {
|
|
4
|
+
const found = inflight.get(key);
|
|
5
|
+
if (found !== undefined)
|
|
6
|
+
return found;
|
|
7
|
+
const pending = Promise.resolve().then(load);
|
|
8
|
+
inflight.set(key, pending);
|
|
9
|
+
pending.catch(() => {
|
|
10
|
+
if (inflight.get(key) === pending)
|
|
11
|
+
inflight.delete(key);
|
|
12
|
+
});
|
|
13
|
+
return pending;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
loadOnce
|
|
17
|
+
};
|