159 lines
4.4 KiB
Go
159 lines
4.4 KiB
Go
package models
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/lib/pq"
|
|
polochon "github.com/odwrtw/polochon/lib"
|
|
)
|
|
|
|
const (
|
|
upsertMovieQuery = `
|
|
INSERT INTO movies (imdb_id, title, rating, votes, plot, tmdb_id, year,
|
|
genres, original_title, runtime, sort_title, tagline)
|
|
VALUES (:imdb_id, :title, :rating, :votes, :plot, :tmdb_id, :year, :genres,
|
|
:original_title, :runtime, :sort_title, :tagline)
|
|
ON CONFLICT (imdb_id)
|
|
DO UPDATE
|
|
SET imdb_id=:imdb_id, title=:title, rating=:rating, votes=:votes,
|
|
plot=:plot, tmdb_id=:tmdb_id, year=:year, genres=:genres,
|
|
original_title=:original_title, runtime=:runtime, sort_title=:sort_title,
|
|
tagline=:tagline
|
|
RETURNING id;`
|
|
|
|
getMovieQueryByImdbID = `
|
|
SELECT *
|
|
FROM movies_with_rating
|
|
WHERE imdb_id=$1;`
|
|
)
|
|
|
|
// movieDB represents the Movie in the DB
|
|
type movieDB struct {
|
|
ID string `db:"id"`
|
|
ImdbID string `db:"imdb_id"`
|
|
TmdbID int `db:"tmdb_id"`
|
|
Title string `db:"title"`
|
|
OriginalTitle string `db:"original_title"`
|
|
SortTitle string `db:"sort_title"`
|
|
Rating float32 `db:"rating"`
|
|
Votes int `db:"votes"`
|
|
Plot string `db:"plot"`
|
|
Year int `db:"year"`
|
|
Runtime int `db:"runtime"`
|
|
Tagline string `db:"tagline"`
|
|
Genres pq.StringArray `db:"genres"`
|
|
Created time.Time `db:"created_at"`
|
|
Updated time.Time `db:"updated_at"`
|
|
}
|
|
|
|
func getMovieDB(db *sqlx.DB, movie *polochon.Movie) (*movieDB, error) {
|
|
var mDB movieDB
|
|
err := db.QueryRowx(getMovieQueryByImdbID, movie.ImdbID).StructScan(&mDB)
|
|
if err != nil {
|
|
return &mDB, err
|
|
}
|
|
return &mDB, nil
|
|
}
|
|
|
|
// GetMovie fills show details of a polochon.Movie
|
|
func GetMovie(db *sqlx.DB, pMovie *polochon.Movie) error {
|
|
if pMovie.ImdbID == "" {
|
|
return fmt.Errorf("Can't get movie details, you have to specify an ImdbID")
|
|
}
|
|
|
|
// Get the movie from the DB
|
|
movie, err := getMovieDB(db, pMovie)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Fills the polochon.Movie from the movieDB
|
|
FillMovieFromDB(movie, pMovie)
|
|
return nil
|
|
}
|
|
|
|
// FillMovieFromDB fills a Movie from a movieDB extracted from the DB
|
|
func FillMovieFromDB(mDB *movieDB, pMovie *polochon.Movie) {
|
|
pMovie.ImdbID = mDB.ImdbID
|
|
pMovie.Title = mDB.Title
|
|
pMovie.Rating = mDB.Rating
|
|
pMovie.Votes = mDB.Votes
|
|
pMovie.Plot = mDB.Plot
|
|
pMovie.TmdbID = mDB.TmdbID
|
|
pMovie.Year = mDB.Year
|
|
pMovie.OriginalTitle = mDB.OriginalTitle
|
|
pMovie.Runtime = mDB.Runtime
|
|
pMovie.Genres = mDB.Genres
|
|
pMovie.SortTitle = mDB.SortTitle
|
|
pMovie.Tagline = mDB.Tagline
|
|
pMovie.Thumb = imageURL("movies/" + mDB.ImdbID + ".jpg")
|
|
pMovie.Fanart = imageURL("movies/" + mDB.ImdbID + "-fanart.jpg")
|
|
}
|
|
|
|
// updateFromMovie will update the movieDB from a Movie
|
|
// We just make sure to never update the movieDB with empty value
|
|
func (m *movieDB) updateFromMovie(movie *polochon.Movie) {
|
|
updateIfNonEmpty(&m.ImdbID, movie.ImdbID)
|
|
updateIfNonEmpty(&m.Title, movie.Title)
|
|
updateIfNonEmpty(&m.OriginalTitle, movie.OriginalTitle)
|
|
updateIfNonEmpty(&m.SortTitle, movie.SortTitle)
|
|
updateIfNonEmpty(&m.Plot, movie.Plot)
|
|
updateIfNonEmpty(&m.Tagline, movie.Tagline)
|
|
updateIfNonZeroInt(&m.TmdbID, movie.TmdbID)
|
|
updateIfNonZeroInt(&m.Votes, movie.Votes)
|
|
updateIfNonZeroInt(&m.Year, movie.Year)
|
|
updateIfNonZeroInt(&m.Runtime, movie.Runtime)
|
|
updateIfNonZeroFloat(&m.Rating, movie.Rating)
|
|
if movie.Genres != nil {
|
|
m.Genres = movie.Genres
|
|
}
|
|
}
|
|
|
|
// UpsertMovie upsert a polochon Movie in the database
|
|
func UpsertMovie(db *sqlx.DB, pMovie *polochon.Movie) error {
|
|
// Try to get the movie
|
|
movieDB, err := getMovieDB(db, pMovie)
|
|
// Return only if the error is != sql.ErrNoRows
|
|
if err != nil {
|
|
if err != sql.ErrNoRows {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Update the movieDB from the movie we have
|
|
movieDB.updateFromMovie(pMovie)
|
|
r, err := db.NamedQuery(upsertMovieQuery, movieDB)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer r.Close()
|
|
|
|
return nil
|
|
}
|
|
|
|
// newMovieDB returns a Movie ready to be put in DB from a
|
|
// polochon Movie
|
|
func newMovieDB(m *polochon.Movie) movieDB {
|
|
genres := []string{}
|
|
if m.Genres != nil {
|
|
genres = m.Genres
|
|
}
|
|
return movieDB{
|
|
ImdbID: m.ImdbID,
|
|
Title: m.Title,
|
|
Rating: m.Rating,
|
|
Votes: m.Votes,
|
|
Plot: m.Plot,
|
|
TmdbID: m.TmdbID,
|
|
Year: m.Year,
|
|
OriginalTitle: m.OriginalTitle,
|
|
Runtime: m.Runtime,
|
|
SortTitle: m.SortTitle,
|
|
Tagline: m.Tagline,
|
|
Genres: genres,
|
|
}
|
|
}
|