package models import ( "fmt" "github.com/jmoiron/sqlx" ) const ( upsertShowWishlistQuery = ` INSERT INTO shows_tracked (imdb_id, user_id, season, episode) VALUES ($1, $2, $3, $4) ON CONFLICT (imdb_id, user_id) DO UPDATE SET imdb_id=$1, user_id=$2, season=$3, episode=$4;` isShowWishlistedQueryByUserID = ` SELECT s.imdb_id, t.season, t.episode FROM shows s INNER JOIN shows_tracked t ON s.imdb_id = t.imdb_id AND t.user_id=$2 WHERE t.imdb_id=$1;` getShowWishlistQueryByUserID = ` SELECT s.imdb_id, t.season, t.episode FROM shows s INNER JOIN shows_tracked t ON s.imdb_id = t.imdb_id AND t.user_id=$1;` deleteShowWishlistedQueryByID = `DELETE FROM shows_tracked WHERE imdb_id=$1 AND user_id=$2;` deleteUserShowsWishlist = `DELETE FROM shows_tracked WHERE user_id=$1;` getAllWishlistedShows = `SELECT DISTINCT(imdb_id) FROM shows_tracked;` ) // showWishlist represents the show wishlist of a user type showWishlist struct { shows map[string]*WishedShow } // WishedShow represents a wished show of a user type WishedShow struct { ImdbID string `db:"imdb_id"` Season int Episode int } // NewShowWishlist returns a new showWishlist func NewShowWishlist() *showWishlist { return &showWishlist{ shows: map[string]*WishedShow{}, } } // add adds a show to the showWishlist object func (w *showWishlist) add(imdbID string, season, episode int) { w.shows[imdbID] = &WishedShow{ ImdbID: imdbID, Season: season, Episode: episode, } } // List return a slice of WishedShow func (w *showWishlist) List() []*WishedShow { shows := make([]*WishedShow, len(w.shows)) i := 0 for _, s := range w.shows { shows[i] = &WishedShow{ ImdbID: s.ImdbID, Season: s.Season, Episode: s.Episode, } i++ } return shows } // GetShowWishlist returns a showWishlist for a user func GetShowWishlist(db *sqlx.DB, userID string) (*showWishlist, error) { var wishedShows = []*WishedShow{} // Get the wishlisted shows err := db.Select(&wishedShows, getShowWishlistQueryByUserID, userID) if err != nil { return nil, err } // Create the new object wishlist := NewShowWishlist() for _, wishedShow := range wishedShows { // Add the show to the wishlist wishlist.add(wishedShow.ImdbID, wishedShow.Season, wishedShow.Episode) } return wishlist, nil } // IsShowInWishlist returns true and the WishedShow if the show is in the // wishlist func (w *showWishlist) IsShowInWishlist(imdbID string) (*WishedShow, bool) { show, ok := w.shows[imdbID] return show, ok } // IsShowWishlisted returns true and the WishedShow if the show is wishlisted func IsShowWishlisted(db *sqlx.DB, userID, imdbID string) (*WishedShow, error) { var wishedShows = []*WishedShow{} err := db.Select(&wishedShows, isShowWishlistedQueryByUserID, imdbID, userID) if err != nil { return nil, err } if len(wishedShows) != 1 { return nil, nil } return wishedShows[0], nil } // AddShowToWishlist Adds a show to a user's wishlist func AddShowToWishlist(db *sqlx.DB, userID, imdbID string, season, episode int) error { _, err := db.Exec(upsertShowWishlistQuery, imdbID, userID, season, episode) if err != nil { return err } return nil } // DeleteShowFromWishlist deletes a show from a user's wishlist func DeleteShowFromWishlist(db *sqlx.DB, userID, imdbID string) error { r, err := db.Exec(deleteShowWishlistedQueryByID, imdbID, userID) if err != nil { return err } count, err := r.RowsAffected() if err != nil { return err } if count != 1 { return fmt.Errorf("unexpected number of row deleted: %d", count) } return nil } // GetAllWishlistedShows returns the list of all wishlisted shows func GetAllWishlistedShows(db *sqlx.DB) ([]string, error) { var shows = []string{} // Get the list of movies err := db.Select(&shows, getAllWishlistedShows) if err != nil { return nil, err } return shows, nil } // DeleteUserShowsWishlist deletes all the wishlisted shows of a user func DeleteUserShowsWishlist(db *sqlx.DB, userID string) error { _, err := db.Exec(deleteUserShowsWishlist, userID) return err }