async Task <IEnumerable <IPackageSearchMetadata> > GetPackagesWithUpdatesAsync(string searchText, SearchFilter searchFilter, CancellationToken cancellationToken)
        {
            if (_context != null)
            {
                _installedPackages = await _context.GetInstalledPackagesAsync();

                _context = null;
            }

            var packages = _installedPackages
                           .GetEarliest()
                           .Where(p => p.Id.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1)
                           .OrderBy(p => p.Id);

            var latestItems = await TaskCombinators.ThrottledAsync(
                packages,
                (p, t) => _metadataProvider.GetLatestPackageMetadataAsync(p, searchFilter.IncludePrerelease, t),
                cancellationToken);

            var packagesWithUpdates = packages
                                      .Join(latestItems.Where(i => i != null),
                                            p => p.Id,
                                            m => m.Identity.Id,
                                            (p, m) => new { cv = p.Version, m = m },
                                            StringComparer.OrdinalIgnoreCase)
                                      .Where(j => VersionComparer.VersionRelease.Compare(j.cv, j.m.Identity.Version) < 0)
                                      .Select(j => j.m);

            return(packagesWithUpdates);
        }
Example #2
0
        public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken)
        {
            var searchToken = continuationToken as FeedSearchContinuationToken;

            if (searchToken == null)
            {
                throw new InvalidOperationException("Invalid token");
            }

            if (_context != null)
            {
                _installedPackages = await _context.GetInstalledPackagesAsync();

                _context = null;
            }

            var packages = _installedPackages
                           .GetLatest()
                           .Where(p => p.Id.IndexOf(searchToken.SearchString, StringComparison.OrdinalIgnoreCase) != -1)
                           .OrderBy(p => p.Id)
                           .Skip(searchToken.StartIndex)
                           .Take(PageSize + 1)
                           .ToArray();

            var hasMoreItems = packages.Length > PageSize;

            if (hasMoreItems)
            {
                packages = packages.Take(packages.Length - 1).ToArray();
            }

            var items = await TaskCombinators.ThrottledAsync(
                packages,
                (p, t) => GetPackageMetadataAsync (p, searchToken.SearchFilter.IncludePrerelease, t),
                cancellationToken);

            //  The packages were originally sorted which is important because we Skip and Take based on that sort
            //  however the asynchronous execution has randomly reordered the set. So we need to resort.
            var result = SearchResult.FromItems(items.OrderBy(p => p.Identity.Id).ToArray());

            var loadingStatus = hasMoreItems
                                ? LoadingStatus.Ready
                                : packages.Length == 0
                                ? LoadingStatus.NoItemsFound
                                : LoadingStatus.NoMoreItems;

            result.SourceSearchStatus = new Dictionary <string, LoadingStatus> {
                { "Installed", loadingStatus }
            };

            if (hasMoreItems)
            {
                result.NextToken = new FeedSearchContinuationToken {
                    SearchString = searchToken.SearchString,
                    SearchFilter = searchToken.SearchFilter,
                    StartIndex   = searchToken.StartIndex + packages.Length
                };
            }

            return(result);
        }
        public override async Task <SearchResult <IPackageSearchMetadata> > ContinueSearchAsync(ContinuationToken continuationToken, CancellationToken cancellationToken)
        {
            var searchToken = continuationToken as FeedSearchContinuationToken;

            if (searchToken == null)
            {
                throw new InvalidOperationException("Invalid token");
            }

            if (_context != null)
            {
                _installedPackages = await _context.GetInstalledPackagesAsync();

                _context = null;
            }

            var packagesNeedingConsolidation = _installedPackages
                                               .GroupById()
                                               .Where(g => g.Count() > 1)
                                               .Select(g => new PackageIdentity(g.Key, g.Max()))
                                               .ToArray();

            var packages = packagesNeedingConsolidation
                           .Where(p => p.Id.IndexOf(searchToken.SearchString, StringComparison.OrdinalIgnoreCase) != -1)
                           .OrderBy(p => p.Id)
                           .Skip(searchToken.StartIndex)
                           .Take(PageSize + 1)
                           .ToArray();

            var hasMoreItems = packages.Length > PageSize;

            if (hasMoreItems)
            {
                packages = packages.Take(packages.Length - 1).ToArray();
            }

            var items = await TaskCombinators.ThrottledAsync(
                packages,
                (p, t) => _metadataProvider.GetPackageMetadataAsync(p, searchToken.SearchFilter.IncludePrerelease, t),
                cancellationToken);

            var result = SearchResult.FromItems(items.ToArray());

            var loadingStatus = hasMoreItems
                                ? LoadingStatus.Ready
                                : packages.Length == 0
                                ? LoadingStatus.NoItemsFound
                                : LoadingStatus.NoMoreItems;

            result.SourceSearchStatus = new Dictionary <string, LoadingStatus> {
                { "Consolidate", loadingStatus }
            };

            if (hasMoreItems)
            {
                result.NextToken = new FeedSearchContinuationToken {
                    SearchString = searchToken.SearchString,
                    SearchFilter = searchToken.SearchFilter,
                    StartIndex   = searchToken.StartIndex + packages.Length
                };
            }

            return(result);
        }