浏览代码

Merge pull request #2339 from MediaBrowser/dev

Dev
Luke 8 年之前
父节点
当前提交
acf71527b5

+ 4 - 7
Emby.Server.Implementations/Activity/ActivityRepository.cs

@@ -85,7 +85,7 @@ namespace Emby.Server.Implementations.Activity
                 using (var connection = CreateConnection(true))
                 {
                     var list = new List<ActivityLogEntry>();
-                    int totalRecordCount = 0;
+                    var result = new QueryResult<ActivityLogEntry>();
 
                     var commandText = BaseActivitySelectText;
                     var whereClauses = new List<string>();
@@ -151,15 +151,12 @@ namespace Emby.Server.Implementations.Activity
                                 statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
                             }
 
-                            totalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
+                            result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
                         }
                     }, ReadTransactionMode);
 
-                    return new QueryResult<ActivityLogEntry>()
-                    {
-                        Items = list.ToArray(),
-                        TotalRecordCount = totalRecordCount
-                    };
+                    result.Items = list.ToArray();
+                    return result;
                 }
             }
         }

+ 92 - 34
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -343,6 +343,9 @@ namespace Emby.Server.Implementations.Data
                 // series
                 "create index if not exists idx_TypeSeriesPresentationUniqueKey1 on TypedBaseItems(Type,SeriesPresentationUniqueKey,PresentationUniqueKey,SortName)",
 
+                // series next up
+                "create index if not exists idx_SeriesPresentationUniqueKey on TypedBaseItems(SeriesPresentationUniqueKey)",
+
                 // live tv programs
                 "create index if not exists idx_TypeTopParentIdStartDate on TypedBaseItems(Type,TopParentId,StartDate)",
 
@@ -2263,6 +2266,10 @@ namespace Emby.Server.Implementations.Data
             {
                 return true;
             }
+            if (sortingFields.Contains(ItemSortBy.SeriesDatePlayed, StringComparer.OrdinalIgnoreCase))
+            {
+                return true;
+            }
 
             if (query.IsFavoriteOrLiked.HasValue)
             {
@@ -2436,6 +2443,66 @@ namespace Emby.Server.Implementations.Data
             return " from TypedBaseItems " + alias;
         }
 
+        public int GetCount(InternalItemsQuery query)
+        {
+            if (query == null)
+            {
+                throw new ArgumentNullException("query");
+            }
+
+            CheckDisposed();
+
+            //Logger.Info("GetItemList: " + _environmentInfo.StackTrace);
+
+            var now = DateTime.UtcNow;
+
+            // Hack for right now since we currently don't support filtering out these duplicates within a query
+            if (query.Limit.HasValue && query.EnableGroupByMetadataKey)
+            {
+                query.Limit = query.Limit.Value + 4;
+            }
+
+            var commandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new [] { "count(distinct PresentationUniqueKey)" })) + GetFromText();
+            commandText += GetJoinUserDataText(query);
+
+            var whereClauses = GetWhereClauses(query, null);
+
+            var whereText = whereClauses.Count == 0 ?
+                string.Empty :
+                " where " + string.Join(" AND ", whereClauses.ToArray());
+
+            commandText += whereText;
+
+            //commandText += GetGroupBy(query);
+
+            int count = 0;
+
+            using (WriteLock.Read())
+            {
+                using (var connection = CreateConnection(true))
+                {
+                    using (var statement = PrepareStatementSafe(connection, commandText))
+                    {
+                        if (EnableJoinUserData(query))
+                        {
+                            statement.TryBind("@UserId", query.User.Id);
+                        }
+
+                        BindSimilarParams(query, statement);
+
+                        // Running this again will bind the params
+                        GetWhereClauses(query, statement);
+
+                        count = statement.ExecuteQuery().SelectScalarInt().First();
+                    }
+                }
+
+                LogQueryTime("GetCount", commandText, now);
+            }
+
+            return count;
+        }
+
         public List<BaseItem> GetItemList(InternalItemsQuery query)
         {
             if (query == null)
@@ -2656,7 +2723,7 @@ namespace Emby.Server.Implementations.Data
                 }
             }
 
-            var totalRecordCount = 0;
+            var result = new QueryResult<BaseItem>();
             var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
 
             var statementTexts = new List<string>();
@@ -2714,23 +2781,23 @@ namespace Emby.Server.Implementations.Data
                                     }
                                 }
                             }
