From b153fae5e3a67e80e42f3ad7e0c1be9f4c6736a7 Mon Sep 17 00:00:00 2001 From: e11sy Date: Fri, 5 Apr 2024 18:52:02 +0300 Subject: [PATCH] separeted saving note visit to two sql queries --- src/domain/entities/noteVisit.ts | 3 +- .../postgres/orm/sequelize/noteVisits.ts | 46 +++++++++++++++---- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/domain/entities/noteVisit.ts b/src/domain/entities/noteVisit.ts index 096471bc..5c8f7996 100644 --- a/src/domain/entities/noteVisit.ts +++ b/src/domain/entities/noteVisit.ts @@ -1,6 +1,5 @@ import type { NoteInternalId } from '@domain/entities/note.ts'; import type User from '@domain/entities/user.ts'; -import type { Literal } from 'sequelize/lib/utils'; /** * NoteVisit is used to store data about the last interaction between the user and the note @@ -24,5 +23,5 @@ export default interface NoteVisit { /** * Time when note was visited for the last time (timestamp with timezone) */ - visitedAt: string | Literal, + visitedAt: string, } \ No newline at end of file diff --git a/src/repository/storage/postgres/orm/sequelize/noteVisits.ts b/src/repository/storage/postgres/orm/sequelize/noteVisits.ts index b0cbabc0..766a5be7 100644 --- a/src/repository/storage/postgres/orm/sequelize/noteVisits.ts +++ b/src/repository/storage/postgres/orm/sequelize/noteVisits.ts @@ -118,19 +118,45 @@ export default class NoteVisitsSequelizeStorage { * If user has already visited note, then existing record will be updated * If user is visiting note for the first time, new record will be created */ - const [recentVisit, _] = await this.model.upsert({ - noteId, - userId, - visitedAt: literal('CURRENT_DATE'), - }, { - conflictWhere: { - 'note_id': noteId, - 'user_id': userId, + const existingVisit = await this.model.findOne({ + where: { + noteId, + userId, }, - returning: true, }); - return recentVisit; + let updatedVisits: NoteVisit[]; + let _; + + if (existingVisit === null) { + return await this.model.create({ + noteId, + userId, + /** + * we should pass to model datatype respectfully to declared in NoteVisitsModel class + * if we will pass just 'CLOCK_TIMESTAMP()' it will be treated by orm just like a string, that is why we should use literal + * but model wants string, this is why we use this cast + */ + visitedAt: literal('CLOCK_TIMESTAMP()') as unknown as string, + }); + } else { + [_, updatedVisits] = await this.model.update({ + /** + * we should pass to model datatype respectfully to declared in NoteVisitsModel class + * if we will pass just 'CLOCK_TIMESTAMP()' it will be treated by orm just like a string, that is why we should use literal + * but model wants string, this is why we use this cast + */ + visitedAt: literal('CLOCK_TIMESTAMP()') as unknown as string, + }, { + where: { + noteId, + userId, + }, + returning: true, + }); + } + + return updatedVisits[0]; } /**