mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-03 19:17:24 -05:00 
			
		
		
		
	update db queries
This commit is contained in:
		
							parent
							
								
									a9e0797878
								
							
						
					
					
						commit
						0bd1f36ece
					
				@ -278,9 +278,11 @@ namespace MediaBrowser.Api
 | 
				
			|||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="request"></param>
 | 
					        /// <param name="request"></param>
 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns></returns>
 | 
				
			||||||
        public async Task Post(RegisterAppstoreSale request)
 | 
					        public void Post(RegisterAppstoreSale request)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            await _securityManager.RegisterAppStoreSale(request.Parameters);
 | 
					            var task = _securityManager.RegisterAppStoreSale(request.Parameters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Task.WaitAll(task);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -275,38 +275,26 @@ namespace MediaBrowser.Api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime();
 | 
					            var minPremiereDate = DateTime.Now.Date.AddDays(-1).ToUniversalTime();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            IEnumerable<BaseItem> items;
 | 
					            var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (string.IsNullOrWhiteSpace(request.ParentId))
 | 
					            var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                items = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                IncludeItemTypes = new[] { typeof(Episode).Name },
 | 
					                IncludeItemTypes = new[] { typeof(Episode).Name },
 | 
				
			||||||
                    SortBy = new[] { "PremiereDate", "SortName" },
 | 
					                SortBy = new[] { "PremiereDate", "AirTime", "SortName" },
 | 
				
			||||||
                SortOrder = SortOrder.Ascending,
 | 
					                SortOrder = SortOrder.Ascending,
 | 
				
			||||||
                    MinPremiereDate = minPremiereDate
 | 
					                MinPremiereDate = minPremiereDate,
 | 
				
			||||||
 | 
					                StartIndex = request.StartIndex,
 | 
				
			||||||
 | 
					                Limit = request.Limit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                }, user);
 | 
					            }, user, parentIds);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Episode && (i.PremiereDate ?? DateTime.MinValue) >= minPremiereDate);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var itemsList = _libraryManager
 | 
					 | 
				
			||||||
                .Sort(items, user, new[] { "PremiereDate", "AirTime", "SortName" }, SortOrder.Ascending)
 | 
					 | 
				
			||||||
                .Cast<Episode>()
 | 
					 | 
				
			||||||
                .ToList();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var pagedItems = ApplyPaging(itemsList, request.StartIndex, request.Limit);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var options = GetDtoOptions(request);
 | 
					            var options = GetDtoOptions(request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var returnItems = _dtoService.GetBaseItemDtos(pagedItems, options, user).ToArray();
 | 
					            var returnItems = _dtoService.GetBaseItemDtos(itemsResult.Items, options, user).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var result = new ItemsResult
 | 
					            var result = new ItemsResult
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                TotalRecordCount = itemsList.Count,
 | 
					                TotalRecordCount = itemsResult.TotalRecordCount,
 | 
				
			||||||
                Items = returnItems
 | 
					                Items = returnItems
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,8 +8,10 @@ using MediaBrowser.Model.Serialization;
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Net;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.Net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MediaBrowser.Common.Implementations.Security
 | 
					namespace MediaBrowser.Common.Implementations.Security
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -219,10 +221,6 @@ namespace MediaBrowser.Common.Implementations.Security
 | 
				
			|||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        SupporterKey = reg.key;
 | 
					                        SupporterKey = reg.key;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        throw new PaymentRequiredException();
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -231,10 +229,15 @@ namespace MediaBrowser.Common.Implementations.Security
 | 
				
			|||||||
                SaveAppStoreInfo(parameters);
 | 
					                SaveAppStoreInfo(parameters);
 | 
				
			||||||
                throw;
 | 
					                throw;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (PaymentRequiredException)
 | 
					            catch (HttpException e)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                SaveAppStoreInfo(parameters);
 | 
					                _logger.ErrorException("Error registering appstore purchase {0}", e, parameters ?? "NO PARMS SENT");
 | 
				
			||||||
                throw;
 | 
					
 | 
				
			||||||
 | 
					                if (e.StatusCode.HasValue && e.StatusCode.Value == HttpStatusCode.PaymentRequired)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    throw new PaymentRequiredException();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                throw new ApplicationException("Error registering store sale");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception e)
 | 
					            catch (Exception e)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
				
			|||||||
