Group O-Counter Filter/Sort (#6122)

This commit is contained in:
EventHoriizon
2025-11-10 00:53:53 +00:00
committed by GitHub
parent 2e766952dd
commit d5b1046267
12 changed files with 128 additions and 0 deletions

View File

@@ -488,6 +488,7 @@ var groupSortOptions = sortOptions{
"random",
"rating",
"scenes_count",
"o_counter",
"sub_group_order",
"tag_count",
"updated_at",
@@ -524,6 +525,8 @@ func (qb *GroupStore) setGroupSort(query *queryBuilder, findFilter *models.FindF
query.sortAndPagination += getCountSort(groupTable, groupsTagsTable, groupIDColumn, direction)
case "scenes_count": // generic getSort won't work for this
query.sortAndPagination += getCountSort(groupTable, groupsScenesTable, groupIDColumn, direction)
case "o_counter":
query.sortAndPagination += qb.sortByOCounter(direction)
default:
query.sortAndPagination += getSort(sort, direction, "groups")
}
@@ -701,3 +704,8 @@ func (qb *GroupStore) FindInAncestors(ctx context.Context, ascestorIDs []int, id
return ret, nil
}
func (qb *GroupStore) sortByOCounter(direction string) string {
// need to sum the o_counter from scenes and images
return " ORDER BY (" + selectGroupOCountSQL + ") " + direction
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
)
type groupFilterHandler struct {
@@ -73,6 +74,7 @@ func (qb *groupFilterHandler) criterionHandler() criterionHandler {
qb.performersCriterionHandler(groupFilter.Performers),
qb.tagsCriterionHandler(groupFilter.Tags),
qb.tagCountCriterionHandler(groupFilter.TagCount),
qb.groupOCounterCriterionHandler(groupFilter.OCounter),
&dateCriterionHandler{groupFilter.Date, "groups.date", nil},
groupHierarchyHandler.ParentsCriterionHandler(groupFilter.ContainingGroups),
groupHierarchyHandler.ChildrenCriterionHandler(groupFilter.SubGroups),
@@ -201,3 +203,37 @@ func (qb *groupFilterHandler) tagCountCriterionHandler(count *models.IntCriterio
return h.handler(count)
}
// used for sorting and filtering on group o-count
var selectGroupOCountSQL = utils.StrFormat(
"SELECT SUM(o_counter) "+
"FROM ("+
"SELECT COUNT({scenes_o_dates}.{o_date}) as o_counter from {groups_scenes} s "+
"LEFT JOIN {scenes} ON {scenes}.id = s.{scene_id} "+
"LEFT JOIN {scenes_o_dates} ON {scenes_o_dates}.{scene_id} = {scenes}.id "+
"WHERE s.{group_id} = {group}.id "+
")",
map[string]interface{}{
"group": groupTable,
"group_id": groupIDColumn,
"groups_scenes": groupsScenesTable,
"scenes": sceneTable,
"scene_id": sceneIDColumn,
"scenes_o_dates": scenesODatesTable,
"o_date": sceneODateColumn,
},
)
func (qb *groupFilterHandler) groupOCounterCriterionHandler(count *models.IntCriterionInput) criterionHandlerFunc {
return func(ctx context.Context, f *filterBuilder) {
if count == nil {
return
}
lhs := "(" + selectGroupOCountSQL + ")"
clause, args := getIntCriterionWhereClause(lhs, *count)
f.addWhere(clause, args...)
}
}

View File

@@ -795,6 +795,29 @@ func (qb *SceneStore) OCountByPerformerID(ctx context.Context, performerID int)
return ret, nil
}
func (qb *SceneStore) OCountByGroupID(ctx context.Context, groupID int) (int, error) {
table := qb.table()
joinTable := scenesGroupsJoinTable
oHistoryTable := goqu.T(scenesODatesTable)
q := dialect.Select(goqu.COUNT("*")).From(table).InnerJoin(
oHistoryTable,
goqu.On(table.Col(idColumn).Eq(oHistoryTable.Col(sceneIDColumn))),
).InnerJoin(
joinTable,
goqu.On(
table.Col(idColumn).Eq(joinTable.Col(sceneIDColumn)),
),
).Where(joinTable.Col(groupIDColumn).Eq(groupID))
var ret int
if err := querySimple(ctx, q, &ret); err != nil {
return 0, err
}
return ret, nil
}
func (qb *SceneStore) FindByGroupID(ctx context.Context, groupID int) ([]*models.Scene, error) {
sq := dialect.From(scenesGroupsJoinTable).Select(scenesGroupsJoinTable.Col(sceneIDColumn)).Where(
scenesGroupsJoinTable.Col(groupIDColumn).Eq(groupID),