package shows import ( "fmt" "gitlab.quimbo.fr/odwrtw/canape-sql/sqly" "gitlab.quimbo.fr/odwrtw/canape-sql/users" "github.com/jmoiron/sqlx" "github.com/odwrtw/polochon/lib" ) const ( addShowQuery = `INSERT INTO shows (imdbid, title) VALUES (:imdbid, :title) RETURNING id;` getShowQuery = `SELECT * FROM shows WHERE imdbid=$1;` deleteShowQuery = `DELETE FROM shows WHERE id=$1;` addEpisodeQuery = `INSERT INTO episodes (shows_id, title, season, episode) VALUES ($1,$2,$3,$4);` getEpisodesQuery = `SELECT title, season, episode FROM episodes WHERE shows_id=$1;` getShowWithUserQuery = ` SELECT shows.id, shows.title, shows.imdbid, COALESCE(shows_tracked.season,0) AS trackedseason, COALESCE(shows_tracked.episode,0) AS trackedepisode FROM shows LEFT JOIN shows_tracked ON shows.id=shows_tracked.shows_id AND shows_tracked.users_id=$2 WHERE shows.imdbid=$1;` ) var ( NotFound = fmt.Errorf("Not found") ) type Show struct { sqly.BaseTable polochon.Show Episodes []*Episode TrackedSeason int TrackedEpisode int } func Get(db *sqlx.DB, imdbID string) (*Show, error) { s := &Show{} err := db.QueryRowx(getShowQuery, imdbID).StructScan(s) if err != nil { if err.Error() == "sql: no rows in result set" { return nil, NotFound } return nil, err } return s, nil } // GetAsUser returns a show with user info like tracked func GetAsUser(db *sqlx.DB, user *users.User, imdbID string) (*Show, error) { s := &Show{} err := db.QueryRowx(getShowWithUserQuery, imdbID, user.ID).StructScan(s) if err != nil { return nil, err } return s, nil } // GetDetails retrieves details for the show, first try to // get info from db, if not exists, use polochon.Detailer // and save informations in the database for future use func (s *Show) GetDetails(db *sqlx.DB) error { return nil } // GetDetailsAsUser like GetDetails but with User context func (s *Show) GetDetailsAsUser(db *sqlx.DB, user *users.User) error { return nil } // IsTracked returns true if the show is tracked use this function // after retrieve the show with GetAsUser or other *AsUser functions func (s *Show) IsTracked() bool { if s.TrackedSeason != 0 && s.TrackedEpisode != 0 { return true } return false } func (s *Show) Add(db *sqlx.DB) error { var id string r, err := db.NamedQuery(addShowQuery, s) if err != nil { return err } for r.Next() { r.Scan(&id) } s.ID = id // When add a show to database use polochon episode details // so s.Show.Episodes for _, pEp := range s.Show.Episodes { err = s.addEpisode(db, pEp) if err != nil { return err } } return nil } func (s *Show) addEpisode(db *sqlx.DB, pEpisode *polochon.ShowEpisode) error { _, err := db.Exec(addEpisodeQuery, s.ID, pEpisode.Title, pEpisode.Season, pEpisode.Episode) if err != nil { return err } return nil } func (s *Show) Delete(db *sqlx.DB) error { r, err := db.Exec(deleteShowQuery, s.ID) if err != nil { return err } count, _ := r.RowsAffected() if count != 1 { return fmt.Errorf("Unexpected number of row deleted: %d", count) } return nil } func (s *Show) GetEpisodes(db *sqlx.DB) error { // When retrive episode's info from database populate the s.Episodes member // and not s.Show.Episodes err := db.Select(&s.Episodes, getEpisodesQuery, s.ID) if err != nil { return err } return nil } type Episode struct { sqly.BaseTable polochon.ShowEpisode }