From 3d86e2739603a5502b5853a5cf7706898eacbe92 Mon Sep 17 00:00:00 2001 From: Richard Simpson Date: Mon, 28 Sep 2015 11:18:30 -0500 Subject: [PATCH] (GH-431) Update Nuget List to use IQueryable as far down as makes sense. Updated Nuget List to attempt to use IQueryable all the way down for queries executed against service based repositories. This allows chocolatey to defer filtering, sorting, and paging to the server rather than the client. Reverts back to the old logic, though, for everything else. --- .../infrastructure.app/nuget/NugetList.cs | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/src/chocolatey/infrastructure.app/nuget/NugetList.cs b/src/chocolatey/infrastructure.app/nuget/NugetList.cs index 88c573311e..b11458b96e 100644 --- a/src/chocolatey/infrastructure.app/nuget/NugetList.cs +++ b/src/chocolatey/infrastructure.app/nuget/NugetList.cs @@ -17,6 +17,7 @@ namespace chocolatey.infrastructure.app.nuget { using System.Collections.Generic; using System.Linq; + using NuGet; using configuration; @@ -25,13 +26,42 @@ namespace chocolatey.infrastructure.app.nuget public static class NugetList { public static IEnumerable GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger) + { + return execute_package_search(configuration, nugetLogger); + } + + private static IQueryable execute_package_search(ChocolateyConfiguration configuration, ILogger nugetLogger) { var packageRepository = NugetCommon.GetRemoteRepository(configuration, nugetLogger); + + // Whether or not the package is remote determines two things: + // 1. Does the repository have a notion of "listed"? + // 2. Does it support prerelease in a straight-forward way? + // Choco previously dealt with this by taking the path of least resistance and manually filtering out and sort unwanted packages + // This result in blocking operations that didn't let service based repositories, like OData, take care of heavy lifting on the server. + bool isRemote; + var aggregateRepo = packageRepository as AggregateRepository; + if (aggregateRepo != null) + { + isRemote = aggregateRepo.Repositories.All(repo => repo is IServiceBasedRepository); + } + else + { + isRemote = packageRepository is IServiceBasedRepository; + } + IQueryable results = packageRepository.Search(configuration.Input, configuration.Prerelease); if (configuration.AllVersions) { - return results.Where(PackageExtensions.IsListed).OrderBy(p => p.Id); + if (isRemote) + { + return results.OrderBy(p => p.Id); + } + else + { + return results.Where(PackageExtensions.IsListed).OrderBy(p => p.Id).AsQueryable(); + } } if (configuration.Prerelease && packageRepository.SupportsPrereleasePackages) @@ -43,17 +73,25 @@ public static IEnumerable GetPackages(ChocolateyConfiguration configur results = results.Where(p => p.IsLatestVersion); } + if (!isRemote) + { + results = + results + .Where(PackageExtensions.IsListed) + .Where(p => configuration.Prerelease || p.IsReleaseVersion()) + .distinct_last(PackageEqualityComparer.Id, PackageComparer.Version) + .AsQueryable(); + } + if (configuration.ListCommand.Page.HasValue) { results = results.Skip(configuration.ListCommand.PageSize * configuration.ListCommand.Page.Value).Take(configuration.ListCommand.PageSize); } - return results.OrderBy(p => p.Id) - .AsEnumerable() - .Where(PackageExtensions.IsListed) - .Where(p => configuration.Prerelease || p.IsReleaseVersion()) - .distinct_last(PackageEqualityComparer.Id, PackageComparer.Version); - } + return results.OrderBy(p => p.Id); + } + + } // ReSharper restore InconsistentNaming