add transaction for creating tvshow and episodes

This commit is contained in:
2024-11-06 19:29:14 +01:00
parent a4591aa177
commit e541681dd1
8 changed files with 92 additions and 173 deletions
+11 -18
View File
@@ -20,27 +20,15 @@ func (hq *Handlers) GetTVShow(c *gin.Context) {
tvShow, err := hq.Queries.CheckTVShowExists(c, ttShowID)
if err != nil {
title, scraperEpisodes = scraper.ScrapeEpisodes(ttShowID)
// TODO: make transactional
ttShow, err := hq.Queries.CreateTVShow(c, sqlc.CreateTVShowParams{
sqlcEpisodes, err = hq.Queries.CreateTvShowWithEpisodes(c, sqlc.CreateTVShowParams{
TtImdb: ttShowID,
Name: title,
})
}, scraperEpisodes)
if err != nil {
slog.Error("failed to create tv show", "ttid", ttShowID, "error", err)
slog.Error("failed to create tv show with episodes", "ttid", ttShowID, "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": ErrorCreating})
}
slog.Info("ttshowid", "id", ttShow.ID)
for _, episode := range scraperEpisodes {
sqlcEpisodesParams := episode.ToEpisodeParams(ttShow.ID)
sqlcEpisode, err := hq.Queries.CreateEpisodes(c, sqlcEpisodesParams)
if err != nil {
slog.Error("failed to create episodes", "ttid", ttShowID, "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": ErrorCreating})
return
}
sqlcEpisodes = append(sqlcEpisodes, sqlcEpisode)
return
}
slog.Info("scraped seasons", "ttid", ttShowID, "title", title)
@@ -53,7 +41,12 @@ func (hq *Handlers) GetTVShow(c *gin.Context) {
return
}
hq.Queries.IncreasePopularity(c, ttShowID)
if err := hq.Queries.IncreasePopularity(c, ttShowID); err != nil {
slog.Error("failed to increase popularity", "ttid", ttShowID, "error", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": ErrorUpdating})
return
}
slog.Info("tv show exists", "ttid", ttShowID, "title", tvShow.Name)
}
-68
View File
@@ -1,68 +0,0 @@
package models
// import (
// "strconv"
// "time"
// )
// type Popularity struct {
// ShowID string `json:"show_id"`
// TimesViewed int `json:"times_viewed"`
// }
// type TvShow struct {
// ShowID string `json:"show_id"`
// Title string `json:"title"`
// Runtime int `json:"runtime"`
// Votes int `json:"votes"`
// AvgRating float64 `json:"avg_rating"`
// MedianRating float64 `json:"median_rating"`
// Seasons []Season `json:"seasons"`
// }
// type Season struct {
// Number int `json:"number"`
// AvgRating float64 `json:"avg_rating"`
// MedianRating float64 `json:"median_rating"`
// Votes int `json:"votes"`
// Episodes []Episode `json:"episodes"`
// }
// type Episode struct {
// Number int `json:"number"`
// EpisodeID string `json:"episode_id"`
// Title string `json:"title"`
// Aired time.Time `json:"aired"`
// AvgRating float64 `json:"avg_rating"`
// Votes int `json:"votes"`
// }
// func (tvShow *TvShow) TvShowBuilder(tvShowDTO TvShowDTO) {
// tvShow.ShowID = tvShowDTO.ShowID
// tvShow.Title = tvShowDTO.Title
// tvShow.Runtime, _ = strconv.Atoi(tvShowDTO.Runtime)
// lastSeasonNumber := tvShowDTO.Episodes[len(tvShowDTO.Episodes)-1].SeasonID
// if lastSeasonNumber == -1 {
// lastSeasonNumber = tvShowDTO.Episodes[len(tvShowDTO.Episodes)-2].SeasonID
// }
// seasons := make([]Season, lastSeasonNumber)
// for currentSeason := 1; currentSeason <= lastSeasonNumber; currentSeason++ {
// for _, episode := range tvShowDTO.Episodes {
// if episode.SeasonID == currentSeason {
// seasons[currentSeason-1].Number = currentSeason
// seasons[currentSeason-1].Episodes = append(seasons[currentSeason-1].Episodes, Episode{
// Number: episode.Number,
// EpisodeID: episode.EpisodeID,
// Title: episode.Title,
// Aired: episode.Aired.Time,
// AvgRating: episode.AvgRating,
// Votes: episode.Votes,
// })
// }
// }
// }
// tvShow.Seasons = seasons
// }
-52
View File
@@ -1,52 +0,0 @@
package models
// type TvShowDTO struct {
// ShowID string `json:"tt_show_id"`
// Title string `json:"title"`
// Runtime string `json:"runtime"`
// Episodes []EpisodeDTO `json:"episodes"`
// }
// type EpisodeDTO struct {
// Number int `json:"number"`
// SeasonID int `json:"season_id"`
// EpisodeID string `json:"tt_episode_id"`
// Title string `json:"title"`
// Aired AiredTime `json:"aired"`
// AvgRating float64 `json:"avg_rating"`
// Votes int `json:"votes"`
// }
// type AiredTime struct {
// time.Time
// }
// func (tvShow *TvShow) UnmarshalJSON(data []byte) error {
// var tvShowDTO TvShowDTO
// err := json.Unmarshal(data, &tvShowDTO)
// if err != nil {
// return err
// }
// tvShow.TvShowBuilder(tvShowDTO)
// return nil
// }
// func (aired *AiredTime) UnmarshalJSON(data []byte) error {
// if string(data) == "null" || string(data) == "" {
// return nil
// }
// var s string
// if err := json.Unmarshal(data, &s); err != nil {
// return nil
// }
// t, err := utils.TimeParser(s)
// if err != nil {
// return err
// }
// aired.Time = t
// return nil
// }
+4
View File
@@ -1,9 +1,13 @@
package repository
import (
"context"
"github.com/zepyrshut/rating-orama/internal/scraper"
"github.com/zepyrshut/rating-orama/internal/sqlc"
)
type ExtendedQuerier interface {
sqlc.Querier
CreateTvShowWithEpisodes(ctx context.Context, tvShow sqlc.CreateTVShowParams, episodes []scraper.Episode) ([]sqlc.Episode, error)
}
+38
View File
@@ -0,0 +1,38 @@
package repository
import (
"context"
"github.com/jackc/pgx/v5"
"log/slog"
"github.com/zepyrshut/rating-orama/internal/scraper"
"github.com/zepyrshut/rating-orama/internal/sqlc"
)
func (r *pgxRepository) CreateTvShowWithEpisodes(ctx context.Context, tvShow sqlc.CreateTVShowParams, episodes []scraper.Episode) ([]sqlc.Episode, error) {
var sqlcEpisodes []sqlc.Episode
err := r.execTx(ctx, func(tx pgx.Tx) error {
qtx := r.WithTx(tx)
tvShow, err := qtx.CreateTVShow(ctx, tvShow)
if err != nil {
return err
}
slog.Info("episodes lenght", "episodes", len(episodes))
for _, episode := range episodes {
sqlcEpisodeParams := episode.ToEpisodeParams(tvShow.ID)
slog.Info("creating episode", "episode", sqlcEpisodeParams)
episode, err := qtx.CreateEpisodes(ctx, sqlcEpisodeParams)
if err != nil {
return err
}
sqlcEpisodes = append(sqlcEpisodes, episode)
}
return nil
})
return sqlcEpisodes, err
}
+6
View File
@@ -107,10 +107,14 @@ func ScrapeEpisodes(ttImdb string) (string, []Episode) {
c.Visit(fmt.Sprintf(visitURL, ttImdb))
c.Wait()
slog.Info("scraped all seasons", "seasons", allSeasons)
return title, allSeasons
}
func extractEpisodesFromSeason(data string) []Episode {
slog.Info("extracting episodes", "data", data)
const pattern = `(S\d+\.E\d+)\s∙\s(.*?)` +
`(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s` +
`(.*?),\s(\d{4})(.*?)` +
@@ -121,6 +125,8 @@ func extractEpisodesFromSeason(data string) []Episode {
episodes := make([]Episode, 0, len(matches))
slog.Info("matches", "num", len(matches))
for _, match := range matches {
var episode Episode