fix: reduce watchlist update complexity
This commit is contained in:
@@ -22,38 +22,38 @@ func NewWatchlistService(repo domain.WatchlistRepository, jikan *jikan.Client, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, animeID int64, status string) error {
|
func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, animeID int64, status string) error {
|
||||||
var anime jikan.Anime
|
anime, fetchedAnime := s.fetchAnimeForWatchlist(ctx, animeID)
|
||||||
var fetchErr error
|
|
||||||
if s.jikan != nil {
|
|
||||||
anime, fetchErr = s.jikan.GetAnimeByID(ctx, int(animeID))
|
|
||||||
}
|
|
||||||
if fetchErr != nil {
|
|
||||||
// still allow status updates for already-known anime rows
|
|
||||||
anime = jikan.Anime{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.repo.InTx(ctx, func(txCtx context.Context, repo domain.WatchlistRepository) error {
|
if err := s.repo.InTx(ctx, func(txCtx context.Context, repo domain.WatchlistRepository) error {
|
||||||
_, err := repo.GetAnime(txCtx, animeID)
|
return s.updateEntryInTx(txCtx, repo, userID, animeID, status, anime, fetchedAnime)
|
||||||
if err != nil && fetchErr == nil && anime.MalID > 0 {
|
|
||||||
durationSeconds := anime.DurationSeconds()
|
|
||||||
duration := sql.NullFloat64{Valid: durationSeconds > 0}
|
|
||||||
if duration.Valid {
|
|
||||||
duration.Float64 = durationSeconds
|
|
||||||
}
|
|
||||||
if _, err := repo.UpsertAnime(txCtx, db.UpsertAnimeParams{
|
|
||||||
ID: int64(anime.MalID),
|
|
||||||
TitleOriginal: anime.Title,
|
|
||||||
TitleEnglish: sql.NullString{String: anime.TitleEnglish, Valid: anime.TitleEnglish != ""},
|
|
||||||
TitleJapanese: sql.NullString{String: anime.TitleJapanese, Valid: anime.TitleJapanese != ""},
|
|
||||||
ImageUrl: anime.Images.Webp.LargeImageURL,
|
|
||||||
Airing: sql.NullBool{Bool: anime.Airing, Valid: true},
|
|
||||||
DurationSeconds: duration,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
s.invalidateTopPicks(userID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *watchlistService) fetchAnimeForWatchlist(ctx context.Context, animeID int64) (jikan.Anime, bool) {
|
||||||
|
if s.jikan == nil {
|
||||||
|
return jikan.Anime{}, false
|
||||||
|
}
|
||||||
|
anime, err := s.jikan.GetAnimeByID(ctx, int(animeID))
|
||||||
|
if err != nil {
|
||||||
|
// still allow status updates for already-known anime rows
|
||||||
|
return jikan.Anime{}, false
|
||||||
|
}
|
||||||
|
return anime, anime.MalID > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *watchlistService) updateEntryInTx(ctx context.Context, repo domain.WatchlistRepository, userID string, animeID int64, status string, anime jikan.Anime, fetchedAnime bool) error {
|
||||||
|
_, err := repo.GetAnime(ctx, animeID)
|
||||||
|
if err != nil && fetchedAnime {
|
||||||
|
if _, err := repo.UpsertAnime(ctx, watchlistAnimeParams(anime)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
existing, err := repo.GetWatchListEntry(txCtx, db.GetWatchListEntryParams{
|
existing, err := repo.GetWatchListEntry(ctx, db.GetWatchListEntryParams{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
AnimeID: animeID,
|
AnimeID: animeID,
|
||||||
})
|
})
|
||||||
@@ -61,7 +61,7 @@ func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, anime
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = repo.UpsertWatchListEntry(txCtx, db.UpsertWatchListEntryParams{
|
_, err = repo.UpsertWatchListEntry(ctx, db.UpsertWatchListEntryParams{
|
||||||
ID: uuid.New().String(),
|
ID: uuid.New().String(),
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
AnimeID: animeID,
|
AnimeID: animeID,
|
||||||
@@ -70,11 +70,23 @@ func (s *watchlistService) UpdateEntry(ctx context.Context, userID string, anime
|
|||||||
CurrentTimeSeconds: existing.CurrentTimeSeconds,
|
CurrentTimeSeconds: existing.CurrentTimeSeconds,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
s.invalidateTopPicks(userID)
|
|
||||||
return nil
|
func watchlistAnimeParams(anime jikan.Anime) db.UpsertAnimeParams {
|
||||||
|
durationSeconds := anime.DurationSeconds()
|
||||||
|
duration := sql.NullFloat64{Valid: durationSeconds > 0}
|
||||||
|
if duration.Valid {
|
||||||
|
duration.Float64 = durationSeconds
|
||||||
|
}
|
||||||
|
return db.UpsertAnimeParams{
|
||||||
|
ID: int64(anime.MalID),
|
||||||
|
TitleOriginal: anime.Title,
|
||||||
|
TitleEnglish: sql.NullString{String: anime.TitleEnglish, Valid: anime.TitleEnglish != ""},
|
||||||
|
TitleJapanese: sql.NullString{String: anime.TitleJapanese, Valid: anime.TitleJapanese != ""},
|
||||||
|
ImageUrl: anime.Images.Webp.LargeImageURL,
|
||||||
|
Airing: sql.NullBool{Bool: anime.Airing, Valid: true},
|
||||||
|
DurationSeconds: duration,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *watchlistService) RemoveEntry(ctx context.Context, userID string, animeID int64) error {
|
func (s *watchlistService) RemoveEntry(ctx context.Context, userID string, animeID int64) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user