mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-05 07:18:47 +01:00
switch to flat file storage
This commit is contained in:
@@ -73,11 +73,6 @@ namespace MediaBrowser.Controller.Dto
|
||||
tasks.Add(AttachPeople(dto, item));
|
||||
}
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
tasks.Add(AttachUserSpecificInfo(dto, item, user, fields));
|
||||
}
|
||||
|
||||
if (fields.Contains(ItemFields.PrimaryImageAspectRatio))
|
||||
{
|
||||
try
|
||||
@@ -91,6 +86,11 @@ namespace MediaBrowser.Controller.Dto
|
||||
}
|
||||
}
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
AttachUserSpecificInfo(dto, item, user, fields);
|
||||
}
|
||||
|
||||
AttachBasicFields(dto, item, fields);
|
||||
|
||||
// Make sure all the tasks we kicked off have completed.
|
||||
@@ -109,7 +109,7 @@ namespace MediaBrowser.Controller.Dto
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="fields">The fields.</param>
|
||||
private async Task AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List<ItemFields> fields)
|
||||
private void AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, List<ItemFields> fields)
|
||||
{
|
||||
if (item.IsFolder && fields.Contains(ItemFields.DisplayPreferencesId))
|
||||
{
|
||||
@@ -127,13 +127,13 @@ namespace MediaBrowser.Controller.Dto
|
||||
// Skip sorting since all we want is a count
|
||||
dto.ChildCount = folder.GetChildren(user).Count();
|
||||
|
||||
await SetSpecialCounts(folder, user, dto, _userDataRepository).ConfigureAwait(false);
|
||||
SetSpecialCounts(folder, user, dto, _userDataRepository);
|
||||
}
|
||||
}
|
||||
|
||||
if (addUserData)
|
||||
{
|
||||
var userData = await _userDataRepository.GetUserData(user.Id, item.GetUserDataKey()).ConfigureAwait(false);
|
||||
var userData = _userDataRepository.GetUserData(user.Id, item.GetUserDataKey());
|
||||
|
||||
dto.UserData = GetUserItemDataDto(userData);
|
||||
|
||||
@@ -529,7 +529,7 @@ namespace MediaBrowser.Controller.Dto
|
||||
/// <param name="dto">The dto.</param>
|
||||
/// <param name="userDataRepository">The user data repository.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private static async Task SetSpecialCounts(Folder folder, User user, BaseItemDto dto, IUserDataRepository userDataRepository)
|
||||
private static void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, IUserDataRepository userDataRepository)
|
||||
{
|
||||
var rcentlyAddedItemCount = 0;
|
||||
var recursiveItemCount = 0;
|
||||
@@ -540,7 +540,7 @@ namespace MediaBrowser.Controller.Dto
|
||||
// Loop through each recursive child
|
||||
foreach (var child in folder.GetRecursiveChildren(user).Where(i => !i.IsFolder).ToList())
|
||||
{
|
||||
var userdata = await userDataRepository.GetUserData(user.Id, child.GetUserDataKey()).ConfigureAwait(false);
|
||||
var userdata = userDataRepository.GetUserData(user.Id, child.GetUserDataKey());
|
||||
|
||||
recursiveItemCount++;
|
||||
|
||||
@@ -767,7 +767,7 @@ namespace MediaBrowser.Controller.Dto
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
throw new ArgumentNullException("data");
|
||||
}
|
||||
|
||||
return new UserItemDataDto
|
||||
|
||||
@@ -273,7 +273,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (!ResolveArgs.IsDirectory)
|
||||
@@ -681,11 +681,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>List{Video}.</returns>
|
||||
private IEnumerable<Trailer> LoadLocalTrailers()
|
||||
{
|
||||
if (LocationType != LocationType.FileSystem)
|
||||
{
|
||||
return new List<Trailer>();
|
||||
}
|
||||
|
||||
ItemResolveArgs resolveArgs;
|
||||
|
||||
try
|
||||
@@ -737,7 +732,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return LibraryManager.ResolvePaths<Trailer>(files, null).Select(video =>
|
||||
{
|
||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||
var dbItem = LibraryManager.RetrieveItem(video.Id) as Trailer;
|
||||
var dbItem = LibraryManager.RetrieveItem(video.Id, typeof(Trailer)) as Trailer;
|
||||
|
||||
if (dbItem != null)
|
||||
{
|
||||
@@ -756,11 +751,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>List{Audio.Audio}.</returns>
|
||||
private IEnumerable<Audio.Audio> LoadThemeSongs()
|
||||
{
|
||||
if (LocationType != LocationType.FileSystem)
|
||||
{
|
||||
return new List<Audio.Audio>();
|
||||
}
|
||||
|
||||
ItemResolveArgs resolveArgs;
|
||||
|
||||
try
|
||||
@@ -803,7 +793,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return LibraryManager.ResolvePaths<Audio.Audio>(files, null).Select(audio =>
|
||||
{
|
||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||
var dbItem = LibraryManager.RetrieveItem(audio.Id) as Audio.Audio;
|
||||
var dbItem = LibraryManager.RetrieveItem(audio.Id, typeof(Audio.Audio)) as Audio.Audio;
|
||||
|
||||
if (dbItem != null)
|
||||
{
|
||||
@@ -821,11 +811,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>List{Video}.</returns>
|
||||
private IEnumerable<Video> LoadThemeVideos()
|
||||
{
|
||||
if (LocationType != LocationType.FileSystem)
|
||||
{
|
||||
return new List<Video>();
|
||||
}
|
||||
|
||||
ItemResolveArgs resolveArgs;
|
||||
|
||||
try
|
||||
@@ -866,7 +851,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return LibraryManager.ResolvePaths<Video>(files, null).Select(item =>
|
||||
{
|
||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||
var dbItem = LibraryManager.RetrieveItem(item.Id) as Video;
|
||||
var dbItem = LibraryManager.RetrieveItem(item.Id, typeof(Video)) as Video;
|
||||
|
||||
if (dbItem != null)
|
||||
{
|
||||
@@ -896,13 +881,20 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var themeSongsChanged = await RefreshThemeSongs(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
var themeSongsChanged = false;
|
||||
|
||||
var themeVideosChanged = await RefreshThemeVideos(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
var themeVideosChanged = false;
|
||||
|
||||
var localTrailersChanged = await RefreshLocalTrailers(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
var localTrailersChanged = false;
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (LocationType == LocationType.FileSystem && Parent != null)
|
||||
{
|
||||
themeSongsChanged = await RefreshThemeSongs(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
|
||||
themeVideosChanged = await RefreshThemeVideos(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
|
||||
localTrailersChanged = await RefreshLocalTrailers(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
@@ -1096,8 +1088,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
parent = parent.Parent;
|
||||
}
|
||||
|
||||
//not found - load from repo
|
||||
return LibraryManager.RetrieveItem(id);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1315,7 +1306,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
var key = GetUserDataKey();
|
||||
|
||||
var data = await userManager.GetUserData(user.Id, key).ConfigureAwait(false);
|
||||
var data = userManager.GetUserData(user.Id, key);
|
||||
|
||||
if (wasPlayed)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using MediaBrowser.Common.Progress;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Localization;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Reflection;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
@@ -21,6 +22,15 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class Folder : BaseItem
|
||||
{
|
||||
private static TypeMapper _typeMapper = new TypeMapper();
|
||||
|
||||
public Folder()
|
||||
{
|
||||
ChildDefinitions = new ConcurrentDictionary<Guid, string>();
|
||||
}
|
||||
|
||||
public ConcurrentDictionary<Guid, string> ChildDefinitions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is folder.
|
||||
/// </summary>
|
||||
@@ -108,16 +118,14 @@ namespace MediaBrowser.Controller.Entities
|
||||
item.DateModified = DateTime.Now;
|
||||
}
|
||||
|
||||
if (!_children.TryAdd(item.Id, item))
|
||||
if (!_children.TryAdd(item.Id, item) || !ChildDefinitions.TryAdd(item.Id, item.GetType().FullName))
|
||||
{
|
||||
throw new InvalidOperationException("Unable to add " + item.Name);
|
||||
}
|
||||
|
||||
var newChildren = Children.ToList();
|
||||
|
||||
await LibraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await LibraryManager.SaveChildren(Id, newChildren, cancellationToken).ConfigureAwait(false);
|
||||
await LibraryManager.UpdateItem(this, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -145,19 +153,18 @@ namespace MediaBrowser.Controller.Entities
|
||||
public Task RemoveChild(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
BaseItem removed;
|
||||
string removedType;
|
||||
|
||||
if (!_children.TryRemove(item.Id, out removed))
|
||||
if (!_children.TryRemove(item.Id, out removed) || !ChildDefinitions.TryRemove(item.Id, out removedType))
|
||||
{
|
||||
throw new InvalidOperationException("Unable to remove " + item.Name);
|
||||
}
|
||||
|
||||
item.Parent = null;
|
||||
|
||||
var newChildren = Children.ToList();
|
||||
|
||||
LibraryManager.ReportItemRemoved(item);
|
||||
|
||||
return LibraryManager.SaveChildren(Id, newChildren, cancellationToken);
|
||||
return LibraryManager.UpdateItem(this, cancellationToken);
|
||||
}
|
||||
|
||||
#region Indexing
|
||||
@@ -652,7 +659,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
var options = new ParallelOptions
|
||||
{
|
||||
MaxDegreeOfParallelism = 50
|
||||
MaxDegreeOfParallelism = 20
|
||||
};
|
||||
|
||||
Parallel.ForEach(nonCachedChildren, options, child =>
|
||||
@@ -702,6 +709,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
string removedType;
|
||||
ChildDefinitions.TryRemove(item.Id, out removedType);
|
||||
|
||||
LibraryManager.ReportItemRemoved(item);
|
||||
}
|
||||
}
|
||||
@@ -716,11 +726,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
ChildDefinitions.TryAdd(item.Id, item.GetType().FullName);
|
||||
|
||||
Logger.Debug("** " + item.Name + " Added to library.");
|
||||
}
|
||||
}
|
||||
|
||||
await LibraryManager.SaveChildren(Id, newChildren, CancellationToken.None).ConfigureAwait(false);
|
||||
await LibraryManager.UpdateItem(this, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
//force the indexes to rebuild next time
|
||||
IndexCache.Clear();
|
||||
@@ -848,9 +860,38 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Get our children from the repo - stubbed for now
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected virtual IEnumerable<BaseItem> GetCachedChildren()
|
||||
protected IEnumerable<BaseItem> GetCachedChildren()
|
||||
{
|
||||
return LibraryManager.RetrieveChildren(this).Select(i => i is IByReferenceItem ? LibraryManager.GetOrAddByReferenceItem(i) : i);
|
||||
var items = ChildDefinitions.ToList().Select(RetrieveChild).Where(i => i != null).ToList();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
item.Parent = this;
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the child.
|
||||
/// </summary>
|
||||
/// <param name="child">The child.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
private BaseItem RetrieveChild(KeyValuePair<Guid,string> child)
|
||||
{
|
||||
var type = child.Value;
|
||||
|
||||
var itemType = _typeMapper.GetType(type);
|
||||
|
||||
if (itemType == null)
|
||||
{
|
||||
Logger.Error("Cannot find type {0}. Probably belongs to plug-in that is no longer loaded.", type);
|
||||
return null;
|
||||
}
|
||||
|
||||
var item = LibraryManager.RetrieveItem(child.Key, itemType);
|
||||
|
||||
return item is IByReferenceItem ? LibraryManager.GetOrAddByReferenceItem(item) : item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -68,7 +68,14 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
// Kick off a task to refresh the main item
|
||||
var result = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
|
||||
var specialFeaturesChanged = await RefreshSpecialFeatures(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
var specialFeaturesChanged = false;
|
||||
|
||||
// Must have a parent to have special features
|
||||
// In other words, it must be part of the Parent/Child tree
|
||||
if (LocationType == LocationType.FileSystem && Parent != null)
|
||||
{
|
||||
specialFeaturesChanged = await RefreshSpecialFeatures(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return specialFeaturesChanged || result;
|
||||
}
|
||||
@@ -95,11 +102,6 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
/// <returns>IEnumerable{Video}.</returns>
|
||||
private IEnumerable<Video> LoadSpecialFeatures()
|
||||
{
|
||||
if (LocationType != LocationType.FileSystem)
|
||||
{
|
||||
return new List<Video>();
|
||||
}
|
||||
|
||||
FileSystemInfo folder;
|
||||
|
||||
try
|
||||
@@ -133,7 +135,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return LibraryManager.ResolvePaths<Video>(files, null).Select(video =>
|
||||
{
|
||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||
var dbItem = LibraryManager.RetrieveItem(video.Id) as Video;
|
||||
var dbItem = LibraryManager.RetrieveItem(video.Id, typeof(Video)) as Video;
|
||||
|
||||
if (dbItem != null)
|
||||
{
|
||||
|
||||
@@ -139,7 +139,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
var additionalPartsChanged = false;
|
||||
|
||||
if (IsMultiPart && LocationType == LocationType.FileSystem)
|
||||
// Must have a parent to have additional parts
|
||||
// In other words, it must be part of the Parent/Child tree
|
||||
// The additional parts won't have additional parts themselves
|
||||
if (IsMultiPart && LocationType == LocationType.FileSystem && Parent != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -164,11 +167,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>Task{System.Boolean}.</returns>
|
||||
private async Task<bool> RefreshAdditionalParts(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true)
|
||||
{
|
||||
if (!IsMultiPart || LocationType != LocationType.FileSystem)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var newItems = LoadAdditionalParts().ToList();
|
||||
|
||||
var newItemIds = newItems.Select(i => i.Id).ToList();
|
||||
@@ -214,7 +212,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return LibraryManager.ResolvePaths<Video>(files, null).Select(video =>
|
||||
{
|
||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||
var dbItem = LibraryManager.RetrieveItem(video.Id) as Video;
|
||||
var dbItem = LibraryManager.RetrieveItem(video.Id, typeof(Video)) as Video;
|
||||
|
||||
if (dbItem != null)
|
||||
{
|
||||
|
||||
@@ -216,24 +216,9 @@ namespace MediaBrowser.Controller.Library
|
||||
/// Retrieves the item.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>Task{BaseItem}.</returns>
|
||||
BaseItem RetrieveItem(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the children.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="children">The children.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveChildren(Guid id, IEnumerable<BaseItem> children, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the children.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
IEnumerable<BaseItem> RetrieveChildren(Folder parent);
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem RetrieveItem(Guid id, Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Validates the artists.
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
<Compile Include="Library\ILibraryPrescanTask.cs" />
|
||||
<Compile Include="Library\IMetadataSaver.cs" />
|
||||
<Compile Include="Localization\ILocalizationManager.cs" />
|
||||
<Compile Include="Reflection\TypeMapper.cs" />
|
||||
<Compile Include="Session\ISessionManager.cs" />
|
||||
<Compile Include="Drawing\ImageExtensions.cs" />
|
||||
<Compile Include="Drawing\ImageHeader.cs" />
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence
|
||||
{
|
||||
@@ -20,36 +21,6 @@ namespace MediaBrowser.Controller.Persistence
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveItem(BaseItem item, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an item
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem GetItem(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets children of a given Folder
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
IEnumerable<BaseItem> RetrieveChildren(Folder parent);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the items.
|
||||
/// </summary>
|
||||
/// <param name="ids">The ids.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
IEnumerable<BaseItem> GetItems(IEnumerable<Guid> ids);
|
||||
|
||||
/// <summary>
|
||||
/// Saves children of a given Folder
|
||||
/// </summary>
|
||||
/// <param name="parentId">The parent id.</param>
|
||||
/// <param name="children">The children.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveChildren(Guid parentId, IEnumerable<BaseItem> children, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the critic reviews.
|
||||
/// </summary>
|
||||
@@ -72,5 +43,46 @@ namespace MediaBrowser.Controller.Persistence
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SaveItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the item.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem RetrieveItem(Guid id, Type type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class ItemRepositoryExtensions
|
||||
/// </summary>
|
||||
public static class ItemRepositoryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves the item.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="repository">The repository.</param>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>``0.</returns>
|
||||
public static T RetrieveItem<T>(this IItemRepository repository, Guid id)
|
||||
where T : BaseItem, new()
|
||||
{
|
||||
return repository.RetrieveItem(id, typeof(T)) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the item.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="repository">The repository.</param>
|
||||
/// <param name="idList">The id list.</param>
|
||||
/// <returns>IEnumerable{``0}.</returns>
|
||||
public static IEnumerable<T> RetrieveItems<T>(this IItemRepository repository, IEnumerable<Guid> idList)
|
||||
where T : BaseItem, new()
|
||||
{
|
||||
return idList.Select(repository.RetrieveItem<T>).Where(i => i != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,6 @@ namespace MediaBrowser.Controller.Persistence
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns>Task{UserItemData}.</returns>
|
||||
Task<UserItemData> GetUserData(Guid userId, string key);
|
||||
UserItemData GetUserData(Guid userId, string key);
|
||||
}
|
||||
}
|
||||
|
||||
47
MediaBrowser.Controller/Reflection/TypeMapper.cs
Normal file
47
MediaBrowser.Controller/Reflection/TypeMapper.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Controller.Reflection
|
||||
{
|
||||
/// <summary>
|
||||
/// Class TypeMapper
|
||||
/// </summary>
|
||||
public class TypeMapper
|
||||
{
|
||||
/// <summary>
|
||||
/// This holds all the types in the running assemblies so that we can de-serialize properly when we don't have strong types
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<string, Type> _typeMap = new ConcurrentDictionary<string, Type>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type.
|
||||
/// </summary>
|
||||
/// <param name="typeName">Name of the type.</param>
|
||||
/// <returns>Type.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public Type GetType(string typeName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(typeName))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return _typeMap.GetOrAdd(typeName, LookupType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lookups the type.
|
||||
/// </summary>
|
||||
/// <param name="typeName">Name of the type.</param>
|
||||
/// <returns>Type.</returns>
|
||||
private Type LookupType(string typeName)
|
||||
{
|
||||
return AppDomain
|
||||
.CurrentDomain
|
||||
.GetAssemblies()
|
||||
.Select(a => a.GetType(typeName, false))
|
||||
.FirstOrDefault(t => t != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user