Skip to content

Commit

Permalink
Add multiple genres to Artists
Browse files Browse the repository at this point in the history
  • Loading branch information
deluan committed Jul 20, 2021
1 parent 1d8607e commit b56e034
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 22 deletions.
1 change: 1 addition & 0 deletions model/artist.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Artist struct {
Name string `json:"name"`
AlbumCount int `json:"albumCount"`
SongCount int `json:"songCount"`
Genres Genres `json:"genres"`
FullText string `json:"fullText"`
SortArtistName string `json:"sortArtistName,omitempty"`
OrderArtistName string `json:"orderArtistName"`
Expand Down
15 changes: 1 addition & 14 deletions persistence/album_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func NewAlbumRepository(ctx context.Context, o orm.Ormer) model.AlbumRepository
"recently_added": recentlyAddedSort(),
}
r.filterMappings = map[string]filterFunc{
"id": idFilter(r.tableName),
"name": fullTextFilter,
"compilation": booleanFilter,
"artist_id": artistFilter,
Expand Down Expand Up @@ -267,20 +268,6 @@ func (r *albumRepository) refresh(ids ...string) error {
return err
}

func getGenres(genreIds string) model.Genres {
ids := strings.Fields(genreIds)
var genres model.Genres
unique := map[string]struct{}{}
for _, id := range ids {
if _, ok := unique[id]; ok {
continue
}
genres = append(genres, model.Genre{ID: id})
unique[id] = struct{}{}
}
return genres
}

func getAlbumArtist(al refreshAlbum) (id, name string) {
if !al.Compilation {
if al.AlbumArtist != "" {
Expand Down
35 changes: 27 additions & 8 deletions persistence/artist_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,40 @@ func NewArtistRepository(ctx context.Context, o orm.Ormer) model.ArtistRepositor
"name": "order_artist_name",
}
r.filterMappings = map[string]filterFunc{
"id": idFilter(r.tableName),
"name": fullTextFilter,
"starred": booleanFilter,
}
return r
}

func (r *artistRepository) selectArtist(options ...model.QueryOptions) SelectBuilder {
return r.newSelectWithAnnotation("artist.id", options...).Columns("*")
return r.newSelectWithAnnotation("artist.id", options...).Columns("artist.*")
}

func (r *artistRepository) CountAll(options ...model.QueryOptions) (int64, error) {
return r.count(r.newSelectWithAnnotation("artist.id"), options...)
}

func (r *artistRepository) Exists(id string) (bool, error) {
return r.exists(Select().Where(Eq{"id": id}))
return r.exists(Select().Where(Eq{"artist.id": id}))
}

func (r *artistRepository) Put(a *model.Artist) error {
genres := a.Genres
a.Genres = nil
defer func() { a.Genres = genres }()
a.FullText = getFullText(a.Name, a.SortArtistName)
dba := r.fromModel(a)
_, err := r.put(dba.ID, dba)
return err
if err != nil {
return err
}
return r.updateGenres(a.ID, r.tableName, genres)
}

func (r *artistRepository) Get(id string) (*model.Artist, error) {
sel := r.selectArtist().Where(Eq{"id": id})
sel := r.selectArtist().Where(Eq{"artist.id": id})
var dba []dbArtist
if err := r.queryAll(sel, &dba); err != nil {
return nil, err
Expand All @@ -72,14 +79,22 @@ func (r *artistRepository) Get(id string) (*model.Artist, error) {
return nil, model.ErrNotFound
}
res := r.toModels(dba)
return &res[0], nil
err := r.loadArtistGenres(&res)
return &res[0], err
}

func (r *artistRepository) GetAll(options ...model.QueryOptions) (model.Artists, error) {
sel := r.selectArtist(options...)
sel := r.selectArtist(options...).
LeftJoin("artist_genres ag on artist.id = ag.artist_id").
LeftJoin("genre on ag.genre_id = genre.id").
GroupBy("artist.id")
var dba []dbArtist
err := r.queryAll(sel, &dba)
if err != nil {
return nil, err
}
res := r.toModels(dba)
err = r.loadArtistGenres(&res)
return res, err
}

Expand Down Expand Up @@ -175,14 +190,17 @@ func (r *artistRepository) refresh(ids ...string) error {
type refreshArtist struct {
model.Artist
CurrentId string
GenreIds string
}
var artists []refreshArtist
sel := Select("f.album_artist_id as id", "f.album_artist as name", "count(*) as album_count", "a.id as current_id",
"group_concat(f.mbz_album_artist_id , ' ') as mbz_artist_id",
"f.sort_album_artist_name as sort_artist_name", "f.order_album_artist_name as order_artist_name",
"sum(f.song_count) as song_count", "sum(f.size) as size").
"sum(f.song_count) as song_count", "sum(f.size) as size",
"group_concat(ag.genre_id, ' ') as genre_ids").
From("album f").
LeftJoin("artist a on f.album_artist_id = a.id").
LeftJoin("album_genres ag on ag.album_id = f.id").
Where(Eq{"f.album_artist_id": ids}).
GroupBy("f.album_artist_id").OrderBy("f.id")
err := r.queryAll(sel, &artists)
Expand All @@ -199,6 +217,7 @@ func (r *artistRepository) refresh(ids ...string) error {
toInsert++
}
ar.MbzArtistID = getMostFrequentMbzID(r.ctx, ar.MbzArtistID, r.tableName, ar.Name)
ar.Genres = getGenres(ar.GenreIds)
err := r.Put(&ar.Artist)
if err != nil {
return err
Expand Down Expand Up @@ -254,7 +273,7 @@ func (r *artistRepository) NewInstance() interface{} {
}

func (r artistRepository) Delete(id string) error {
return r.delete(Eq{"id": id})
return r.delete(Eq{"artist.id": id})
}

func (r artistRepository) Save(entity interface{}) (string, error) {
Expand Down
14 changes: 14 additions & 0 deletions persistence/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,17 @@ func getMostFrequentMbzID(ctx context.Context, mbzIDs, entityName, name string)
}
return topId
}

func getGenres(genreIds string) model.Genres {
ids := strings.Fields(genreIds)
var genres model.Genres
unique := map[string]struct{}{}
for _, id := range ids {
if _, ok := unique[id]; ok {
continue
}
genres = append(genres, model.Genre{ID: id})
unique[id] = struct{}{}
}
return genres
}
27 changes: 27 additions & 0 deletions persistence/sql_genres.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,30 @@ func (r *sqlRepository) loadAlbumGenres(mfs *model.Albums) error {
}
return nil
}

func (r *sqlRepository) loadArtistGenres(mfs *model.Artists) error {
var ids []string
m := map[string]*model.Artist{}
for i := range *mfs {
mf := &(*mfs)[i]
ids = append(ids, mf.ID)
m[mf.ID] = mf
}

sql := Select("g.*", "ag.artist_id").From("genre g").Join("artist_genres ag on ag.genre_id = g.id").
Where(Eq{"ag.artist_id": ids}).OrderBy("ag.artist_id", "ag.rowid")
var genres []struct {
model.Genre
ArtistId string
}

err := r.queryAll(sql, &genres)
if err != nil {
return err
}
for _, g := range genres {
mf := m[g.ArtistId]
mf.Genres = append(mf.Genres, g.Genre)
}
return nil
}
6 changes: 6 additions & 0 deletions persistence/sql_restful.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,9 @@ func booleanFilter(field string, value interface{}) Sqlizer {
func fullTextFilter(field string, value interface{}) Sqlizer {
return fullTextExpr(value.(string))
}

func idFilter(tableName string) func(string, interface{}) Sqlizer {
return func(field string, value interface{}) Sqlizer {
return Eq{tableName + ".id": value}
}
}

0 comments on commit b56e034

Please sign in to comment.