+                        }
 
-                            if (query.EnableTotalRecordCount)
+                        if (query.EnableTotalRecordCount)
+                        {
+                            using (var statement = statements[statements.Count - 1])
                             {
-                                using (var statement = statements[statements.Count - 1])
+                                if (EnableJoinUserData(query))
                                 {
-                                    if (EnableJoinUserData(query))
-                                    {
-                                        statement.TryBind("@UserId", query.User.Id);
-                                    }
+                                    statement.TryBind("@UserId", query.User.Id);
+                                }
 
-                                    BindSimilarParams(query, statement);
+                                BindSimilarParams(query, statement);
 
-                                    // Running this again will bind the params
-                                    GetWhereClauses(query, statement);
+                                // Running this again will bind the params
+                                GetWhereClauses(query, statement);
 
-                                    totalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
-                                }
+                                result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
                             }
                         }
 
@@ -2738,11 +2805,8 @@ namespace Emby.Server.Implementations.Data
 
                     LogQueryTime("GetItems", commandText, now);
 
-                    return new QueryResult<BaseItem>()
-                    {
-                        Items = list.ToArray(),
-                        TotalRecordCount = totalRecordCount
-                    };
+                    result.Items = list.ToArray();
+                    return result;
                 }
             }
         }
@@ -2855,7 +2919,7 @@ namespace Emby.Server.Implementations.Data
             }
             if (string.Equals(name, ItemSortBy.SeriesDatePlayed, StringComparison.OrdinalIgnoreCase))
             {
-                return new Tuple<string, bool>("(Select MAX(LastPlayedDate) from TypedBaseItems B" + GetJoinUserDataText(query) + " where B.Guid in (Select ItemId from AncestorIds where AncestorId in (select guid from typedbaseitems c where C.Type = 'MediaBrowser.Controller.Entities.TV.Series' And C.Guid in (Select AncestorId from AncestorIds where ItemId=A.Guid))))", false);
+                return new Tuple<string, bool>("(Select MAX(LastPlayedDate) from TypedBaseItems B" + GetJoinUserDataText(query) + " where Played=1 and B.SeriesPresentationUniqueKey=A.PresentationUniqueKey)", false);
             }
 
             return new Tuple<string, bool>(name, false);
@@ -3094,7 +3158,7 @@ namespace Emby.Server.Implementations.Data
             {
                 using (var connection = CreateConnection(true))
                 {
-                    var totalRecordCount = 0;
+                    var result = new QueryResult<Guid>();
 
                     connection.RunInTransaction(db =>
                     {
@@ -3136,7 +3200,7 @@ namespace Emby.Server.Implementations.Data
                                 // Running this again will bind the params
                                 GetWhereClauses(query, statement);
 
-                                totalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
+                                result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
                             }
                         }
 
@@ -3144,11 +3208,8 @@ namespace Emby.Server.Implementations.Data
 
                     LogQueryTime("GetItemIds", commandText, now);
 
-                    return new QueryResult<Guid>()
-                    {
-                        Items = list.ToArray(),
-                        TotalRecordCount = totalRecordCount
-                    };
+                    result.Items = list.ToArray();
+                    return result;
                 }
             }
         }
@@ -5026,7 +5087,7 @@ namespace Emby.Server.Implementations.Data
             var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
 
             var list = new List<Tuple<BaseItem, ItemCounts>>();
-            var count = 0;
+            var result = new QueryResult<Tuple<BaseItem, ItemCounts>>();
 
             var statementTexts = new List<string>();
             if (!isReturningZeroItems)
@@ -5106,7 +5167,7 @@ namespace Emby.Server.Implementations.Data
                                 GetWhereClauses(innerQuery, statement);
                                 GetWhereClauses(outerQuery, statement);
 
-                                count = statement.ExecuteQuery().SelectScalarInt().First();
+                                result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
 
                                 LogQueryTime("GetItemValues", commandText, now);
                             }
@@ -5115,16 +5176,13 @@ namespace Emby.Server.Implementations.Data
                 }
             }
 
-            if (count == 0)
+            if (result.TotalRecordCount == 0)
             {
-                count = list.Count;
+                result.TotalRecordCount = list.Count;
             }
+            result.Items = list.ToArray();
 
