@vantreeseba/drizzle-graphql 15.1.3 → 15.1.4
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 +6 -1
- package/dist/index.cjs +98 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +98 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1112,6 +1112,11 @@ declare const drizzleExecutorKey: unique symbol;
|
|
|
1112
1112
|
* Returns the JS property name of the local column on the parent table and the
|
|
1113
1113
|
* Column object for the foreign column on the target table, or undefined if the
|
|
1114
1114
|
* relation internals are not accessible.
|
|
1115
|
+
*
|
|
1116
|
+
* Only the relation's *first* column pair is reported. A relation joined on several columns
|
|
1117
|
+
* (`from: [a, b], to: [x, y]`) is not described fully by it, so anything that reads rows by
|
|
1118
|
+
* this pair alone mixes up parents that share the first column. Read paths use
|
|
1119
|
+
* {@link extractRelationJoinColumnPairs}, which returns every pair.
|
|
1115
1120
|
*/
|
|
1116
1121
|
declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
|
|
1117
1122
|
localColPropName: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1112,6 +1112,11 @@ declare const drizzleExecutorKey: unique symbol;
|
|
|
1112
1112
|
* Returns the JS property name of the local column on the parent table and the
|
|
1113
1113
|
* Column object for the foreign column on the target table, or undefined if the
|
|
1114
1114
|
* relation internals are not accessible.
|
|
1115
|
+
*
|
|
1116
|
+
* Only the relation's *first* column pair is reported. A relation joined on several columns
|
|
1117
|
+
* (`from: [a, b], to: [x, y]`) is not described fully by it, so anything that reads rows by
|
|
1118
|
+
* this pair alone mixes up parents that share the first column. Read paths use
|
|
1119
|
+
* {@link extractRelationJoinColumnPairs}, which returns every pair.
|
|
1115
1120
|
*/
|
|
1116
1121
|
declare const extractRelationJoinColumns: (relEntry: TableNamedRelations, parentTable: Table, targetTable: Table) => {
|
|
1117
1122
|
localColPropName: string;
|
package/dist/index.js
CHANGED
|
@@ -1778,6 +1778,11 @@ const warnUnresolvedJoin = (relEntry, tableName, relationName, omitted) => {
|
|
|
1778
1778
|
* Returns the JS property name of the local column on the parent table and the
|
|
1779
1779
|
* Column object for the foreign column on the target table, or undefined if the
|
|
1780
1780
|
* relation internals are not accessible.
|
|
1781
|
+
*
|
|
1782
|
+
* Only the relation's *first* column pair is reported. A relation joined on several columns
|
|
1783
|
+
* (`from: [a, b], to: [x, y]`) is not described fully by it, so anything that reads rows by
|
|
1784
|
+
* this pair alone mixes up parents that share the first column. Read paths use
|
|
1785
|
+
* {@link extractRelationJoinColumnPairs}, which returns every pair.
|
|
1781
1786
|
*/
|
|
1782
1787
|
const extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
|
|
1783
1788
|
const rel = relEntry.relation ?? relEntry;
|
|
@@ -1796,6 +1801,48 @@ const extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
|
|
|
1796
1801
|
};
|
|
1797
1802
|
};
|
|
1798
1803
|
/**
|
|
1804
|
+
* Every column pair the relation joins on, in declaration order — one for an ordinary relation,
|
|
1805
|
+
* several for one declared `from: [a, b], to: [x, y]`. A row of the target belongs to a parent
|
|
1806
|
+
* only when *all* pairs match, so a read path has to correlate on every one of them.
|
|
1807
|
+
*
|
|
1808
|
+
* `undefined` when the relation's columns cannot be matched to the two tables, or when its two
|
|
1809
|
+
* sides list a different number of columns.
|
|
1810
|
+
*/
|
|
1811
|
+
const extractRelationJoinColumnPairs = (relEntry, parentTable, targetTable) => {
|
|
1812
|
+
const rel = relEntry.relation ?? relEntry;
|
|
1813
|
+
const sourceCols = relationColumns(rel, "source");
|
|
1814
|
+
const targetCols = relationColumns(rel, "target");
|
|
1815
|
+
if (!sourceCols?.length || sourceCols.length !== targetCols?.length) return;
|
|
1816
|
+
const parentEntries = Object.entries(getColumns(parentTable));
|
|
1817
|
+
const targetEntries = Object.entries(getColumns(targetTable));
|
|
1818
|
+
const pairs = [];
|
|
1819
|
+
for (let i = 0; i < sourceCols.length; i++) {
|
|
1820
|
+
const localCol = sourceCols[i];
|
|
1821
|
+
const foreignCol = targetCols[i];
|
|
1822
|
+
const localColPropName = parentEntries.find(([, c]) => c === localCol)?.[0];
|
|
1823
|
+
const foreignColPropName = targetEntries.find(([, c]) => c === foreignCol)?.[0];
|
|
1824
|
+
if (!localColPropName || !foreignColPropName) return;
|
|
1825
|
+
pairs.push({
|
|
1826
|
+
localColPropName,
|
|
1827
|
+
localCol,
|
|
1828
|
+
foreignColPropName,
|
|
1829
|
+
foreignCol
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
return pairs;
|
|
1833
|
+
};
|
|
1834
|
+
/**
|
|
1835
|
+
* A string identifying one combination of join-column values, for grouping a batch's rows by
|
|
1836
|
+
* parent. Values are compared by their string form, as a single-column key always has been.
|
|
1837
|
+
*/
|
|
1838
|
+
const joinKeyOf = (values) => values.length === 1 ? String(values[0]) : JSON.stringify(values.map((value) => String(value)));
|
|
1839
|
+
/**
|
|
1840
|
+
* The rows whose `cols` hold one of `keys`: `col IN (…)` for a single join column, and an `OR`
|
|
1841
|
+
* of per-parent equalities for several — `(a = 1 AND b = 1) OR (a = 1 AND b = 2)` — which
|
|
1842
|
+
* every dialect accepts, unlike a row-value `IN` list.
|
|
1843
|
+
*/
|
|
1844
|
+
const parentKeyCondition = (cols, keys) => cols.length === 1 ? inArray(cols[0], keys.map((key) => key[0])) : or(...keys.map((key) => and(...cols.map((col, i) => eq(col, key[i])))));
|
|
1845
|
+
/**
|
|
1799
1846
|
* The junction table and its two columns for a `.through()` (many-to-many) relation:
|
|
1800
1847
|
* `sourceCol` holds the parent's key, `targetCol` the target's. `undefined` for a relation
|
|
1801
1848
|
* with no junction; `null` for one whose junction cannot be used here — more than one column
|
|
@@ -1826,16 +1873,18 @@ const extractJunctionColumns = (relEntry) => {
|
|
|
1826
1873
|
*
|
|
1827
1874
|
* A reversed filter (inherited from the relation on the other side) is written against the
|
|
1828
1875
|
* parent table, so it is applied as "the row's parent key belongs to a parent that passes it".
|
|
1829
|
-
* `
|
|
1830
|
-
* the parent key for each row — the target's foreign key, or the junction's source
|
|
1876
|
+
* `parentKeyCols` are the parent's join columns and `groupCols` the columns in the query that
|
|
1877
|
+
* hold the parent key for each row — the target's foreign key, or the junction's source
|
|
1878
|
+
* column — in the same order. A key of several columns is compared as a row value.
|
|
1831
1879
|
*/
|
|
1832
|
-
const relationOwnCondition = (relEntry, parentTable, targetTable,
|
|
1880
|
+
const relationOwnCondition = (relEntry, parentTable, targetTable, parentKeyCols, groupCols) => {
|
|
1833
1881
|
const rel = relEntry.relation ?? relEntry;
|
|
1834
1882
|
const ownWhere = relationOwnWhere(rel);
|
|
1835
1883
|
if (!ownWhere) return;
|
|
1836
1884
|
if (!isRelationFilterReversed(rel)) return relationsFilterToSQL(targetTable, ownWhere);
|
|
1837
1885
|
const parentFilter = relationsFilterToSQL(parentTable, ownWhere);
|
|
1838
|
-
return sql`${
|
|
1886
|
+
if (groupCols.length === 1) return sql`${groupCols[0]} in (select ${parentKeyCols[0]} from ${parentTable} where ${parentFilter})`;
|
|
1887
|
+
return sql`(${sql.join([...groupCols], sql`, `)}) in (select ${sql.join([...parentKeyCols], sql`, `)} from ${parentTable} where ${parentFilter})`;
|
|
1839
1888
|
};
|
|
1840
1889
|
/**
|
|
1841
1890
|
* Whether a to-one relation can back a relation orderBy hop. `.through()` (junction)
|
|
@@ -3821,8 +3870,7 @@ const relationJoinColumns = (tree, table, selectionCtx) => {
|
|
|
3821
3870
|
const relEntry = fieldData.name.endsWith(AGGREGATE_FIELD_SUFFIX) ? relations[fieldData.name.slice(0, -9)] : relations[fieldData.name];
|
|
3822
3871
|
const targetTable = relEntry ? selectionCtx.tables[relEntry.targetTableName] : void 0;
|
|
3823
3872
|
if (!relEntry || !targetTable) continue;
|
|
3824
|
-
const
|
|
3825
|
-
if (joinCols) needed.push(joinCols.localColPropName);
|
|
3873
|
+
for (const pair of extractRelationJoinColumnPairs(relEntry, table, targetTable) ?? []) needed.push(pair.localColPropName);
|
|
3826
3874
|
}
|
|
3827
3875
|
return needed;
|
|
3828
3876
|
};
|
|
@@ -4843,13 +4891,12 @@ const identifyRows = (field, args) => {
|
|
|
4843
4891
|
* Window functions require PostgreSQL, MySQL >= 8.0, or SQLite >= 3.25.
|
|
4844
4892
|
* Returns raw rows (NOT remapped); the caller groups + remaps them.
|
|
4845
4893
|
*/
|
|
4846
|
-
const batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, columns, orderCtx, whereArgs, junction) => {
|
|
4894
|
+
const batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, partitionCols, whereCondition, orderByArg, limit, offset, pkNames, columns, orderCtx, whereArgs, junction) => {
|
|
4847
4895
|
const cols = columns ?? getColumns(targetTable);
|
|
4848
4896
|
const orderExprs = [...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx, whereArgs) : [], ...primaryKeyOrderExprs(targetTable, pkNames)];
|
|
4849
4897
|
const orderClause = orderExprs.length ? sql` order by ${sql.join(orderExprs, sql`, `)}` : sql``;
|
|
4850
4898
|
const RN = "__drizzle_graphql_rn";
|
|
4851
|
-
const
|
|
4852
|
-
const rowNumber = sql`row_number() over (partition by ${partitionCol}${orderClause})`.as(RN);
|
|
4899
|
+
const rowNumber = sql`row_number() over (partition by ${sql.join([...partitionCols], sql`, `)}${orderClause})`.as(RN);
|
|
4853
4900
|
const sub = withJunction(db.select({
|
|
4854
4901
|
...cols,
|
|
4855
4902
|
[RN]: rowNumber
|
|
@@ -4888,13 +4935,14 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
|
|
|
4888
4935
|
const targetTableName = relEntry.targetTableName;
|
|
4889
4936
|
const targetTable = tables[targetTableName];
|
|
4890
4937
|
if (!parentTable || !targetTable) return;
|
|
4891
|
-
const
|
|
4892
|
-
if (!
|
|
4893
|
-
const
|
|
4938
|
+
const joinPairs = extractRelationJoinColumnPairs(relEntry, parentTable, targetTable);
|
|
4939
|
+
if (!joinPairs) return;
|
|
4940
|
+
const localColPropNames = joinPairs.map((pair) => pair.localColPropName);
|
|
4941
|
+
const foreignCol = joinPairs[0].foreignCol;
|
|
4894
4942
|
const junction = extractJunctionColumns(relEntry);
|
|
4895
|
-
const
|
|
4896
|
-
const
|
|
4897
|
-
const ownCondition = relationOwnCondition(relEntry, parentTable, targetTable,
|
|
4943
|
+
const groupCols = junction ? [junction.sourceCol] : joinPairs.map((pair) => pair.foreignCol);
|
|
4944
|
+
const groupKeys = junction ? [PARENT_KEY] : joinPairs.map((pair) => pair.foreignColPropName);
|
|
4945
|
+
const ownCondition = relationOwnCondition(relEntry, parentTable, targetTable, joinPairs.map((pair) => pair.localCol), groupCols);
|
|
4898
4946
|
const defaultDeleted = relationDeletedDefault(policies?.softDelete, targetTableName, isOne && relEntry.relation?.optional === false);
|
|
4899
4947
|
const limitPolicy = isOne ? void 0 : limits?.(targetTableName);
|
|
4900
4948
|
const targetPkNames = relEntry.targetPkNames ?? [];
|
|
@@ -4923,7 +4971,7 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
|
|
|
4923
4971
|
allRelations: filterCtx?.relationMap
|
|
4924
4972
|
});
|
|
4925
4973
|
const targetColumns = getColumns(targetTable);
|
|
4926
|
-
columns[foreignColPropName] = foreignCol;
|
|
4974
|
+
for (const pair of joinPairs) columns[pair.foreignColPropName] = pair.foreignCol;
|
|
4927
4975
|
for (const [columnName] of cursorEntries ?? []) {
|
|
4928
4976
|
const column = targetColumns[columnName];
|
|
4929
4977
|
if (column) columns[columnName] = column;
|
|
@@ -4935,8 +4983,8 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
|
|
|
4935
4983
|
};
|
|
4936
4984
|
const resolve = async (parent, args, context, info) => {
|
|
4937
4985
|
if (parent[relationName] !== void 0) return parent[relationName];
|
|
4938
|
-
const
|
|
4939
|
-
if (
|
|
4986
|
+
const localValues = localColPropNames.map((name) => parent[name]);
|
|
4987
|
+
if (localValues.some((value) => value == null)) return isOne ? null : [];
|
|
4940
4988
|
const { where: whereArg, limit: requestedLimit, offset, after, deleted } = args ?? {};
|
|
4941
4989
|
const { orderByArg, limit, distinct, cursorEntries, cursorValues, columns, loaderKey } = getOrCreateRequestValue(context, info?.fieldNodes?.[0], `relation:${tableName}::${relationName}`, () => {
|
|
4942
4990
|
const orderByArg = isOne ? args?.orderBy : withDefaultOrderBy(args ?? {}, targetTableName, policies?.defaultOrderBy).orderBy;
|
|
@@ -4977,11 +5025,11 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
|
|
|
4977
5025
|
};
|
|
4978
5026
|
});
|
|
4979
5027
|
if (junction === null) throw drizzleError(`Relation '${tableName}.${relationName}' goes through a junction with a composite key, which can only be loaded together with its parent. Leave it to eager loading (eagerLoadRelations).`, { code: "DRIZZLE_UNSUPPORTED_RELATION" });
|
|
4980
|
-
return getOrCreateLoader(context, loaderKey, async (
|
|
5028
|
+
return getOrCreateLoader(context, loaderKey, async (parentKeys) => {
|
|
4981
5029
|
const executor = resolveExecutor(db, context);
|
|
4982
|
-
const
|
|
5030
|
+
const uniqueKeys = [...new Map(parentKeys.map((key) => [joinKeyOf(key), key])).values()];
|
|
4983
5031
|
const scope = resolveScope(policies, context, filterCtx);
|
|
4984
|
-
let whereCondition = withScope(scope, targetTableName, targetTable, and(
|
|
5032
|
+
let whereCondition = withScope(scope, targetTableName, targetTable, and(parentKeyCondition(groupCols, uniqueKeys), ownCondition, whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName, scope)) : void 0, cursorValues ? buildCursorCondition(targetTable, cursorEntries, cursorValues, nullOrdering) : void 0), deleted ?? defaultDeleted);
|
|
4985
5033
|
if (distinct) {
|
|
4986
5034
|
const keys = await selectDistinctKeys({
|
|
4987
5035
|
db: executor,
|
|
@@ -4991,22 +5039,22 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
|
|
|
4991
5039
|
pkNames: targetPkNames,
|
|
4992
5040
|
where: whereCondition,
|
|
4993
5041
|
orderBy: orderByArg,
|
|
4994
|
-
partitionBy:
|
|
5042
|
+
partitionBy: groupCols,
|
|
4995
5043
|
junction: junction ? {
|
|
4996
5044
|
table: junction.table,
|
|
4997
5045
|
on: eq(junction.targetCol, foreignCol),
|
|
4998
|
-
parentKey:
|
|
5046
|
+
parentKey: junction.sourceCol
|
|
4999
5047
|
} : void 0
|
|
5000
5048
|
});
|
|
5001
|
-
if (!keys.length) return
|
|
5002
|
-
whereCondition = and(whereCondition, junction ? or(...keys.map((key) => and(eq(
|
|
5049
|
+
if (!keys.length) return parentKeys.map(() => isOne ? null : []);
|
|
5050
|
+
whereCondition = and(whereCondition, junction ? or(...keys.map((key) => and(eq(junction.sourceCol, key[DISTINCT_PARENT]), primaryKeyRestriction(targetTable, targetPkNames, [key])))) : primaryKeyRestriction(targetTable, targetPkNames, keys));
|
|
5003
5051
|
}
|
|
5004
5052
|
const selection = junction ? {
|
|
5005
5053
|
...columns ?? getColumns(targetTable),
|
|
5006
|
-
[PARENT_KEY]:
|
|
5054
|
+
[PARENT_KEY]: junction.sourceCol
|
|
5007
5055
|
} : columns;
|
|
5008
5056
|
let rows;
|
|
5009
|
-
if (limit != null || offset != null) rows = await batchedPaginatedRelationQuery(executor, targetTable, foreignCol, whereCondition, orderByArg, limit ?? null, offset ?? null, targetPkNames, selection, relationFilterCtx(filterCtx, targetTableName, scope), whereArg, junction);
|
|
5057
|
+
if (limit != null || offset != null) rows = await batchedPaginatedRelationQuery(executor, targetTable, foreignCol, groupCols, whereCondition, orderByArg, limit ?? null, offset ?? null, targetPkNames, selection, relationFilterCtx(filterCtx, targetTableName, scope), whereArg, junction);
|
|
5010
5058
|
else {
|
|
5011
5059
|
let q = withJunction((selection ? executor.select(selection) : executor.select()).from(targetTable), junction, foreignCol).where(whereCondition);
|
|
5012
5060
|
const orderExprs = cursorEntries ? cursorOrderExprs(targetTable, cursorEntries) : orderByArg ? extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName, scope), whereArg) : [];
|
|
@@ -5015,20 +5063,20 @@ const createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limi
|
|
|
5015
5063
|
}
|
|
5016
5064
|
if (cursorEntries) attachRowCursors(rows, cursorEntries);
|
|
5017
5065
|
const keyOf = (row) => {
|
|
5018
|
-
const key =
|
|
5066
|
+
const key = joinKeyOf(groupKeys.map((name) => row[name]));
|
|
5019
5067
|
if (junction) delete row[PARENT_KEY];
|
|
5020
5068
|
return key;
|
|
5021
5069
|
};
|
|
5022
5070
|
if (isOne) {
|
|
5023
5071
|
const byKey = new Map(rows.map((row) => [keyOf(row), row]));
|
|
5024
5072
|
remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
|
|
5025
|
-
return
|
|
5073
|
+
return parentKeys.map((key) => byKey.get(joinKeyOf(key)) ?? null);
|
|
5026
5074
|
}
|
|
5027
|
-
const grouped = new Map(
|
|
5075
|
+
const grouped = new Map(uniqueKeys.map((key) => [joinKeyOf(key), []]));
|
|
5028
5076
|
for (const row of rows) grouped.get(keyOf(row))?.push(row);
|
|
5029
5077
|
remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
|
|
5030
|
-
return
|
|
5031
|
-
}).load(
|
|
5078
|
+
return parentKeys.map((key) => grouped.get(joinKeyOf(key)) ?? []);
|
|
5079
|
+
}).load(localValues);
|
|
5032
5080
|
};
|
|
5033
5081
|
return async (parent, args, context, info) => {
|
|
5034
5082
|
try {
|
|
@@ -6104,8 +6152,8 @@ const createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, fi
|
|
|
6104
6152
|
const targetTableName = relEntry.targetTableName;
|
|
6105
6153
|
const targetTable = tables[targetTableName];
|
|
6106
6154
|
if (!parentTable || !targetTable) return;
|
|
6107
|
-
const
|
|
6108
|
-
if (!
|
|
6155
|
+
const joinPairs = extractRelationJoinColumnPairs(relEntry, parentTable, targetTable);
|
|
6156
|
+
if (!joinPairs) {
|
|
6109
6157
|
const key = `${tableName}.${relationName}`;
|
|
6110
6158
|
if (!warned.has(key)) {
|
|
6111
6159
|
warned.add(key);
|
|
@@ -6113,11 +6161,13 @@ const createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, fi
|
|
|
6113
6161
|
}
|
|
6114
6162
|
return;
|
|
6115
6163
|
}
|
|
6116
|
-
const
|
|
6164
|
+
const localColPropNames = joinPairs.map((pair) => pair.localColPropName);
|
|
6165
|
+
const foreignCol = joinPairs[0].foreignCol;
|
|
6117
6166
|
const junction = extractJunctionColumns(relEntry);
|
|
6118
6167
|
if (junction === null) return;
|
|
6119
|
-
const
|
|
6120
|
-
const
|
|
6168
|
+
const groupCols = junction ? [junction.sourceCol] : joinPairs.map((pair) => pair.foreignCol);
|
|
6169
|
+
const groupAliases = groupCols.map((_, i) => `${GROUP_KEY}${i}`);
|
|
6170
|
+
const ownCondition = relationOwnCondition(relEntry, parentTable, targetTable, joinPairs.map((pair) => pair.localCol), groupCols);
|
|
6121
6171
|
const defaultDeleted = relationDeletedDefault(policies?.softDelete, targetTableName, false);
|
|
6122
6172
|
const targetTypeName = resolveTypeName(targetTableName, typeNameMapper);
|
|
6123
6173
|
const type = generateAggregateTypes(targetTable, targetTableName, targetTypeName, cacheCtx);
|
|
@@ -6141,24 +6191,25 @@ const createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, fi
|
|
|
6141
6191
|
};
|
|
6142
6192
|
});
|
|
6143
6193
|
if (!Object.keys(request.selection).length) return {};
|
|
6144
|
-
const
|
|
6145
|
-
if (
|
|
6194
|
+
const localValues = localColPropNames.map((name) => parent[name]);
|
|
6195
|
+
if (localValues.some((value) => value == null)) return assembleAggregateRow({}, request, target);
|
|
6146
6196
|
const whereArg = args?.where;
|
|
6147
6197
|
const deleted = args?.deleted;
|
|
6148
|
-
const loader = getOrCreateLoader(context, loaderKey, async (
|
|
6198
|
+
const loader = getOrCreateLoader(context, loaderKey, async (parentKeys) => {
|
|
6149
6199
|
const executor = resolveExecutor(db, context);
|
|
6150
|
-
const
|
|
6200
|
+
const uniqueKeys = [...new Map(parentKeys.map((key) => [joinKeyOf(key), key])).values()];
|
|
6151
6201
|
const scope = resolveScope(policies, context, filterCtx);
|
|
6152
|
-
const whereCondition = withScope(scope, targetTableName, targetTable, and(
|
|
6202
|
+
const whereCondition = withScope(scope, targetTableName, targetTable, and(parentKeyCondition(groupCols, uniqueKeys), ownCondition, whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName, scope)) : void 0), deleted ?? defaultDeleted);
|
|
6203
|
+
const groupSelection = Object.fromEntries(groupAliases.map((alias, i) => [alias, groupCols[i]]));
|
|
6153
6204
|
const selected = executor.select({
|
|
6154
|
-
|
|
6205
|
+
...groupSelection,
|
|
6155
6206
|
...request.selection
|
|
6156
6207
|
}).from(targetTable);
|
|
6157
|
-
const rows = await (junction ? selected.innerJoin(junction.table, eq(junction.targetCol, foreignCol)) : selected).where(whereCondition).groupBy(
|
|
6158
|
-
const byKey = new Map(rows.map((row) => [row[
|
|
6159
|
-
return
|
|
6208
|
+
const rows = await (junction ? selected.innerJoin(junction.table, eq(junction.targetCol, foreignCol)) : selected).where(whereCondition).groupBy(...groupCols);
|
|
6209
|
+
const byKey = new Map(rows.map((row) => [joinKeyOf(groupAliases.map((alias) => row[alias])), row]));
|
|
6210
|
+
return parentKeys.map((key) => byKey.get(joinKeyOf(key)) ?? {});
|
|
6160
6211
|
});
|
|
6161
|
-
return assembleAggregateRow(await loader.load(
|
|
6212
|
+
return assembleAggregateRow(await loader.load(localValues), request, target);
|
|
6162
6213
|
} catch (e) {
|
|
6163
6214
|
throw withErrorContext(toGraphQLError(e), errorCtx);
|
|
6164
6215
|
}
|