2020-01-15 23:49:09 +01:00
|
|
|
package persistence
|
|
|
|
|
|
|
|
import (
|
2020-01-28 14:22:17 +01:00
|
|
|
"context"
|
2020-01-15 23:49:09 +01:00
|
|
|
|
2023-01-18 03:04:18 +01:00
|
|
|
"github.com/google/uuid"
|
|
|
|
|
2020-01-28 14:22:17 +01:00
|
|
|
. "github.com/Masterminds/squirrel"
|
2022-07-30 18:43:48 +02:00
|
|
|
"github.com/beego/beego/v2/client/orm"
|
2021-07-19 03:55:11 +02:00
|
|
|
"github.com/deluan/rest"
|
|
|
|
"github.com/navidrome/navidrome/log"
|
2020-01-24 01:44:08 +01:00
|
|
|
"github.com/navidrome/navidrome/model"
|
2020-01-15 23:49:09 +01:00
|
|
|
)
|
|
|
|
|
2020-01-19 21:37:41 +01:00
|
|
|
type genreRepository struct {
|
2020-01-28 14:22:17 +01:00
|
|
|
sqlRepository
|
2021-07-16 01:53:40 +02:00
|
|
|
sqlRestful
|
2020-01-19 21:37:41 +01:00
|
|
|
}
|
2020-01-15 23:49:09 +01:00
|
|
|
|
2022-07-30 18:43:48 +02:00
|
|
|
func NewGenreRepository(ctx context.Context, o orm.QueryExecutor) model.GenreRepository {
|
2020-01-28 14:22:17 +01:00
|
|
|
r := &genreRepository{}
|
|
|
|
r.ctx = ctx
|
|
|
|
r.ormer = o
|
2021-07-16 01:53:40 +02:00
|
|
|
r.tableName = "genre"
|
2021-07-17 01:41:49 +02:00
|
|
|
r.filterMappings = map[string]filterFunc{
|
|
|
|
"name": containsFilter,
|
|
|
|
}
|
2020-01-28 14:22:17 +01:00
|
|
|
return r
|
2020-01-15 23:49:09 +01:00
|
|
|
}
|
|
|
|
|
2021-07-19 21:30:22 +02:00
|
|
|
func (r *genreRepository) GetAll(opt ...model.QueryOptions) (model.Genres, error) {
|
|
|
|
sq := r.newSelect(opt...).Columns("genre.id", "genre.name", "a.album_count", "m.song_count").
|
|
|
|
LeftJoin("(select ag.genre_id, count(ag.album_id) as album_count from album_genres ag group by ag.genre_id) a on a.genre_id = genre.id").
|
|
|
|
LeftJoin("(select mg.genre_id, count(mg.media_file_id) as song_count from media_file_genres mg group by mg.genre_id) m on m.genre_id = genre.id")
|
2020-01-31 22:47:13 +01:00
|
|
|
res := model.Genres{}
|
2020-02-01 20:48:22 +01:00
|
|
|
err := r.queryAll(sq, &res)
|
2020-01-28 14:22:17 +01:00
|
|
|
return res, err
|
2020-01-15 23:49:09 +01:00
|
|
|
}
|
2021-07-16 01:53:40 +02:00
|
|
|
|
2023-01-18 03:04:18 +01:00
|
|
|
// Put is an Upsert operation, based on the name of the genre: If the name already exists, returns its ID, or else
|
|
|
|
// insert the new genre in the DB and returns its new created ID.
|
2021-07-16 01:53:40 +02:00
|
|
|
func (r *genreRepository) Put(m *model.Genre) error {
|
2023-01-18 03:04:18 +01:00
|
|
|
if m.ID == "" {
|
|
|
|
m.ID = uuid.NewString()
|
|
|
|
}
|
|
|
|
sql := Insert("genre").Columns("id", "name").Values(m.ID, m.Name).
|
|
|
|
Suffix("on conflict (name) do update set name=excluded.name returning id")
|
|
|
|
resp := model.Genre{}
|
|
|
|
err := r.queryOne(sql, &resp)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
m.ID = resp.ID
|
|
|
|
return nil
|
2021-07-16 01:53:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *genreRepository) Count(options ...rest.QueryOptions) (int64, error) {
|
|
|
|
return r.count(Select(), r.parseRestOptions(options...))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *genreRepository) Read(id string) (interface{}, error) {
|
|
|
|
sel := r.newSelect().Columns("*").Where(Eq{"id": id})
|
|
|
|
var res model.Genre
|
|
|
|
err := r.queryOne(sel, &res)
|
|
|
|
return &res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *genreRepository) ReadAll(options ...rest.QueryOptions) (interface{}, error) {
|
|
|
|
sel := r.newSelect(r.parseRestOptions(options...)).Columns("*")
|
|
|
|
res := model.Genres{}
|
|
|
|
err := r.queryAll(sel, &res)
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *genreRepository) EntityName() string {
|
|
|
|
return r.tableName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *genreRepository) NewInstance() interface{} {
|
|
|
|
return &model.Genre{}
|
|
|
|
}
|
|
|
|
|
2021-07-17 00:32:22 +02:00
|
|
|
func (r *genreRepository) purgeEmpty() error {
|
|
|
|
del := Delete(r.tableName).Where(`id in (
|
|
|
|
select genre.id from genre
|
|
|
|
left join album_genres ag on genre.id = ag.genre_id
|
|
|
|
left join artist_genres a on genre.id = a.genre_id
|
|
|
|
left join media_file_genres mfg on genre.id = mfg.genre_id
|
|
|
|
where ag.genre_id is null
|
|
|
|
and a.genre_id is null
|
|
|
|
and mfg.genre_id is null
|
|
|
|
)`)
|
|
|
|
c, err := r.executeSQL(del)
|
|
|
|
if err == nil {
|
|
|
|
if c > 0 {
|
|
|
|
log.Debug(r.ctx, "Purged unused genres", "totalDeleted", c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-07-16 01:53:40 +02:00
|
|
|
var _ model.GenreRepository = (*genreRepository)(nil)
|
|
|
|
var _ model.ResourceRepository = (*genreRepository)(nil)
|