fix(db): accumulate many-includes and nest relations in prisma facade

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
simoleo89
2026-07-31 20:57:52 +02:00
co-authored by Cursor
parent e5ff7ec9e5
commit 20b85381fe
3 changed files with 97 additions and 11 deletions
+46 -10
View File
@@ -270,24 +270,36 @@ async function queryRelationRows(
rel: any,
opts: any,
keyValues: unknown[],
mode: "one" | "many",
): Promise<Map<string, any>> {
const join = resolveJoin(table, rel);
const byCol = join.fkCols[0];
const condition = inArray(byCol, coerceArray(byCol, keyValues));
const parts = [
inArray(byCol, coerceArray(byCol, keyValues)),
buildCondition(rel.referencedTable, opts.where),
].filter(Boolean);
const condition = parts.length === 1 ? parts[0] : and(...parts);
const sel = projection(rel.referencedTable, opts.select);
const orderBy = buildOrderBy(rel.referencedTable, opts.orderBy);
let stmt: any = sel
? client.select({ ...sel, __fk: byCol }).from(rel.referencedTable)
: client.select().from(rel.referencedTable);
stmt = stmt.where(condition);
if (condition) stmt = stmt.where(condition);
if (orderBy.length) stmt = stmt.orderBy(...orderBy);
const rows = (await stmt) as any[];
const map = new Map<string, any>();
for (const row of rows) {
const key = row.__fk ?? row[colKey(byCol)];
map.set(String(key), sel ? pickRow(row, opts.select) : row);
const key = String(row.__fk ?? row[colKey(byCol)]);
const cleaned = sel ? pickRow(row, opts.select) : row;
if (mode === "many") {
const list = map.get(key);
if (Array.isArray(list)) list.push(cleaned);
else map.set(key, [cleaned]);
} else if (!map.has(key)) {
map.set(key, cleaned);
}
}
return map;
}
@@ -386,13 +398,25 @@ async function attachIncludes(
for (const row of rows) row[rel.fieldName] = null;
continue;
}
const map = await queryRelationRows(client, table, rel, opts, values);
const map = await queryRelationRows(
client,
table,
rel,
opts,
values,
"one",
);
const join = resolveJoin(table, rel);
const refCol = join.refCols[0];
const related: any[] = [];
for (const row of rows) {
const refValue = row[colKey(refCol)];
row[rel.fieldName] =
refValue == null ? null : (map.get(String(refValue)) ?? null);
const hit = refValue == null ? null : (map.get(String(refValue)) ?? null);
row[rel.fieldName] = hit;
if (hit) related.push(hit);
}
if (opts.include && related.length > 0) {
await attachIncludes(client, rel.referencedTable, related, opts.include);
}
}
@@ -402,13 +426,25 @@ async function attachIncludes(
for (const row of rows) row[rel.fieldName] = [];
continue;
}
const map = await queryRelationRows(client, table, rel, opts, values);
const map = await queryRelationRows(
client,
table,
rel,
opts,
values,
"many",
);
const join = resolveJoin(table, rel);
const refCol = join.refCols[0];
const related: any[] = [];
for (const row of rows) {
const refValue = row[colKey(refCol)];
row[rel.fieldName] =
refValue == null ? [] : (map.get(String(refValue)) ?? []);
const list = refValue == null ? [] : (map.get(String(refValue)) ?? []);
row[rel.fieldName] = list;
for (const item of list) related.push(item);
}
if (opts.include && related.length > 0) {
await attachIncludes(client, rel.referencedTable, related, opts.include);
}
}