okmodel 0.0.0 → 0.1.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/README.md +44 -1
- package/dist/adapters/capabilities.d.ts +62 -0
- package/dist/adapters/error.d.ts +91 -0
- package/dist/adapters/failure.d.ts +39 -0
- package/dist/adapters/pg/batch.d.ts +36 -0
- package/dist/adapters/pg/call.d.ts +59 -0
- package/dist/adapters/pg/pglite.d.ts +21 -0
- package/dist/adapters/pg/postgres-extra.d.ts +43 -0
- package/dist/adapters/pg/postgresjs.d.ts +95 -0
- package/dist/adapters/pg/result.d.ts +30 -0
- package/dist/contracts/catalog/build.d.ts +18 -0
- package/dist/contracts/catalog/document.d.ts +79 -0
- package/dist/contracts/catalog/enum.d.ts +35 -0
- package/dist/contracts/catalog/identifier.d.ts +71 -0
- package/dist/contracts/catalog/identity.d.ts +98 -0
- package/dist/contracts/catalog/index.d.ts +11 -0
- package/dist/contracts/catalog/json.d.ts +17 -0
- package/dist/contracts/catalog/object.d.ts +142 -0
- package/dist/contracts/catalog/order.d.ts +43 -0
- package/dist/contracts/catalog/rewrite.d.ts +18 -0
- package/dist/contracts/catalog/types.d.ts +292 -0
- package/dist/contracts/catalog/words.d.ts +13 -0
- package/dist/contracts/connection.d.ts +33 -0
- package/dist/contracts/driver.d.ts +163 -0
- package/dist/contracts/error.d.ts +298 -0
- package/dist/contracts/index.d.ts +11 -0
- package/dist/contracts/index.js +16 -0
- package/dist/contracts/internal.d.ts +15 -0
- package/dist/contracts/internal.js +68 -0
- package/dist/contracts/nearest.d.ts +15 -0
- package/dist/contracts/rows.d.ts +84 -0
- package/dist/contracts/sha256.d.ts +14 -0
- package/dist/contracts/utf8.d.ts +33 -0
- package/dist/dialects/pg/array-literal.d.ts +25 -0
- package/dist/dialects/pg/bool.d.ts +46 -0
- package/dist/dialects/pg/column.d.ts +386 -0
- package/dist/dialects/pg/compile.d.ts +81 -0
- package/dist/dialects/pg/custom.d.ts +21 -0
- package/dist/dialects/pg/ddl.d.ts +70 -0
- package/dist/dialects/pg/decimal.d.ts +62 -0
- package/dist/dialects/pg/declarations.d.ts +34 -0
- package/dist/dialects/pg/emit.d.ts +18 -0
- package/dist/dialects/pg/enum.d.ts +30 -0
- package/dist/dialects/pg/errors.d.ts +30 -0
- package/dist/dialects/pg/finite.d.ts +15 -0
- package/dist/dialects/pg/geometry.d.ts +55 -0
- package/dist/dialects/pg/index.d.ts +45 -0
- package/dist/dialects/pg/index.js +1821 -0
- package/dist/dialects/pg/integer.d.ts +96 -0
- package/dist/dialects/pg/introspect.d.ts +43 -0
- package/dist/dialects/pg/json.d.ts +43 -0
- package/dist/dialects/pg/keys.d.ts +32 -0
- package/dist/dialects/pg/misuse.d.ts +31 -0
- package/dist/dialects/pg/model.d.ts +71 -0
- package/dist/dialects/pg/namespace.d.ts +63 -0
- package/dist/dialects/pg/network.d.ts +28 -0
- package/dist/dialects/pg/operators.d.ts +71 -0
- package/dist/dialects/pg/ops/between.d.ts +10 -0
- package/dist/dialects/pg/ops/contains.d.ts +8 -0
- package/dist/dialects/pg/ops/endsWith.d.ts +8 -0
- package/dist/dialects/pg/ops/eq.d.ts +9 -0
- package/dist/dialects/pg/ops/every.d.ts +9 -0
- package/dist/dialects/pg/ops/gt.d.ts +9 -0
- package/dist/dialects/pg/ops/gte.d.ts +9 -0
- package/dist/dialects/pg/ops/has.d.ts +9 -0
- package/dist/dialects/pg/ops/ilike.d.ts +8 -0
- package/dist/dialects/pg/ops/inList.d.ts +9 -0
- package/dist/dialects/pg/ops/inc.d.ts +13 -0
- package/dist/dialects/pg/ops/like.d.ts +8 -0
- package/dist/dialects/pg/ops/lt.d.ts +9 -0
- package/dist/dialects/pg/ops/lte.d.ts +9 -0
- package/dist/dialects/pg/ops/none.d.ts +9 -0
- package/dist/dialects/pg/ops/not.d.ts +9 -0
- package/dist/dialects/pg/ops/notIn.d.ts +9 -0
- package/dist/dialects/pg/ops/or.d.ts +9 -0
- package/dist/dialects/pg/ops/startsWith.d.ts +8 -0
- package/dist/dialects/pg/quote.d.ts +24 -0
- package/dist/dialects/pg/range.d.ts +50 -0
- package/dist/dialects/pg/relations.d.ts +45 -0
- package/dist/dialects/pg/schema.d.ts +77 -0
- package/dist/dialects/pg/search.d.ts +23 -0
- package/dist/dialects/pg/table.d.ts +201 -0
- package/dist/dialects/pg/temporal.d.ts +211 -0
- package/dist/dialects/pg/text.d.ts +44 -0
- package/dist/dialects/pg/time.d.ts +46 -0
- package/dist/okm.js +2 -0
- package/dist/okmodel.js +2 -0
- package/dist/runtime/client.d.ts +47 -0
- package/dist/runtime/conflict.d.ts +38 -0
- package/dist/runtime/drift-detail.d.ts +32 -0
- package/dist/runtime/drift.d.ts +29 -0
- package/dist/runtime/include.d.ts +15 -0
- package/dist/runtime/pg/pglite.d.ts +25 -0
- package/dist/runtime/pg/pglite.js +48 -0
- package/dist/runtime/pg/postgresjs.d.ts +29 -0
- package/dist/runtime/pg/postgresjs.js +62 -0
- package/dist/runtime/plan.d.ts +167 -0
- package/dist/runtime/tx.d.ts +29 -0
- package/dist/runtime/types.d.ts +369 -0
- package/dist/runtime/write.d.ts +48 -0
- package/dist/shared/4j72449d.js +37 -0
- package/dist/shared/79ggp945.js +148 -0
- package/dist/shared/7ck0dtry.js +259 -0
- package/dist/shared/8b04d28c.js +14 -0
- package/dist/shared/ax16zpvm.js +171 -0
- package/dist/shared/ckb1p0a4.js +566 -0
- package/dist/shared/cn0n68ft.js +16 -0
- package/dist/shared/dynq16vb.js +81 -0
- package/dist/shared/f5thc1s0.js +1050 -0
- package/dist/shared/fgqgsb5z.js +281 -0
- package/dist/shared/g2v6gnc8.js +347 -0
- package/dist/shared/g5fhqmwe.js +188 -0
- package/dist/shared/gk7cs7sp.js +566 -0
- package/dist/shared/hd293j9g.js +98 -0
- package/dist/shared/j5cn2963.js +701 -0
- package/dist/shared/kynx7vbm.js +1490 -0
- package/dist/shared/mkjmqjv4.js +456 -0
- package/dist/shared/mtkwv8wx.js +18 -0
- package/dist/shared/ngk8gj61.js +40 -0
- package/dist/shared/p0cbr3g2.js +79 -0
- package/dist/shared/px90pf9p.js +396 -0
- package/dist/shared/qk3hxfja.js +83 -0
- package/dist/shared/tb4ze1tr.js +119 -0
- package/dist/shared/vkm3q4x1.js +30 -0
- package/dist/shared/w8samvk1.js +18 -0
- package/dist/shared/xy79j5hq.js +177 -0
- package/dist/shared/y9m15dfv.js +888 -0
- package/dist/shared/ycwz42az.js +412 -0
- package/dist/shared/zhc5vmgf.js +257 -0
- package/dist/tooling/cli.d.ts +1 -0
- package/dist/tooling/cli.js +193 -0
- package/dist/tooling/errors/registry.d.ts +33 -0
- package/dist/tooling/migrate/apply.d.ts +86 -0
- package/dist/tooling/migrate/commands.d.ts +21 -0
- package/dist/tooling/migrate/config.d.ts +48 -0
- package/dist/tooling/migrate/dev.d.ts +16 -0
- package/dist/tooling/migrate/equal.d.ts +15 -0
- package/dist/tooling/migrate/files.d.ts +19 -0
- package/dist/tooling/migrate/index.d.ts +7 -0
- package/dist/tooling/migrate/index.js +7 -0
- package/dist/tooling/migrate/plan.d.ts +76 -0
- package/dist/tooling/migrate/policy.d.ts +78 -0
- package/dist/tooling/migrate/project.d.ts +69 -0
- package/dist/tooling/migrate/status.d.ts +74 -0
- package/dist/tooling/migrate/values.d.ts +29 -0
- package/package.json +94 -7
- package/dist/index.js +0 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeResult,
|
|
3
|
+
emitJoin,
|
|
4
|
+
emitWhere,
|
|
5
|
+
emitOrder,
|
|
6
|
+
emitPrimaryOrder,
|
|
7
|
+
selectedColumns,
|
|
8
|
+
rejectKeys,
|
|
9
|
+
readLimit,
|
|
10
|
+
projectExpr,
|
|
11
|
+
jsonExpr,
|
|
12
|
+
cell,
|
|
13
|
+
indexes,
|
|
14
|
+
quote,
|
|
15
|
+
list,
|
|
16
|
+
isRecord,
|
|
17
|
+
fail
|
|
18
|
+
} from "./f5thc1s0.js";
|
|
19
|
+
import {
|
|
20
|
+
throwNamed2
|
|
21
|
+
} from "./ycwz42az.js";
|
|
22
|
+
|
|
23
|
+
// src/runtime/include.ts
|
|
24
|
+
var INCLUDE_OPTIONS = ["all", "include", "limit", "orderBy", "select", "where"];
|
|
25
|
+
function emitIncludeSelect(include, alias, sink, outputs, column) {
|
|
26
|
+
const selected = include.columns;
|
|
27
|
+
sink.mark(`i:${include.name}:${include.relation.kind}`);
|
|
28
|
+
if (include.relation.kind === "many") {
|
|
29
|
+
if (column > 0 || outputs?.fields.length)
|
|
30
|
+
sink.text(", ");
|
|
31
|
+
sink.text(alias);
|
|
32
|
+
sink.text(".rows");
|
|
33
|
+
outputs?.includes.push({
|
|
34
|
+
name: include.name,
|
|
35
|
+
kind: "many",
|
|
36
|
+
at: column,
|
|
37
|
+
fields: selected.map((item, index) => ({
|
|
38
|
+
key: item.field,
|
|
39
|
+
at: index,
|
|
40
|
+
decode: item.decode
|
|
41
|
+
})),
|
|
42
|
+
nested: include.nested.map((nested, index) => ({
|
|
43
|
+
name: nested.name,
|
|
44
|
+
kind: nested.relation.kind,
|
|
45
|
+
at: selected.length + index,
|
|
46
|
+
fields: nested.columns.map((item, at) => ({
|
|
47
|
+
key: item.field,
|
|
48
|
+
at,
|
|
49
|
+
decode: item.decode
|
|
50
|
+
})),
|
|
51
|
+
nested: []
|
|
52
|
+
}))
|
|
53
|
+
});
|
|
54
|
+
return column + 1;
|
|
55
|
+
}
|
|
56
|
+
const projected = include.presence === undefined ? selected : [...selected, include.presence];
|
|
57
|
+
const start = column;
|
|
58
|
+
for (let index = 0;index < projected.length; index += 1) {
|
|
59
|
+
if (start + index > 0)
|
|
60
|
+
sink.text(", ");
|
|
61
|
+
sink.text(alias);
|
|
62
|
+
sink.text(".c");
|
|
63
|
+
sink.text(String(index));
|
|
64
|
+
sink.mark(`s:${projected[index]?.field ?? ""}`);
|
|
65
|
+
}
|
|
66
|
+
const nestedStart = start + projected.length;
|
|
67
|
+
let cursor = nestedStart;
|
|
68
|
+
const nestedOut = [];
|
|
69
|
+
for (let index = 0;index < include.nested.length; index += 1) {
|
|
70
|
+
const nested = include.nested[index];
|
|
71
|
+
if (nested === undefined)
|
|
72
|
+
continue;
|
|
73
|
+
const width = nested.relation.kind === "many" ? 1 : nested.presence === undefined ? nested.columns.length : nested.columns.length + 1;
|
|
74
|
+
for (let slot = 0;slot < width; slot += 1) {
|
|
75
|
+
sink.text(", ");
|
|
76
|
+
sink.text(alias);
|
|
77
|
+
sink.text(".n");
|
|
78
|
+
sink.text(String(index));
|
|
79
|
+
sink.text("_");
|
|
80
|
+
sink.text(String(slot));
|
|
81
|
+
}
|
|
82
|
+
nestedOut.push({
|
|
83
|
+
name: nested.name,
|
|
84
|
+
kind: nested.relation.kind,
|
|
85
|
+
at: nested.relation.kind === "many" ? cursor : nested.presence === undefined ? cursor : cursor + nested.columns.length,
|
|
86
|
+
fields: nested.columns.map((item, at) => ({
|
|
87
|
+
key: item.field,
|
|
88
|
+
at: nested.relation.kind === "many" ? at : cursor + at,
|
|
89
|
+
decode: item.decode
|
|
90
|
+
})),
|
|
91
|
+
nested: []
|
|
92
|
+
});
|
|
93
|
+
cursor += width;
|
|
94
|
+
}
|
|
95
|
+
outputs?.includes.push({
|
|
96
|
+
name: include.name,
|
|
97
|
+
kind: "one",
|
|
98
|
+
at: start + include.anchor,
|
|
99
|
+
fields: selected.map((item, index) => ({
|
|
100
|
+
key: item.field,
|
|
101
|
+
at: start + index,
|
|
102
|
+
decode: item.decode
|
|
103
|
+
})),
|
|
104
|
+
nested: nestedOut
|
|
105
|
+
});
|
|
106
|
+
return cursor;
|
|
107
|
+
}
|
|
108
|
+
function emitIncludeJoin(schema, include, sink, parentAlias, alias, depth) {
|
|
109
|
+
const child = indexes(schema).get(include.relation.table);
|
|
110
|
+
if (child === undefined) {
|
|
111
|
+
fail("OKM1120", `Relation ${include.name} names ${include.relation.table}, which is not in the schema.`);
|
|
112
|
+
}
|
|
113
|
+
const childAlias = `r${String(depth)}_${include.name}`;
|
|
114
|
+
sink.text(" left join lateral (");
|
|
115
|
+
if (include.relation.kind === "many") {
|
|
116
|
+
sink.text("select coalesce(json_agg(item order by ord), '[]'::json) as rows from (select item, row_number() over () as ord from (select json_build_array(");
|
|
117
|
+
const selected = include.columns;
|
|
118
|
+
for (let index = 0;index < selected.length; index += 1) {
|
|
119
|
+
const item = selected[index];
|
|
120
|
+
if (item === undefined)
|
|
121
|
+
continue;
|
|
122
|
+
if (index > 0)
|
|
123
|
+
sink.text(", ");
|
|
124
|
+
sink.text(jsonExpr(`${childAlias}.${quote(item.sql)}`, item.dataType));
|
|
125
|
+
}
|
|
126
|
+
if (selected.length === 0)
|
|
127
|
+
sink.text("1");
|
|
128
|
+
for (const nested of include.nested) {
|
|
129
|
+
sink.text(", ");
|
|
130
|
+
emitNestedAggregate(schema, nested, sink, childAlias, depth + 1);
|
|
131
|
+
}
|
|
132
|
+
sink.text(") as item from ");
|
|
133
|
+
sink.text(quote(child.model.sql));
|
|
134
|
+
sink.text(" ");
|
|
135
|
+
sink.text(childAlias);
|
|
136
|
+
sink.text(" where ");
|
|
137
|
+
emitJoin(sink, parentAlias, childAlias, include.relation);
|
|
138
|
+
emitWhere(schema, child, include.where, sink, childAlias, depth + 1, true);
|
|
139
|
+
emitOrder(child, include.orderBy, sink, childAlias);
|
|
140
|
+
if (include.orderBy === undefined && child.model.primary.length > 0) {
|
|
141
|
+
emitPrimaryOrder(child, sink, childAlias);
|
|
142
|
+
}
|
|
143
|
+
if (include.limit !== undefined) {
|
|
144
|
+
sink.text(" limit ");
|
|
145
|
+
sink.param(String(include.limit));
|
|
146
|
+
sink.mark(`l:${String(include.limit)}`);
|
|
147
|
+
}
|
|
148
|
+
sink.text(") limited) ordered) ");
|
|
149
|
+
sink.text(alias);
|
|
150
|
+
sink.text(" on true");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
sink.text("select ");
|
|
154
|
+
const projected = include.presence === undefined ? include.columns : [...include.columns, include.presence];
|
|
155
|
+
for (let index = 0;index < projected.length; index += 1) {
|
|
156
|
+
const item = projected[index];
|
|
157
|
+
if (item === undefined)
|
|
158
|
+
continue;
|
|
159
|
+
if (index > 0)
|
|
160
|
+
sink.text(", ");
|
|
161
|
+
sink.text(projectExpr(`${childAlias}.${quote(item.sql)}`, item.dataType));
|
|
162
|
+
sink.text(" as c");
|
|
163
|
+
sink.text(String(index));
|
|
164
|
+
}
|
|
165
|
+
if (projected.length === 0)
|
|
166
|
+
sink.text("1 as c0");
|
|
167
|
+
for (let index = 0;index < include.nested.length; index += 1) {
|
|
168
|
+
const nested = include.nested[index];
|
|
169
|
+
if (nested === undefined)
|
|
170
|
+
continue;
|
|
171
|
+
if (nested.relation.kind === "many") {
|
|
172
|
+
sink.text(", ");
|
|
173
|
+
sink.text("n");
|
|
174
|
+
sink.text(String(index));
|
|
175
|
+
sink.text(".rows as n");
|
|
176
|
+
sink.text(String(index));
|
|
177
|
+
sink.text("_0");
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const width = nested.presence === undefined ? nested.columns.length : nested.columns.length + 1;
|
|
181
|
+
for (let slot = 0;slot < width; slot += 1) {
|
|
182
|
+
sink.text(", ");
|
|
183
|
+
sink.text("n");
|
|
184
|
+
sink.text(String(index));
|
|
185
|
+
sink.text(".c");
|
|
186
|
+
sink.text(String(slot));
|
|
187
|
+
sink.text(" as n");
|
|
188
|
+
sink.text(String(index));
|
|
189
|
+
sink.text("_");
|
|
190
|
+
sink.text(String(slot));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
sink.text(" from ");
|
|
194
|
+
sink.text(quote(child.model.sql));
|
|
195
|
+
sink.text(" ");
|
|
196
|
+
sink.text(childAlias);
|
|
197
|
+
for (let index = 0;index < include.nested.length; index += 1) {
|
|
198
|
+
const nested = include.nested[index];
|
|
199
|
+
if (nested === undefined)
|
|
200
|
+
continue;
|
|
201
|
+
emitIncludeJoin(schema, nested, sink, childAlias, `n${String(index)}`, depth + 1);
|
|
202
|
+
}
|
|
203
|
+
sink.text(" where ");
|
|
204
|
+
emitJoin(sink, parentAlias, childAlias, include.relation);
|
|
205
|
+
emitWhere(schema, child, include.where, sink, childAlias, depth + 1, true);
|
|
206
|
+
sink.text(" limit 1) ");
|
|
207
|
+
sink.text(alias);
|
|
208
|
+
sink.text(" on true");
|
|
209
|
+
}
|
|
210
|
+
function emitNestedAggregate(schema, include, sink, alias, depth) {
|
|
211
|
+
const child = indexes(schema).get(include.relation.table);
|
|
212
|
+
if (child === undefined) {
|
|
213
|
+
fail("OKM1120", `Relation ${include.name} names ${include.relation.table}, which is not in the schema.`);
|
|
214
|
+
}
|
|
215
|
+
const childAlias = `n${String(depth)}_${include.name}`;
|
|
216
|
+
sink.text("(select coalesce(json_agg(item order by ord), '[]'::json) from (select item, row_number() over () as ord from (select json_build_array(");
|
|
217
|
+
for (let index = 0;index < include.columns.length; index += 1) {
|
|
218
|
+
const item = include.columns[index];
|
|
219
|
+
if (item === undefined)
|
|
220
|
+
continue;
|
|
221
|
+
if (index > 0)
|
|
222
|
+
sink.text(", ");
|
|
223
|
+
sink.text(jsonExpr(`${childAlias}.${quote(item.sql)}`, item.dataType));
|
|
224
|
+
}
|
|
225
|
+
if (include.columns.length === 0)
|
|
226
|
+
sink.text("1");
|
|
227
|
+
sink.text(") as item from ");
|
|
228
|
+
sink.text(quote(child.model.sql));
|
|
229
|
+
sink.text(" ");
|
|
230
|
+
sink.text(childAlias);
|
|
231
|
+
sink.text(" where ");
|
|
232
|
+
emitJoin(sink, alias, childAlias, include.relation);
|
|
233
|
+
emitWhere(schema, child, include.where, sink, childAlias, depth, true);
|
|
234
|
+
emitOrder(child, include.orderBy, sink, childAlias);
|
|
235
|
+
if (include.orderBy === undefined && child.model.primary.length > 0) {
|
|
236
|
+
emitPrimaryOrder(child, sink, childAlias);
|
|
237
|
+
}
|
|
238
|
+
if (include.limit !== undefined) {
|
|
239
|
+
sink.text(" limit ");
|
|
240
|
+
sink.param(String(include.limit));
|
|
241
|
+
sink.mark(`l:${String(include.limit)}`);
|
|
242
|
+
}
|
|
243
|
+
sink.text(") limited) ordered)");
|
|
244
|
+
}
|
|
245
|
+
function readIncludes(schema, table, include, all) {
|
|
246
|
+
if (include === undefined)
|
|
247
|
+
return [];
|
|
248
|
+
if (!isRecord(include)) {
|
|
249
|
+
fail("OKM1120", "include must be an object of relations.");
|
|
250
|
+
}
|
|
251
|
+
const parsed = [];
|
|
252
|
+
for (const name of Object.keys(include)) {
|
|
253
|
+
const relation = table.relations.get(name);
|
|
254
|
+
if (relation === undefined) {
|
|
255
|
+
throwNamed2("OKM1120", name, [...table.relations.keys()], `Include ${name} is not a relation of ${table.model.name}. Accepted names: ${list([...table.relations.keys()])}.`);
|
|
256
|
+
}
|
|
257
|
+
parsed.push(parseInclude(schema, name, relation, include[name], all));
|
|
258
|
+
}
|
|
259
|
+
return parsed;
|
|
260
|
+
}
|
|
261
|
+
function parseInclude(schema, name, relation, value, all) {
|
|
262
|
+
if (value === true) {
|
|
263
|
+
if (relation.kind === "many" && all === undefined) {
|
|
264
|
+
fail("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
|
|
265
|
+
}
|
|
266
|
+
const child = childIndex(schema, relation);
|
|
267
|
+
const columns = selectedColumns(child, undefined);
|
|
268
|
+
return {
|
|
269
|
+
name,
|
|
270
|
+
relation,
|
|
271
|
+
where: undefined,
|
|
272
|
+
orderBy: undefined,
|
|
273
|
+
limit: undefined,
|
|
274
|
+
columns,
|
|
275
|
+
...anchored(child, columns),
|
|
276
|
+
nested: []
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
if (!isRecord(value)) {
|
|
280
|
+
fail("OKM1120", `Include ${name} must be true or an object.`);
|
|
281
|
+
}
|
|
282
|
+
rejectKeys(value, INCLUDE_OPTIONS, `include ${name}`);
|
|
283
|
+
const reason = typeof value.all === "string" ? value.all : all;
|
|
284
|
+
let limit;
|
|
285
|
+
if (value.limit !== undefined)
|
|
286
|
+
limit = readLimit(value.limit);
|
|
287
|
+
if (relation.kind === "many" && limit === undefined && reason === undefined) {
|
|
288
|
+
fail("OKM1105", `Include ${name} is to-many and has no limit. Pass limit, or call .all(reason).`);
|
|
289
|
+
}
|
|
290
|
+
const child = childIndex(schema, relation);
|
|
291
|
+
const columns = selectedColumns(child, value.select);
|
|
292
|
+
const nestedValue = value.include;
|
|
293
|
+
const nested = nestedValue === undefined ? [] : readIncludes(schema, child, nestedValue, reason);
|
|
294
|
+
return {
|
|
295
|
+
name,
|
|
296
|
+
relation,
|
|
297
|
+
where: value.where,
|
|
298
|
+
orderBy: value.orderBy,
|
|
299
|
+
limit,
|
|
300
|
+
columns,
|
|
301
|
+
...anchored(child, columns),
|
|
302
|
+
nested
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function anchored(table, columns) {
|
|
306
|
+
const pk = table.model.primary[0];
|
|
307
|
+
const selected = pk === undefined ? -1 : columns.findIndex((column) => column.field === pk);
|
|
308
|
+
if (selected >= 0)
|
|
309
|
+
return { presence: undefined, anchor: selected };
|
|
310
|
+
return { presence: pk === undefined ? undefined : table.columns.get(pk), anchor: columns.length };
|
|
311
|
+
}
|
|
312
|
+
function childIndex(schema, relation) {
|
|
313
|
+
const child = indexes(schema).get(relation.table);
|
|
314
|
+
if (child === undefined) {
|
|
315
|
+
fail("OKM1120", `Relation ${relation.name} names ${relation.table}, which is not in the schema.`);
|
|
316
|
+
}
|
|
317
|
+
return child;
|
|
318
|
+
}
|
|
319
|
+
function decodeIncluded(plan, rows, table) {
|
|
320
|
+
return decodeResult(plan, rows, table, decodeRowIncluded);
|
|
321
|
+
}
|
|
322
|
+
function decodeRowIncluded(outputs, row) {
|
|
323
|
+
const result = {};
|
|
324
|
+
for (const field of outputs.fields) {
|
|
325
|
+
result[field.key] = cell(row[field.at], field.decode);
|
|
326
|
+
}
|
|
327
|
+
for (const include of outputs.includes) {
|
|
328
|
+
result[include.name] = decodeInclude(include, row);
|
|
329
|
+
}
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
function decodeInclude(include, row) {
|
|
333
|
+
if (include.kind === "many") {
|
|
334
|
+
const raw = row[include.at];
|
|
335
|
+
if (raw === null || raw === undefined)
|
|
336
|
+
return [];
|
|
337
|
+
const parsed = JSON.parse(raw);
|
|
338
|
+
if (!Array.isArray(parsed))
|
|
339
|
+
return [];
|
|
340
|
+
const rows = [];
|
|
341
|
+
for (const item of parsed) {
|
|
342
|
+
if (!Array.isArray(item))
|
|
343
|
+
continue;
|
|
344
|
+
const child = {};
|
|
345
|
+
for (const field of include.fields) {
|
|
346
|
+
child[field.key] = jsonCell(item[field.at], field.decode);
|
|
347
|
+
}
|
|
348
|
+
for (const nested of include.nested) {
|
|
349
|
+
child[nested.name] = decodeJsonInclude(nested, item[nested.at]);
|
|
350
|
+
}
|
|
351
|
+
rows.push(child);
|
|
352
|
+
}
|
|
353
|
+
return rows;
|
|
354
|
+
}
|
|
355
|
+
const presence = row[include.at];
|
|
356
|
+
if (presence === null || presence === undefined)
|
|
357
|
+
return null;
|
|
358
|
+
const child = {};
|
|
359
|
+
for (const field of include.fields) {
|
|
360
|
+
child[field.key] = cell(row[field.at], field.decode);
|
|
361
|
+
}
|
|
362
|
+
for (const nested of include.nested) {
|
|
363
|
+
child[nested.name] = decodeInclude(nested, row);
|
|
364
|
+
}
|
|
365
|
+
return child;
|
|
366
|
+
}
|
|
367
|
+
function decodeJsonInclude(include, value) {
|
|
368
|
+
if (!Array.isArray(value))
|
|
369
|
+
return include.kind === "many" ? [] : null;
|
|
370
|
+
const rows = [];
|
|
371
|
+
for (const item of value) {
|
|
372
|
+
if (!Array.isArray(item))
|
|
373
|
+
continue;
|
|
374
|
+
const child = {};
|
|
375
|
+
for (const field of include.fields) {
|
|
376
|
+
child[field.key] = jsonCell(item[field.at], field.decode);
|
|
377
|
+
}
|
|
378
|
+
rows.push(child);
|
|
379
|
+
}
|
|
380
|
+
return include.kind === "one" ? rows[0] ?? null : rows;
|
|
381
|
+
}
|
|
382
|
+
function jsonCell(value, decode) {
|
|
383
|
+
if (value === null || value === undefined)
|
|
384
|
+
return null;
|
|
385
|
+
const wire = typeof value === "string" ? value : JSON.stringify(value);
|
|
386
|
+
return decode === undefined ? wire : decode(wire);
|
|
387
|
+
}
|
|
388
|
+
var includeHooks = {
|
|
389
|
+
read: readIncludes,
|
|
390
|
+
select: emitIncludeSelect,
|
|
391
|
+
join: emitIncludeJoin
|
|
392
|
+
};
|
|
393
|
+
export {
|
|
394
|
+
decodeIncluded,
|
|
395
|
+
includeHooks
|
|
396
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError2
|
|
3
|
+
} from "./ycwz42az.js";
|
|
4
|
+
|
|
5
|
+
// src/runtime/drift.ts
|
|
6
|
+
async function assertCompatible(pool, schema, recordedHash, source, options) {
|
|
7
|
+
const code = await codeHash(schema, source);
|
|
8
|
+
if (code.hash === recordedHash)
|
|
9
|
+
return;
|
|
10
|
+
if (code.artifact !== undefined) {
|
|
11
|
+
const { loadTrustedCatalog } = await import("./w8samvk1.js");
|
|
12
|
+
loadTrustedCatalog(code.artifact.text, code.artifact.hash);
|
|
13
|
+
} else {
|
|
14
|
+
const artifact = await readCatalogFile(source.catalogDir);
|
|
15
|
+
if (artifact !== undefined) {
|
|
16
|
+
const { loadTrustedCatalog } = await import("./w8samvk1.js");
|
|
17
|
+
loadTrustedCatalog(artifact.text, artifact.hash);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const { assertDrift } = await import("./p0cbr3g2.js");
|
|
21
|
+
await assertDrift(pool, code.hash, recordedHash, options);
|
|
22
|
+
}
|
|
23
|
+
async function codeHash(schema, source) {
|
|
24
|
+
if (source.catalog !== undefined)
|
|
25
|
+
return { hash: source.catalog.hash, artifact: source.catalog };
|
|
26
|
+
const listed = await readHashFile(source.catalogDir);
|
|
27
|
+
if (listed !== undefined)
|
|
28
|
+
return { hash: listed };
|
|
29
|
+
const { catalogHash } = await import("./w8samvk1.js");
|
|
30
|
+
return { hash: catalogHash(schemaCatalog(schema)) };
|
|
31
|
+
}
|
|
32
|
+
function schemaCatalog(schema) {
|
|
33
|
+
const value = Reflect.get(schema, "catalog");
|
|
34
|
+
if (typeof value !== "object" || value === null || !("objects" in value)) {
|
|
35
|
+
throw new OkmError2("OKM1520", "The schema has no catalog to compare.", {
|
|
36
|
+
fix: {
|
|
37
|
+
summary: "Pass the schema() result to connect, or a catalog artifact from okm build."
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
async function readHashFile(catalogDir) {
|
|
44
|
+
const text = await readText(`${artifactDir(catalogDir)}/catalog.hash`);
|
|
45
|
+
if (text === undefined)
|
|
46
|
+
return;
|
|
47
|
+
const hash = text.trim();
|
|
48
|
+
return hash.length === 0 ? undefined : hash;
|
|
49
|
+
}
|
|
50
|
+
async function readCatalogFile(catalogDir) {
|
|
51
|
+
const dir = artifactDir(catalogDir);
|
|
52
|
+
const hash = await readHashFile(catalogDir);
|
|
53
|
+
const text = await readText(`${dir}/catalog.json`);
|
|
54
|
+
if (hash === undefined || text === undefined)
|
|
55
|
+
return;
|
|
56
|
+
return { text, hash };
|
|
57
|
+
}
|
|
58
|
+
function artifactDir(catalogDir) {
|
|
59
|
+
if (catalogDir !== undefined)
|
|
60
|
+
return catalogDir.replace(/\/$/, "");
|
|
61
|
+
const cwd = globalThis.process?.cwd?.() ?? ".";
|
|
62
|
+
return `${cwd}/.okm`;
|
|
63
|
+
}
|
|
64
|
+
async function readText(path) {
|
|
65
|
+
const bun = globalThis.Bun;
|
|
66
|
+
if (bun !== undefined) {
|
|
67
|
+
const file = bun.file(path);
|
|
68
|
+
if (!await file.exists())
|
|
69
|
+
return;
|
|
70
|
+
return file.text();
|
|
71
|
+
}
|
|
72
|
+
const loader = globalThis.process?.getBuiltinModule;
|
|
73
|
+
if (loader === undefined)
|
|
74
|
+
return;
|
|
75
|
+
try {
|
|
76
|
+
return await loader("node:fs/promises").readFile(path, "utf8");
|
|
77
|
+
} catch {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
assertCompatible
|
|
83
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PgSession
|
|
3
|
+
} from "./7ck0dtry.js";
|
|
4
|
+
import {
|
|
5
|
+
driverErrors,
|
|
6
|
+
rejectClosed,
|
|
7
|
+
mapFailure,
|
|
8
|
+
runCall,
|
|
9
|
+
rowsFrom
|
|
10
|
+
} from "./xy79j5hq.js";
|
|
11
|
+
|
|
12
|
+
// src/adapters/pg/postgres-extra.ts
|
|
13
|
+
var RESET_ALL = "RESET ALL";
|
|
14
|
+
var UNLOCK = "SELECT pg_advisory_unlock_all()";
|
|
15
|
+
async function checkout(pool) {
|
|
16
|
+
if (pool.isClosed())
|
|
17
|
+
return rejectClosed();
|
|
18
|
+
const reserved = await reserveConnection(pool.sql, pool.acquireMs, pool.counters);
|
|
19
|
+
pool.counters.reserved += 1;
|
|
20
|
+
const local = new Set;
|
|
21
|
+
const session = new PgSession(reserved, pool.counters, "reserved", local, pool.isClosed, pool.poolInflight, pool.notices, pool.named);
|
|
22
|
+
let released = false;
|
|
23
|
+
return {
|
|
24
|
+
execute: (text, params, options) => runCall(pool.isClosed(), options, (watch) => session.query(text, params, watch)),
|
|
25
|
+
batch: (statements, options) => runCall(pool.isClosed(), options, async (watch) => {
|
|
26
|
+
const { runAtomicBatch } = await import("./dynq16vb.js");
|
|
27
|
+
return runAtomicBatch(session, statements, watch);
|
|
28
|
+
}),
|
|
29
|
+
cancel() {
|
|
30
|
+
session.cancel();
|
|
31
|
+
},
|
|
32
|
+
async release() {
|
|
33
|
+
if (released)
|
|
34
|
+
return;
|
|
35
|
+
released = true;
|
|
36
|
+
try {
|
|
37
|
+
await resetConnection(reserved, session.depth());
|
|
38
|
+
} finally {
|
|
39
|
+
pool.counters.reserved = Math.max(0, pool.counters.reserved - 1);
|
|
40
|
+
reserved.release();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async function describe(sql, text, params) {
|
|
46
|
+
const pending = sql.unsafe(text, asParams(params), { prepare: true });
|
|
47
|
+
const described = await pending.describe();
|
|
48
|
+
return {
|
|
49
|
+
columns: described.columns.map((column) => column.name),
|
|
50
|
+
parameterCount: described.types.length
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async function* stream(sql, text, params) {
|
|
54
|
+
const pending = sql.unsafe(text, asParams(params));
|
|
55
|
+
for await (const chunk of pending.cursor(64)) {
|
|
56
|
+
yield rowsFrom(chunk);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function reserveConnection(sql, acquireMs, counters) {
|
|
60
|
+
counters.waiting += 1;
|
|
61
|
+
let settled = false;
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
let timer;
|
|
64
|
+
if (acquireMs !== undefined) {
|
|
65
|
+
timer = setTimeout(() => {
|
|
66
|
+
settled = true;
|
|
67
|
+
counters.waiting = Math.max(0, counters.waiting - 1);
|
|
68
|
+
driverErrors().then((errors) => {
|
|
69
|
+
reject(errors.acquireTimeout());
|
|
70
|
+
});
|
|
71
|
+
}, acquireMs);
|
|
72
|
+
}
|
|
73
|
+
sql.reserve().then((connection) => {
|
|
74
|
+
if (settled) {
|
|
75
|
+
resetConnection(connection, 0).finally(() => {
|
|
76
|
+
connection.release();
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (timer !== undefined)
|
|
81
|
+
clearTimeout(timer);
|
|
82
|
+
counters.waiting = Math.max(0, counters.waiting - 1);
|
|
83
|
+
resolve(connection);
|
|
84
|
+
}, (error) => {
|
|
85
|
+
if (settled)
|
|
86
|
+
return;
|
|
87
|
+
if (timer !== undefined)
|
|
88
|
+
clearTimeout(timer);
|
|
89
|
+
counters.waiting = Math.max(0, counters.waiting - 1);
|
|
90
|
+
mapFailure(error).then(reject);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async function resetConnection(sql, depth) {
|
|
95
|
+
if (depth > 0)
|
|
96
|
+
await sql.unsafe("ROLLBACK").catch(() => {
|
|
97
|
+
return;
|
|
98
|
+
});
|
|
99
|
+
try {
|
|
100
|
+
await sql.unsafe(RESET_ALL);
|
|
101
|
+
await sql.unsafe(UNLOCK);
|
|
102
|
+
} catch {
|
|
103
|
+
await sql.unsafe("ROLLBACK").catch(() => {
|
|
104
|
+
return;
|
|
105
|
+
});
|
|
106
|
+
await sql.unsafe(RESET_ALL);
|
|
107
|
+
await sql.unsafe(UNLOCK);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function asParams(params) {
|
|
111
|
+
if (params === undefined)
|
|
112
|
+
return [];
|
|
113
|
+
return params;
|
|
114
|
+
}
|
|
115
|
+
export {
|
|
116
|
+
checkout,
|
|
117
|
+
describe,
|
|
118
|
+
stream
|
|
119
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import"./y9m15dfv.js";
|
|
2
|
+
import {
|
|
3
|
+
listTargets,
|
|
4
|
+
loadConfig
|
|
5
|
+
} from "./kynx7vbm.js";
|
|
6
|
+
|
|
7
|
+
// src/tooling/migrate/dev.ts
|
|
8
|
+
import { mkdirSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
async function devProject(cwd) {
|
|
11
|
+
const config = await loadConfig(cwd);
|
|
12
|
+
const named = listTargets(config).find((target) => target.name === "dev");
|
|
13
|
+
if (named !== undefined)
|
|
14
|
+
return `target ${named.name}
|
|
15
|
+
`;
|
|
16
|
+
const directory = join(cwd, config.out ?? ".okm", "dev-db");
|
|
17
|
+
mkdirSync(directory, { recursive: true });
|
|
18
|
+
const { open } = await import("./8b04d28c.js");
|
|
19
|
+
const pool = await open({ dataDir: directory });
|
|
20
|
+
try {
|
|
21
|
+
await pool.execute("select 1");
|
|
22
|
+
} finally {
|
|
23
|
+
await pool.close();
|
|
24
|
+
}
|
|
25
|
+
return `${directory}
|
|
26
|
+
`;
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
devProject
|
|
30
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
creationOrder2,
|
|
3
|
+
renameColumn2,
|
|
4
|
+
renameTable2,
|
|
5
|
+
serializeCatalog2,
|
|
6
|
+
catalogHash2,
|
|
7
|
+
loadTrustedCatalog2,
|
|
8
|
+
parseCatalog2
|
|
9
|
+
} from "./y9m15dfv.js";
|
|
10
|
+
export {
|
|
11
|
+
catalogHash2 as catalogHash,
|
|
12
|
+
creationOrder2 as creationOrder,
|
|
13
|
+
loadTrustedCatalog2 as loadTrustedCatalog,
|
|
14
|
+
parseCatalog2 as parseCatalog,
|
|
15
|
+
renameColumn2 as renameColumn,
|
|
16
|
+
renameTable2 as renameTable,
|
|
17
|
+
serializeCatalog2 as serializeCatalog
|
|
18
|
+
};
|