mirror of https://github.com/Sonarr/Sonarr
Added populate lazy-loading extensions.
This commit is contained in:
parent
88cd6a3213
commit
b133fa9585
|
@ -1,17 +1,22 @@
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Api.Episodes
|
||||
{
|
||||
public class EpisodeModule : NzbDroneRestModule<EpisodeResource>
|
||||
{
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly MediaFileRepository _mediaFileRepository;
|
||||
|
||||
public EpisodeModule(IEpisodeService episodeService)
|
||||
public EpisodeModule(IEpisodeService episodeService, MediaFileRepository mediaFileRepository)
|
||||
: base("/episodes")
|
||||
{
|
||||
_episodeService = episodeService;
|
||||
_mediaFileRepository = mediaFileRepository;
|
||||
|
||||
GetResourceAll = GetEpisodes;
|
||||
}
|
||||
|
@ -25,7 +30,10 @@ namespace NzbDrone.Api.Episodes
|
|||
throw new BadRequestException("seriesId is missing");
|
||||
}
|
||||
|
||||
return ToListResource(() => _episodeService.GetEpisodeBySeries(seriesId.Value));
|
||||
var resource = ToListResource(() => _episodeService.GetEpisodeBySeries(seriesId.Value))
|
||||
.LoadSubtype(e => e.EpisodeFileId, _mediaFileRepository);
|
||||
|
||||
return resource.ToList();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Api.Extensions
|
||||
{
|
||||
public static class LazyExtensions
|
||||
{
|
||||
private static readonly ICached<MethodInfo> SetterCache = new Cached<MethodInfo>();
|
||||
|
||||
public static IEnumerable<TParent> LoadSubtype<TParent, TChild>(this IEnumerable<TParent> parents, Func<TParent, int> foreignKeySelector, IBasicRepository<TChild> childRepository)
|
||||
where TChild : ModelBase, new()
|
||||
where TParent : RestResource
|
||||
{
|
||||
var parentList = parents.Where(p => foreignKeySelector(p) != 0).ToList();
|
||||
|
||||
if (!parentList.Any())
|
||||
{
|
||||
return parents;
|
||||
}
|
||||
|
||||
var ids = parentList.Select(foreignKeySelector).Distinct();
|
||||
var childDictionary = childRepository.Get(ids).ToDictionary(child => child.Id, child => child);
|
||||
|
||||
var childSetter = GetChildSetter<TParent, TChild>();
|
||||
|
||||
foreach (var episode in parentList)
|
||||
{
|
||||
childSetter.Invoke(episode, new object[] { childDictionary[foreignKeySelector(episode)] });
|
||||
}
|
||||
|
||||
return parents;
|
||||
}
|
||||
|
||||
|
||||
private static MethodInfo GetChildSetter<TParent, TChild>()
|
||||
where TChild : ModelBase
|
||||
where TParent : RestResource
|
||||
{
|
||||
var key = typeof(TChild).FullName + typeof(TParent).FullName;
|
||||
|
||||
return SetterCache.Get(key, () =>
|
||||
{
|
||||
var property = typeof(TParent).GetProperties().Single(c => c.PropertyType == typeof(TChild));
|
||||
return property.GetSetMethod();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -86,6 +86,9 @@
|
|||
<Reference Include="Microsoft.CSharp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\NzbDrone.Common\Properties\SharedAssemblyInfo.cs">
|
||||
<Link>Properties\SharedAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Authentication\AuthenticationService.cs" />
|
||||
<Compile Include="Authentication\EnableBasicAuthInNancy.cs" />
|
||||
<Compile Include="Authentication\NzbDroneUser.cs" />
|
||||
|
@ -111,6 +114,7 @@
|
|||
<Compile Include="Indexers\IndexerModule.cs" />
|
||||
<Compile Include="Indexers\IndexerResource.cs" />
|
||||
<Compile Include="Indexers\ReleaseModule.cs" />
|
||||
<Compile Include="Extensions\LazyExtensions.cs" />
|
||||
<Compile Include="Mapping\CloneInjection.cs" />
|
||||
<Compile Include="Mapping\MappingValidation.cs" />
|
||||
<Compile Include="Mapping\ResourceMappingException.cs" />
|
||||
|
|
|
@ -2,36 +2,10 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("NzbDrone.Api")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("NzbDrone.Api")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("4c0922d7-979e-4ff7-b44b-b8ac2100eeb5")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ using Marr.Data;
|
|||
using Marr.Data.QGen;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Common;
|
||||
|
||||
|
||||
namespace NzbDrone.Core.Datastore
|
||||
|
@ -79,12 +80,14 @@ namespace NzbDrone.Core.Datastore
|
|||
|
||||
public IEnumerable<TModel> Get(IEnumerable<int> ids)
|
||||
{
|
||||
var idList = ids.ToList();
|
||||
var result = Query.Where(String.Format("Id IN ({0})", String.Join(",", idList))).ToList();
|
||||
var resultCount = result.Count;
|
||||
var query = String.Format("Id IN ({0})", String.Join(",", ids));
|
||||
|
||||
if (resultCount != idList.Count || result.Select(r => r.Id).Distinct().Count() != resultCount)
|
||||
throw new InvalidOperationException("Unexpected result from query");
|
||||
var result = Query.Where(query).ToList();
|
||||
|
||||
if (result.Count != ids.Count())
|
||||
{
|
||||
throw new ApplicationException("Expected query to return {0} rows but returned {1}".Inject(ids.Count(), result.Count));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue