navidrome/persistence/playlist_repository.go

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

164 lines
4.2 KiB
Go
Raw Normal View History

package persistence
2020-01-13 03:59:06 +01:00
import (
"context"
"time"
2020-01-13 03:59:06 +01:00
. "github.com/Masterminds/squirrel"
2020-01-13 03:59:06 +01:00
"github.com/astaxie/beego/orm"
"github.com/deluan/navidrome/log"
2020-01-24 01:44:08 +01:00
"github.com/deluan/navidrome/model"
2020-05-04 02:05:03 +02:00
"github.com/deluan/rest"
2020-01-13 03:59:06 +01:00
)
type playlistRepository struct {
sqlRepository
2020-05-04 02:05:03 +02:00
sqlRestful
2020-01-13 03:59:06 +01:00
}
func NewPlaylistRepository(ctx context.Context, o orm.Ormer) model.PlaylistRepository {
2020-01-13 03:59:06 +01:00
r := &playlistRepository{}
r.ctx = ctx
r.ormer = o
2020-01-13 06:04:11 +01:00
r.tableName = "playlist"
2020-01-13 03:59:06 +01:00
return r
}
2020-05-04 02:05:03 +02:00
func (r *playlistRepository) CountAll(options ...model.QueryOptions) (int64, error) {
return r.count(Select(), options...)
}
func (r *playlistRepository) Exists(id string) (bool, error) {
return r.exists(Select().Where(Eq{"id": id}))
}
func (r *playlistRepository) Delete(id string) error {
del := Delete("playlist_tracks").Where(Eq{"playlist_id": id})
_, err := r.executeSQL(del)
if err != nil {
return err
}
return r.delete(Eq{"id": id})
}
2020-01-15 04:22:34 +01:00
func (r *playlistRepository) Put(p *model.Playlist) error {
if p.ID == "" {
p.CreatedAt = time.Now()
}
p.UpdatedAt = time.Now()
// Save tracks for later and set it to nil, to avoid trying to save it to the DB
tracks := p.Tracks
p.Tracks = nil
id, err := r.put(p.ID, p)
if err != nil {
return err
}
err = r.updateTracks(id, tracks)
return err
2020-01-13 03:59:06 +01:00
}
2020-01-15 04:22:34 +01:00
func (r *playlistRepository) Get(id string) (*model.Playlist, error) {
sel := r.newSelect().Columns("*").Where(Eq{"id": id})
var pls model.Playlist
err := r.queryOne(sel, &pls)
if err != nil {
return nil, err
}
err = r.loadTracks(&pls)
return &pls, err
}
2020-01-15 04:22:34 +01:00
func (r *playlistRepository) GetAll(options ...model.QueryOptions) (model.Playlists, error) {
sel := r.newSelect(options...).Columns("*")
var res model.Playlists
err := r.queryAll(sel, &res)
return res, err
2020-01-13 03:59:06 +01:00
}
func (r *playlistRepository) Tracks(playlistId string) model.PlaylistTracksRepository {
p := &playlistTracksRepository{}
p.playlistId = playlistId
p.ctx = r.ctx
p.ormer = r.ormer
p.tableName = "playlist_tracks"
return p
}
func (r *playlistRepository) updateTracks(id string, tracks model.MediaFiles) error {
// Remove old tracks
del := Delete("playlist_tracks").Where(Eq{"playlist_id": id})
_, err := r.executeSQL(del)
if err != nil {
return err
}
// Add new tracks
for i, t := range tracks {
ins := Insert("playlist_tracks").Columns("playlist_id", "media_file_id", "id").
Values(id, t.ID, i)
_, err = r.executeSQL(ins)
if err != nil {
return err
}
}
// Get total playlist duration and count
statsSql := Select("sum(duration) as duration", "count(*) as count").From("media_file").
Join("playlist_tracks f on f.media_file_id = media_file.id").
Where(Eq{"playlist_id": id})
var res struct{ Duration, Count float32 }
err = r.queryOne(statsSql, &res)
if err != nil {
return err
}
// Update total playlist duration and count
upd := Update(r.tableName).
Set("duration", res.Duration).
Set("song_count", res.Count).
Where(Eq{"id": id})
_, err = r.executeSQL(upd)
return err
}
func (r *playlistRepository) loadTracks(pls *model.Playlist) (err error) {
tracksQuery := Select().From("playlist_tracks").
LeftJoin("annotation on ("+
"annotation.item_id = media_file_id"+
" AND annotation.item_type = 'media_file'"+
" AND annotation.user_id = '"+userId(r.ctx)+"')").
Columns("starred", "starred_at", "play_count", "play_date", "rating", "f.*").
Join("media_file f on f.id = media_file_id").
Where(Eq{"playlist_id": pls.ID}).OrderBy("playlist_tracks.id")
err = r.queryAll(tracksQuery, &pls.Tracks)
if err != nil {
log.Error("Error loading playlist tracks", "playlist", pls.Name, "id", pls.ID)
}
return
}
2020-05-04 02:05:03 +02:00
func (r *playlistRepository) Count(options ...rest.QueryOptions) (int64, error) {
return r.CountAll(r.parseRestOptions(options...))
}
func (r *playlistRepository) Read(id string) (interface{}, error) {
return r.Get(id)
}
func (r *playlistRepository) ReadAll(options ...rest.QueryOptions) (interface{}, error) {
return r.GetAll(r.parseRestOptions(options...))
}
func (r *playlistRepository) EntityName() string {
return "playlist"
}
func (r *playlistRepository) NewInstance() interface{} {
return &model.Playlist{}
}
2020-01-15 04:22:34 +01:00
var _ model.PlaylistRepository = (*playlistRepository)(nil)
2020-05-04 02:05:03 +02:00
var _ model.ResourceRepository = (*playlistRepository)(nil)