@ -128,7 +128,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// <returns>IEnumerable{BaseItem}.</returns>
 | 
					        /// <returns>IEnumerable{BaseItem}.</returns>
 | 
				
			||||||
        protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
 | 
					        protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return base.GetNonCachedChildren(directoryService).Concat(_virtualChildren);
 | 
					            return base.GetNonCachedChildren(directoryService);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -1898,5 +1898,24 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                DateLastSaved.Ticks.ToString(CultureInfo.InvariantCulture)
 | 
					                DateLastSaved.Ticks.ToString(CultureInfo.InvariantCulture)
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public virtual IEnumerable<Guid> GetAncestorIds()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return Parents.Select(i => i.Id).Concat(LibraryManager.GetCollectionFolders(this).Select(i => i.Id));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
 | 
					        public virtual bool SupportsAncestors
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public virtual IEnumerable<Guid> GetIdsForAncestorQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new[] { Id };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -149,8 +149,16 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
 | 
					            await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!EnableNewFolderQuerying())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false);
 | 
					                await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static bool EnableNewFolderQuerying()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return ConfigurationManager.Configuration.MigrationVersion >= 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected void AddChildrenInternal(IEnumerable<BaseItem> children)
 | 
					        protected void AddChildrenInternal(IEnumerable<BaseItem> children)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -222,9 +230,14 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            item.SetParent(null);
 | 
					            item.SetParent(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!EnableNewFolderQuerying())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                return ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken);
 | 
					                return ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return Task.FromResult(true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Clears the children.
 | 
					        /// Clears the children.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
@ -471,6 +484,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
 | 
					                            child.SetParent(this);
 | 
				
			||||||
                            newItems.Add(child);
 | 
					                            newItems.Add(child);
 | 
				
			||||||
                            validChildren.Add(child);
 | 
					                            validChildren.Add(child);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
@ -478,6 +492,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        // Brand new item - needs to be added
 | 
					                        // Brand new item - needs to be added
 | 
				
			||||||
 | 
					                        child.SetParent(this);
 | 
				
			||||||
                        newItems.Add(child);
 | 
					                        newItems.Add(child);
 | 
				
			||||||
                        validChildren.Add(child);
 | 
					                        validChildren.Add(child);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@ -506,7 +521,6 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            await UpdateIsOffline(item, false).ConfigureAwait(false);
 | 
					 | 
				
			||||||
                            actualRemovals.Add(item);
 | 
					                            actualRemovals.Add(item);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@ -517,6 +531,9 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                        foreach (var item in actualRemovals)
 | 
					                        foreach (var item in actualRemovals)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
 | 
					                            item.SetParent(null);
 | 
				
			||||||
 | 
					                            item.IsOffline = false;
 | 
				
			||||||
 | 
					                            await LibraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false);
 | 
				
			||||||
                            LibraryManager.ReportItemRemoved(item);
 | 
					                            LibraryManager.ReportItemRemoved(item);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@ -525,9 +542,12 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    AddChildrenInternal(newItems);
 | 
					                    AddChildrenInternal(newItems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (!EnableNewFolderQuerying())
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
                        await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false);
 | 
					                        await ItemRepository.SaveChildren(Id, ActualChildren.Select(i => i.Id).ToList(), cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            progress.Report(10);
 | 
					            progress.Report(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -755,20 +775,17 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        /// <returns>IEnumerable{BaseItem}.</returns>
 | 
					        /// <returns>IEnumerable{BaseItem}.</returns>
 | 
				
			||||||
        protected IEnumerable<BaseItem> GetCachedChildren()
 | 
					        protected IEnumerable<BaseItem> GetCachedChildren()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (ConfigurationManager.Configuration.DisableStartupScan)
 | 
					            if (EnableNewFolderQuerying())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
 | 
					                return ItemRepository.GetItemList(new InternalItemsQuery
 | 
				
			||||||
                //return ItemRepository.GetItems(new InternalItemsQuery
 | 
					                {
 | 
				
			||||||
                //{
 | 
					                    ParentId = Id
 | 
				
			||||||
                //    ParentId = Id
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                //}).Items.Select(RetrieveChild).Where(i => i != null);
 | 
					                }).Select(RetrieveChild).Where(i => i != null);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
            return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
 | 
					            return ItemRepository.GetChildrenItems(Id).Select(RetrieveChild).Where(i => i != null);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private BaseItem RetrieveChild(BaseItem child)
 | 
					        private BaseItem RetrieveChild(BaseItem child)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
				
			|||||||
@ -102,6 +102,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
        public LocationType? LocationType { get; set; }
 | 
					        public LocationType? LocationType { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Guid? ParentId { get; set; }
 | 
					        public Guid? ParentId { get; set; }
 | 
				
			||||||
 | 
					        public string[] AncestorIds { get; set; }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
        public InternalItemsQuery()
 | 
					        public InternalItemsQuery()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -121,6 +122,7 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            PersonIds = new string[] { };
 | 
					            PersonIds = new string[] { };
 | 
				
			||||||
            ChannelIds = new string[] { };
 | 
					            ChannelIds = new string[] { };
 | 
				
			||||||
            ItemIds = new string[] { };
 | 
					            ItemIds = new string[] { };
 | 
				
			||||||
 | 
					            AncestorIds = new string[] { };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public InternalItemsQuery(User user)
 | 
					        public InternalItemsQuery(User user)
 | 
				
			||||||
@ -130,6 +132,8 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                var policy = user.Policy;
 | 
					                var policy = user.Policy;
 | 
				
			||||||
                MaxParentalRating = policy.MaxParentalRating;
 | 
					                MaxParentalRating = policy.MaxParentalRating;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                User = user;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -101,6 +101,15 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
 | 
					        public override bool SupportsAncestors
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -265,6 +265,20 @@ namespace MediaBrowser.Controller.Entities.TV
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override IEnumerable<Guid> GetAncestorIds()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var list = base.GetAncestorIds().ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var seasonId = SeasonId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (seasonId.HasValue && !list.Contains(seasonId.Value))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                list.Add(seasonId.Value);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return list;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public override IEnumerable<string> GetDeletePaths()
 | 
					        public override IEnumerable<string> GetDeletePaths()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new[] { Path };
 | 
					            return new[] { Path };
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,21 @@ namespace MediaBrowser.Controller.Entities
 | 
				
			|||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override IEnumerable<Guid> GetIdsForAncestorQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var list = new List<Guid>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (DisplayParentId != Guid.Empty)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                list.Add(DisplayParentId);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (ParentId != Guid.Empty)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                list.Add(ParentId);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return list;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        public override Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
 | 
					        public override Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var parent = this as Folder;
 | 
					            var parent = this as Folder;
 | 
				
			||||||
 | 
				
			|||||||
@ -549,7 +549,17 @@ namespace MediaBrowser.Controller.Library
 | 
				
			|||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="query">The query.</param>
 | 
					        /// <param name="query">The query.</param>
 | 
				
			||||||
        /// <param name="user">The user.</param>
 | 
					        /// <param name="user">The user.</param>
 | 
				
			||||||
 | 
					        /// <param name="parentIds">The parent ids.</param>
 | 
				
			||||||
        /// <returns>List<BaseItem>.</returns>
 | 
					        /// <returns>List<BaseItem>.</returns>
 | 
				
			||||||
        IEnumerable<BaseItem> GetItems(InternalItemsQuery query, User user);
 | 
					        IEnumerable<BaseItem> GetItems(InternalItemsQuery query, User user, IEnumerable<string> parentIds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Gets the items result.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="query">The query.</param>
 | 
				
			||||||
 | 
					        /// <param name="user">The user.</param>
 | 
				
			||||||
 | 
					        /// <param name="parentIds">The parent ids.</param>
 | 
				
			||||||
 | 
					        /// <returns>QueryResult<BaseItem>.</returns>
 | 
				
			||||||
 | 
					        QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query, User user, IEnumerable<string> parentIds);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -217,5 +217,14 @@ namespace MediaBrowser.Controller.LiveTv
 | 
				
			|||||||
                return base.SupportsPeople;
 | 
					                return base.SupportsPeople;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [IgnoreDataMember]
 | 
				
			||||||
 | 
					        public override bool SupportsAncestors
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -176,6 +176,13 @@ namespace MediaBrowser.Controller.Persistence
 | 
				
			|||||||
        /// <param name="query">The query.</param>
 | 
					        /// <param name="query">The query.</param>
 | 
				
			||||||
        /// <returns>QueryResult<Tuple<Guid, System.String>>.</returns>
 | 
					        /// <returns>QueryResult<Tuple<Guid, System.String>>.</returns>
 | 
				
			||||||
        QueryResult<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query);
 | 
					        QueryResult<Tuple<Guid, string>> GetItemIdsWithPath(InternalItemsQuery query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Gets the item list.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="query">The query.</param>
 | 
				
			||||||
 | 
					        /// <returns>List<BaseItem>.</returns>
 | 
				
			||||||
 | 
					        IEnumerable<BaseItem> GetItemList(InternalItemsQuery query);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -481,23 +481,17 @@ namespace MediaBrowser.Dlna.ContentDirectory
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private QueryResult<ServerItem> GetItemsFromPerson(Person person, User user, int? startIndex, int? limit)
 | 
					        private QueryResult<ServerItem> GetItemsFromPerson(Person person, User user, int? startIndex, int? limit)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var itemsWithPerson = _libraryManager.GetItems(new InternalItemsQuery
 | 
					            var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Person = person.Name
 | 
					                Person = person.Name,
 | 
				
			||||||
 | 
					                IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name, typeof(ChannelVideoItem).Name },
 | 
				
			||||||
 | 
					                SortBy = new[] { ItemSortBy.SortName },
 | 
				
			||||||
 | 
					                Limit = limit,
 | 
				
			||||||
 | 
					                StartIndex = startIndex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }).Items;
 | 
					            }, user, new string[] { });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var items = itemsWithPerson
 | 
					            var serverItems = itemsResult.Items.Select(i => new ServerItem
 | 
				
			||||||
                .Where(i => i is Movie || i is Series || i is IChannelItem)
 | 
					 | 
				
			||||||
                .Where(i => i.IsVisibleStandalone(user))
 | 
					 | 
				
			||||||
                .ToList();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            items = _libraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending)
 | 
					 | 
				
			||||||
                .Skip(startIndex ?? 0)
 | 
					 | 
				
			||||||
                .Take(limit ?? int.MaxValue)
 | 
					 | 
				
			||||||
                .ToList();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var serverItems = items.Select(i => new ServerItem
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Item = i,
 | 
					                Item = i,
 | 
				
			||||||
                StubType = null
 | 
					                StubType = null
 | 
				
			||||||
@ -506,7 +500,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return new QueryResult<ServerItem>
 | 
					            return new QueryResult<ServerItem>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                TotalRecordCount = serverItems.Length,
 | 
					                TotalRecordCount = itemsResult.TotalRecordCount,
 | 
				
			||||||
                Items = serverItems
 | 
					                Items = serverItems
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -234,6 +234,8 @@ namespace MediaBrowser.Model.Configuration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public string[] Migrations { get; set; }
 | 
					        public string[] Migrations { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int MigrationVersion { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
 | 
					        /// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
@ -583,7 +585,8 @@ namespace MediaBrowser.Model.Configuration
 | 
				
			|||||||
                            Limit = 0,
 | 
					                            Limit = 0,
 | 
				
			||||||
                            Type = ImageType.Thumb
 | 
					                            Type = ImageType.Thumb
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    },
 | 
				
			||||||
 | 
					                    DisabledMetadataFetchers = new []{ "TheMovieDb" }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,7 @@ namespace MediaBrowser.Server.Implementations.Collections
 | 
				
			|||||||
        public Folder GetCollectionsFolder(string userId)
 | 
					        public Folder GetCollectionsFolder(string userId)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return _libraryManager.RootFolder.Children.OfType<ManualCollectionsFolder>()
 | 
					            return _libraryManager.RootFolder.Children.OfType<ManualCollectionsFolder>()
 | 
				
			||||||
 | 
					                .FirstOrDefault() ?? _libraryManager.GetUserRootFolder().Children.OfType<ManualCollectionsFolder>()
 | 
				
			||||||
                .FirstOrDefault();
 | 
					                .FirstOrDefault();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -163,16 +163,11 @@ namespace MediaBrowser.Server.Implementations.Dto
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (person != null)
 | 
					            if (person != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var items = _libraryManager.GetItems(new InternalItemsQuery
 | 
					                var items = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Person = byName.Name
 | 
					                    Person = byName.Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                }).Items;
 | 
					                }, user, new string[] { });
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (user != null)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    return items.Where(i => i.IsVisibleStandalone(user)).ToList();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return items.ToList();
 | 
					                return items.ToList();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -471,8 +466,7 @@ namespace MediaBrowser.Server.Implementations.Dto
 | 
				
			|||||||
                dto.ChildCount = GetChildCount(folder, user);
 | 
					                dto.ChildCount = GetChildCount(folder, user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // These are just far too slow. 
 | 
					                // These are just far too slow. 
 | 
				
			||||||
                // TODO: Disable for CollectionFolder
 | 
					                if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is IChannelItem) && !(folder is ICollectionFolder))
 | 
				
			||||||
                if (!(folder is UserRootFolder) && !(folder is UserView) && !(folder is IChannelItem))
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    SetSpecialCounts(folder, user, dto, fields, syncProgress);
 | 
					                    SetSpecialCounts(folder, user, dto, fields, syncProgress);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -83,13 +83,11 @@ namespace MediaBrowser.Server.Implementations.Intros
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (config.EnableIntrosFromMoviesInLibrary)
 | 
					            if (config.EnableIntrosFromMoviesInLibrary)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var inputItems = _libraryManager.GetItems(new InternalItemsQuery
 | 
					                var inputItems = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    IncludeItemTypes = new[] { typeof(Movie).Name },
 | 
					                    IncludeItemTypes = new[] { typeof(Movie).Name }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    User = user
 | 
					                }, user, new string[]{});
 | 
				
			||||||
 | 
					 | 
				
			||||||
                }).Items;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var itemsWithTrailers = inputItems
 | 
					                var itemsWithTrailers = inputItems
 | 
				
			||||||
                    .Where(i =>
 | 
					                    .Where(i =>
 | 
				
			||||||
 | 
				
			|||||||
@ -727,6 +727,13 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
                        folder = dbItem;
 | 
					                        folder = dbItem;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    //if (folder.ParentId != rootFolder.Id)
 | 
				
			||||||
 | 
					                    //{
 | 
				
			||||||
 | 
					                    //    folder.ParentId = rootFolder.Id;
 | 
				
			||||||
 | 
					                    //    var task = folder.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None);
 | 
				
			||||||
 | 
					                    //    Task.WaitAll(task);
 | 
				
			||||||
 | 
					                    //}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    rootFolder.AddVirtualChild(folder);
 | 
					                    rootFolder.AddVirtualChild(folder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    RegisterItem(folder);
 | 
					                    RegisterItem(folder);
 | 
				
			||||||
@ -1280,9 +1287,29 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
            return ItemRepository.GetItemIdsList(query);
 | 
					            return ItemRepository.GetItemIdsList(query);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IEnumerable<BaseItem> GetItems(InternalItemsQuery query, User user)
 | 
					        public IEnumerable<BaseItem> GetItems(InternalItemsQuery query, User user, IEnumerable<string> parentIds)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return GetItemIds(query).Select(GetItemById).Where(i => i.IsVisibleStandalone(user));
 | 
					            var parents = parentIds.Select(i => GetItemById(new Guid(i))).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var items = GetItemIds(query).Select(GetItemById);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (user != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                items = items.Where(i => i.IsVisibleStandalone(user));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return items;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query, User user, IEnumerable<string> parentIds)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var parents = parentIds.Select(i => GetItemById(new Guid(i))).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            query.AncestorIds = parents.SelectMany(i => i.GetIdsForAncestorQuery()).Select(i => i.ToString("N")).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return GetItems(query);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
@ -1719,8 +1746,7 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase))
 | 
					            if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                item.ViewType = viewType;
 | 
					                refresh = true;
 | 
				
			||||||
                await item.UpdateToRepository(ItemUpdateType.MetadataEdit, cancellationToken).ConfigureAwait(false);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!refresh)
 | 
					            if (!refresh)
 | 
				
			||||||
 | 
				
			|||||||
