package persistence import ( . "github.com/Masterminds/squirrel" "github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/utils/slice" ) func (r sqlRepository) withGenres(sql SelectBuilder) SelectBuilder { return sql.LeftJoin(r.tableName + "_genres ag on " + r.tableName + ".id = ag." + r.tableName + "_id"). LeftJoin("genre on ag.genre_id = genre.id") } func (r *sqlRepository) updateGenres(id string, tableName string, genres model.Genres) error { del := Delete(tableName + "_genres").Where(Eq{tableName + "_id": id}) _, err := r.executeSQL(del) if err != nil { return err } if len(genres) == 0 { return nil } var genreIds []string for _, g := range genres { genreIds = append(genreIds, g.ID) } err = slice.RangeByChunks(genreIds, 100, func(ids []string) error { ins := Insert(tableName+"_genres").Columns("genre_id", tableName+"_id") for _, gid := range ids { ins = ins.Values(gid, id) } _, err = r.executeSQL(ins) return err }) return err } func (r *sqlRepository) loadMediaFileGenres(mfs *model.MediaFiles) error { var ids []string m := map[string]*model.MediaFile{} for i := range *mfs { mf := &(*mfs)[i] ids = append(ids, mf.ID) m[mf.ID] = mf } return slice.RangeByChunks(ids, 900, func(ids []string) error { sql := Select("g.*", "mg.media_file_id").From("genre g").Join("media_file_genres mg on mg.genre_id = g.id"). Where(Eq{"mg.media_file_id": ids}).OrderBy("mg.media_file_id", "mg.rowid") var genres []struct { model.Genre MediaFileId string } err := r.queryAll(sql, &genres) if err != nil { return err } for _, g := range genres { mf := m[g.MediaFileId] mf.Genres = append(mf.Genres, g.Genre) } return nil }) } func (r *sqlRepository) loadAlbumGenres(mfs *model.Albums) error { var ids []string m := map[string]*model.Album{} for i := range *mfs { mf := &(*mfs)[i] ids = append(ids, mf.ID) m[mf.ID] = mf } return slice.RangeByChunks(ids, 900, func(ids []string) error { sql := Select("g.*", "ag.album_id").From("genre g").Join("album_genres ag on ag.genre_id = g.id"). Where(Eq{"ag.album_id": ids}).OrderBy("ag.album_id", "ag.rowid") var genres []struct { model.Genre AlbumId string } err := r.queryAll(sql, &genres) if err != nil { return err } for _, g := range genres { mf := m[g.AlbumId] mf.Genres = append(mf.Genres, g.Genre) } 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 } return slice.RangeByChunks(ids, 900, func(ids []string) error { 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 }) }