-            return new QueryResult<Tuple<BaseItem, ItemCounts>>
-            {
-                Items = list.ToArray(),
-                TotalRecordCount = count
-            };
+            return result;
         }
 
         private ItemCounts GetItemCounts(IReadOnlyList<IResultSetValue> reader, int countStartColumn, List<string> typesToCount)

+ 20 - 0
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -1279,6 +1279,26 @@ namespace Emby.Server.Implementations.Library
             return ItemRepository.GetItemList(query);
         }
 
+        public int GetCount(InternalItemsQuery query)
+        {
+            if (query.Recursive && query.ParentId.HasValue)
+            {
+                var parent = GetItemById(query.ParentId.Value);
+                if (parent != null)
+                {
+                    SetTopParentIdsOrAncestors(query, new List<BaseItem> { parent });
+                    query.ParentId = null;
+                }
+            }
+
+            if (query.User != null)
+            {
+                AddUserToQuery(query, query.User);
+            }
+
+            return ItemRepository.GetCount(query);
+        }
+
         public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
         {
             SetTopParentIdsOrAncestors(query, parents);

+ 5 - 7
Emby.Server.Implementations/Security/AuthenticationRepository.cs

@@ -201,12 +201,13 @@ namespace Emby.Server.Implementations.Security
             }
 
             var list = new List<AuthenticationInfo>();
-            int totalRecordCount = 0;
 
             using (WriteLock.Read())
             {
                 using (var connection = CreateConnection(true))
                 {
+                    var result = new QueryResult<AuthenticationInfo>();
+
                     connection.RunInTransaction(db =>
                     {
                         var statementTexts = new List<string>();
@@ -229,7 +230,7 @@ namespace Emby.Server.Implementations.Security
                             {
                                 BindAuthenticationQueryParams(query, totalCountStatement);
 
-                                totalRecordCount = totalCountStatement.ExecuteQuery()
+                                result.TotalRecordCount = totalCountStatement.ExecuteQuery()
                                     .SelectScalarInt()
                                     .First();
                             }
@@ -237,11 +238,8 @@ namespace Emby.Server.Implementations.Security
 
                     }, ReadTransactionMode);
 
-                    return new QueryResult<AuthenticationInfo>()
-                    {
-                        Items = list.ToArray(),
-                        TotalRecordCount = totalRecordCount
-                    };
+                    result.Items = list.ToArray();
+                    return result;
                 }
             }
         }

+ 12 - 11
Emby.Server.Implementations/TV/TVSeriesManager.cs

@@ -58,7 +58,8 @@ namespace Emby.Server.Implementations.TV
             var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 IncludeItemTypes = new[] { typeof(Series).Name },
-                SortOrder = SortOrder.Ascending,
+                SortBy = new[] { ItemSortBy.SeriesDatePlayed },
+                SortOrder = SortOrder.Descending,
                 PresentationUniqueKey = presentationUniqueKey,
                 Limit = limit,
                 ParentId = parentIdGuid,
@@ -71,7 +72,7 @@ namespace Emby.Server.Implementations.TV
                     }
                 }
 
-            }).Cast<Series>();
+            }).Cast<Series>().Select(GetUniqueSeriesKey);
 
             // Avoid implicitly captured closure
             var episodes = GetNextUpEpisodes(request, user, items);
@@ -109,19 +110,20 @@ namespace Emby.Server.Implementations.TV
             var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
             {
                 IncludeItemTypes = new[] { typeof(Series).Name },
-                SortOrder = SortOrder.Ascending,
+                SortBy = new[] { ItemSortBy.SeriesDatePlayed },
+                SortOrder = SortOrder.Descending,
                 PresentationUniqueKey = presentationUniqueKey,
                 Limit = limit,
                 DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
                 {
                     Fields = new List<ItemFields>
                     {
-                        
+
                     },
                     EnableImages = false
                 }
 
-            }, parentsFolders.Cast<BaseItem>().ToList()).Cast<Series>();
+            }, parentsFolders.Cast<BaseItem>().ToList()).Cast<Series>().Select(GetUniqueSeriesKey);
 
             // Avoid implicitly captured closure
             var episodes = GetNextUpEpisodes(request, user, items);
@@ -129,15 +131,15 @@ namespace Emby.Server.Implementations.TV
             return GetResult(episodes, null, request);
         }
 
