fix(housekeeping): align poll deletion lock order
This commit is contained in:
1 parent
b4193bea6c
commit
6e16b948e6
2 files changed
+33
-2
No files matched your search
+28
-2
@@ -19,6 +19,7 @@ const database = vi.hoisted(() => {
|
||||
let selectedQueue: Record<string, unknown>[] = [];
|
||||
let selectedTable: string | undefined;
|
||||
let lockedTables: Array<readonly [string | undefined, string]> = [];
|
||||
let mutationSteps: string[] = [];
|
||||
const insertedValues = vi.fn(async (_values: Record<string, unknown>) => [
|
||||
{ insertId: 8 },
|
||||
]);
|
||||
@@ -32,6 +33,7 @@ const database = vi.hoisted(() => {
|
||||
const limit = vi.fn(async () => nextSelected());
|
||||
const lock = vi.fn(async (strength: string) => {
|
||||
lockedTables.push([selectedTable, strength]);
|
||||
mutationSteps.push(`lock:${selectedTable ?? "unknown"}`);
|
||||
return nextSelected();
|
||||
});
|
||||
const where = vi.fn(() => ({ for: lock, limit }));
|
||||
@@ -42,7 +44,12 @@ const database = vi.hoisted(() => {
|
||||
const select = vi.fn(() => ({ from }));
|
||||
const execute = vi.fn(async () => undefined);
|
||||
const deleteWhere = vi.fn(async () => undefined);
|
||||
const remove = vi.fn((_table: unknown) => ({ where: deleteWhere }));
|
||||
const remove = vi.fn((table: unknown) => {
|
||||
mutationSteps.push(
|
||||
`delete:${(table as { tableName?: string }).tableName ?? "unknown"}`,
|
||||
);
|
||||
return { where: deleteWhere };
|
||||
});
|
||||
return {
|
||||
execute,
|
||||
insert,
|
||||
@@ -51,6 +58,9 @@ const database = vi.hoisted(() => {
|
||||
lockedTables() {
|
||||
return [...lockedTables];
|
||||
},
|
||||
mutationSteps() {
|
||||
return [...mutationSteps];
|
||||
},
|
||||
set,
|
||||
update,
|
||||
select,
|
||||
@@ -66,6 +76,7 @@ const database = vi.hoisted(() => {
|
||||
selectedQueue = [];
|
||||
selectedTable = undefined;
|
||||
lockedTables = [];
|
||||
mutationSteps = [];
|
||||
},
|
||||
queueSelected(...values: Record<string, unknown>[]) {
|
||||
selectedQueue = [...values];
|
||||
@@ -186,7 +197,17 @@ describe("Content database mutation runtime partial updates", () => {
|
||||
"WebsitePollQuestion",
|
||||
"WebsitePoll",
|
||||
]);
|
||||
expect(database.lockedTables()).toEqual([["WebsitePoll", "update"]]);
|
||||
expect(database.lockedTables()).toEqual([
|
||||
["WebsitePoll", "update"],
|
||||
["WebsitePollQuestion", "update"],
|
||||
]);
|
||||
expect(database.mutationSteps()).toEqual([
|
||||
"lock:WebsitePoll",
|
||||
"lock:WebsitePollQuestion",
|
||||
"delete:WebsitePollVote",
|
||||
"delete:WebsitePollQuestion",
|
||||
"delete:WebsitePoll",
|
||||
]);
|
||||
});
|
||||
|
||||
it("deletes question votes before the question and retains its audit snapshot", async () => {
|
||||
@@ -219,6 +240,11 @@ describe("Content database mutation runtime partial updates", () => {
|
||||
expect(database.lockedTables()).toEqual([
|
||||
["WebsitePollQuestion", "update"],
|
||||
]);
|
||||
expect(database.mutationSteps()).toEqual([
|
||||
"lock:WebsitePollQuestion",
|
||||
"delete:WebsitePollVote",
|
||||
"delete:WebsitePollQuestion",
|
||||
]);
|
||||
});
|
||||
|
||||
it("rejects moving a question to another poll during update", async () => {
|
||||
|
||||
@@ -635,6 +635,11 @@ async function pollChange(
|
||||
.for("update");
|
||||
if (!existing) throw notFound();
|
||||
if (action === "delete") {
|
||||
await connection
|
||||
.select({ id: WebsitePollQuestion.id })
|
||||
.from(WebsitePollQuestion)
|
||||
.where(eq(WebsitePollQuestion.pollId, id))
|
||||
.for("update");
|
||||
await connection
|
||||
.delete(WebsitePollVote)
|
||||
.where(
|
||||
|
||||
Reference in new issue
Block a user