From a7a2257ccbda10cdfe1112fefb8391c8f2d698d0 Mon Sep 17 00:00:00 2001
From: JPVenson <github@jpb.email>
Date: Tue, 12 Nov 2024 13:29:29 +0000
Subject: [PATCH] Fixed Search ordering and NextUp

---
 .../Item/BaseItemRepository.cs                | 96 +++++++++++++------
 1 file changed, 69 insertions(+), 27 deletions(-)

diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs
index e46d4eab12..3d04cf95fa 100644
--- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs
+++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs
@@ -23,12 +23,10 @@ using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.LiveTv;
 using MediaBrowser.Controller.Persistence;
-using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.LiveTv;
 using MediaBrowser.Model.Querying;
-using Microsoft.AspNetCore.Http.Json;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Logging;
 using BaseItemDto = MediaBrowser.Controller.Entities.BaseItem;
@@ -202,7 +200,42 @@ public sealed class BaseItemRepository(
 
         using var context = dbProvider.CreateDbContext();
 
-        result.Items = PrepareItemQuery(context, filter).AsEnumerable().Select(w => DeserialiseBaseItem(w, filter.SkipDeserialization)).ToImmutableArray();
+        IQueryable<BaseItemEntity> dbQuery = context.BaseItems.AsNoTracking()
+            .Include(e => e.TrailerTypes)
+            .Include(e => e.Provider)
+            .Include(e => e.LockedFields);
+
+        if (filter.DtoOptions.EnableImages)
+        {
+            dbQuery = dbQuery.Include(e => e.Images);
+        }
+
+        dbQuery = TranslateQuery(dbQuery, context, filter);
+        dbQuery = dbQuery.Distinct();
+        // .DistinctBy(e => e.Id);
+        if (filter.EnableTotalRecordCount)
+        {
+            result.TotalRecordCount = dbQuery.Count();
+        }
+
+        dbQuery = ApplyOrder(dbQuery, filter);
+
+        if (filter.Limit.HasValue || filter.StartIndex.HasValue)
+        {
+            var offset = filter.StartIndex ?? 0;
+
+            if (offset > 0)
+            {
+                dbQuery = dbQuery.Skip(offset);
+            }
+
+            if (filter.Limit.HasValue)
+            {
+                dbQuery = dbQuery.Take(filter.Limit.Value);
+            }
+        }
+
+        result.Items = dbQuery.AsEnumerable().Select(w => DeserialiseBaseItem(w, filter.SkipDeserialization)).ToImmutableArray();
         result.StartIndex = filter.StartIndex ?? 0;
         return result;
     }
@@ -218,29 +251,33 @@ public sealed class BaseItemRepository(
         return PrepareItemQuery(context, filter).AsEnumerable().Select(w => DeserialiseBaseItem(w, filter.SkipDeserialization)).ToImmutableArray();
     }
 
-    private IQueryable<BaseItemEntity> ApplyQueryFilter(IQueryable<BaseItemEntity> dbQuery, JellyfinDbContext context, InternalItemsQuery filter)
+    private IQueryable<BaseItemEntity> ApplyGroupingFilter(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
     {
-        dbQuery = TranslateQuery(dbQuery, context, filter);
-        dbQuery = ApplyOrder(dbQuery, filter);
+        dbQuery = dbQuery.Distinct();
+
+        // var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter);
+        // if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey)
+        // {
+        //     dbQuery = dbQuery.GroupBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey }).Select(e => e.First());
+        // }
+        // else if (enableGroupByPresentationUniqueKey)
+        // {
+        //     dbQuery = dbQuery.GroupBy(e => e.PresentationUniqueKey).Select(e => e.First());
+        // }
+        // else if (filter.GroupBySeriesPresentationUniqueKey)
+        // {
+        //     dbQuery = dbQuery.GroupBy(e => e.SeriesPresentationUniqueKey).Select(e => e.First());
+        // }
+        // else
+        // {
+        //     dbQuery = dbQuery.Distinct();
+        // }
 
-        var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter);
-        if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey)
-        {
-            dbQuery = dbQuery.GroupBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey }).Select(e => e.First());
-        }
-        else if (enableGroupByPresentationUniqueKey)
-        {
-            dbQuery = dbQuery.GroupBy(e => e.PresentationUniqueKey).Select(e => e.First());
-        }
-        else if (filter.GroupBySeriesPresentationUniqueKey)
-        {
-            dbQuery = dbQuery.GroupBy(e => e.SeriesPresentationUniqueKey).Select(e => e.First());
-        }
-        else
-        {
-            dbQuery = dbQuery.Distinct();
-        }
+        return dbQuery;
+    }
 
+    private IQueryable<BaseItemEntity> ApplyQueryPageing(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
+    {
         if (filter.Limit.HasValue || filter.StartIndex.HasValue)
         {
             var offset = filter.StartIndex ?? 0;
@@ -259,6 +296,15 @@ public sealed class BaseItemRepository(
         return dbQuery;
     }
 
+    private IQueryable<BaseItemEntity> ApplyQueryFilter(IQueryable<BaseItemEntity> dbQuery, JellyfinDbContext context, InternalItemsQuery filter)
+    {
+        dbQuery = TranslateQuery(dbQuery, context, filter);
+        dbQuery = ApplyOrder(dbQuery, filter);
+        dbQuery = ApplyGroupingFilter(dbQuery, filter);
+        dbQuery = ApplyQueryPageing(dbQuery, filter);
+        return dbQuery;
+    }
+
     private IQueryable<BaseItemEntity> PrepareItemQuery(JellyfinDbContext context, InternalItemsQuery filter)
     {
         IQueryable<BaseItemEntity> dbQuery = context.BaseItems.AsNoTracking()
@@ -1456,10 +1502,6 @@ public sealed class BaseItemRepository(
         {
             dto.ImageInfos = entity.Images.Select(Map).ToArray();
         }
-        else
-        {
-            System.Console.WriteLine();
-        }
 
         // dto.Type = entity.Type;
         // dto.Data = entity.Data;