From 1a9a62eae939e25bb71634d246216983ea535492 Mon Sep 17 00:00:00 2001 From: BigBangClock2 <220599702+BigBangClock2@users.noreply.github.com> Date: Sun, 9 Nov 2025 23:49:40 +0000 Subject: [PATCH] Add sorting by performer age (#6009) --- pkg/sqlite/scene.go | 24 ++++++++++++++++++++++++ pkg/sqlite/scene_test.go | 7 +++++++ ui/v2.5/src/models/list-filter/scenes.ts | 1 + 3 files changed, 32 insertions(+) diff --git a/pkg/sqlite/scene.go b/pkg/sqlite/scene.go index ccabbbcf6..6cc5aa339 100644 --- a/pkg/sqlite/scene.go +++ b/pkg/sqlite/scene.go @@ -1100,6 +1100,7 @@ var sceneSortOptions = sortOptions{ "tag_count", "title", "updated_at", + "performer_age", } func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindFilterType) error { @@ -1209,6 +1210,29 @@ func (qb *SceneStore) setSceneSort(query *queryBuilder, findFilter *models.FindF query.sortAndPagination += fmt.Sprintf(" ORDER BY (SELECT MAX(o_date) FROM %s AS sort WHERE sort.%s = %s.id) %s", scenesODatesTable, sceneIDColumn, sceneTable, getSortDirection(direction)) case "o_counter": query.sortAndPagination += getCountSort(sceneTable, scenesODatesTable, sceneIDColumn, direction) + case "performer_age": + // Looking at the youngest performer by default + aggregation := "MIN" + if direction == "DESC" { + // When sorting by performer_'s age DESC, I should consider the oldest performer instead + aggregation = "MAX" + } + fallback := "NULL" + if direction == "ASC" { + // When sorting ascending, NULLs are first by default. Coalescing to the MAX int value supported by sqlite + fallback = "9223372036854775807" + } + query.sortAndPagination += fmt.Sprintf( + " ORDER BY (SELECT COALESCE(%s(JulianDay(scenes.date) - JulianDay(performers.birthdate)), %s) FROM %s as performers INNER JOIN %s AS aggregation WHERE performers.id = aggregation.%s AND aggregation.%s = %s.id) %s", + aggregation, + fallback, + performerTable, + performersScenesTable, + performerIDColumn, + sceneIDColumn, + sceneTable, + getSortDirection(direction), + ) case "studio": query.join(studioTable, "", "scenes.studio_id = studios.id") query.sortAndPagination += getSort("name", direction, studioTable) diff --git a/pkg/sqlite/scene_test.go b/pkg/sqlite/scene_test.go index 410819a34..b39b47129 100644 --- a/pkg/sqlite/scene_test.go +++ b/pkg/sqlite/scene_test.go @@ -4131,6 +4131,13 @@ func TestSceneQuerySorting(t *testing.T) { sceneIDs[sceneIdx1WithPerformer], -1, }, + { + "performer_age", + "performer_age", + models.SortDirectionEnumDesc, + -1, + -1, + }, } qb := db.Scene diff --git a/ui/v2.5/src/models/list-filter/scenes.ts b/ui/v2.5/src/models/list-filter/scenes.ts index d59f87d99..8bd3918f9 100644 --- a/ui/v2.5/src/models/list-filter/scenes.ts +++ b/ui/v2.5/src/models/list-filter/scenes.ts @@ -53,6 +53,7 @@ const sortByOptions = [ "interactive", "interactive_speed", "perceptual_similarity", + "performer_age", "studio", ...MediaSortByOptions, ]