package models import ( "fmt" "github.com/jmoiron/sqlx" ) const ( upsertMovieWishlistQuery = ` INSERT INTO movies_tracked (imdb_id, user_id) VALUES ($1, $2) ON CONFLICT (imdb_id, user_id) DO UPDATE SET imdb_id=$1, user_id=$2;` isMovieWishlistedQueryByUserID = ` SELECT COUNT(*) FROM movies INNER JOIN movies_tracked ON movies.imdb_id=movies_tracked.imdb_id AND movies_tracked.user_id=$2 WHERE movies.imdb_id=$1;` getMovieWishlistQueryByUserID = ` SELECT movies.imdb_id FROM movies INNER JOIN movies_tracked ON movies.imdb_id=movies_tracked.imdb_id AND movies_tracked.user_id=$1;` deleteMovieWishlistedQueryByID = `DELETE FROM movies_tracked WHERE imdb_id=$1 AND user_id=$2;` getAllWishlistedMovies = `SELECT DISTINCT(imdb_id) FROM movies_tracked;` ) // movieWishlist represents the list of movies wishlisted by a user type movieWishlist struct { movies map[string]struct{} } // NewMovieWishlist returns a new movieWishlist func NewMovieWishlist() *movieWishlist { return &movieWishlist{ movies: map[string]struct{}{}, } } // add adds movie to the movieWishlist func (w *movieWishlist) add(imdbID string) { w.movies[imdbID] = struct{}{} } // List return a slice of imdbID wishlisted func (w *movieWishlist) List() []string { movies := make([]string, len(w.movies)) i := 0 for imdbID := range w.movies { movies[i] = imdbID i++ } return movies } // GetMovieWishlist returns a movieWishlist obejct for a user func GetMovieWishlist(db *sqlx.DB, userID string) (*movieWishlist, error) { var movies = []string{} // Get the list of movies err := db.Select(&movies, getMovieWishlistQueryByUserID, userID) if err != nil { return nil, err } // Create a new movieWishlist wishlist := NewMovieWishlist() for _, imdbID := range movies { // add the movie to the wishlist object wishlist.add(imdbID) } return wishlist, nil } // IsMovieInWishlist returns true if the movie is in the wishlist func (w *movieWishlist) IsMovieInWishlist(imdbID string) bool { _, ok := w.movies[imdbID] return ok } // IsMovieWishlisted returns true if the movie is wishlisted func IsMovieWishlisted(db *sqlx.DB, userID, imdbID string) (bool, error) { var count int // Check if the movie is wishlisted by the user err := db.Get(&count, isMovieWishlistedQueryByUserID, imdbID, userID) if err != nil { return false, err } if count > 0 { return true, nil } return false, nil } // AddMovieToWishlist Adds a movie to a user's wishlist in DB func AddMovieToWishlist(db *sqlx.DB, userID, imdbID string) error { _, err := db.Exec(upsertMovieWishlistQuery, imdbID, userID) if err != nil { return err } return nil } // DeleteMovieFromWishlist deletes a movie from a user's wishlist in DB func DeleteMovieFromWishlist(db *sqlx.DB, userID, imdbID string) error { r, err := db.Exec(deleteMovieWishlistedQueryByID, 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 } // GetAllWishlistedMovies returns the list of all wishlisted movies func GetAllWishlistedMovies(db *sqlx.DB) ([]string, error) { var movies = []string{} // Get the list of movies err := db.Select(&movies, getAllWishlistedMovies) if err != nil { return nil, err } return movies, nil }