turbine-orm 0.81.0 → 0.90.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 +26 -25
- package/dist/checkout.d.ts +27 -2
- package/dist/checkout.js +75 -4
- package/dist/cjs/checkout.d.ts +27 -2
- package/dist/cjs/checkout.js +76 -3
- package/dist/cjs/cli/code-first-tags.d.ts +62 -0
- package/dist/cjs/cli/code-first-tags.js +124 -0
- package/dist/cjs/cli/compile-query.js +9 -0
- package/dist/cjs/cli/config.d.ts +35 -6
- package/dist/cjs/cli/config.js +17 -1
- package/dist/cjs/cli/destructive.d.ts +7 -4
- package/dist/cjs/cli/destructive.js +224 -20
- package/dist/cjs/cli/error-catalog.js +36 -0
- package/dist/cjs/cli/error-text.d.ts +15 -0
- package/dist/cjs/cli/error-text.js +40 -0
- package/dist/cjs/cli/index.d.ts +62 -4
- package/dist/cjs/cli/index.js +568 -108
- package/dist/cjs/cli/local-server-guard.d.ts +53 -0
- package/dist/cjs/cli/local-server-guard.js +119 -0
- package/dist/cjs/cli/local-server-output.d.ts +41 -0
- package/dist/cjs/cli/local-server-output.js +103 -0
- package/dist/cjs/cli/mcp.d.ts +8 -0
- package/dist/cjs/cli/mcp.js +121 -32
- package/dist/cjs/cli/migrate.d.ts +113 -5
- package/dist/cjs/cli/migrate.js +270 -21
- package/dist/cjs/cli/observe.d.ts +6 -1
- package/dist/cjs/cli/observe.js +85 -55
- package/dist/cjs/cli/pii-predicate-guard.d.ts +43 -23
- package/dist/cjs/cli/pii-predicate-guard.js +98 -37
- package/dist/cjs/cli/prisma-resolve.js +17 -13
- package/dist/cjs/cli/prisma-schema.js +12 -4
- package/dist/cjs/cli/studio-ui.generated.js +1 -1
- package/dist/cjs/cli/studio.d.ts +14 -2
- package/dist/cjs/cli/studio.js +244 -69
- package/dist/cjs/cli/ui.d.ts +1 -1
- package/dist/cjs/client.d.ts +558 -85
- package/dist/cjs/client.js +1270 -395
- package/dist/cjs/connection-guard.d.ts +13 -0
- package/dist/cjs/connection-guard.js +28 -0
- package/dist/cjs/connection-url.d.ts +51 -16
- package/dist/cjs/connection-url.js +67 -34
- package/dist/cjs/diagnostics.d.ts +81 -0
- package/dist/cjs/diagnostics.js +147 -0
- package/dist/cjs/dialect.d.ts +449 -20
- package/dist/cjs/dialect.js +117 -76
- package/dist/cjs/engine-config.d.ts +7 -6
- package/dist/cjs/errors.d.ts +126 -6
- package/dist/cjs/errors.js +256 -13
- package/dist/cjs/generate.d.ts +57 -7
- package/dist/cjs/generate.js +635 -279
- package/dist/cjs/global-filters-config.d.ts +59 -0
- package/dist/cjs/global-filters-config.js +367 -0
- package/dist/cjs/index.d.ts +9 -4
- package/dist/cjs/index.js +10 -2
- package/dist/cjs/introspect.d.ts +31 -6
- package/dist/cjs/introspect.js +108 -50
- package/dist/cjs/log-codes.d.ts +12 -0
- package/dist/cjs/log-codes.js +77 -0
- package/dist/cjs/logger.d.ts +87 -0
- package/dist/cjs/logger.js +98 -0
- package/dist/cjs/mssql.d.ts +8 -5
- package/dist/cjs/mssql.js +352 -65
- package/dist/cjs/mysql.d.ts +3 -5
- package/dist/cjs/mysql.js +420 -70
- package/dist/cjs/nested-write.d.ts +3 -0
- package/dist/cjs/nested-write.js +179 -114
- package/dist/cjs/pipeline-submittable.d.ts +12 -0
- package/dist/cjs/pipeline-submittable.js +118 -44
- package/dist/cjs/pipeline.js +21 -26
- package/dist/cjs/powdb-introspect.d.ts +5 -2
- package/dist/cjs/powdb-introspect.js +20 -15
- package/dist/cjs/powdb-shared.d.ts +36 -5
- package/dist/cjs/powdb-shared.js +67 -8
- package/dist/cjs/powdb.d.ts +4 -0
- package/dist/cjs/powdb.js +183 -51
- package/dist/cjs/powql.d.ts +394 -51
- package/dist/cjs/powql.js +1829 -284
- package/dist/cjs/prisma-compat.d.ts +23 -15
- package/dist/cjs/prisma-compat.js +507 -372
- package/dist/cjs/query/aggregates.d.ts +17 -1
- package/dist/cjs/query/aggregates.js +261 -29
- package/dist/cjs/query/batched-loader.d.ts +25 -6
- package/dist/cjs/query/batched-loader.js +103 -20
- package/dist/cjs/query/builder.d.ts +325 -184
- package/dist/cjs/query/builder.js +1452 -490
- package/dist/cjs/query/column-ref.d.ts +61 -0
- package/dist/cjs/query/column-ref.js +73 -0
- package/dist/cjs/query/compound-unique.d.ts +21 -0
- package/dist/cjs/query/compound-unique.js +98 -18
- package/dist/cjs/query/deferred.d.ts +53 -16
- package/dist/cjs/query/expr.d.ts +217 -0
- package/dist/cjs/query/expr.js +859 -0
- package/dist/cjs/query/filters.d.ts +155 -53
- package/dist/cjs/query/filters.js +613 -76
- package/dist/cjs/query/index.d.ts +2 -0
- package/dist/cjs/query/index.js +7 -1
- package/dist/cjs/query/json-value.d.ts +43 -0
- package/dist/cjs/query/json-value.js +59 -0
- package/dist/cjs/query/normalize-args.d.ts +87 -0
- package/dist/cjs/query/normalize-args.js +527 -0
- package/dist/cjs/query/option-surface.d.ts +16 -4
- package/dist/cjs/query/option-surface.js +57 -14
- package/dist/cjs/query/relation-names.d.ts +14 -0
- package/dist/cjs/query/relation-names.js +77 -18
- package/dist/cjs/query/relations.d.ts +30 -3
- package/dist/cjs/query/relations.js +219 -63
- package/dist/cjs/query/row-lock.d.ts +49 -0
- package/dist/cjs/query/row-lock.js +138 -0
- package/dist/cjs/query/sql-comment.d.ts +161 -0
- package/dist/cjs/query/sql-comment.js +381 -0
- package/dist/cjs/query/stream-idle.d.ts +132 -0
- package/dist/cjs/query/stream-idle.js +212 -0
- package/dist/cjs/query/table-client.d.ts +101 -0
- package/dist/cjs/query/table-client.js +74 -0
- package/dist/cjs/query/types.d.ts +677 -298
- package/dist/cjs/query/utils.d.ts +105 -6
- package/dist/cjs/query/utils.js +426 -19
- package/dist/cjs/query/warn-registry.d.ts +18 -0
- package/dist/cjs/query/warn-registry.js +18 -0
- package/dist/cjs/query/where-compile.d.ts +138 -14
- package/dist/cjs/query/where-compile.js +513 -29
- package/dist/cjs/query/where.d.ts +159 -59
- package/dist/cjs/query/where.js +716 -246
- package/dist/cjs/query/writes.d.ts +112 -50
- package/dist/cjs/query/writes.js +1498 -200
- package/dist/cjs/query-events.d.ts +4 -2
- package/dist/cjs/query-events.js +3 -1
- package/dist/cjs/realtime.d.ts +7 -3
- package/dist/cjs/realtime.js +13 -2
- package/dist/cjs/schema-builder.d.ts +55 -4
- package/dist/cjs/schema-builder.js +382 -18
- package/dist/cjs/schema-metadata.d.ts +21 -1
- package/dist/cjs/schema-metadata.js +29 -7
- package/dist/cjs/schema-sql.d.ts +75 -5
- package/dist/cjs/schema-sql.js +497 -45
- package/dist/cjs/schema.d.ts +26 -5
- package/dist/cjs/schema.js +110 -13
- package/dist/cjs/sql-placeholders.d.ts +56 -0
- package/dist/cjs/sql-placeholders.js +204 -0
- package/dist/cjs/sqlite.d.ts +75 -20
- package/dist/cjs/sqlite.js +593 -95
- package/dist/cjs/supplied-pool-types.d.ts +48 -0
- package/dist/cjs/supplied-pool-types.js +256 -0
- package/dist/cjs/transaction-control.d.ts +51 -0
- package/dist/cjs/transaction-control.js +316 -0
- package/dist/cjs/transaction-state.d.ts +342 -0
- package/dist/cjs/transaction-state.js +707 -0
- package/dist/cjs/typed-sql.d.ts +37 -3
- package/dist/cjs/typed-sql.js +102 -8
- package/dist/cli/code-first-tags.d.ts +62 -0
- package/dist/cli/code-first-tags.js +120 -0
- package/dist/cli/compile-query.js +9 -0
- package/dist/cli/config.d.ts +35 -6
- package/dist/cli/config.js +16 -1
- package/dist/cli/destructive.d.ts +7 -4
- package/dist/cli/destructive.js +224 -20
- package/dist/cli/error-catalog.js +36 -0
- package/dist/cli/error-text.d.ts +15 -0
- package/dist/cli/error-text.js +37 -0
- package/dist/cli/index.d.ts +62 -4
- package/dist/cli/index.js +569 -112
- package/dist/cli/local-server-guard.d.ts +53 -0
- package/dist/cli/local-server-guard.js +113 -0
- package/dist/cli/local-server-output.d.ts +41 -0
- package/dist/cli/local-server-output.js +98 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +121 -34
- package/dist/cli/migrate.d.ts +113 -5
- package/dist/cli/migrate.js +261 -21
- package/dist/cli/observe.d.ts +6 -1
- package/dist/cli/observe.js +84 -54
- package/dist/cli/pii-predicate-guard.d.ts +43 -23
- package/dist/cli/pii-predicate-guard.js +100 -35
- package/dist/cli/prisma-resolve.js +15 -11
- package/dist/cli/prisma-schema.js +12 -4
- package/dist/cli/studio-ui.generated.js +1 -1
- package/dist/cli/studio.d.ts +14 -2
- package/dist/cli/studio.js +246 -71
- package/dist/cli/ui.d.ts +1 -1
- package/dist/client.d.ts +558 -85
- package/dist/client.js +1275 -400
- package/dist/connection-guard.d.ts +13 -0
- package/dist/connection-guard.js +27 -0
- package/dist/connection-url.d.ts +51 -16
- package/dist/connection-url.js +63 -34
- package/dist/diagnostics.d.ts +81 -0
- package/dist/diagnostics.js +144 -0
- package/dist/dialect.d.ts +449 -20
- package/dist/dialect.js +115 -43
- package/dist/engine-config.d.ts +7 -6
- package/dist/errors.d.ts +126 -6
- package/dist/errors.js +252 -12
- package/dist/generate.d.ts +57 -7
- package/dist/generate.js +635 -281
- package/dist/global-filters-config.d.ts +59 -0
- package/dist/global-filters-config.js +361 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +4 -2
- package/dist/introspect.d.ts +31 -6
- package/dist/introspect.js +106 -50
- package/dist/log-codes.d.ts +12 -0
- package/dist/log-codes.js +74 -0
- package/dist/logger.d.ts +87 -0
- package/dist/logger.js +93 -0
- package/dist/mssql.d.ts +8 -5
- package/dist/mssql.js +354 -67
- package/dist/mysql.d.ts +3 -5
- package/dist/mysql.js +423 -73
- package/dist/nested-write.d.ts +3 -0
- package/dist/nested-write.js +177 -112
- package/dist/pipeline-submittable.d.ts +12 -0
- package/dist/pipeline-submittable.js +117 -44
- package/dist/pipeline.js +21 -26
- package/dist/powdb-introspect.d.ts +5 -2
- package/dist/powdb-introspect.js +21 -16
- package/dist/powdb-shared.d.ts +36 -5
- package/dist/powdb-shared.js +65 -8
- package/dist/powdb.d.ts +4 -0
- package/dist/powdb.js +183 -51
- package/dist/powql.d.ts +394 -51
- package/dist/powql.js +1836 -291
- package/dist/prisma-compat.d.ts +23 -15
- package/dist/prisma-compat.js +508 -373
- package/dist/query/aggregates.d.ts +17 -1
- package/dist/query/aggregates.js +263 -32
- package/dist/query/batched-loader.d.ts +25 -6
- package/dist/query/batched-loader.js +101 -21
- package/dist/query/builder.d.ts +325 -184
- package/dist/query/builder.js +1458 -495
- package/dist/query/column-ref.d.ts +61 -0
- package/dist/query/column-ref.js +66 -0
- package/dist/query/compound-unique.d.ts +21 -0
- package/dist/query/compound-unique.js +97 -19
- package/dist/query/deferred.d.ts +53 -16
- package/dist/query/expr.d.ts +217 -0
- package/dist/query/expr.js +848 -0
- package/dist/query/filters.d.ts +155 -53
- package/dist/query/filters.js +597 -72
- package/dist/query/index.d.ts +2 -0
- package/dist/query/index.js +4 -0
- package/dist/query/json-value.d.ts +43 -0
- package/dist/query/json-value.js +54 -0
- package/dist/query/normalize-args.d.ts +87 -0
- package/dist/query/normalize-args.js +517 -0
- package/dist/query/option-surface.d.ts +16 -4
- package/dist/query/option-surface.js +56 -13
- package/dist/query/relation-names.d.ts +14 -0
- package/dist/query/relation-names.js +77 -19
- package/dist/query/relations.d.ts +30 -3
- package/dist/query/relations.js +220 -67
- package/dist/query/row-lock.d.ts +49 -0
- package/dist/query/row-lock.js +131 -0
- package/dist/query/sql-comment.d.ts +161 -0
- package/dist/query/sql-comment.js +374 -0
- package/dist/query/stream-idle.d.ts +132 -0
- package/dist/query/stream-idle.js +203 -0
- package/dist/query/table-client.d.ts +101 -0
- package/dist/query/table-client.js +70 -0
- package/dist/query/types.d.ts +677 -298
- package/dist/query/utils.d.ts +105 -6
- package/dist/query/utils.js +414 -18
- package/dist/query/warn-registry.d.ts +18 -0
- package/dist/query/warn-registry.js +18 -0
- package/dist/query/where-compile.d.ts +138 -14
- package/dist/query/where-compile.js +508 -31
- package/dist/query/where.d.ts +159 -59
- package/dist/query/where.js +711 -248
- package/dist/query/writes.d.ts +112 -50
- package/dist/query/writes.js +1496 -202
- package/dist/query-events.d.ts +4 -2
- package/dist/query-events.js +3 -1
- package/dist/realtime.d.ts +7 -3
- package/dist/realtime.js +13 -2
- package/dist/schema-builder.d.ts +55 -4
- package/dist/schema-builder.js +381 -18
- package/dist/schema-metadata.d.ts +21 -1
- package/dist/schema-metadata.js +28 -7
- package/dist/schema-sql.d.ts +75 -5
- package/dist/schema-sql.js +494 -44
- package/dist/schema.d.ts +26 -5
- package/dist/schema.js +109 -13
- package/dist/sql-placeholders.d.ts +56 -0
- package/dist/sql-placeholders.js +200 -0
- package/dist/sqlite.d.ts +75 -20
- package/dist/sqlite.js +597 -99
- package/dist/supplied-pool-types.d.ts +48 -0
- package/dist/supplied-pool-types.js +247 -0
- package/dist/transaction-control.d.ts +51 -0
- package/dist/transaction-control.js +311 -0
- package/dist/transaction-state.d.ts +342 -0
- package/dist/transaction-state.js +696 -0
- package/dist/typed-sql.d.ts +37 -3
- package/dist/typed-sql.js +100 -8
- package/package.json +7 -4
- package/skills/turbine-orm/SKILL.md +56 -6
|
@@ -55,7 +55,10 @@
|
|
|
55
55
|
* @module
|
|
56
56
|
*/
|
|
57
57
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
exports.STITCH_ONLY_FIELDS = void 0;
|
|
58
59
|
exports.defaultProjectionFields = defaultProjectionFields;
|
|
60
|
+
exports.stitchOnlyFields = stitchOnlyFields;
|
|
61
|
+
exports.markStitchOnly = markStitchOnly;
|
|
59
62
|
exports.assertProjectionShape = assertProjectionShape;
|
|
60
63
|
exports.includeKeysForBatching = includeKeysForBatching;
|
|
61
64
|
exports.stripFields = stripFields;
|
|
@@ -250,14 +253,40 @@ includePii) {
|
|
|
250
253
|
return hidden.size === 0 ? undefined : { hidden, visible };
|
|
251
254
|
}
|
|
252
255
|
/**
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
* were added ONLY for stitching and must be stripped from the final entities.
|
|
256
|
+
* Key under which {@link includeKeysForBatching} records the fields IT added to
|
|
257
|
+
* a `select`, as a `ReadonlySet<string>` of field names.
|
|
256
258
|
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
259
|
+
* Why it exists: naming a PII-tagged column in `select` is refused unless the
|
|
260
|
+
* query passes `includePii: UNSAFE` (see `resolveProjection`), and the loader
|
|
261
|
+
* has to project a correlation or ordering column that may itself be tagged.
|
|
262
|
+
* That column is stripped from every entity before the caller sees it, so it is
|
|
263
|
+
* the one legitimate way a PII name reaches a `select` without the caller
|
|
264
|
+
* writing it. The marker is a symbol key: `Object.keys`, `Object.entries`,
|
|
265
|
+
* spreads of a parsed body and `JSON.stringify` never see one, and
|
|
266
|
+
* `JSON.parse` cannot produce one, so request data cannot forge the exemption.
|
|
260
267
|
*/
|
|
268
|
+
exports.STITCH_ONLY_FIELDS = Symbol.for('turbine.stitchOnlyFields');
|
|
269
|
+
/** The fields the batched loader (not the caller) added to this `select`, if any. */
|
|
270
|
+
function stitchOnlyFields(select) {
|
|
271
|
+
if (!select)
|
|
272
|
+
return undefined;
|
|
273
|
+
const marked = select[exports.STITCH_ONLY_FIELDS];
|
|
274
|
+
return marked instanceof Set ? marked : undefined;
|
|
275
|
+
}
|
|
276
|
+
/** Record `fields` on `select` as added by an engine loader, not by the caller. Returns `select`. */
|
|
277
|
+
function markStitchOnly(select, fields) {
|
|
278
|
+
// Non-enumerable, like the other engine-written markers: the select object is
|
|
279
|
+
// passed by reference from here to the child build, and an enumerable symbol
|
|
280
|
+
// would show up in deep-equality comparisons of the projection.
|
|
281
|
+
if (fields.length > 0) {
|
|
282
|
+
Object.defineProperty(select, exports.STITCH_ONLY_FIELDS, {
|
|
283
|
+
value: new Set(fields),
|
|
284
|
+
enumerable: false,
|
|
285
|
+
configurable: true,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
return select;
|
|
289
|
+
}
|
|
261
290
|
/**
|
|
262
291
|
* The two projection SHAPE rules from `resolveProjection`, checked on the RAW
|
|
263
292
|
* caller args BEFORE `includeKeysForBatching` adjusts them. The adjustment
|
|
@@ -279,6 +308,16 @@ function assertProjectionShape(table, select, omit) {
|
|
|
279
308
|
throw new errors_js_1.ValidationError((0, utils_js_1.selectOmitExclusiveMessage)(table));
|
|
280
309
|
}
|
|
281
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Adjust a `select`/`omit` pair so that `fields` are guaranteed present in the
|
|
313
|
+
* query result, returning the adjusted projection plus the list of fields that
|
|
314
|
+
* were added ONLY for stitching and must be stripped from the final entities.
|
|
315
|
+
*
|
|
316
|
+
* Used both for the base query (parent keys) and each follow-up query (child
|
|
317
|
+
* keys) so a caller's `select: { title: true }` on a relation still stitches even
|
|
318
|
+
* though the FK was not requested, and the FK never appears in the output. A
|
|
319
|
+
* returned `select` carries {@link STITCH_ONLY_FIELDS} for the fields added here.
|
|
320
|
+
*/
|
|
282
321
|
function includeKeysForBatching(
|
|
283
322
|
/**
|
|
284
323
|
* The table the projection is compiled against. `select` / `omit` keys are
|
|
@@ -331,7 +370,7 @@ defaultProjection) {
|
|
|
331
370
|
next[f] = true;
|
|
332
371
|
strip.push(f); // not requested by the caller, added only to stitch
|
|
333
372
|
}
|
|
334
|
-
return { select: next, omit, strip };
|
|
373
|
+
return { select: markStitchOnly(next, strip), omit, strip };
|
|
335
374
|
}
|
|
336
375
|
if (omit) {
|
|
337
376
|
const next = { ...omit };
|
|
@@ -357,7 +396,7 @@ defaultProjection) {
|
|
|
357
396
|
explicit[f] = true;
|
|
358
397
|
for (const f of hiddenKeys)
|
|
359
398
|
explicit[f] = true;
|
|
360
|
-
return { select: explicit, omit: undefined, strip: hiddenKeys };
|
|
399
|
+
return { select: markStitchOnly(explicit, hiddenKeys), omit: undefined, strip: hiddenKeys };
|
|
361
400
|
}
|
|
362
401
|
return { select, omit, strip: [] };
|
|
363
402
|
}
|
|
@@ -439,8 +478,22 @@ function resolveCountRelations(parentMeta, countSpec) {
|
|
|
439
478
|
}
|
|
440
479
|
return out;
|
|
441
480
|
}
|
|
442
|
-
/**
|
|
481
|
+
/**
|
|
482
|
+
* Stringified stitch key, robust to number/uuid/bigint type drift across a join.
|
|
483
|
+
* A binary key is keyed by its bytes: `String()` of a Buffer decodes it as
|
|
484
|
+
* UTF-8, which maps different invalid sequences to the same replacement text.
|
|
485
|
+
* A Date by its instant, which `String()` truncates to the second.
|
|
486
|
+
*/
|
|
443
487
|
function keyOf(value) {
|
|
488
|
+
if (value instanceof Uint8Array) {
|
|
489
|
+
// No Buffer: this module runs on edge runtimes too.
|
|
490
|
+
let hex = '\u0000bytes:';
|
|
491
|
+
for (const byte of value)
|
|
492
|
+
hex += byte.toString(16).padStart(2, '0');
|
|
493
|
+
return hex;
|
|
494
|
+
}
|
|
495
|
+
if (value instanceof Date)
|
|
496
|
+
return `\u0000date:${value.getTime()}`;
|
|
444
497
|
return String(value);
|
|
445
498
|
}
|
|
446
499
|
/**
|
|
@@ -609,6 +662,34 @@ function seedRelationKeys(parents, parentMeta, resolved, hasCount) {
|
|
|
609
662
|
parent._count = existingCount ?? {};
|
|
610
663
|
}
|
|
611
664
|
}
|
|
665
|
+
/**
|
|
666
|
+
* A to-many relation's per-parent page (`skip` / `take` are folded into
|
|
667
|
+
* `offset` / `limit` at the args seam), validated as the join plan validates
|
|
668
|
+
* it: a non-negative integer, numeric strings coerced. Checked before anything
|
|
669
|
+
* runs, so both strategies accept and refuse the same values.
|
|
670
|
+
*/
|
|
671
|
+
function relationPage(options, table) {
|
|
672
|
+
const check = (value, arg) => {
|
|
673
|
+
if (value === undefined)
|
|
674
|
+
return undefined;
|
|
675
|
+
const n = Number(value);
|
|
676
|
+
if (!Number.isSafeInteger(n) || n < 0) {
|
|
677
|
+
throw new errors_js_1.ValidationError(`${arg} on "${table}" must be a non-negative integer, received: ${String(value)}`);
|
|
678
|
+
}
|
|
679
|
+
return n;
|
|
680
|
+
};
|
|
681
|
+
return {
|
|
682
|
+
limit: check(options.limit, 'relation limit'),
|
|
683
|
+
offset: check(options.offset, 'relation offset'),
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
/** One parent's window of its own related rows. */
|
|
687
|
+
function pageOf(rows, page) {
|
|
688
|
+
if (page.limit === undefined && !page.offset)
|
|
689
|
+
return rows;
|
|
690
|
+
const start = page.offset ?? 0;
|
|
691
|
+
return rows.slice(start, page.limit === undefined ? undefined : start + page.limit);
|
|
692
|
+
}
|
|
612
693
|
/**
|
|
613
694
|
* hasMany / hasOne / belongsTo: one follow-up `SELECT ... WHERE childKey = ANY($1)`
|
|
614
695
|
* (chunked), grouped by the correlation key and attached (array vs single-or-null).
|
|
@@ -630,6 +711,7 @@ async function loadToOneOrMany(ctx, parents, rel, relName, options, timeout, dep
|
|
|
630
711
|
assertCorrelationKeyProjected(parents, parentKeyField, relName, ctx.parentMeta.name);
|
|
631
712
|
const keys = uniqueKeys(parents, parentKeyField);
|
|
632
713
|
const single = rel.type === 'belongsTo' || rel.type === 'hasOne';
|
|
714
|
+
const page = single ? {} : relationPage(options, ctx.parentMeta.name);
|
|
633
715
|
// The follow-up must project the child correlation key even if the caller's
|
|
634
716
|
// select/omit excluded it; strip it back off afterwards so the shape matches join.
|
|
635
717
|
//
|
|
@@ -648,7 +730,7 @@ async function loadToOneOrMany(ctx, parents, rel, relName, options, timeout, dep
|
|
|
648
730
|
// again afterwards). `null` means this relation keeps the client-side slice,
|
|
649
731
|
// which is the case for every shape whose ordering does not force WHICH rows
|
|
650
732
|
// the limit keeps. See {@link partitionOrderBy} and {@link boundedChildQuery}.
|
|
651
|
-
const windowOrder = single ||
|
|
733
|
+
const windowOrder = single || page.limit === undefined ? null : partitionOrderBy(targetMeta, options.orderBy);
|
|
652
734
|
const pushDownLimit = windowOrder !== null && ctx.buildPartitionLimit !== undefined;
|
|
653
735
|
// THE ONE PII EXCEPTION IN THE READ PATH, recorded here because the contract
|
|
654
736
|
// in schema.ts says a PII column is excluded from every default projection
|
|
@@ -699,7 +781,8 @@ async function loadToOneOrMany(ctx, parents, rel, relName, options, timeout, dep
|
|
|
699
781
|
const chunkResults = await Promise.all(chunks.map(async (chunk) => {
|
|
700
782
|
const deferred = buildChunk(chunk);
|
|
701
783
|
const bounded = pushDownLimit
|
|
702
|
-
?
|
|
784
|
+
? // The first offset + limit rows of each parent; the slice below drops the offset.
|
|
785
|
+
boundedChildQuery(ctx, deferred, childKeyCol, windowOrder ?? [], (page.offset ?? 0) + page.limit)
|
|
703
786
|
: deferred;
|
|
704
787
|
const result = await ctx.exec(bounded.sql, bounded.params, bounded.preparedName);
|
|
705
788
|
if (bounded !== deferred)
|
|
@@ -721,14 +804,13 @@ async function loadToOneOrMany(ctx, parents, rel, relName, options, timeout, dep
|
|
|
721
804
|
// what was true of the parent side until this week.
|
|
722
805
|
assertCorrelationKeyProjected(allChildren, childKeyField, relName, targetMeta.name);
|
|
723
806
|
const byKey = groupBy(allChildren, childKeyField);
|
|
724
|
-
const limit = options.limit;
|
|
725
807
|
for (const parent of parents) {
|
|
726
808
|
const bucket = byKey.get(keyOf(parent[parentKeyField])) ?? [];
|
|
727
809
|
if (single) {
|
|
728
810
|
parent[relName] = bucket[0] ?? null;
|
|
729
811
|
}
|
|
730
812
|
else {
|
|
731
|
-
parent[relName] =
|
|
813
|
+
parent[relName] = pageOf(bucket, page);
|
|
732
814
|
}
|
|
733
815
|
}
|
|
734
816
|
stripFields(allChildren, proj.strip);
|
|
@@ -789,7 +871,7 @@ function boundedChildQuery(ctx, deferred, partitionColumn, orderBy, limit) {
|
|
|
789
871
|
return {
|
|
790
872
|
sql,
|
|
791
873
|
params: [...deferred.params, limit],
|
|
792
|
-
preparedName: deferred.preparedName ? (0, utils_js_1.
|
|
874
|
+
preparedName: deferred.preparedName ? (0, utils_js_1.boundedPreparedName)(sql) : deferred.preparedName,
|
|
793
875
|
transform: deferred.transform,
|
|
794
876
|
};
|
|
795
877
|
}
|
|
@@ -829,6 +911,7 @@ async function loadManyToMany(ctx, parents, rel, relName, options, timeout, dept
|
|
|
829
911
|
const targetPkCol = targetMeta.primaryKey[0];
|
|
830
912
|
const parentRefField = ctx.parentMeta.reverseColumnMap[sourceRefCol] ?? sourceRefCol;
|
|
831
913
|
const targetPkField = targetMeta.reverseColumnMap[targetPkCol] ?? targetPkCol;
|
|
914
|
+
const page = relationPage(options, ctx.parentMeta.name);
|
|
832
915
|
assertCorrelationKeyProjected(parents, parentRefField, relName, ctx.parentMeta.name);
|
|
833
916
|
// No early return on zero parent keys: the code below flows through
|
|
834
917
|
// naturally (zero junction chunks, zero target chunks), and the compile-only
|
|
@@ -920,7 +1003,7 @@ async function loadManyToMany(ctx, parents, rel, relName, options, timeout, dept
|
|
|
920
1003
|
// link, which spends exactly the bytes the pushdown exists to save; and the
|
|
921
1004
|
// bound would still have to respect a `limit` measured per parent, not per
|
|
922
1005
|
// fetched row. So the m2m loader keeps the slice below, on every engine.
|
|
923
|
-
const
|
|
1006
|
+
const end = page.limit === undefined ? undefined : (page.offset ?? 0) + page.limit;
|
|
924
1007
|
for (const parent of parents) {
|
|
925
1008
|
const linked = new Set((targetsBySource.get(keyOf(parent[parentRefField])) ?? []).map(keyOf));
|
|
926
1009
|
if (linked.size === 0) {
|
|
@@ -929,13 +1012,13 @@ async function loadManyToMany(ctx, parents, rel, relName, options, timeout, dept
|
|
|
929
1012
|
}
|
|
930
1013
|
const out = [];
|
|
931
1014
|
for (const t of targetsInOrder) {
|
|
932
|
-
|
|
1015
|
+
// Checked before the push, so `limit: 0` keeps nothing.
|
|
1016
|
+
if (end !== undefined && out.length >= end)
|
|
1017
|
+
break;
|
|
1018
|
+
if (linked.has(keyOf(t[targetPkField])))
|
|
933
1019
|
out.push(t);
|
|
934
|
-
if (limit !== undefined && out.length >= limit)
|
|
935
|
-
break;
|
|
936
|
-
}
|
|
937
1020
|
}
|
|
938
|
-
parent[relName] = out;
|
|
1021
|
+
parent[relName] = pageOf(out, { offset: page.offset });
|
|
939
1022
|
}
|
|
940
1023
|
stripFields(targetsInOrder, proj.strip);
|
|
941
1024
|
}
|