Deterministic pagination in random albums sort (#1841)

* Deterministic pagination in random albums sort

* Reseed on first random page

* Add unit tests

* Use rand in Subsonic API

* Use different seeds per user on SEEDEDRAND() SQLite3 function

* Small refactor

* Fix id mismatch

* Add seeded random to media_file (subsonic endpoint `getRandomSongs`)

* Refactor

* Remove unneeded import

---------

Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Guilherme Souza
2024-05-18 15:10:53 -03:00
committed by GitHub
parent a9feeac793
commit 98218d045e
7 changed files with 110 additions and 8 deletions
+13
View File
@@ -14,6 +14,7 @@ import (
"github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/model/request"
"github.com/navidrome/navidrome/utils/hasher"
"github.com/pocketbase/dbx"
)
@@ -137,6 +138,18 @@ func (r sqlRepository) applyFilters(sq SelectBuilder, options ...model.QueryOpti
return sq
}
func (r sqlRepository) seededRandomSort() string {
u, _ := request.UserFrom(r.ctx)
return fmt.Sprintf("SEEDEDRAND('%s', id)", r.tableName+u.ID)
}
func (r sqlRepository) resetSeededRandom(options []model.QueryOptions) {
if len(options) > 0 && options[0].Offset == 0 && options[0].Sort == "random" {
u, _ := request.UserFrom(r.ctx)
hasher.Reseed(r.tableName + u.ID)
}
}
func (r sqlRepository) executeSQL(sq Sqlizer) (int64, error) {
query, args, err := r.toSQL(sq)
if err != nil {