@ -80,15 +80,13 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            var genreList = genres.ToList();
 | 
					            var genreList = genres.ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var inputItems = _libraryManager.GetItems(new InternalItemsQuery
 | 
					            var inputItems = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                IncludeItemTypes = new[] { typeof(Audio).Name },
 | 
					                IncludeItemTypes = new[] { typeof(Audio).Name },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Genres = genreList.ToArray(),
 | 
					                Genres = genreList.ToArray()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                User = user
 | 
					            }, user, new string[] { });
 | 
				
			||||||
 | 
					 | 
				
			||||||
            }).Items;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var genresDictionary = genreList.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
 | 
					            var genresDictionary = genreList.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -162,12 +162,12 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
                NameContains = searchTerm,
 | 
					                NameContains = searchTerm,
 | 
				
			||||||
                ExcludeItemTypes = excludeItemTypes.ToArray(),
 | 
					                ExcludeItemTypes = excludeItemTypes.ToArray(),
 | 
				
			||||||
                IncludeItemTypes = includeItemTypes.ToArray(),
 | 
					                IncludeItemTypes = includeItemTypes.ToArray(),
 | 
				
			||||||
                Limit = (query.Limit.HasValue ? (int?)(query.Limit.Value * 3) : null),
 | 
					                Limit = (query.Limit.HasValue ? (int?)(query.Limit.Value * 2) : null),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }).Items;
 | 
					            }, user, new string[] { });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Add search hints based on item name
 | 
					            // Add search hints based on item name
 | 
				
			||||||
            hints.AddRange(mediaItems.Where(i => IncludeInSearch(i) && IsVisible(i, user)).Select(item =>
 | 
					            hints.AddRange(mediaItems.Where(IncludeInSearch).Select(item =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var index = GetIndex(item.Name, searchTerm, terms);
 | 
					                var index = GetIndex(item.Name, searchTerm, terms);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -183,25 +183,6 @@ namespace MediaBrowser.Server.Implementations.Library
 | 
				
			|||||||
            return Task.FromResult(returnValue);
 | 
					            return Task.FromResult(returnValue);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private bool IsVisible(BaseItem item, User user)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (user == null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (item is IItemByName)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var dual = item as IHasDualAccess;
 | 
					 | 
				
			||||||
                if (dual == null || dual.IsAccessedByName)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return item.IsVisibleStandalone(user);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private bool IncludeInSearch(BaseItem item)
 | 
					        private bool IncludeInSearch(BaseItem item)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var episode = item as Episode;
 | 
					            var episode = item as Episode;
 | 
				
			||||||
 | 
				
			|||||||
@ -1357,7 +1357,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            await RefreshRecordings(cancellationToken).ConfigureAwait(false);
 | 
					            await RefreshRecordings(cancellationToken).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var internalQuery = new InternalItemsQuery
 | 
					            var internalQuery = new InternalItemsQuery(user)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }
 | 
					                IncludeItemTypes = new[] { typeof(LiveTvVideoRecording).Name, typeof(LiveTvAudioRecording).Name }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@ -1367,8 +1367,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 | 
				
			|||||||
                internalQuery.ChannelIds = new[] { query.ChannelId };
 | 
					                internalQuery.ChannelIds = new[] { query.ChannelId };
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var queryResult = _libraryManager.GetItems(internalQuery);
 | 
					            var queryResult = _libraryManager.GetItems(internalQuery, user, new string[]{});
 | 
				
			||||||
            IEnumerable<ILiveTvRecording> recordings = queryResult.Items.Cast<ILiveTvRecording>();
 | 
					            IEnumerable<ILiveTvRecording> recordings = queryResult.Cast<ILiveTvRecording>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!string.IsNullOrEmpty(query.Id))
 | 
					            if (!string.IsNullOrEmpty(query.Id))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -1405,12 +1405,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 | 
				
			|||||||
                    .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid);
 | 
					                    .Where(i => _tvDtoService.GetInternalSeriesTimerId(i.ServiceName, i.SeriesTimerId) == guid);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (user != null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var currentUser = user;
 | 
					 | 
				
			||||||
                recordings = recordings.Where(i => i.IsParentalAllowed(currentUser));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            recordings = recordings.OrderByDescending(i => i.StartDate);
 | 
					            recordings = recordings.OrderByDescending(i => i.StartDate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var entityList = recordings.ToList();
 | 
					            var entityList = recordings.ToList();
 | 
				
			||||||
@ -1771,19 +1765,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var now = DateTime.UtcNow;
 | 
					            var now = DateTime.UtcNow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var programs = _libraryManager.GetItems(new InternalItemsQuery
 | 
					            var programs = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
 | 
					                IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
 | 
				
			||||||
                ChannelIds = new[] { id },
 | 
					                ChannelIds = new[] { id },
 | 
				
			||||||
                MaxStartDate = now,
 | 
					                MaxStartDate = now,
 | 
				
			||||||
                MinEndDate = now,
 | 
					                MinEndDate = now,
 | 
				
			||||||
                Limit = 1
 | 
					                Limit = 1,
 | 
				
			||||||
 | 
					                SortBy = new[] { "StartDate"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }).Items.Cast<LiveTvProgram>();
 | 
					            }, user, new string[]{}).Cast<LiveTvProgram>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var currentProgram = programs
 | 
					            var currentProgram = programs.FirstOrDefault();
 | 
				
			||||||
                .OrderBy(i => i.StartDate)
 | 
					 | 
				
			||||||
                .FirstOrDefault();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var dto = _tvDtoService.GetChannelInfoDto(channel, new DtoOptions(), currentProgram, user);
 | 
					            var dto = _tvDtoService.GetChannelInfoDto(channel, new DtoOptions(), currentProgram, user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1796,19 +1789,18 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var now = DateTime.UtcNow;
 | 
					            var now = DateTime.UtcNow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var programs = _libraryManager.GetItems(new InternalItemsQuery
 | 
					            var programs = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
 | 
					                IncludeItemTypes = new[] { typeof(LiveTvProgram).Name },
 | 
				
			||||||
                ChannelIds = new[] { channel.Id.ToString("N") },
 | 
					                ChannelIds = new[] { channel.Id.ToString("N") },
 | 
				
			||||||
                MaxStartDate = now,
 | 
					                MaxStartDate = now,
 | 
				
			||||||
                MinEndDate = now,
 | 
					                MinEndDate = now,
 | 
				
			||||||
                Limit = 1
 | 
					                Limit = 1,
 | 
				
			||||||
 | 
					                SortBy = new[] { "StartDate" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }).Items.Cast<LiveTvProgram>();
 | 
					            }, user, new string []{}).Cast<LiveTvProgram>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var currentProgram = programs
 | 
					            var currentProgram = programs.FirstOrDefault();
 | 
				
			||||||
                .OrderBy(i => i.StartDate)
 | 
					 | 
				
			||||||
                .FirstOrDefault();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (currentProgram != null)
 | 
					            if (currentProgram != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
        private readonly IServerConfigurationManager _config;
 | 
					        private readonly IServerConfigurationManager _config;
 | 
				
			||||||
        private readonly IFileSystem _fileSystem;
 | 
					        private readonly IFileSystem _fileSystem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public const int MigrationVersion = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem)
 | 
					        public CleanDatabaseScheduledTask(ILibraryManager libraryManager, IItemRepository itemRepo, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _libraryManager = libraryManager;
 | 
					            _libraryManager = libraryManager;
 | 
				
			||||||
@ -121,6 +123,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                _config.SaveConfiguration();
 | 
					                _config.SaveConfiguration();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (_config.Configuration.MigrationVersion < MigrationVersion)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _config.Configuration.MigrationVersion = MigrationVersion;
 | 
				
			||||||
 | 
					                _config.SaveConfiguration();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            progress.Report(100);
 | 
					            progress.Report(100);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -77,7 +77,10 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
        private IDbCommand _deleteStreamsCommand;
 | 
					        private IDbCommand _deleteStreamsCommand;
 | 
				
			||||||
        private IDbCommand _saveStreamCommand;
 | 
					        private IDbCommand _saveStreamCommand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private const int LatestSchemaVersion = 17;
 | 
					        private IDbCommand _deleteAncestorsCommand;
 | 
				
			||||||
 | 
					        private IDbCommand _saveAncestorCommand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private const int LatestSchemaVersion = 18;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
 | 
					        /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
 | 
				
			||||||
@ -126,8 +129,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            string[] queries = {
 | 
					            string[] queries = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB)",
 | 
					                                "create table if not exists TypedBaseItems (guid GUID primary key, type TEXT, data BLOB, ParentId GUID)",
 | 
				
			||||||
                                "create index if not exists idx_TypedBaseItems on TypedBaseItems(guid)",
 | 
					                                "create index if not exists idx_TypedBaseItems on TypedBaseItems(guid)",
 | 
				
			||||||
 | 
					                                "create index if not exists idx_ParentIdTypedBaseItems on TypedBaseItems(ParentId)",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                "create table if not exists AncestorIds (ItemId GUID, AncestorId GUID, PRIMARY KEY (ItemId, AncestorId))",
 | 
				
			||||||
 | 
					                                "create index if not exists idx_AncestorIds on AncestorIds(ItemId,AncestorId)",
 | 
				
			||||||
                                
 | 
					                                
 | 
				
			||||||
                                "create table if not exists ChildrenIds (ParentId GUID, ItemId GUID, PRIMARY KEY (ParentId, ItemId))",
 | 
					                                "create table if not exists ChildrenIds (ParentId GUID, ItemId GUID, PRIMARY KEY (ParentId, ItemId))",
 | 
				
			||||||
                                "create index if not exists idx_ChildrenIds on ChildrenIds(ParentId,ItemId)",
 | 
					                                "create index if not exists idx_ChildrenIds on ChildrenIds(ParentId,ItemId)",
 | 
				
			||||||
@ -205,6 +212,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
            _connection.AddColumn(_logger, "TypedBaseItems", "Studios", "Text");
 | 
					            _connection.AddColumn(_logger, "TypedBaseItems", "Studios", "Text");
 | 
				
			||||||
            _connection.AddColumn(_logger, "TypedBaseItems", "Audio", "Text");
 | 
					            _connection.AddColumn(_logger, "TypedBaseItems", "Audio", "Text");
 | 
				
			||||||
            _connection.AddColumn(_logger, "TypedBaseItems", "ExternalServiceId", "Text");
 | 
					            _connection.AddColumn(_logger, "TypedBaseItems", "ExternalServiceId", "Text");
 | 
				
			||||||
 | 
					            _connection.AddColumn(_logger, "TypedBaseItems", "Tags", "Text");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PrepareStatements();
 | 
					            PrepareStatements();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -429,7 +437,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                "LockedFields",
 | 
					                "LockedFields",
 | 
				
			||||||
                "Studios",
 | 
					                "Studios",
 | 
				
			||||||
                "Audio",
 | 
					                "Audio",
 | 
				
			||||||
                "ExternalServiceId"
 | 
					                "ExternalServiceId",
 | 
				
			||||||
 | 
					                "Tags"
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            _saveItemCommand = _connection.CreateCommand();
 | 
					            _saveItemCommand = _connection.CreateCommand();
 | 
				
			||||||
            _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
 | 
					            _saveItemCommand.CommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
 | 
				
			||||||
@ -473,6 +482,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
            _savePersonCommand.Parameters.Add(_savePersonCommand, "@SortOrder");
 | 
					            _savePersonCommand.Parameters.Add(_savePersonCommand, "@SortOrder");
 | 
				
			||||||
            _savePersonCommand.Parameters.Add(_savePersonCommand, "@ListOrder");
 | 
					            _savePersonCommand.Parameters.Add(_savePersonCommand, "@ListOrder");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					            // Ancestors
 | 
				
			||||||
 | 
					            _deleteAncestorsCommand = _connection.CreateCommand();
 | 
				
			||||||
 | 
					            _deleteAncestorsCommand.CommandText = "delete from AncestorIds where ItemId=@Id";
 | 
				
			||||||
 | 
					            _deleteAncestorsCommand.Parameters.Add(_deleteAncestorsCommand, "@Id");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _saveAncestorCommand = _connection.CreateCommand();
 | 
				
			||||||
 | 
					            _saveAncestorCommand.CommandText = "insert into AncestorIds (ItemId, AncestorId) values (@ItemId, @AncestorId)";
 | 
				
			||||||
 | 
					            _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@ItemId");
 | 
				
			||||||
 | 
					            _saveAncestorCommand.Parameters.Add(_saveAncestorCommand, "@AncestorId");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Chapters
 | 
					            // Chapters
 | 
				
			||||||
            _deleteChaptersCommand = _connection.CreateCommand();
 | 
					            _deleteChaptersCommand = _connection.CreateCommand();
 | 
				
			||||||
            _deleteChaptersCommand.CommandText = "delete from " + ChaptersTableName + " where ItemId=@ItemId";
 | 
					            _deleteChaptersCommand.CommandText = "delete from " + ChaptersTableName + " where ItemId=@ItemId";
 | 
				
			||||||
@ -682,9 +701,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                        _saveItemCommand.GetParameter(index++).Value = null;
 | 
					                        _saveItemCommand.GetParameter(index++).Value = null;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    _saveItemCommand.GetParameter(index++).Value = string.Join("|", item.Tags.ToArray());
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
                    _saveItemCommand.Transaction = transaction;
 | 
					                    _saveItemCommand.Transaction = transaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    _saveItemCommand.ExecuteNonQuery();
 | 
					                    _saveItemCommand.ExecuteNonQuery();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (item.SupportsAncestors)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        UpdateAncestors(item.Id, item.GetAncestorIds().Distinct().ToList(), transaction);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                transaction.Commit();
 | 
					                transaction.Commit();
 | 
				
			||||||
@ -765,22 +791,32 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            BaseItem item;
 | 
					            BaseItem item = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var stream = reader.GetMemoryStream(1))
 | 
					            using (var stream = reader.GetMemoryStream(1))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    item = _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem;
 | 
					                    item = _jsonSerializer.DeserializeFromStream(stream, type) as BaseItem;
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (item == null)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        return null;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (SerializationException ex)
 | 
					                catch (SerializationException ex)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    _logger.ErrorException("Error deserializing item", ex);
 | 
					                    _logger.ErrorException("Error deserializing item", ex);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (item == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        item = Activator.CreateInstance(type) as BaseItem;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (item == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    return null;
 | 
					                    return null;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1328,6 +1364,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                cmd.Parameters.Add(cmd, "@ParentId", DbType.Guid).Value = parentId;
 | 
					                cmd.Parameters.Add(cmd, "@ParentId", DbType.Guid).Value = parentId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //_logger.Debug(cmd.CommandText);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
 | 
					                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    while (reader.Read())
 | 
					                    while (reader.Read())
 | 
				
			||||||
@ -1373,6 +1411,50 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<BaseItem> GetItemList(InternalItemsQuery query)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (query == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("query");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CheckDisposed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using (var cmd = _connection.CreateCommand())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                cmd.CommandText = "select " + string.Join(",", _retriveItemColumns) + " from TypedBaseItems";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var whereClauses = GetWhereClauses(query, cmd, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var whereText = whereClauses.Count == 0 ?
 | 
				
			||||||
 | 
					                    string.Empty :
 | 
				
			||||||
 | 
					                    " where " + string.Join(" AND ", whereClauses.ToArray());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                cmd.CommandText += whereText;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                cmd.CommandText += GetOrderByText(query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (query.Limit.HasValue)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(CultureInfo.InvariantCulture);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //_logger.Debug(cmd.CommandText);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    while (reader.Read())
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var item = GetItem(reader);
 | 
				
			||||||
 | 
					                        if (item != null)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            yield return item;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public QueryResult<BaseItem> GetItems(InternalItemsQuery query)
 | 
					        public QueryResult<BaseItem> GetItems(InternalItemsQuery query)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (query == null)
 | 
					            if (query == null)
 | 
				
			||||||
@ -1453,6 +1535,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private string MapOrderByField(string name)
 | 
					        private string MapOrderByField(string name)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if (string.Equals(name, "airtime", StringComparison.OrdinalIgnoreCase))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // TODO
 | 
				
			||||||
 | 
					                return "SortName";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return name;
 | 
					            return name;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1813,6 +1901,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (query.AncestorIds.Length == 1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                whereClauses.Add("Guid in (select itemId from AncestorIds where AncestorId=@AncestorId)");
 | 
				
			||||||
 | 
					                cmd.Parameters.Add(cmd, "@AncestorId", DbType.Guid).Value = new Guid(query.AncestorIds[0]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (query.AncestorIds.Length > 1)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var inClause = string.Join(",", query.AncestorIds.Select(i => "'" + i + "'").ToArray());
 | 
				
			||||||
 | 
					                whereClauses.Add(string.Format("Guid in (select itemId from AncestorIds where AncestorId in ({0}))", inClause));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (addPaging)
 | 
					            if (addPaging)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (query.StartIndex.HasValue && query.StartIndex.Value > 0)
 | 
					                if (query.StartIndex.HasValue && query.StartIndex.Value > 0)
 | 
				
			||||||
@ -1847,6 +1946,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
            typeof(Movie),
 | 
					            typeof(Movie),
 | 
				
			||||||
            typeof(BoxSet),
 | 
					            typeof(BoxSet),
 | 
				
			||||||
            typeof(Episode),
 | 
					            typeof(Episode),
 | 
				
			||||||
 | 
					            typeof(ChannelVideoItem),
 | 
				
			||||||
            typeof(Season),
 | 
					            typeof(Season),
 | 
				
			||||||
            typeof(Series),
 | 
					            typeof(Series),
 | 
				
			||||||
            typeof(Book),
 | 
					            typeof(Book),
 | 
				
			||||||
@ -1934,6 +2034,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
                _deleteStreamsCommand.Transaction = transaction;
 | 
					                _deleteStreamsCommand.Transaction = transaction;
 | 
				
			||||||
                _deleteStreamsCommand.ExecuteNonQuery();
 | 
					                _deleteStreamsCommand.ExecuteNonQuery();
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
 | 
					                // Delete ancestors
 | 
				
			||||||
 | 
					                _deleteAncestorsCommand.GetParameter(0).Value = id;
 | 
				
			||||||
 | 
					                _deleteAncestorsCommand.Transaction = transaction;
 | 
				
			||||||
 | 
					                _deleteAncestorsCommand.ExecuteNonQuery();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Delete the item
 | 
					                // Delete the item
 | 
				
			||||||
                _deleteItemCommand.GetParameter(0).Value = id;
 | 
					                _deleteItemCommand.GetParameter(0).Value = id;
 | 
				
			||||||
                _deleteItemCommand.Transaction = transaction;
 | 
					                _deleteItemCommand.Transaction = transaction;
 | 
				
			||||||
@ -2167,6 +2272,37 @@ namespace MediaBrowser.Server.Implementations.Persistence
 | 
				
			|||||||
            return whereClauses;
 | 
					            return whereClauses;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void UpdateAncestors(Guid itemId, List<Guid> ancestorIds, IDbTransaction transaction)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (itemId == Guid.Empty)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("itemId");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (ancestorIds == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new ArgumentNullException("ancestorIds");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CheckDisposed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // First delete 
 | 
				
			||||||
 | 
					            _deleteAncestorsCommand.GetParameter(0).Value = itemId;
 | 
				
			||||||
 | 
					            _deleteAncestorsCommand.Transaction = transaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _deleteAncestorsCommand.ExecuteNonQuery();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var ancestorId in ancestorIds)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _saveAncestorCommand.GetParameter(0).Value = itemId;
 | 
				
			||||||
 | 
					                _saveAncestorCommand.GetParameter(1).Value = ancestorId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _saveAncestorCommand.Transaction = transaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _saveAncestorCommand.ExecuteNonQuery();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task UpdatePeople(Guid itemId, List<PersonInfo> people)
 | 
					        public async Task UpdatePeople(Guid itemId, List<PersonInfo> people)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (itemId == Guid.Empty)
 | 
					            if (itemId == Guid.Empty)
 | 
				
			||||||
 | 
				
			|||||||
@ -264,6 +264,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
 | 
				
			|||||||
        public Folder GetPlaylistsFolder(string userId)
 | 
					        public Folder GetPlaylistsFolder(string userId)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return _libraryManager.RootFolder.Children.OfType<PlaylistsFolder>()
 | 
					            return _libraryManager.RootFolder.Children.OfType<PlaylistsFolder>()
 | 
				
			||||||
 | 
					                .FirstOrDefault() ?? _libraryManager.GetUserRootFolder().Children.OfType<PlaylistsFolder>()
 | 
				
			||||||
                .FirstOrDefault();
 | 
					                .FirstOrDefault();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -36,22 +36,12 @@ namespace MediaBrowser.Server.Implementations.TV
 | 
				
			|||||||
                ? new string[] { }
 | 
					                ? new string[] { }
 | 
				
			||||||
                : new[] { request.ParentId };
 | 
					                : new[] { request.ParentId };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            IEnumerable<Series> items;
 | 
					            var items = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (parentIds.Length == 0)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                items = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                IncludeItemTypes = new[] { typeof(Series).Name },
 | 
					                IncludeItemTypes = new[] { typeof(Series).Name },
 | 
				
			||||||
                SortOrder = SortOrder.Ascending
 | 
					                SortOrder = SortOrder.Ascending
 | 
				
			||||||
 | 
					
 | 
				
			||||||
               }, user).Cast<Series>();
 | 
					            }, user, parentIds).Cast<Series>();
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                items = GetAllLibraryItems(user, parentIds, i => i is Series)
 | 
					 | 
				
			||||||
                   .Cast<Series>();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Avoid implicitly captured closure
 | 
					            // Avoid implicitly captured closure
 | 
				
			||||||
            var episodes = GetNextUpEpisodes(request, user, items);
 | 
					            var episodes = GetNextUpEpisodes(request, user, items);
 | 
				
			||||||
@ -68,9 +58,12 @@ namespace MediaBrowser.Server.Implementations.TV
 | 
				
			|||||||
                throw new ArgumentException("User not found");
 | 
					                throw new ArgumentException("User not found");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var items = parentsFolders
 | 
					            var items = _libraryManager.GetItems(new InternalItemsQuery(user)
 | 
				
			||||||
                .SelectMany(i => i.GetRecursiveChildren(user, s => s is Series))
 | 
					            {
 | 
				
			||||||
                .Cast<Series>();
 | 
					                IncludeItemTypes = new[] { typeof(Series).Name },
 | 
				
			||||||
 | 
					                SortOrder = SortOrder.Ascending
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }, user, parentsFolders.Select(i => i.Id.ToString("N"))).Cast<Series>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Avoid implicitly captured closure
 | 
					            // Avoid implicitly captured closure
 | 
				
			||||||
            var episodes = GetNextUpEpisodes(request, user, items);
 | 
					            var episodes = GetNextUpEpisodes(request, user, items);
 | 
				
			||||||
@ -78,27 +71,6 @@ namespace MediaBrowser.Server.Implementations.TV
 | 
				
			|||||||
            return GetResult(episodes, null, request);
 | 
					            return GetResult(episodes, null, request);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private IEnumerable<BaseItem> GetAllLibraryItems(User user, string[] parentIds, Func<BaseItem, bool> filter)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (parentIds.Length > 0)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return parentIds.SelectMany(i =>
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    var folder = (Folder)_libraryManager.GetItemById(new Guid(i));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    return folder.GetRecursiveChildren(user, filter);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (user == null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                throw new ArgumentException("User not found");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return user.RootFolder.GetRecursiveChildren(user, filter);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable<Series> series)
 | 
					        public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable<Series> series)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Avoid implicitly captured closure
 | 
					            // Avoid implicitly captured closure
 | 
				
			||||||
 | 
				
			|||||||
@ -363,7 +363,7 @@ namespace MediaBrowser.Server.Startup.Common
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            var migrations = new List<IVersionMigration>
 | 
					            var migrations = new List<IVersionMigration>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                new Release5767(ServerConfigurationManager, TaskManager)
 | 
					                new DbMigration(ServerConfigurationManager, TaskManager)
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var task in migrations)
 | 
					            foreach (var task in migrations)
 | 
				
			||||||
 | 
				
			|||||||
@ -72,7 +72,7 @@
 | 
				
			|||||||
    <Compile Include="INativeApp.cs" />
 | 
					    <Compile Include="INativeApp.cs" />
 | 
				
			||||||
    <Compile Include="MbLinkShortcutHandler.cs" />
 | 
					    <Compile Include="MbLinkShortcutHandler.cs" />
 | 
				
			||||||
    <Compile Include="Migrations\IVersionMigration.cs" />
 | 
					    <Compile Include="Migrations\IVersionMigration.cs" />
 | 
				
			||||||
    <Compile Include="Migrations\Release5767.cs" />
 | 
					    <Compile Include="Migrations\DbMigration.cs" />
 | 
				
			||||||
    <Compile Include="Migrations\RenameXmlOptions.cs" />
 | 
					    <Compile Include="Migrations\RenameXmlOptions.cs" />
 | 
				
			||||||
    <Compile Include="NativeEnvironment.cs" />
 | 
					    <Compile Include="NativeEnvironment.cs" />
 | 
				
			||||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
					    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										34
									
								
								MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using MediaBrowser.Common.ScheduledTasks;
 | 
				
			||||||
 | 
					using MediaBrowser.Controller.Configuration;
 | 
				
			||||||
 | 
					using MediaBrowser.Server.Implementations.Persistence;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace MediaBrowser.Server.Startup.Common.Migrations
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class DbMigration : IVersionMigration
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly IServerConfigurationManager _config;
 | 
				
			||||||
 | 
					        private readonly ITaskManager _taskManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DbMigration(IServerConfigurationManager config, ITaskManager taskManager)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config = config;
 | 
				
			||||||
 | 
					            _taskManager = taskManager;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Run()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_config.Configuration.MigrationVersion < CleanDatabaseScheduledTask.MigrationVersion)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Task.Run(async () =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await Task.Delay(2000).ConfigureAwait(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _taskManager.QueueScheduledTask<CleanDatabaseScheduledTask>();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,48 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Threading.Tasks;
 | 
					 | 
				
			||||||
using MediaBrowser.Common.ScheduledTasks;
 | 
					 | 
				
			||||||
using MediaBrowser.Controller.Configuration;
 | 
					 | 
				
			||||||
using MediaBrowser.Server.Implementations.LiveTv;
 | 
					 | 
				
			||||||
using MediaBrowser.Server.Implementations.Persistence;
 | 
					 | 
				
			||||||
using MediaBrowser.Server.Implementations.ScheduledTasks;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace MediaBrowser.Server.Startup.Common.Migrations
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class Release5767 : IVersionMigration
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        private readonly IServerConfigurationManager _config;
 | 
					 | 
				
			||||||
        private readonly ITaskManager _taskManager;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public Release5767(IServerConfigurationManager config, ITaskManager taskManager)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _config = config;
 | 
					 | 
				
			||||||
            _taskManager = taskManager;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public async void Run()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var name = "5767.1";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (_config.Configuration.Migrations.Contains(name, StringComparer.OrdinalIgnoreCase))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Task.Run(async () =>
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                await Task.Delay(3000).ConfigureAwait(false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                _taskManager.QueueScheduledTask<CleanDatabaseScheduledTask>();
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Wait a few minutes before marking this as done. Make sure the server doesn't get restarted.
 | 
					 | 
				
			||||||
            await Task.Delay(300000).ConfigureAwait(false);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            var list = _config.Configuration.Migrations.ToList();
 | 
					 | 
				
			||||||
            list.Add(name);
 | 
					 | 
				
			||||||
            _config.Configuration.Migrations = list.ToArray();
 | 
					 | 
				
			||||||
            _config.SaveConfiguration();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user