Skip to content

Commit

Permalink
Fix "too many SQL variables" error in GetStarred endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
deluan committed Jul 21, 2021
1 parent 4f9d546 commit 4fcb238
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 45 deletions.
97 changes: 52 additions & 45 deletions persistence/sql_genres.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package persistence
import (
. "github.com/Masterminds/squirrel"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/utils"
)

func (r sqlRepository) withGenres(sql SelectBuilder) SelectBuilder {
Expand Down Expand Up @@ -37,22 +38,24 @@ func (r *sqlRepository) loadMediaFileGenres(mfs *model.MediaFiles) error {
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").
Where(Eq{"mg.media_file_id": ids}).OrderBy("mg.media_file_id", "mg.rowid")
var genres []struct {
model.Genre
MediaFileId string
}
return utils.RangeByChunks(ids, 100, 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
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 {
Expand All @@ -64,22 +67,24 @@ func (r *sqlRepository) loadAlbumGenres(mfs *model.Albums) error {
m[mf.ID] = mf
}

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
}
return utils.RangeByChunks(ids, 100, 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
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 {
Expand All @@ -91,20 +96,22 @@ func (r *sqlRepository) loadArtistGenres(mfs *model.Artists) error {
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
}
return utils.RangeByChunks(ids, 100, 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
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
})
}
11 changes: 11 additions & 0 deletions utils/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ func BreakUpStringSlice(items []string, chunkSize int) [][]string {
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 {
if len(list) == 0 {
return ""
Expand Down

0 comments on commit 4fcb238

Please sign in to comment.