Skip to content

Commit

Permalink
separeted saving note visit to two sql queries
Browse files Browse the repository at this point in the history
  • Loading branch information
e11sy committed Apr 5, 2024
1 parent 83710c1 commit b153fae
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
3 changes: 1 addition & 2 deletions src/domain/entities/noteVisit.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
}
46 changes: 36 additions & 10 deletions src/repository/storage/postgres/orm/sequelize/noteVisits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}

/**
Expand Down

0 comments on commit b153fae

Please sign in to comment.