@prisma/orm-family-sql 8.0.0-rc.18-dev.3 → 8.0.0-rc.18-dev.5
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/builder.d.mts +1 -1
- package/dist/builder__runtime.d.mts +3 -3
- package/dist/builder__runtime.mjs +1 -1
- package/dist/builder__types.d.mts +3 -2
- package/dist/collection-methods-BnR4UjcW-tiz3frtf.d.mts +77 -0
- package/dist/collection-methods-BnR4UjcW-tiz3frtf.d.mts.map +1 -0
- package/dist/collection-methods-DoBrRR69.d.mts +1 -0
- package/dist/{db-BmrN9nRS-DEogPltL.d.mts → db-BmrN9nRS-CDq1n2be.d.mts} +3 -2
- package/dist/db-BmrN9nRS-CDq1n2be.d.mts.map +1 -0
- package/dist/{index-qr6LA3dl.d.mts → index-CmKqLvvO.d.mts} +4 -4
- package/dist/{index-qr6LA3dl.d.mts.map → index-CmKqLvvO.d.mts.map} +1 -1
- package/dist/{index-reference-CflkzYSd.d.mts → index-reference-DJX-CNsb-D2qUlYq2.d.mts} +12 -3
- package/dist/index-reference-DJX-CNsb-D2qUlYq2.d.mts.map +1 -0
- package/dist/{index-reference-D693Lu-E.mjs → index-reference-DR62gjQS.mjs} +16 -3
- package/dist/index-reference-DR62gjQS.mjs.map +1 -0
- package/dist/index-reference-ZZrszBDq.d.mts +1 -0
- package/dist/orm-client.d.mts +63 -17
- package/dist/orm-client.d.mts.map +1 -1
- package/dist/orm-client.mjs +349 -341
- package/dist/orm-client.mjs.map +1 -1
- package/dist/{prepared-statement-Bs9TKj5u-CInk8vXF.d.mts → prepared-statement-BwHkxfuI-CKkkrS6r.d.mts} +9 -6
- package/dist/prepared-statement-BwHkxfuI-CKkkrS6r.d.mts.map +1 -0
- package/dist/{query-lane-context-C2AXsoFa-COSQOvZz.d.mts → query-lane-context-C42-u9L1-Bxa4DkI_.d.mts} +7 -2
- package/dist/query-lane-context-C42-u9L1-Bxa4DkI_.d.mts.map +1 -0
- package/dist/query-lane-context-DW5q2RAY.d.mts +1 -0
- package/dist/relational-core.d.mts +3 -3
- package/dist/relational-core__aggregate-descriptor-registry.d.mts +1 -1
- package/dist/relational-core__codec-descriptor-registry.d.mts +1 -1
- package/dist/relational-core__collection-methods.d.mts +3 -0
- package/dist/relational-core__collection-methods.mjs +1 -0
- package/dist/relational-core__index-reference.d.mts +3 -2
- package/dist/relational-core__index-reference.mjs +2 -2
- package/dist/relational-core__query-lane-context.d.mts +2 -2
- package/dist/relational-core__types.d.mts +2 -2
- package/dist/runtime.d.mts +3 -3
- package/dist/runtime.mjs +2 -1
- package/dist/runtime.mjs.map +1 -1
- package/dist/runtime__internal__prepared-query.d.mts +1 -1
- package/dist/types-BkA6tyT-.d.mts +1 -0
- package/dist/{types-D09NAayg-CNrpjo7Z.d.mts → types-Cl4MLNrS-lbf-K25i.d.mts} +3 -3
- package/dist/{types-D09NAayg-CNrpjo7Z.d.mts.map → types-Cl4MLNrS-lbf-K25i.d.mts.map} +1 -1
- package/package.json +19 -18
- package/dist/db-BmrN9nRS-DEogPltL.d.mts.map +0 -1
- package/dist/index-reference-CflkzYSd.d.mts.map +0 -1
- package/dist/index-reference-D693Lu-E.mjs.map +0 -1
- package/dist/prepared-statement-Bs9TKj5u-CInk8vXF.d.mts.map +0 -1
- package/dist/query-lane-context-BsZs5lvB.d.mts +0 -1
- package/dist/query-lane-context-C2AXsoFa-COSQOvZz.d.mts.map +0 -1
- package/dist/types-DAkmn9FV.d.mts +0 -1
package/dist/orm-client.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { C as lockStrengthCapabilities, S as lockOptionCapabilities, T as missin
|
|
|
6
6
|
import { a as isExpression, s as toExpr, t as ExpressionImpl } from "./expression-impl-B-XNINxr-vYwKVFeP.mjs";
|
|
7
7
|
import { n as codecRefForStorageColumn } from "./codec-descriptor-registry-CYK0Wzja.mjs";
|
|
8
8
|
import { t as createFunctions } from "./functions-0YWByawj.mjs";
|
|
9
|
-
import { t as createIndexReferences } from "./index-reference-
|
|
9
|
+
import { t as createIndexReferences } from "./index-reference-DR62gjQS.mjs";
|
|
10
10
|
import { o as settlementOf } from "./transaction-state-BfXhs7D7-3k10jZ8I.mjs";
|
|
11
11
|
import { structuredError } from "@prisma/orm-framework/utils/structured-error";
|
|
12
12
|
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
@@ -1252,6 +1252,14 @@ function buildPrimaryKeyJoinOn(left, right, primaryKeyColumns) {
|
|
|
1252
1252
|
if (primaryKeyColumns.length === 1 && firstColumn !== void 0) return EqColJoinOn.of(left.column(firstColumn), right.column(firstColumn));
|
|
1253
1253
|
return AndExpr.of(primaryKeyColumns.map((column) => BinaryExpr.eq(left.column(column), right.column(column))));
|
|
1254
1254
|
}
|
|
1255
|
+
function labeledVariantColumn(contract, variantTable, column) {
|
|
1256
|
+
const { namespaceId, tableName } = variantTable.storage;
|
|
1257
|
+
return ProjectionItem.of(variantColumnLabel(variantTable, column), variantTable.column(column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column));
|
|
1258
|
+
}
|
|
1259
|
+
function variantReturning(contract, variantTable, variantModelName, keyColumns) {
|
|
1260
|
+
const { namespaceId, tableName } = variantTable.storage;
|
|
1261
|
+
return getColumnsReadOnTable(contract, namespaceId, variantModelName, tableName).filter((column) => !keyColumns.includes(column)).map((column) => labeledVariantColumn(contract, variantTable, column));
|
|
1262
|
+
}
|
|
1255
1263
|
function buildMtiJoins(contract, tables, polyInfo, variantValue, selectedColumnsByVariant) {
|
|
1256
1264
|
const joins = [];
|
|
1257
1265
|
const projection = [];
|
|
@@ -1272,7 +1280,7 @@ function buildMtiJoins(contract, tables, polyInfo, variantValue, selectedColumns
|
|
|
1272
1280
|
for (const col of variantColumns) {
|
|
1273
1281
|
if (pkColumns.includes(col)) continue;
|
|
1274
1282
|
if (selectedColumnsByVariant !== void 0 && selectedVariantColumns?.has(col) !== true) continue;
|
|
1275
|
-
projection.push(
|
|
1283
|
+
projection.push(labeledVariantColumn(contract, variantTable, col));
|
|
1276
1284
|
}
|
|
1277
1285
|
}
|
|
1278
1286
|
return {
|
|
@@ -1610,9 +1618,12 @@ function aliasTarget(namespaceId, tableName) {
|
|
|
1610
1618
|
tableName
|
|
1611
1619
|
});
|
|
1612
1620
|
}
|
|
1613
|
-
function
|
|
1621
|
+
function projectTableColumn(contract, target, column) {
|
|
1614
1622
|
const { namespaceId, tableName } = target.storage;
|
|
1615
|
-
return
|
|
1623
|
+
return ProjectionItem.of(column, target.column(column), codecRefForStorageColumn(contract.storage, namespaceId, tableName, column));
|
|
1624
|
+
}
|
|
1625
|
+
function projectTableColumns(contract, target, columns) {
|
|
1626
|
+
return columns.map((column) => projectTableColumn(contract, target, column));
|
|
1616
1627
|
}
|
|
1617
1628
|
function returningProjection(contract, modelName, target, returningColumns) {
|
|
1618
1629
|
const { namespaceId, tableName } = target.storage;
|
|
@@ -1672,17 +1683,19 @@ function conflictSkipClause(target, conflictSkip) {
|
|
|
1672
1683
|
if (conflictSkip.columns.length === 0) return InsertOnConflict.doNothing();
|
|
1673
1684
|
return InsertOnConflict.on(conflictSkip.columns.map((column) => target.column(column))).doNothing();
|
|
1674
1685
|
}
|
|
1686
|
+
function insertAst(contract, target, rows, conflictSkip) {
|
|
1687
|
+
const { namespaceId, tableName } = target.storage;
|
|
1688
|
+
const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
|
|
1689
|
+
return InsertAst.into(target.tableSource(contract)).withRows(normalizedRows).withOnConflict(conflictSkipClause(target, conflictSkip));
|
|
1690
|
+
}
|
|
1675
1691
|
function compileInsertReturning(contract, namespaceId, modelName, tableName, rows, returningColumns, conflictSkip) {
|
|
1676
1692
|
const target = aliasTarget(namespaceId, tableName);
|
|
1677
|
-
const
|
|
1678
|
-
const ast = InsertAst.into(target.tableSource(contract)).withRows(normalizedRows).withOnConflict(conflictSkipClause(target, conflictSkip)).withReturning(returningProjection(contract, modelName, target, returningColumns));
|
|
1693
|
+
const ast = insertAst(contract, target, rows, conflictSkip).withReturning(returningProjection(contract, modelName, target, returningColumns));
|
|
1679
1694
|
const { params } = deriveParamsFromAst(ast);
|
|
1680
1695
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1681
1696
|
}
|
|
1682
1697
|
function compileInsertCount(contract, namespaceId, tableName, rows, conflictSkip) {
|
|
1683
|
-
const
|
|
1684
|
-
const { rows: normalizedRows } = normalizeInsertRows(contract, namespaceId, tableName, rows);
|
|
1685
|
-
const ast = InsertAst.into(target.tableSource(contract)).withRows(normalizedRows).withOnConflict(conflictSkipClause(target, conflictSkip));
|
|
1698
|
+
const ast = insertAst(contract, aliasTarget(namespaceId, tableName), rows, conflictSkip);
|
|
1686
1699
|
const { params } = deriveParamsFromAst(ast);
|
|
1687
1700
|
return buildOrmQueryPlan(contract, ast, params);
|
|
1688
1701
|
}
|
|
@@ -1718,31 +1731,15 @@ function groupRowsByColumnSignature(rows) {
|
|
|
1718
1731
|
if (currentGroup.length > 0) groups.push(currentGroup);
|
|
1719
1732
|
return groups;
|
|
1720
1733
|
}
|
|
1721
|
-
function
|
|
1722
|
-
|
|
1723
|
-
method: "create",
|
|
1724
|
-
namespaceId,
|
|
1725
|
-
tableName
|
|
1726
|
-
} });
|
|
1727
|
-
return groupRowsByColumnSignature(rows).map((group) => compileInsertReturning(contract, namespaceId, modelName, tableName, group, returningColumns, conflictSkip));
|
|
1728
|
-
}
|
|
1729
|
-
function compileInsertCountSplit(contract, namespaceId, tableName, rows, conflictSkip) {
|
|
1730
|
-
if (rows.length === 0) throw ormError("ORM.MUTATION_DATA_MISSING", "createAndCount() requires at least one row", { meta: {
|
|
1731
|
-
method: "createAndCount",
|
|
1732
|
-
namespaceId,
|
|
1733
|
-
tableName
|
|
1734
|
-
} });
|
|
1735
|
-
return groupRowsByColumnSignature(rows).map((group) => compileInsertCount(contract, namespaceId, tableName, group, conflictSkip));
|
|
1736
|
-
}
|
|
1737
|
-
function compileUpsertReturning(contract, namespaceId, modelName, tableName, createValues, updateValues, conflictColumns, returningColumns) {
|
|
1734
|
+
function upsertAst(contract, target, createValues, conflictColumns, updateSet) {
|
|
1735
|
+
const { namespaceId, tableName } = target.storage;
|
|
1738
1736
|
const createAssignments = toParamAssignments(contract, namespaceId, tableName, createValues);
|
|
1739
|
-
const updateAssignments = Object.keys(updateValues).length > 0 ? toParamAssignments(contract, namespaceId, tableName, updateValues) : void 0;
|
|
1740
|
-
const target = aliasTarget(namespaceId, tableName);
|
|
1741
1737
|
const conflictTarget = InsertOnConflict.on(conflictColumns.map((column) => target.column(column)));
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1738
|
+
return InsertAst.into(target.tableSource(contract)).withRows([createAssignments.assignments]).withOnConflict(updateSet === void 0 ? conflictTarget.doNothing() : conflictTarget.doUpdateSet(updateSet));
|
|
1739
|
+
}
|
|
1740
|
+
function updateAssignments(contract, target, values) {
|
|
1741
|
+
const { namespaceId, tableName } = target.storage;
|
|
1742
|
+
return toParamAssignments(contract, namespaceId, tableName, values).assignments;
|
|
1746
1743
|
}
|
|
1747
1744
|
function updateAst(contract, tables, setValues, where) {
|
|
1748
1745
|
const { root } = tables;
|
|
@@ -2630,46 +2627,6 @@ function consumeIncludeRows(context, state, namespaceId, modelName, rows) {
|
|
|
2630
2627
|
* include query can't observe an already-deleted row, so delete reads
|
|
2631
2628
|
* its snapshot before issuing the DELETE (see `collection.ts`).
|
|
2632
2629
|
*/
|
|
2633
|
-
function reloadMutationRowsByIdentities(options) {
|
|
2634
|
-
const { context, runtime, tables, modelName, namespaceId, identityRows, selectedFields, includes } = options;
|
|
2635
|
-
const { contract } = context;
|
|
2636
|
-
const { tableName } = tables.root.storage;
|
|
2637
|
-
if (identityRows.length === 0) return emptyResult();
|
|
2638
|
-
const identityColumns = resolveRowIdentityColumns(contract, namespaceId, tableName);
|
|
2639
|
-
if (identityColumns.length === 0) throw ormError("ORM.ROW_IDENTITY_MISSING", `Cannot load includes for the mutation result on model "${modelName}": table "${tableName}" has no primary key or unique constraint to key the include read-back on.`, { meta: {
|
|
2640
|
-
model: modelName,
|
|
2641
|
-
table: tableName
|
|
2642
|
-
} });
|
|
2643
|
-
const identityFilter = buildIdentityInFilter(contract, tables.root, identityColumns, identityRows);
|
|
2644
|
-
if (!identityFilter) return emptyResult();
|
|
2645
|
-
return dispatchCollectionRows({
|
|
2646
|
-
context,
|
|
2647
|
-
runtime,
|
|
2648
|
-
state: {
|
|
2649
|
-
...emptyState(tables),
|
|
2650
|
-
filters: [identityFilter],
|
|
2651
|
-
selectedFields,
|
|
2652
|
-
includes
|
|
2653
|
-
},
|
|
2654
|
-
modelName,
|
|
2655
|
-
namespaceId
|
|
2656
|
-
});
|
|
2657
|
-
}
|
|
2658
|
-
function emptyResult() {
|
|
2659
|
-
return new AsyncIterableResult((async function* () {})());
|
|
2660
|
-
}
|
|
2661
|
-
function buildIdentityInFilter(contract, table, identityColumns, identityRows) {
|
|
2662
|
-
const { storage } = table;
|
|
2663
|
-
const [singleColumn, ...rest] = identityColumns;
|
|
2664
|
-
if (singleColumn !== void 0 && rest.length === 0) {
|
|
2665
|
-
const values = identityRows.map((row) => row[singleColumn]).filter((value) => value !== void 0);
|
|
2666
|
-
if (values.length === 0) return;
|
|
2667
|
-
return BinaryExpr.in(table.column(singleColumn), ListExpression.of(values.map((value) => paramRefForStorageColumn(contract, storage, singleColumn, value))));
|
|
2668
|
-
}
|
|
2669
|
-
if (identityRows.length === 0) return;
|
|
2670
|
-
const tuples = identityRows.map((row) => AndExpr.of(identityColumns.map((column) => BinaryExpr.eq(table.column(column), paramRefForStorageColumn(contract, storage, column, row[column])))));
|
|
2671
|
-
return OrExpr.of(tuples);
|
|
2672
|
-
}
|
|
2673
2630
|
/**
|
|
2674
2631
|
* Decode a single-query include payload from a parent row's raw cell
|
|
2675
2632
|
* into the model-shaped value that downstream consumers see. Recurses
|
|
@@ -2928,90 +2885,112 @@ function parseIncludePayload(value) {
|
|
|
2928
2885
|
return [];
|
|
2929
2886
|
}
|
|
2930
2887
|
}
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2888
|
+
const tablesByContext = /* @__PURE__ */ new WeakMap();
|
|
2889
|
+
const NO_METHODS = Object.freeze({});
|
|
2890
|
+
function modelKey(namespaceId, modelName) {
|
|
2891
|
+
return JSON.stringify([namespaceId, modelName]);
|
|
2934
2892
|
}
|
|
2935
|
-
function
|
|
2936
|
-
const
|
|
2937
|
-
const {
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
return mapRow(mapped);
|
|
2943
|
-
});
|
|
2944
|
-
const generator = async function* () {
|
|
2945
|
-
const identityRows = await queryPlanRows(runtime, compiled).toArray();
|
|
2946
|
-
yield* reloadMutationRowsByIdentities({
|
|
2947
|
-
context,
|
|
2948
|
-
runtime,
|
|
2949
|
-
tables,
|
|
2950
|
-
modelName,
|
|
2951
|
-
namespaceId,
|
|
2952
|
-
identityRows,
|
|
2953
|
-
selectedFields,
|
|
2954
|
-
includes
|
|
2893
|
+
function assertUniqueIds(contributions) {
|
|
2894
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2895
|
+
for (const { id } of contributions) {
|
|
2896
|
+
if (seen.has(id)) throw ormError("ORM.ARGUMENT_INVALID", `Two collection method contributions have the id "${id}".`, {
|
|
2897
|
+
why: "A contribution is registered under its id in CollectionMethodRegistry, so an id names one contribution.",
|
|
2898
|
+
fix: "List each extension once, or give one of the two contributions another id.",
|
|
2899
|
+
meta: { id }
|
|
2955
2900
|
});
|
|
2956
|
-
|
|
2957
|
-
|
|
2901
|
+
seen.add(id);
|
|
2902
|
+
}
|
|
2958
2903
|
}
|
|
2959
|
-
function
|
|
2960
|
-
const { context, runtime, plans, tables, modelName, namespaceId, variantValue, includes, selectedFields, hiddenColumns, mapRow } = options;
|
|
2904
|
+
function modelViews(context) {
|
|
2961
2905
|
const { contract } = context;
|
|
2962
|
-
const
|
|
2963
|
-
const
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2906
|
+
const views = [];
|
|
2907
|
+
for (const [namespaceId, namespace] of Object.entries(contract.domain.namespaces)) for (const [name, model] of Object.entries(namespace.models)) {
|
|
2908
|
+
const tableName = model.storage["table"];
|
|
2909
|
+
const resolved = typeof tableName === "string" ? resolveTableForContract(contract, namespaceId, tableName) : void 0;
|
|
2910
|
+
if (resolved === void 0) throw new InternalError(`Model "${name}" in namespace "${namespaceId}" has no storage table the contract declares.`);
|
|
2911
|
+
views.push([modelKey(namespaceId, name), {
|
|
2912
|
+
target: contract.target,
|
|
2913
|
+
name,
|
|
2914
|
+
fields: model.fields,
|
|
2915
|
+
relations: model.relations,
|
|
2916
|
+
table: resolved.table
|
|
2917
|
+
}]);
|
|
2918
|
+
}
|
|
2919
|
+
return views;
|
|
2920
|
+
}
|
|
2921
|
+
function methodsOf(contribution, view) {
|
|
2922
|
+
let methods;
|
|
2923
|
+
try {
|
|
2924
|
+
methods = contribution.methodsFor(view);
|
|
2925
|
+
} catch (cause) {
|
|
2926
|
+
throw ormError("ORM.ARGUMENT_INVALID", `Collection method contribution "${contribution.id}" failed for model "${view.name}".`, {
|
|
2927
|
+
why: "The ORM client asks every contribution for every model's methods when it is created.",
|
|
2928
|
+
fix: `Fix or remove the extension that contributes "${contribution.id}"; the cause is the contribution's own error.`,
|
|
2929
|
+
meta: {
|
|
2930
|
+
model: view.name,
|
|
2931
|
+
contribution: contribution.id
|
|
2932
|
+
},
|
|
2933
|
+
cause
|
|
2934
|
+
});
|
|
2935
|
+
}
|
|
2936
|
+
if (typeof methods !== "object" || methods === null) throw ormError("ORM.ARGUMENT_INVALID", `Collection method contribution "${contribution.id}" returned no object of methods for model "${view.name}".`, {
|
|
2937
|
+
why: "A contribution returns an object holding a model's methods by name, empty when it gives the model none.",
|
|
2938
|
+
fix: `Fix or remove the extension that contributes "${contribution.id}".`,
|
|
2939
|
+
meta: {
|
|
2940
|
+
model: view.name,
|
|
2941
|
+
contribution: contribution.id
|
|
2978
2942
|
}
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2943
|
+
});
|
|
2944
|
+
for (const [name, body] of Object.entries(methods)) if (typeof body !== "function") throw ormError("ORM.ARGUMENT_INVALID", `Collection method "${name}" that contribution "${contribution.id}" gives model "${view.name}" is not a function.`, {
|
|
2945
|
+
why: "A contribution returns each of a model's methods as a function of the collection and the caller's arguments.",
|
|
2946
|
+
fix: `Fix or remove the extension that contributes "${contribution.id}".`,
|
|
2947
|
+
meta: {
|
|
2948
|
+
model: view.name,
|
|
2949
|
+
method: name,
|
|
2950
|
+
contribution: contribution.id
|
|
2983
2951
|
}
|
|
2984
|
-
};
|
|
2985
|
-
return
|
|
2952
|
+
});
|
|
2953
|
+
return blindCast(methods);
|
|
2954
|
+
}
|
|
2955
|
+
function mergedTable(view, contributions) {
|
|
2956
|
+
const methods = Object.create(null);
|
|
2957
|
+
const owners = /* @__PURE__ */ new Map();
|
|
2958
|
+
for (const contribution of contributions) for (const [name, body] of Object.entries(methodsOf(contribution, view))) {
|
|
2959
|
+
const owner = owners.get(name);
|
|
2960
|
+
if (owner !== void 0) throw ormError("ORM.ARGUMENT_INVALID", `Collection method "${name}" of model "${view.name}" is contributed by both "${owner}" and "${contribution.id}".`, {
|
|
2961
|
+
why: "A collection offers one method under each name in `using`.",
|
|
2962
|
+
fix: "Remove one of the extensions that contribute these methods.",
|
|
2963
|
+
meta: {
|
|
2964
|
+
model: view.name,
|
|
2965
|
+
method: name,
|
|
2966
|
+
contributions: [owner, contribution.id]
|
|
2967
|
+
}
|
|
2968
|
+
});
|
|
2969
|
+
owners.set(name, contribution.id);
|
|
2970
|
+
methods[name] = body;
|
|
2971
|
+
}
|
|
2972
|
+
return Object.freeze(methods);
|
|
2986
2973
|
}
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
selectedFields,
|
|
3008
|
-
includes
|
|
3009
|
-
})) return row;
|
|
3010
|
-
throw ormError("ORM.MUTATION_ROW_MISSING", onMissingRowMessage, { meta: {
|
|
3011
|
-
operation,
|
|
3012
|
-
model: modelName,
|
|
3013
|
-
tableName: tables.root.storage.tableName
|
|
3014
|
-
} });
|
|
2974
|
+
/**
|
|
2975
|
+
* Asks each contribution for each model's methods, once per execution context. Throws `ORM.ARGUMENT_INVALID` when two contributions share an id, give one model two methods with the same name, fail, or return a method that is not a function.
|
|
2976
|
+
*/
|
|
2977
|
+
function collectionMethodTables(context) {
|
|
2978
|
+
const cached = tablesByContext.get(context);
|
|
2979
|
+
if (cached !== void 0) return cached;
|
|
2980
|
+
const contributions = context.collectionMethods ?? [];
|
|
2981
|
+
assertUniqueIds(contributions);
|
|
2982
|
+
const tables = /* @__PURE__ */ new Map();
|
|
2983
|
+
for (const [key, view] of modelViews(context)) tables.set(key, mergedTable(view, contributions));
|
|
2984
|
+
tablesByContext.set(context, tables);
|
|
2985
|
+
return tables;
|
|
2986
|
+
}
|
|
2987
|
+
/** The contributed methods of a model, by name. */
|
|
2988
|
+
function collectionMethodTable(context, namespaceId, modelName) {
|
|
2989
|
+
return collectionMethodTables(context).get(modelKey(namespaceId, modelName)) ?? NO_METHODS;
|
|
2990
|
+
}
|
|
2991
|
+
/** The run-time value of `collection.using`. */
|
|
2992
|
+
function createCollectionMethods(receiver, table) {
|
|
2993
|
+
return Object.freeze(Object.fromEntries(Object.entries(table).map(([name, body]) => [name, (...args) => body(receiver, ...args)])));
|
|
3015
2994
|
}
|
|
3016
2995
|
/** The filter expression of a condition: a condition from `fns` becomes its AST. */
|
|
3017
2996
|
function conditionExpr(condition) {
|
|
@@ -3280,6 +3259,7 @@ function defineDeclaredFieldsFragment(declarations, body) {
|
|
|
3280
3259
|
});
|
|
3281
3260
|
}
|
|
3282
3261
|
const NO_INDEXES = Object.freeze({});
|
|
3262
|
+
const NO_COLLECTION_METHODS = Object.freeze({});
|
|
3283
3263
|
const collectionsBehindViews = /* @__PURE__ */ new WeakMap();
|
|
3284
3264
|
const BODY_CHAIN_METHODS = {
|
|
3285
3265
|
where: true,
|
|
@@ -3288,10 +3268,11 @@ const BODY_CHAIN_METHODS = {
|
|
|
3288
3268
|
offset: true
|
|
3289
3269
|
};
|
|
3290
3270
|
/**
|
|
3291
|
-
* The collection as the body of a fragment for any model sees it: a `where` or `orderBy` callback receives `fns` and an `indexes` with no members, as the body does not know its model.
|
|
3271
|
+
* The collection as the body of a fragment for any model sees it: a `where` or `orderBy` callback receives `fns` and an `indexes` with no members, and `using` has no members, as the body does not know its model.
|
|
3292
3272
|
*/
|
|
3293
3273
|
function withoutIndexes(collection) {
|
|
3294
3274
|
const view = new Proxy(collection, { get(target, prop) {
|
|
3275
|
+
if (prop === "using") return NO_COLLECTION_METHODS;
|
|
3295
3276
|
const member = Reflect.get(target, prop, target);
|
|
3296
3277
|
if (typeof member !== "function") return member;
|
|
3297
3278
|
if (!Object.hasOwn(BODY_CHAIN_METHODS, prop)) return member.bind(target);
|
|
@@ -4593,15 +4574,37 @@ function getRelationDefinitions(contract, namespaceId, modelName) {
|
|
|
4593
4574
|
function toFieldName(contract, namespaceId, modelName, columnName) {
|
|
4594
4575
|
return fieldOfColumn(getModelColumnFields(contract, namespaceId, modelName), modelName, columnName);
|
|
4595
4576
|
}
|
|
4577
|
+
var Node = class {};
|
|
4578
|
+
function executeStatement$1(ast, run) {
|
|
4579
|
+
return ast.kind === "select" || ast.returning !== void 0 ? run.query(ast) : run.execute(ast);
|
|
4580
|
+
}
|
|
4581
|
+
function rowsResult(rows) {
|
|
4582
|
+
const generator = async function* () {
|
|
4583
|
+
yield* rows;
|
|
4584
|
+
};
|
|
4585
|
+
return new AsyncIterableResult(generator());
|
|
4586
|
+
}
|
|
4587
|
+
var CrossJoin = class extends Node {
|
|
4588
|
+
constructor() {
|
|
4589
|
+
super();
|
|
4590
|
+
Object.freeze(this);
|
|
4591
|
+
}
|
|
4592
|
+
execute(inputs, _run) {
|
|
4593
|
+
const [left] = inputs.left;
|
|
4594
|
+
const [right] = inputs.right;
|
|
4595
|
+
if (left === void 0 || right === void 0) return rowsResult([]);
|
|
4596
|
+
return rowsResult([{
|
|
4597
|
+
...left,
|
|
4598
|
+
...right
|
|
4599
|
+
}]);
|
|
4600
|
+
}
|
|
4601
|
+
};
|
|
4596
4602
|
function executeFiltered(ast, filter, run) {
|
|
4597
4603
|
if (filter === null) return executeStatement$1(ast, run);
|
|
4598
|
-
if (filter.some((conditions) => conditions.length === 0)) return
|
|
4604
|
+
if (filter.some((conditions) => conditions.length === 0)) return rowsResult([]);
|
|
4599
4605
|
const where = combineWhereExprs([...ast.where === void 0 ? [] : [ast.where], ...filter.map(anyOf)]);
|
|
4600
4606
|
return executeStatement$1(ast.withWhere(where), run);
|
|
4601
4607
|
}
|
|
4602
|
-
function executeStatement$1(ast, run) {
|
|
4603
|
-
return ast.kind === "select" || ast.returning !== void 0 ? run.query(ast) : run.execute(ast);
|
|
4604
|
-
}
|
|
4605
4608
|
function anyOf(conditions) {
|
|
4606
4609
|
const [first, ...others] = conditions;
|
|
4607
4610
|
return first !== void 0 && others.length === 0 ? first : OrExpr.of(conditions);
|
|
@@ -4610,12 +4613,8 @@ function withColumns(returned, columns) {
|
|
|
4610
4613
|
const present = new Set(returned.map((item) => item.alias));
|
|
4611
4614
|
return [...returned, ...columns.filter((column) => !present.has(column.alias))];
|
|
4612
4615
|
}
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
return new AsyncIterableResult(generator());
|
|
4616
|
-
}
|
|
4617
|
-
var Node = class {};
|
|
4618
|
-
var Delete = class Delete extends Node {
|
|
4616
|
+
var StatementNode = class extends Node {};
|
|
4617
|
+
var Delete = class Delete extends StatementNode {
|
|
4619
4618
|
ast;
|
|
4620
4619
|
constructor(ast) {
|
|
4621
4620
|
super();
|
|
@@ -4654,7 +4653,7 @@ var FilterData = class extends Edge {
|
|
|
4654
4653
|
return first !== void 0 && others.length === 0 ? first : AndExpr.of(conditions);
|
|
4655
4654
|
}
|
|
4656
4655
|
};
|
|
4657
|
-
var Find = class Find extends
|
|
4656
|
+
var Find = class Find extends StatementNode {
|
|
4658
4657
|
ast;
|
|
4659
4658
|
constructor(ast) {
|
|
4660
4659
|
super();
|
|
@@ -4694,7 +4693,8 @@ var Graph = class {
|
|
|
4694
4693
|
reader: id,
|
|
4695
4694
|
edge
|
|
4696
4695
|
});
|
|
4697
|
-
|
|
4696
|
+
const source = this.#nodes[edge.from];
|
|
4697
|
+
if (source instanceof StatementNode) this.#nodes[edge.from] = source.withReturning(edge.columns.map(([column]) => column));
|
|
4698
4698
|
}
|
|
4699
4699
|
return id;
|
|
4700
4700
|
}
|
|
@@ -4703,7 +4703,7 @@ var Graph = class {
|
|
|
4703
4703
|
}
|
|
4704
4704
|
remove(id) {
|
|
4705
4705
|
for (const edge of Object.values(this.inputsOf(id)).flat()) this.#readers[edge.from] = this.readersOf(edge.from).filter((entry) => entry.edge !== edge);
|
|
4706
|
-
for (const { reader, edge } of this.readersOf(id)) this.#inputs[reader] = Object.fromEntries(Object.entries(this.inputsOf(reader)).map(([
|
|
4706
|
+
for (const { reader, edge } of this.readersOf(id)) this.#inputs[reader] = Object.fromEntries(Object.entries(this.inputsOf(reader)).map(([name, slot]) => [name, Array.isArray(slot) ? slot.filter((other) => other !== edge) : slot]));
|
|
4707
4707
|
this.#nodes[id] = void 0;
|
|
4708
4708
|
this.#inputs[id] = {};
|
|
4709
4709
|
this.#readers[id] = [];
|
|
@@ -4721,7 +4721,88 @@ var Graph = class {
|
|
|
4721
4721
|
return this.#readers[id] ?? [];
|
|
4722
4722
|
}
|
|
4723
4723
|
};
|
|
4724
|
-
var
|
|
4724
|
+
var Insert = class Insert extends StatementNode {
|
|
4725
|
+
ast;
|
|
4726
|
+
constructor(ast) {
|
|
4727
|
+
super();
|
|
4728
|
+
this.ast = ast;
|
|
4729
|
+
Object.freeze(this);
|
|
4730
|
+
}
|
|
4731
|
+
get returns() {
|
|
4732
|
+
return this.ast.returning ?? [];
|
|
4733
|
+
}
|
|
4734
|
+
execute(inputs, run) {
|
|
4735
|
+
if (inputs.payload === null) return executeStatement$1(this.ast, run);
|
|
4736
|
+
if (inputs.payload.some((records) => records.length === 0)) return rowsResult([]);
|
|
4737
|
+
const payload = Object.assign({}, ...inputs.payload.map(([record]) => record));
|
|
4738
|
+
const rows = this.ast.rows.map((row) => ({
|
|
4739
|
+
...row,
|
|
4740
|
+
...payload
|
|
4741
|
+
}));
|
|
4742
|
+
return executeStatement$1(this.ast.withRows(rows), run);
|
|
4743
|
+
}
|
|
4744
|
+
withReturning(columns) {
|
|
4745
|
+
return new Insert(this.ast.withReturning(withColumns(this.returns, columns)));
|
|
4746
|
+
}
|
|
4747
|
+
};
|
|
4748
|
+
var InsertChunked = class InsertChunked extends StatementNode {
|
|
4749
|
+
asts;
|
|
4750
|
+
constructor(asts) {
|
|
4751
|
+
super();
|
|
4752
|
+
this.asts = Object.freeze([...asts]);
|
|
4753
|
+
Object.freeze(this);
|
|
4754
|
+
}
|
|
4755
|
+
get returns() {
|
|
4756
|
+
return this.asts[0]?.returning ?? [];
|
|
4757
|
+
}
|
|
4758
|
+
execute(_inputs, run) {
|
|
4759
|
+
if (this.returns.length === 0) return this.#sumOfCounts(run);
|
|
4760
|
+
const asts = this.asts;
|
|
4761
|
+
const generator = async function* () {
|
|
4762
|
+
for (const ast of asts) yield* run.query(ast);
|
|
4763
|
+
};
|
|
4764
|
+
return new AsyncIterableResult(generator());
|
|
4765
|
+
}
|
|
4766
|
+
withReturning(columns) {
|
|
4767
|
+
return new InsertChunked(this.asts.map((ast) => ast.withReturning(withColumns(ast.returning ?? [], columns))));
|
|
4768
|
+
}
|
|
4769
|
+
async #sumOfCounts(run) {
|
|
4770
|
+
let count = 0;
|
|
4771
|
+
for (const ast of this.asts) count += await run.execute(ast);
|
|
4772
|
+
return count;
|
|
4773
|
+
}
|
|
4774
|
+
};
|
|
4775
|
+
var PayloadData = class extends Edge {
|
|
4776
|
+
constructor(from, columns) {
|
|
4777
|
+
super(from, columns);
|
|
4778
|
+
Object.freeze(this);
|
|
4779
|
+
}
|
|
4780
|
+
output(sourceRow) {
|
|
4781
|
+
return Object.fromEntries(this.columns.map(([source, target]) => [target.alias, ParamRef.of(sourceRow[source.alias], {
|
|
4782
|
+
name: target.alias,
|
|
4783
|
+
...ifDefined("codec", target.codec)
|
|
4784
|
+
})]));
|
|
4785
|
+
}
|
|
4786
|
+
};
|
|
4787
|
+
var Rows = class extends Edge {
|
|
4788
|
+
constructor(from, columns) {
|
|
4789
|
+
super(from, columns);
|
|
4790
|
+
Object.freeze(this);
|
|
4791
|
+
}
|
|
4792
|
+
output(sourceRow) {
|
|
4793
|
+
return Object.fromEntries(this.columns.map(([source]) => [source.alias, sourceRow[source.alias]]));
|
|
4794
|
+
}
|
|
4795
|
+
};
|
|
4796
|
+
var UnionAll = class extends Node {
|
|
4797
|
+
constructor() {
|
|
4798
|
+
super();
|
|
4799
|
+
Object.freeze(this);
|
|
4800
|
+
}
|
|
4801
|
+
execute(inputs, _run) {
|
|
4802
|
+
return rowsResult((inputs.rows ?? []).flat());
|
|
4803
|
+
}
|
|
4804
|
+
};
|
|
4805
|
+
var Update = class Update extends StatementNode {
|
|
4725
4806
|
ast;
|
|
4726
4807
|
constructor(ast) {
|
|
4727
4808
|
super();
|
|
@@ -4794,6 +4875,61 @@ function deleteFirstGraph(collection) {
|
|
|
4794
4875
|
graph.setResult(withIncludes ? find : deleted);
|
|
4795
4876
|
return graph;
|
|
4796
4877
|
}
|
|
4878
|
+
function createAllGraph(collection, rows, conflict) {
|
|
4879
|
+
const { context, state } = collection;
|
|
4880
|
+
const graph = new Graph();
|
|
4881
|
+
if (rows.length === 0) return graph;
|
|
4882
|
+
requireIdentityColumnsForIncludes(collection);
|
|
4883
|
+
const { contract } = context;
|
|
4884
|
+
const { root } = state.tables;
|
|
4885
|
+
const inserted = supportsDefaultInInsert(contract) ? graph.add(new Insert(insertAst(contract, root, rows, conflict)), { payload: [] }) : graph.add(new InsertChunked(groupRowsByColumnSignature(rows).map((group) => insertAst(contract, root, group, conflict))), {});
|
|
4886
|
+
graph.setResult(addWithIncludes(graph, collection, inserted));
|
|
4887
|
+
return graph;
|
|
4888
|
+
}
|
|
4889
|
+
function supportsDefaultInInsert(contract) {
|
|
4890
|
+
return contract.capabilities["sql"]?.["defaultInInsert"] === true;
|
|
4891
|
+
}
|
|
4892
|
+
function createAllVariantGraph(collection, variantTable, variantModelName, rows) {
|
|
4893
|
+
const { context, modelName, state } = collection;
|
|
4894
|
+
const { contract } = context;
|
|
4895
|
+
const { root } = state.tables;
|
|
4896
|
+
const graph = new Graph();
|
|
4897
|
+
const keyColumns = resolvePrimaryKeyColumns(contract, root.storage.namespaceId, root.storage.tableName);
|
|
4898
|
+
const keyPairs = keyColumns.map((column) => [projectTableColumn(contract, root, column), projectTableColumn(contract, variantTable, column)]);
|
|
4899
|
+
const baseColumns = returningProjection(contract, modelName, root, void 0);
|
|
4900
|
+
const variantColumns = variantReturning(contract, variantTable, variantModelName, keyColumns);
|
|
4901
|
+
const joins = rows.map((row) => {
|
|
4902
|
+
const baseInsert = insertAst(contract, root, [row.base], void 0).withReturning(baseColumns);
|
|
4903
|
+
const base = graph.add(new Insert(baseInsert), { payload: [] });
|
|
4904
|
+
const variantInsert = insertAst(contract, variantTable, [row.variant], void 0).withReturning(variantColumns);
|
|
4905
|
+
const variant = graph.add(new Insert(variantInsert), { payload: [new PayloadData(base, keyPairs)] });
|
|
4906
|
+
return graph.add(new CrossJoin(), {
|
|
4907
|
+
left: new Rows(base, sameColumns(baseColumns)),
|
|
4908
|
+
right: new Rows(variant, sameColumns(variantColumns))
|
|
4909
|
+
});
|
|
4910
|
+
});
|
|
4911
|
+
const [only, ...others] = joins;
|
|
4912
|
+
if (only !== void 0 && others.length === 0) graph.setResult(only);
|
|
4913
|
+
else if (only !== void 0) {
|
|
4914
|
+
const joined = sameColumns([...baseColumns, ...variantColumns]);
|
|
4915
|
+
graph.setResult(graph.add(new UnionAll(), { rows: joins.map((join) => new Rows(join, joined)) }));
|
|
4916
|
+
}
|
|
4917
|
+
return graph;
|
|
4918
|
+
}
|
|
4919
|
+
function sameColumns(columns) {
|
|
4920
|
+
return columns.map((column) => [column, column]);
|
|
4921
|
+
}
|
|
4922
|
+
function upsertGraph(collection, create, update, conflictColumns) {
|
|
4923
|
+
const { context, state } = collection;
|
|
4924
|
+
const { root } = state.tables;
|
|
4925
|
+
const graph = new Graph();
|
|
4926
|
+
requireIdentityColumnsForIncludes(collection);
|
|
4927
|
+
const updateSet = Object.keys(update).length > 0 ? updateAssignments(context.contract, root, update) : Object.fromEntries(conflictColumns.slice(0, 1).map((column) => [column, ColumnRef.of("excluded", column)]));
|
|
4928
|
+
const upsert = upsertAst(context.contract, root, create, conflictColumns, updateSet);
|
|
4929
|
+
const upserted = graph.add(new Insert(upsert), { payload: [] });
|
|
4930
|
+
graph.setResult(addWithIncludes(graph, collection, upserted));
|
|
4931
|
+
return graph;
|
|
4932
|
+
}
|
|
4797
4933
|
function addWithIncludes(graph, collection, written) {
|
|
4798
4934
|
const { state } = collection;
|
|
4799
4935
|
if (state.includes.length === 0) return written;
|
|
@@ -4872,7 +5008,7 @@ async function executeGraph(graph, ctx, annotations) {
|
|
|
4872
5008
|
function returnCallerColumns(graph, callerRows) {
|
|
4873
5009
|
const { context, modelName, state } = callerRows;
|
|
4874
5010
|
const columns = returningProjection(context.contract, modelName, state.tables.root, state.selectedFields);
|
|
4875
|
-
for (const [id, node] of graph.nodes()) if (id === graph.result) graph.replace(id, node.withReturning(columns));
|
|
5011
|
+
for (const [id, node] of graph.nodes()) if (id === graph.result && node instanceof StatementNode) graph.replace(id, node.withReturning(columns));
|
|
4876
5012
|
}
|
|
4877
5013
|
function runAllNodes(graph, ctx, annotations, callerRows) {
|
|
4878
5014
|
if (graph.nodes().length > 1) return withMutationScope(ctx.runtime, (scope) => runNodesInOrder(graph, {
|
|
@@ -4901,11 +5037,9 @@ async function runNodesInOrder(graph, ctx, annotations, callerRows) {
|
|
|
4901
5037
|
}
|
|
4902
5038
|
function inputsOf(graph, id, collected) {
|
|
4903
5039
|
const outputs = {};
|
|
4904
|
-
const
|
|
4905
|
-
for (const slot
|
|
4906
|
-
|
|
4907
|
-
outputs[slot] = edges.length === 0 ? null : edges.map((edge) => rowsOf(collected[edge.from]).map((row) => edge.output(row)));
|
|
4908
|
-
}
|
|
5040
|
+
const outputOf = (edge) => rowsOf(collected[edge.from]).map((row) => edge.output(row));
|
|
5041
|
+
for (const [name, slot] of Object.entries(graph.inputsOf(id))) if (!Array.isArray(slot)) outputs[name] = outputOf(slot);
|
|
5042
|
+
else outputs[name] = slot.length === 0 ? null : slot.map(outputOf);
|
|
4909
5043
|
return outputs;
|
|
4910
5044
|
}
|
|
4911
5045
|
function runOn(ctx, annotations) {
|
|
@@ -5099,6 +5233,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5099
5233
|
registry;
|
|
5100
5234
|
/** @internal */
|
|
5101
5235
|
includeRefinementMode;
|
|
5236
|
+
#using;
|
|
5102
5237
|
constructor(ctx, modelName, options) {
|
|
5103
5238
|
this.ctx = ctx;
|
|
5104
5239
|
this.contract = ctx.context.contract;
|
|
@@ -5164,6 +5299,13 @@ var CollectionBase = class CollectionBase {
|
|
|
5164
5299
|
filters: [...this.state.filters, filter]
|
|
5165
5300
|
});
|
|
5166
5301
|
}
|
|
5302
|
+
/**
|
|
5303
|
+
* The collection methods packages contribute for this model. Each contribution reads the model and names its methods. Each method returns this collection with the method's filter and order added.
|
|
5304
|
+
*/
|
|
5305
|
+
get using() {
|
|
5306
|
+
this.#using ??= createCollectionMethods(blindCast(this), collectionMethodTable(this.ctx.context, this.namespaceId, this.modelName));
|
|
5307
|
+
return blindCast(this.#using);
|
|
5308
|
+
}
|
|
5167
5309
|
whereUnique(criterion) {
|
|
5168
5310
|
if (this.includeRefinementMode) throw ormError("ORM.INCLUDE_INVALID", "whereUnique() is not available inside include() refinement callbacks", { meta: { action: "whereUnique()" } });
|
|
5169
5311
|
if (!hasCompleteUniqueKey(this.contract, this.namespaceId, this.modelName, criterion)) throw ormError("ORM.ARGUMENT_INVALID", `whereUnique() for model "${this.modelName}" needs a value for every field of the primary key or of one unique constraint`, { meta: {
|
|
@@ -5523,40 +5665,16 @@ var CollectionBase = class CollectionBase {
|
|
|
5523
5665
|
assertReturningCapability(this.contract, "createAll()");
|
|
5524
5666
|
const rows = blindCast(data);
|
|
5525
5667
|
const mtiContext = this.#resolveMtiCreateContext();
|
|
5526
|
-
if (mtiContext)
|
|
5668
|
+
if (mtiContext) {
|
|
5669
|
+
const variantTable = requireVariantTable(this.state.tables, mtiContext.variant.value);
|
|
5670
|
+
return queryGraph(createAllVariantGraph(this.#descriptionWithoutIncludes(), variantTable, mtiContext.variant.modelName, this.#variantCreateRows(rows, mtiContext, variantTable)), this.ctx, annotationsMap, this.#descriptionWithoutIncludes());
|
|
5671
|
+
}
|
|
5672
|
+
return queryGraph(createAllGraph(this.#descriptionOptions(), this.#createValues(rows), conflictSkip), this.ctx, annotationsMap, this.#descriptionOptions());
|
|
5673
|
+
}
|
|
5674
|
+
#createValues(rows) {
|
|
5527
5675
|
const mappedRows = this.#mapCreateRows(rows);
|
|
5528
5676
|
applyCreateDefaults(this.ctx, this.namespaceId, this.tableName, mappedRows);
|
|
5529
|
-
|
|
5530
|
-
if (this.contract.capabilities?.["sql"]?.["defaultInInsert"] !== true) {
|
|
5531
|
-
const plans = compileInsertReturningSplit(this.contract, this.namespaceId, this.modelName, this.tableName, mappedRows, selectedForInsert, conflictSkip).map((plan) => mergeAnnotations(plan, annotationsMap));
|
|
5532
|
-
return dispatchSplitMutationRows({
|
|
5533
|
-
context: this.ctx.context,
|
|
5534
|
-
runtime: this.ctx.runtime,
|
|
5535
|
-
plans,
|
|
5536
|
-
tables: this.state.tables,
|
|
5537
|
-
modelName: this.modelName,
|
|
5538
|
-
namespaceId: this.namespaceId,
|
|
5539
|
-
variantValue: this.state.variantValue,
|
|
5540
|
-
includes: this.state.includes,
|
|
5541
|
-
selectedFields: this.state.selectedFields,
|
|
5542
|
-
hiddenColumns,
|
|
5543
|
-
mapRow: (mapped) => blindCast(mapped)
|
|
5544
|
-
});
|
|
5545
|
-
}
|
|
5546
|
-
const compiled = mergeAnnotations(compileInsertReturning(this.contract, this.namespaceId, this.modelName, this.tableName, mappedRows, selectedForInsert, conflictSkip), annotationsMap);
|
|
5547
|
-
return dispatchMutationRows({
|
|
5548
|
-
context: this.ctx.context,
|
|
5549
|
-
runtime: this.ctx.runtime,
|
|
5550
|
-
compiled,
|
|
5551
|
-
tables: this.state.tables,
|
|
5552
|
-
modelName: this.modelName,
|
|
5553
|
-
namespaceId: this.namespaceId,
|
|
5554
|
-
variantValue: this.state.variantValue,
|
|
5555
|
-
includes: this.state.includes,
|
|
5556
|
-
selectedFields: this.state.selectedFields,
|
|
5557
|
-
hiddenColumns,
|
|
5558
|
-
mapRow: (mapped) => blindCast(mapped)
|
|
5559
|
-
});
|
|
5677
|
+
return mappedRows;
|
|
5560
5678
|
}
|
|
5561
5679
|
#resolveConflictSkip(options, method) {
|
|
5562
5680
|
if (options === void 0) return void 0;
|
|
@@ -5595,76 +5713,39 @@ var CollectionBase = class CollectionBase {
|
|
|
5595
5713
|
if (!polyInfo) return null;
|
|
5596
5714
|
const variant = polyInfo.variants.get(variantValue);
|
|
5597
5715
|
if (!isMtiVariantInfo(variant)) return null;
|
|
5598
|
-
const baseFieldToColumn = getModelFieldColumns(this.contract, this.namespaceId, this.modelName);
|
|
5599
|
-
const variantFieldToColumn = getOwnFieldColumns(this.contract, variant.namespaceId, variant.modelName);
|
|
5600
|
-
const pkColumns = resolvePrimaryKeyColumns(this.contract, this.namespaceId, this.tableName);
|
|
5601
5716
|
return {
|
|
5602
5717
|
polyInfo,
|
|
5603
5718
|
variant,
|
|
5604
|
-
baseFieldToColumn,
|
|
5605
|
-
variantFieldToColumn,
|
|
5606
|
-
mergedFieldToColumn: getModelAndVariantFieldColumns(this.contract, this.namespaceId, this.modelName, variant.value)
|
|
5607
|
-
pkColumns
|
|
5719
|
+
baseFieldToColumn: getModelFieldColumns(this.contract, this.namespaceId, this.modelName),
|
|
5720
|
+
variantFieldToColumn: getOwnFieldColumns(this.contract, variant.namespaceId, variant.modelName),
|
|
5721
|
+
mergedFieldToColumn: getModelAndVariantFieldColumns(this.contract, this.namespaceId, this.modelName, variant.value)
|
|
5608
5722
|
};
|
|
5609
5723
|
}
|
|
5610
|
-
#
|
|
5611
|
-
const { polyInfo, variant, baseFieldToColumn, variantFieldToColumn, mergedFieldToColumn
|
|
5612
|
-
const contract = this.contract;
|
|
5613
|
-
const collectionCtx = this.ctx;
|
|
5614
|
-
const runtime = collectionCtx.runtime;
|
|
5615
|
-
const tableName = this.tableName;
|
|
5616
|
-
const modelName = this.modelName;
|
|
5617
|
-
const namespaceId = this.namespaceId;
|
|
5618
|
-
const tables = this.state.tables;
|
|
5619
|
-
const variantTable = requireVariantTable(tables, variant.value);
|
|
5724
|
+
#variantCreateRows(data, mtiCtx, variantTable) {
|
|
5725
|
+
const { polyInfo, variant, baseFieldToColumn, variantFieldToColumn, mergedFieldToColumn } = mtiCtx;
|
|
5620
5726
|
const baseFieldColumns = new Set(Object.values(baseFieldToColumn));
|
|
5621
5727
|
const variantFieldColumns = new Set(Object.values(variantFieldToColumn));
|
|
5622
|
-
const
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
allMapped[columnOfCallerField(contract, variant.namespaceId, mergedFieldToColumn, variant.modelName, fieldName)] = value;
|
|
5629
|
-
}
|
|
5630
|
-
allMapped[polyInfo.discriminatorColumn] = variant.value;
|
|
5631
|
-
const baseRow = {};
|
|
5632
|
-
const variantRow = {};
|
|
5633
|
-
for (const [col, val] of Object.entries(allMapped)) {
|
|
5634
|
-
if (baseFieldColumns.has(col) || col === polyInfo.discriminatorColumn) baseRow[col] = val;
|
|
5635
|
-
if (variantFieldColumns.has(col)) variantRow[col] = val;
|
|
5636
|
-
}
|
|
5637
|
-
yield blindCast(await withMutationScope(runtime, async (scope) => {
|
|
5638
|
-
applyCreateDefaults(collectionCtx, namespaceId, tableName, [baseRow], defaultValueCache);
|
|
5639
|
-
const baseCreated = (await queryPlanRows(scope, compileInsertReturning(contract, namespaceId, modelName, tableName, [baseRow], void 0)).toArray())[0];
|
|
5640
|
-
if (!baseCreated) throw ormError("ORM.MUTATION_ROW_MISSING", `MTI base INSERT for model "${modelName}" did not return a row`, { meta: {
|
|
5641
|
-
operation: "create",
|
|
5642
|
-
model: modelName,
|
|
5643
|
-
table: tableName,
|
|
5644
|
-
phase: "mti-base"
|
|
5645
|
-
} });
|
|
5646
|
-
for (const pkColumn of pkColumns) variantRow[pkColumn] = baseCreated[pkColumn];
|
|
5647
|
-
applyCreateDefaults(collectionCtx, variantTable.storage.namespaceId, variantTable.storage.tableName, [variantRow], defaultValueCache);
|
|
5648
|
-
const variantCreated = (await queryPlanRows(scope, compileInsertReturning(contract, variantTable.storage.namespaceId, variant.modelName, variantTable.storage.tableName, [variantRow], void 0)).toArray())[0];
|
|
5649
|
-
if (!variantCreated) throw ormError("ORM.MUTATION_ROW_MISSING", `MTI variant INSERT for model "${modelName}" into "${variant.table}" did not return a row`, { meta: {
|
|
5650
|
-
operation: "create",
|
|
5651
|
-
model: modelName,
|
|
5652
|
-
table: variant.table,
|
|
5653
|
-
phase: "mti-variant"
|
|
5654
|
-
} });
|
|
5655
|
-
const prefixedVariant = {};
|
|
5656
|
-
for (const [col, val] of Object.entries(variantCreated)) {
|
|
5657
|
-
if (pkColumns.includes(col)) continue;
|
|
5658
|
-
prefixedVariant[variantColumnLabel(variantTable, col)] = val;
|
|
5659
|
-
}
|
|
5660
|
-
return mapPolymorphicRow(contract, namespaceId, modelName, polyInfo, tables, {
|
|
5661
|
-
...baseCreated,
|
|
5662
|
-
...prefixedVariant
|
|
5663
|
-
}, variant.value);
|
|
5664
|
-
}));
|
|
5728
|
+
const defaultValueCache = /* @__PURE__ */ new Map();
|
|
5729
|
+
return data.map((row) => {
|
|
5730
|
+
const allMapped = {};
|
|
5731
|
+
for (const [fieldName, value] of Object.entries(row)) {
|
|
5732
|
+
if (value === void 0) continue;
|
|
5733
|
+
allMapped[columnOfCallerField(this.contract, this.namespaceId, mergedFieldToColumn, variant.modelName, fieldName)] = value;
|
|
5665
5734
|
}
|
|
5666
|
-
|
|
5667
|
-
|
|
5735
|
+
allMapped[polyInfo.discriminatorColumn] = variant.value;
|
|
5736
|
+
const baseRow = {};
|
|
5737
|
+
const variantRow = {};
|
|
5738
|
+
for (const [column, value] of Object.entries(allMapped)) {
|
|
5739
|
+
if (baseFieldColumns.has(column) || column === polyInfo.discriminatorColumn) baseRow[column] = value;
|
|
5740
|
+
if (variantFieldColumns.has(column)) variantRow[column] = value;
|
|
5741
|
+
}
|
|
5742
|
+
applyCreateDefaults(this.ctx, this.namespaceId, this.tableName, [baseRow], defaultValueCache);
|
|
5743
|
+
applyCreateDefaults(this.ctx, variantTable.storage.namespaceId, variantTable.storage.tableName, [variantRow], defaultValueCache);
|
|
5744
|
+
return {
|
|
5745
|
+
base: baseRow,
|
|
5746
|
+
variant: variantRow
|
|
5747
|
+
};
|
|
5748
|
+
});
|
|
5668
5749
|
}
|
|
5669
5750
|
#mapCreateRows(data) {
|
|
5670
5751
|
const variantValue = this.state.variantValue;
|
|
@@ -5717,19 +5798,7 @@ var CollectionBase = class CollectionBase {
|
|
|
5717
5798
|
this.#assertNotMtiVariant("createAndCount()");
|
|
5718
5799
|
const annotationsMap = this.#collectAnnotationsFromMeta(configureCallback, "write", "createAndCount");
|
|
5719
5800
|
const rows = blindCast(data);
|
|
5720
|
-
|
|
5721
|
-
applyCreateDefaults(this.ctx, this.namespaceId, this.tableName, mappedRows);
|
|
5722
|
-
if (this.contract.capabilities?.["sql"]?.["defaultInInsert"] !== true) {
|
|
5723
|
-
const plans = compileInsertCountSplit(this.contract, this.namespaceId, this.tableName, mappedRows, conflictSkip).map((plan) => mergeAnnotations(plan, annotationsMap));
|
|
5724
|
-
let affectedRows = 0;
|
|
5725
|
-
for (const plan of plans) {
|
|
5726
|
-
const stats = await this.ctx.runtime.execute(plan);
|
|
5727
|
-
affectedRows += stats.affectedRows;
|
|
5728
|
-
}
|
|
5729
|
-
return affectedRows;
|
|
5730
|
-
}
|
|
5731
|
-
const compiled = mergeAnnotations(compileInsertCount(this.contract, this.namespaceId, this.tableName, mappedRows, conflictSkip), annotationsMap);
|
|
5732
|
-
return (await this.ctx.runtime.execute(compiled)).affectedRows;
|
|
5801
|
+
return (await executeGraph(createAllGraph(this.#descriptionWithoutIncludes(), this.#createValues(rows), conflictSkip), this.ctx, annotationsMap)).affectedRows;
|
|
5733
5802
|
}
|
|
5734
5803
|
async upsert(input, configure) {
|
|
5735
5804
|
assertLockCompatible(this.state, "mutation");
|
|
@@ -5739,36 +5808,14 @@ var CollectionBase = class CollectionBase {
|
|
|
5739
5808
|
const createValues = this.#mapCreateRows([blindCast(input.create)])[0] ?? {};
|
|
5740
5809
|
applyCreateDefaults(this.ctx, this.namespaceId, this.tableName, [createValues]);
|
|
5741
5810
|
const updateValues = mapModelDataToStorageRow(this.contract, this.namespaceId, this.modelName, input.update);
|
|
5742
|
-
|
|
5743
|
-
if (hasUpdateValues) applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, updateValues);
|
|
5811
|
+
if (Object.keys(updateValues).length > 0) applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, updateValues);
|
|
5744
5812
|
const conflictColumns = resolveUpsertConflictColumns(this.contract, this.namespaceId, this.modelName, blindCast(input.conflictOn));
|
|
5745
5813
|
if (conflictColumns.length === 0) throw ormError("ORM.ARGUMENT_INVALID", `upsert() for model "${this.modelName}" requires conflict columns`, { meta: {
|
|
5746
5814
|
method: "upsert",
|
|
5747
5815
|
model: this.modelName
|
|
5748
5816
|
} });
|
|
5749
|
-
const
|
|
5750
|
-
const compiled = mergeAnnotations(compileUpsertReturning(this.contract, this.namespaceId, this.modelName, this.tableName, createValues, updateValues, conflictColumns, selectedForUpsert), annotationsMap);
|
|
5751
|
-
const row = await executeMutationReturningSingleRow({
|
|
5752
|
-
context: this.ctx.context,
|
|
5753
|
-
runtime: this.ctx.runtime,
|
|
5754
|
-
compiled,
|
|
5755
|
-
tables: this.state.tables,
|
|
5756
|
-
modelName: this.modelName,
|
|
5757
|
-
namespaceId: this.namespaceId,
|
|
5758
|
-
variantValue: this.state.variantValue,
|
|
5759
|
-
includes: this.state.includes,
|
|
5760
|
-
selectedFields: this.state.selectedFields,
|
|
5761
|
-
hiddenColumns,
|
|
5762
|
-
mapRow: (mapped) => blindCast(mapped),
|
|
5763
|
-
operation: "upsert",
|
|
5764
|
-
onMissingRowMessage: `upsert() for model "${this.modelName}" did not return a row`
|
|
5765
|
-
});
|
|
5817
|
+
const row = await consumeFirstRow(queryGraph(upsertGraph(this.#descriptionOptions(), createValues, updateValues, conflictColumns), this.ctx, annotationsMap, this.#descriptionOptions()));
|
|
5766
5818
|
if (row) return row;
|
|
5767
|
-
if (!hasUpdateValues) {
|
|
5768
|
-
const conflictCriterion = this.#buildUpsertConflictCriterion(createValues, conflictColumns);
|
|
5769
|
-
const existing = await this.#reloadMutationRowByCriterion(conflictCriterion, "upsert conflict");
|
|
5770
|
-
if (existing) return existing;
|
|
5771
|
-
}
|
|
5772
5819
|
throw ormError("ORM.MUTATION_ROW_MISSING", `upsert() for model "${this.modelName}" did not return a row`, { meta: {
|
|
5773
5820
|
operation: "upsert",
|
|
5774
5821
|
model: this.modelName
|
|
@@ -5845,46 +5892,6 @@ var CollectionBase = class CollectionBase {
|
|
|
5845
5892
|
if (Object.keys(values).length > 0) applyUpdateDefaults(this.ctx, this.namespaceId, this.tableName, values);
|
|
5846
5893
|
return values;
|
|
5847
5894
|
}
|
|
5848
|
-
#buildUpsertConflictCriterion(createValues, conflictColumns) {
|
|
5849
|
-
const criterion = {};
|
|
5850
|
-
for (const columnName of conflictColumns) {
|
|
5851
|
-
if (!(columnName in createValues)) throw ormError("ORM.ARGUMENT_INVALID", `upsert() for model "${this.modelName}" requires create value for conflict column "${columnName}"`, { meta: {
|
|
5852
|
-
method: "upsert",
|
|
5853
|
-
model: this.modelName,
|
|
5854
|
-
column: columnName
|
|
5855
|
-
} });
|
|
5856
|
-
const fieldName = fieldOfColumn(getModelColumnFields(this.contract, this.namespaceId, this.modelName), this.modelName, columnName);
|
|
5857
|
-
criterion[fieldName] = createValues[columnName];
|
|
5858
|
-
}
|
|
5859
|
-
return criterion;
|
|
5860
|
-
}
|
|
5861
|
-
/**
|
|
5862
|
-
* Shape the projection for a mutation's `RETURNING` clause.
|
|
5863
|
-
*
|
|
5864
|
-
* Without includes, the mutation returns the caller's projection
|
|
5865
|
-
* directly. With includes, it returns only the row identity columns
|
|
5866
|
-
* (PK / unique): those rows are reloaded through the read path
|
|
5867
|
-
* (`reloadMutationRowsByIdentities`), which re-selects the caller's
|
|
5868
|
-
* projection together with the relations, so the `RETURNING` clause
|
|
5869
|
-
* need only carry enough to key that read-back.
|
|
5870
|
-
*/
|
|
5871
|
-
#augmentMutationSelection() {
|
|
5872
|
-
if (this.state.includes.length > 0) {
|
|
5873
|
-
const identityColumns = resolveRowIdentityColumns(this.contract, this.namespaceId, this.tableName);
|
|
5874
|
-
if (identityColumns.length === 0) throw ormError("ORM.ROW_IDENTITY_MISSING", `Cannot load includes for the mutation result on model "${this.modelName}": table "${this.tableName}" has no primary key or unique constraint to key the include read-back on.`, { meta: {
|
|
5875
|
-
model: this.modelName,
|
|
5876
|
-
table: this.tableName
|
|
5877
|
-
} });
|
|
5878
|
-
return {
|
|
5879
|
-
selectedForQuery: identityColumns,
|
|
5880
|
-
hiddenColumns: []
|
|
5881
|
-
};
|
|
5882
|
-
}
|
|
5883
|
-
return {
|
|
5884
|
-
selectedForQuery: this.state.selectedFields,
|
|
5885
|
-
hiddenColumns: []
|
|
5886
|
-
};
|
|
5887
|
-
}
|
|
5888
5895
|
async #reloadMutationRowByIdentity(criterion) {
|
|
5889
5896
|
return this.#reloadMutationRowByCriterion(criterion, "row identity");
|
|
5890
5897
|
}
|
|
@@ -6048,6 +6055,7 @@ function assertAggregateOperationsNotReserved(registry) {
|
|
|
6048
6055
|
function orm(options) {
|
|
6049
6056
|
const { runtime, collections, context } = options;
|
|
6050
6057
|
assertAggregateOperationsNotReserved(context.aggregateDescriptors);
|
|
6058
|
+
collectionMethodTables(context);
|
|
6051
6059
|
const contract = context.contract;
|
|
6052
6060
|
const ctx = {
|
|
6053
6061
|
runtime,
|