From 1a854faa0974861fa9c701052ad5eaabe77f4e5f Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 23 Feb 2025 10:53:19 -0800 Subject: [PATCH 1/2] fix(delegate): deleteMany fails when the model has compound id fields fixes #1998 --- .../runtime/src/enhancements/node/delegate.ts | 21 ++++++- tests/regression/tests/issue-1998.test.ts | 60 +++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 tests/regression/tests/issue-1998.test.ts diff --git a/packages/runtime/src/enhancements/node/delegate.ts b/packages/runtime/src/enhancements/node/delegate.ts index 06c1526e5..59bc79793 100644 --- a/packages/runtime/src/enhancements/node/delegate.ts +++ b/packages/runtime/src/enhancements/node/delegate.ts @@ -1106,7 +1106,18 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler { const entities = await db[model].findMany(findArgs); // recursively delete base entities (they all have the same id values) - await Promise.all(entities.map((entity) => this.doDelete(db, model, { where: entity }))); + + await Promise.all( + entities.map((entity) => { + let deleteFilter = entity; + if (Object.keys(deleteFilter).length > 1) { + // if the model has compound id fields, we need to compose a compound key filter, + // otherwise calling Prisma's `delete` won't work + deleteFilter = this.queryUtils.composeCompoundUniqueField(model, deleteFilter); + } + return this.doDelete(db, model, { where: deleteFilter }); + }) + ); return { count: entities.length }; } @@ -1114,7 +1125,13 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler { private async deleteBaseRecursively(db: CrudContract, model: string, idValues: any) { let base = this.getBaseModel(model); while (base) { - await db[base.name].delete({ where: idValues }); + let deleteFilter = idValues; + if (Object.keys(idValues).length > 1) { + // if the model has compound id fields, we need to compose a compound key filter, + // otherwise calling Prisma's `delete` won't work + deleteFilter = this.queryUtils.composeCompoundUniqueField(base.name, deleteFilter); + } + await db[base.name].delete({ where: deleteFilter }); base = this.getBaseModel(base.name); } } diff --git a/tests/regression/tests/issue-1998.test.ts b/tests/regression/tests/issue-1998.test.ts new file mode 100644 index 000000000..ad7d0b73a --- /dev/null +++ b/tests/regression/tests/issue-1998.test.ts @@ -0,0 +1,60 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('issue 1998', () => { + it('regression', async () => { + const { enhance } = await loadSchema( + ` + model Entity { + id String @id + type String + updatable Boolean + children Relation[] @relation("children") + parents Relation[] @relation("parents") + + @@delegate(type) + @@allow('create,read', true) + @@allow('update', updatable) + } + + model A extends Entity {} + + model B extends Entity {} + + model Relation { + parent Entity @relation("children", fields: [parentId], references: [id]) + parentId String + child Entity @relation("parents", fields: [childId], references: [id]) + childId String + + @@allow('create', true) + @@allow('read', check(parent, 'read') && check(child, 'read')) + @@allow('delete', check(parent, 'update') && check(child, 'update')) + + @@id([parentId, childId]) + } + `, + { logPrismaQuery: true } + ); + + const db = enhance(); + + await db.a.create({ data: { id: '1', updatable: true } }); + await db.b.create({ data: { id: '2', updatable: true } }); + await db.relation.create({ data: { parentId: '1', childId: '2' } }); + + await expect( + db.relation.deleteMany({ + where: { parentId: '1', childId: '2' }, + }) + ).resolves.toEqual({ count: 1 }); + + await db.a.create({ data: { id: '3', updatable: false } }); + await db.b.create({ data: { id: '4', updatable: false } }); + await db.relation.create({ data: { parentId: '3', childId: '4' } }); + await expect( + db.relation.deleteMany({ + where: { parentId: '3', childId: '4' }, + }) + ).resolves.toEqual({ count: 0 }); + }); +}); From 7b7cb6656c293e5f5da886d954fadf561808a2a9 Mon Sep 17 00:00:00 2001 From: ymc9 <104139426+ymc9@users.noreply.github.com> Date: Sun, 23 Feb 2025 10:54:03 -0800 Subject: [PATCH 2/2] update --- tests/regression/tests/issue-1998.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/regression/tests/issue-1998.test.ts b/tests/regression/tests/issue-1998.test.ts index ad7d0b73a..a2810dfea 100644 --- a/tests/regression/tests/issue-1998.test.ts +++ b/tests/regression/tests/issue-1998.test.ts @@ -32,8 +32,7 @@ describe('issue 1998', () => { @@id([parentId, childId]) } - `, - { logPrismaQuery: true } + ` ); const db = enhance();