-        public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable<Series> series)
+        public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable<string> seriesKeys)
         {
             // Avoid implicitly captured closure
             var currentUser = user;
 
-            var allNextUp = series
-                .Select(i => GetNextUp(GetUniqueSeriesKey(i), currentUser))
-                // Include if an episode was found, and either the series is not unwatched or the specific series was requested
-                .OrderByDescending(i => i.Item1);
+            var allNextUp = seriesKeys
+                .Select(i => GetNextUp(i, currentUser));
+
+            //allNextUp = allNextUp.OrderByDescending(i => i.Item1);
 
             // If viewing all next up for all series, remove first episodes
             // But if that returns empty, keep those first episodes (avoid completely empty view)
@@ -160,7 +162,6 @@ namespace Emby.Server.Implementations.TV
 
                     return true;
                 })
-                .Take(request.Limit.HasValue ? (request.Limit.Value * 2) : int.MaxValue)
                 .Select(i => i.Item2())
                 .Where(i => i != null)
                 .Take(request.Limit ?? int.MaxValue);

+ 22 - 8
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -138,16 +138,24 @@ namespace MediaBrowser.Controller.Entities.TV
             var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey;
             var seriesKey = GetUniqueSeriesKey(this);
 
-            var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user)
+            var result = LibraryManager.GetCount(new InternalItemsQuery(user)
             {
                 AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey,
                 SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null,
                 IncludeItemTypes = new[] { typeof(Season).Name },
                 IsVirtualItem = false,
-                Limit = 0
+                Limit = 0,
+                DtoOptions = new Dto.DtoOptions
+                {
+                    Fields = new List<ItemFields>
+                    {
+
+                    },
+                    EnableImages = false
+                }
             });
 
-            return result.TotalRecordCount;
+            return result;
         }
 
         public override int GetRecursiveChildCount(User user)
@@ -159,19 +167,25 @@ namespace MediaBrowser.Controller.Entities.TV
             {
                 AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey,
                 SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null,
+                DtoOptions = new Dto.DtoOptions
+                {
+                    Fields = new List<ItemFields>
+                    {
+                        
+                    },
+                    EnableImages = false
+                }
             };
 
-            if (query.SortBy.Length == 0)
-            {
-                query.SortBy = new[] { ItemSortBy.SortName };
-            }
             if (query.IncludeItemTypes.Length == 0)
             {
                 query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
             }
             query.IsVirtualItem = false;
             query.Limit = 0;
-            return LibraryManager.GetItemsResult(query).TotalRecordCount;
+            var totalRecordCount = LibraryManager.GetCount(query);
+
+            return totalRecordCount;
         }
 
         /// <summary>

+ 1 - 0
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -571,5 +571,6 @@ namespace MediaBrowser.Controller.Library
 
         void RegisterIgnoredPath(string path);
         void UnRegisterIgnoredPath(string path);
+        int GetCount(InternalItemsQuery query);
     }
 }

+ 2 - 0
MediaBrowser.Controller/Persistence/IItemRepository.cs

@@ -163,6 +163,8 @@ namespace MediaBrowser.Controller.Persistence
         /// <returns>Task.</returns>
         Task UpdateInheritedValues(CancellationToken cancellationToken);
 
+        int GetCount(InternalItemsQuery query);
+
         QueryResult<Tuple<BaseItem, ItemCounts>> GetGenres(InternalItemsQuery query);
         QueryResult<Tuple<BaseItem, ItemCounts>> GetMusicGenres(InternalItemsQuery query);
         QueryResult<Tuple<BaseItem, ItemCounts>> GetGameGenres(InternalItemsQuery query);

+ 19 - 0
src/Emby.Server/project.json

@@ -18,6 +18,25 @@
     "SQLitePCLRaw.provider.sqlite3.netstandard11": "1.1.1-pre20161109081005"
   },
 
+  "runtimes": {
+    "win7-x86": {},
+    "win7-x64": {},
+    "win8-x86": {},
+    "win8-x64": {},
+    "win8-arm": {},
+    "win81-x86": {},
+    "win81-x64": {},
+    "win81-arm": {},
+    "win10-x86": {},
+    "win10-x64": {},
+    "win10-arm": {},
+    "win10-arm64": {},
+    "osx.10.10-x64": {},
+    "osx.10.11-x64": {},
+    "osx.10.12-x64": {},
+    "ubuntu.14.04-x64": {}
+  },
+
   "frameworks": {
     "netcoreapp1.1": {
       "imports": "dnxcore50",