Skip to content

Commit 60ff807

Browse files
authored
Triggers: Fix patch/delete with explicit table names (#881)
1 parent 6f1b4f0 commit 60ff807

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

packages/convex-helpers/server/triggers.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ const schema = defineSchema({
3232
lastName: v.string(),
3333
fullName: v.string(),
3434
}),
35+
36+
userCount: defineTable({
37+
count: v.number(),
38+
}),
3539
});
3640
type DataModel = DataModelFromSchemaDefinition<typeof schema>;
3741
const rawMutation = mutationGeneric as MutationBuilder<DataModel, "public">;
@@ -70,6 +74,20 @@ triggers.register("usersExplicitIncorrectTable", async (ctx, change) => {
7074
}
7175
});
7276

77+
// Keep a denormalized count of all users.
78+
triggers.register("usersExplicit", async (ctx, change) => {
79+
const countDoc = await ctx.db.query("userCount").first();
80+
const currentCount = countDoc?.count ?? 0;
81+
const countId =
82+
countDoc?._id ?? (await ctx.db.insert("userCount", { count: 0 }));
83+
84+
if (change.operation === "insert") {
85+
await ctx.db.patch("userCount", countId, { count: currentCount + 1 });
86+
} else if (change.operation === "delete") {
87+
await ctx.db.patch("userCount", countId, { count: currentCount - 1 });
88+
}
89+
});
90+
7391
const mutation = customMutation(rawMutation, customCtx(triggers.wrapDB));
7492

7593
export const createUser = mutation({
@@ -105,11 +123,30 @@ export const createUserExplicitIncorrectTable = mutation({
105123
},
106124
});
107125

126+
export const updateUser = mutation({
127+
args: {
128+
id: v.id("usersExplicit"),
129+
firstName: v.string(),
130+
},
131+
handler: async (ctx, { id, firstName }) => {
132+
return ctx.db.patch("usersExplicit", id, { firstName });
133+
},
134+
});
135+
136+
export const deleteUser = mutation({
137+
args: { id: v.id("usersExplicit") },
138+
handler: async (ctx, args) => {
139+
return ctx.db.delete("usersExplicit", args.id);
140+
},
141+
});
142+
108143
const testApi: ApiFromModules<{
109144
fns: {
110145
createUser: typeof createUser;
111146
createUserExplicit: typeof createUserExplicit;
112147
createUserExplicitIncorrectTable: typeof createUserExplicitIncorrectTable;
148+
updateUser: typeof updateUser;
149+
deleteUser: typeof deleteUser;
113150
};
114151
}>["fns"] = anyApi["triggers.test"] as any;
115152

@@ -148,3 +185,40 @@ test("trigger with wrong usage of explicit IDs fails", async () => {
148185
"Invalid argument `id`, expected ID in table 'users' but got ID in table 'usersExplicitIncorrectTable'",
149186
);
150187
});
188+
189+
test("create, update and delete", async () => {
190+
const t = convexTest(schema, modules);
191+
192+
async function getUserCount() {
193+
return await t.run(async (ctx) => {
194+
const countDoc = await ctx.db.query("userCount").first();
195+
return countDoc?.count ?? null;
196+
});
197+
}
198+
199+
expect(await getUserCount()).toBeNull();
200+
201+
const userId = await t.mutation(testApi.createUserExplicit, {
202+
firstName: "Jane",
203+
lastName: "Smith",
204+
});
205+
expect(await getUserCount()).toBe(1);
206+
207+
const user2Id = await t.mutation(testApi.createUserExplicit, {
208+
firstName: "Alex",
209+
lastName: "Johnson",
210+
});
211+
expect(await getUserCount()).toBe(2);
212+
213+
await t.mutation(testApi.updateUser, {
214+
id: userId,
215+
firstName: "Janet",
216+
});
217+
expect(await getUserCount()).toBe(2);
218+
219+
await t.mutation(testApi.deleteUser, { id: userId });
220+
expect(await getUserCount()).toBe(1);
221+
222+
await t.mutation(testApi.deleteUser, { id: user2Id });
223+
expect(await getUserCount()).toBe(0);
224+
});

packages/convex-helpers/server/triggers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ async function _queueTriggers<
439439
db: writerWithTriggers(ctx, innerDb, triggers, true),
440440
innerDb: innerDb,
441441
};
442-
for (const trigger of triggers.registered[tableName]!) {
442+
for (const trigger of triggers.registered[tableName] ?? []) {
443443
triggerQueue.push(async () => {
444444
await trigger(recursiveCtx, change);
445445
});

0 commit comments

Comments
 (0)