From 76e6bbdbbf4d6df6c8565576b5d0830afbb36e9b Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Mon, 15 May 2023 20:28:42 +0200 Subject: [PATCH] Add event versioning capabilities --- src/models/calendar/events/events.router.ts | 2 +- src/models/calendar/events/events.service.ts | 53 ++++++++++++++++---- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/models/calendar/events/events.router.ts b/src/models/calendar/events/events.router.ts index fea28cd..0422e6a 100644 --- a/src/models/calendar/events/events.router.ts +++ b/src/models/calendar/events/events.router.ts @@ -276,7 +276,7 @@ eventsRouter.delete('/:eventId', async (req: Request, res: Response) => { createdDate: new Date(), location: '', createdBy: '', - createdById: -1, + createdById: user.userId ?? -1, url: '', wholeDay: false, status: 'DELETED' diff --git a/src/models/calendar/events/events.service.ts b/src/models/calendar/events/events.service.ts index a52a5d7..14bae21 100644 --- a/src/models/calendar/events/events.service.ts +++ b/src/models/calendar/events/events.service.ts @@ -14,7 +14,19 @@ export const getAllEvents = async (calendarId: number): Promise => { let conn = await NachklangCalendarDB.getConnection(); let eventRows: Event[] = []; try { - const eventsQuery = 'SELECT e.*, u.full_name FROM events e LEFT OUTER JOIN users u ON e.created_by_id = u.user_id WHERE calendar_id = ? AND status=\'PUBLIC\''; + const eventsQuery = ` + SELECT e.calendar_id, u.full_name, v.* FROM events e + INNER JOIN ( + SELECT event_id, MAX(event_version_id) AS latest_version + FROM event_versions + GROUP BY event_id + ) latest_versions + ON e.event_id = latest_versions.event_id + INNER JOIN event_versions v + ON v.event_id = latest_versions.event_id AND v.event_version_id = latest_versions.latest_version + LEFT OUTER JOIN users u ON u.user_id = e.created_by_id + WHERE e.calendar_id = ? AND v.status = 'PUBLIC' + ORDER BY e.event_id`; const eventsRes = await conn.query(eventsQuery, calendarId); for (let row of eventsRes) { @@ -48,7 +60,19 @@ export const getAllEventsAdmin = async (calendarId: number): Promise => let conn = await NachklangCalendarDB.getConnection(); let eventRows: Event[] = []; try { - const eventsQuery = 'SELECT e.*, u.full_name FROM events e LEFT OUTER JOIN users u ON e.created_by_id = u.user_id WHERE calendar_id = ?'; + const eventsQuery = ` + SELECT e.calendar_id, u.full_name, v.* FROM events e + INNER JOIN ( + SELECT event_id, MAX(event_version_id) AS latest_version + FROM event_versions + GROUP BY event_id + ) latest_versions + ON e.event_id = latest_versions.event_id + INNER JOIN event_versions v + ON v.event_id = latest_versions.event_id AND v.event_version_id = latest_versions.latest_version + LEFT OUTER JOIN users u ON u.user_id = e.created_by_id + WHERE e.calendar_id = ? + ORDER BY e.event_id`; const eventsRes = await conn.query(eventsQuery, calendarId); for (let row of eventsRes) { @@ -87,8 +111,13 @@ export const createEvent = async (event: Event): Promise => { let conn = await NachklangCalendarDB.getConnection(); try { let eventUUID = Guid.create().toString(); - const eventsQuery = 'INSERT INTO events (calendar_id, uuid, name, description, start_datetime, end_datetime, location, created_by_id, url, whole_day, status) VALUES (?,?,?,?,?,?,?,?,?,?,?) RETURNING event_id'; - const eventsRes = await conn.execute(eventsQuery, [event.calendarId, eventUUID, event.name, event.description, event.startDateTime, event.endDateTime, event.location, event.createdById, event.url, event.wholeDay, event.status]); + const eventsQuery = 'INSERT INTO events (calendar_id, uuid, created_by_id) VALUES (?,?,?) RETURNING event_id'; + const eventsRes = await conn.execute(eventsQuery, [event.calendarId, eventUUID, event.createdById]); + + const versionQuery = 'INSERT INTO event_versions (event_id, name, description, start_datetime, end_datetime, whole_day, location, url, status, version_created_by_id) VALUES (?,?,?,?,?,?,?,?,?,?);' + const versionRes = await conn.execute(versionQuery, [eventsRes[0].event_id, event.name, event.description, event.startDateTime, event.endDateTime, event.wholeDay, event.location, event.url, event.status, event.createdById]); + + await conn.commit(); return eventsRes[0].event_id; } catch (err) { @@ -108,10 +137,12 @@ export const createEvent = async (event: Event): Promise => { export const updateEvent = async (event: Event): Promise => { let conn = await NachklangCalendarDB.getConnection(); try { - const eventsQuery = 'UPDATE events SET name = ?, description = ?, start_datetime = ?, end_datetime = ?, location = ?, created_by_id = ?, url = ?, whole_day = ?, status = ? WHERE event_id = ?'; - const eventsRes = await conn.execute(eventsQuery, [event.name, event.description, event.startDateTime, event.endDateTime, event.location, event.createdById, event.url, event.wholeDay, event.status, event.eventId]); + const versionQuery = 'INSERT INTO event_versions (event_id, name, description, start_datetime, end_datetime, whole_day, location, url, status, version_created_by_id) VALUES (?,?,?,?,?,?,?,?,?,?);' + const versionRes = await conn.execute(versionQuery, [event.eventId, event.name, event.description, event.startDateTime, event.endDateTime, event.wholeDay, event.location, event.url, event.status, event.createdById]); - return eventsRes.affectedRows; + await conn.commit(); + + return versionRes.affectedRows; } catch (err) { await conn.rollback(); throw err; @@ -129,10 +160,12 @@ export const updateEvent = async (event: Event): Promise => { export const deleteEvent = async (event: Event): Promise => { let conn = await NachklangCalendarDB.getConnection(); try { - const eventsQuery = 'UPDATE events SET status=\'DELETED\' WHERE event_id = ?'; - const eventsRes = await conn.execute(eventsQuery, [event.eventId]); + const versionQuery = 'INSERT INTO event_versions (event_id, status, version_created_by_id) VALUES (?,?,?);' + const versionRes = await conn.execute(versionQuery, [event.eventId, 'DELETED', event.createdById]); - return eventsRes.affectedRows === 1; + await conn.commit(); + + return versionRes.affectedRows === 1; } catch (err) { await conn.rollback(); throw err;