Handle referential integrity with prisma

This commit is contained in:
Luke Vella 2022-05-22 16:53:02 +01:00
parent 00cf0827b4
commit 7b30342803
6 changed files with 84 additions and 92 deletions

View file

@ -5,8 +5,8 @@ on:
query:
description: "Query params for house keeping endpoint"
required: false
# schedule:
# - cron: "0 6 * * *" # Every day at 6:00am UTC
schedule:
- cron: "0 6 * * *" # Every day at 6:00am UTC
jobs:
clean:

View file

@ -0,0 +1,29 @@
-- DropForeignKey
ALTER TABLE "comments" DROP CONSTRAINT "comments_poll_id_fkey";
-- DropForeignKey
ALTER TABLE "comments" DROP CONSTRAINT "comments_user_id_fkey";
-- DropForeignKey
ALTER TABLE "links" DROP CONSTRAINT "links_poll_id_fkey";
-- DropForeignKey
ALTER TABLE "options" DROP CONSTRAINT "options_poll_id_fkey";
-- DropForeignKey
ALTER TABLE "participants" DROP CONSTRAINT "participants_poll_id_fkey";
-- DropForeignKey
ALTER TABLE "participants" DROP CONSTRAINT "participants_user_id_fkey";
-- DropForeignKey
ALTER TABLE "polls" DROP CONSTRAINT "polls_user_id_fkey";
-- DropForeignKey
ALTER TABLE "votes" DROP CONSTRAINT "votes_option_id_fkey";
-- DropForeignKey
ALTER TABLE "votes" DROP CONSTRAINT "votes_participant_id_fkey";
-- DropForeignKey
ALTER TABLE "votes" DROP CONSTRAINT "votes_poll_id_fkey";

View file

@ -1,10 +1,12 @@
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
referentialIntegrity = "prisma"
}
generator client {
provider = "prisma-client-js"
previewFeatures = ["referentialIntegrity"]
}
model User {
@ -111,9 +113,9 @@ enum VoteType {
model Vote {
id String @id @default(cuid())
participant Participant @relation(fields: [participantId], references: [id])
participant Participant @relation(fields: [participantId], references: [id], onDelete: Cascade)
participantId String @map("participant_id")
option Option @relation(fields: [optionId], references: [id])
option Option @relation(fields: [optionId], references: [id], onDelete: Cascade)
optionId String @map("option_id")
poll Poll @relation(fields: [pollId], references: [urlId])
pollId String @map("poll_id")

View file

@ -7,7 +7,8 @@ import { prisma } from "~/prisma/db";
/**
* This endpoint will permanently delete polls that:
* * have been soft deleted OR
* * are demo polls that are older than 1 day
* * are demo polls that are older than 1 day OR
* * polls that have not been accessed for 30 days
* All dependant records are also deleted.
*/
export default async function handler(
@ -72,78 +73,52 @@ export default async function handler(
if (pollIds.length !== 0) {
// Delete links
await prisma.$transaction([
prisma.$executeRawUnsafe("ALTER TABLE links DISABLE TRIGGER ALL"),
prisma.link.deleteMany({
where: {
pollId: {
in: pollIds,
},
await prisma.link.deleteMany({
where: {
pollId: {
in: pollIds,
},
}),
prisma.$executeRawUnsafe("ALTER TABLE links ENABLE TRIGGER ALL"),
]);
},
});
// Delete comments
await prisma.$transaction([
prisma.$executeRawUnsafe("ALTER TABLE comments DISABLE TRIGGER ALL"),
prisma.comment.deleteMany({
where: {
pollId: {
in: pollIds,
},
await prisma.comment.deleteMany({
where: {
pollId: {
in: pollIds,
},
}),
prisma.$executeRawUnsafe("ALTER TABLE comments ENABLE TRIGGER ALL"),
]);
},
});
await prisma.$transaction([
prisma.$executeRawUnsafe("ALTER TABLE votes DISABLE TRIGGER ALL"),
prisma.vote.deleteMany({
where: {
pollId: {
in: pollIds,
},
await prisma.vote.deleteMany({
where: {
pollId: {
in: pollIds,
},
}),
prisma.$executeRawUnsafe("ALTER TABLE votes ENABLE TRIGGER ALL"),
]);
},
});
// Delete participants
await prisma.$transaction([
prisma.$executeRawUnsafe("ALTER TABLE participants DISABLE TRIGGER ALL"),
prisma.participant.deleteMany({
where: {
pollId: {
in: pollIds,
},
await prisma.participant.deleteMany({
where: {
pollId: {
in: pollIds,
},
}),
prisma.$executeRawUnsafe("ALTER TABLE participants ENABLE TRIGGER ALL"),
]);
},
});
// Delete options
await prisma.$transaction([
prisma.$executeRawUnsafe("ALTER TABLE options DISABLE TRIGGER ALL"),
prisma.option.deleteMany({
where: {
pollId: {
in: pollIds,
},
await prisma.option.deleteMany({
where: {
pollId: {
in: pollIds,
},
}),
prisma.$executeRawUnsafe("ALTER TABLE options ENABLE TRIGGER ALL"),
]);
},
});
// Delete polls
await prisma.$transaction([
prisma.$executeRawUnsafe("ALTER TABLE polls DISABLE TRIGGER ALL"),
// Using raw query to bypass soft delete middleware
prisma.$executeRaw`DELETE FROM polls WHERE url_id IN (${Prisma.join(
pollIds,
)})`,
prisma.$executeRawUnsafe("ALTER TABLE polls ENABLE TRIGGER ALL"),
]);
prisma.$executeRaw`DELETE FROM polls WHERE url_id IN (${Prisma.join(
pollIds,
)})`;
}
res.status(200).json({

View file

@ -165,23 +165,14 @@ export const polls = createRouter()
const { pollId } = link;
if (input.optionsToDelete && input.optionsToDelete.length > 0) {
await prisma.$transaction([
prisma.vote.deleteMany({
where: {
optionId: {
in: input.optionsToDelete,
},
await prisma.option.deleteMany({
where: {
pollId,
id: {
in: input.optionsToDelete,
},
}),
prisma.option.deleteMany({
where: {
pollId,
id: {
in: input.optionsToDelete,
},
},
}),
]);
},
});
}
if (input.optionsToAdd && input.optionsToAdd.length > 0) {

View file

@ -35,19 +35,14 @@ export const participants = createRouter()
participantId: z.string(),
}),
resolve: async ({ input: { participantId, pollId } }) => {
await prisma.$transaction([
prisma.vote.deleteMany({
where: { participantId: participantId },
}),
prisma.participant.delete({
where: {
id_pollId: {
id: participantId,
pollId: pollId,
},
await prisma.participant.delete({
where: {
id_pollId: {
id: participantId,
pollId: pollId,
},
}),
]);
},
});
},
})
.mutation("add", {