Fix "too many SQL variables" error in GetStarred endpoint

This commit is contained in:
Deluan 2021-07-21 10:45:52 -04:00
parent 4f9d546da4
commit 4fcb238295
2 changed files with 63 additions and 45 deletions

View file

@ -3,6 +3,7 @@ package persistence
import ( import (
. "github.com/Masterminds/squirrel" . "github.com/Masterminds/squirrel"
"github.com/navidrome/navidrome/model" "github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/utils"
) )
func (r sqlRepository) withGenres(sql SelectBuilder) SelectBuilder { func (r sqlRepository) withGenres(sql SelectBuilder) SelectBuilder {
@ -37,22 +38,24 @@ func (r *sqlRepository) loadMediaFileGenres(mfs *model.MediaFiles) error {
m[mf.ID] = mf m[mf.ID] = mf
} }
sql := Select("g.*", "mg.media_file_id").From("genre g").Join("media_file_genres mg on mg.genre_id = g.id"). return utils.RangeByChunks(ids, 100, func(ids []string) error {
Where(Eq{"mg.media_file_id": ids}).OrderBy("mg.media_file_id", "mg.rowid") sql := Select("g.*", "mg.media_file_id").From("genre g").Join("media_file_genres mg on mg.genre_id = g.id").
var genres []struct { Where(Eq{"mg.media_file_id": ids}).OrderBy("mg.media_file_id", "mg.rowid")
model.Genre var genres []struct {
MediaFileId string model.Genre
} MediaFileId string
}
err := r.queryAll(sql, &genres) err := r.queryAll(sql, &genres)
if err != nil { if err != nil {
return err return err
} }
for _, g := range genres { for _, g := range genres {
mf := m[g.MediaFileId] mf := m[g.MediaFileId]
mf.Genres = append(mf.Genres, g.Genre) mf.Genres = append(mf.Genres, g.Genre)
} }
return nil return nil
})
} }
func (r *sqlRepository) loadAlbumGenres(mfs *model.Albums) error { func (r *sqlRepository) loadAlbumGenres(mfs *model.Albums) error {
@ -64,22 +67,24 @@ func (r *sqlRepository) loadAlbumGenres(mfs *model.Albums) error {
m[mf.ID] = mf m[mf.ID] = mf
} }
sql := Select("g.*", "ag.album_id").From("genre g").Join("album_genres ag on ag.genre_id = g.id"). return utils.RangeByChunks(ids, 100, func(ids []string) error {
Where(Eq{"ag.album_id": ids}).OrderBy("ag.album_id", "ag.rowid") sql := Select("g.*", "ag.album_id").From("genre g").Join("album_genres ag on ag.genre_id = g.id").
var genres []struct { Where(Eq{"ag.album_id": ids}).OrderBy("ag.album_id", "ag.rowid")
model.Genre var genres []struct {
AlbumId string model.Genre
} AlbumId string
}
err := r.queryAll(sql, &genres) err := r.queryAll(sql, &genres)
if err != nil { if err != nil {
return err return err
} }
for _, g := range genres { for _, g := range genres {
mf := m[g.AlbumId] mf := m[g.AlbumId]
mf.Genres = append(mf.Genres, g.Genre) mf.Genres = append(mf.Genres, g.Genre)
} }
return nil return nil
})
} }
func (r *sqlRepository) loadArtistGenres(mfs *model.Artists) error { func (r *sqlRepository) loadArtistGenres(mfs *model.Artists) error {
@ -91,20 +96,22 @@ func (r *sqlRepository) loadArtistGenres(mfs *model.Artists) error {
m[mf.ID] = mf m[mf.ID] = mf
} }
sql := Select("g.*", "ag.artist_id").From("genre g").Join("artist_genres ag on ag.genre_id = g.id"). return utils.RangeByChunks(ids, 100, func(ids []string) error {
Where(Eq{"ag.artist_id": ids}).OrderBy("ag.artist_id", "ag.rowid") sql := Select("g.*", "ag.artist_id").From("genre g").Join("artist_genres ag on ag.genre_id = g.id").
var genres []struct { Where(Eq{"ag.artist_id": ids}).OrderBy("ag.artist_id", "ag.rowid")
model.Genre var genres []struct {
ArtistId string model.Genre
} ArtistId string
}
err := r.queryAll(sql, &genres) err := r.queryAll(sql, &genres)
if err != nil { if err != nil {
return err return err
} }
for _, g := range genres { for _, g := range genres {
mf := m[g.ArtistId] mf := m[g.ArtistId]
mf.Genres = append(mf.Genres, g.Genre) mf.Genres = append(mf.Genres, g.Genre)
} }
return nil return nil
})
} }

View file

@ -53,6 +53,17 @@ func BreakUpStringSlice(items []string, chunkSize int) [][]string {
return chunks return chunks
} }
func RangeByChunks(items []string, chunkSize int, cb func([]string) error) error {
chunks := BreakUpStringSlice(items, chunkSize)
for _, chunk := range chunks {
err := cb(chunk)
if err != nil {
return err
}
}
return nil
}
func LongestCommonPrefix(list []string) string { func LongestCommonPrefix(list []string) string {
if len(list) == 0 { if len(list) == 0 {
return "" return ""