private void Merge(EntityContext context, CatalogPageEntity existing, CatalogPageEntity latest) { if (existing == null) { context.CatalogPages.Add(latest); return; } var commitIdToCommit = existing .CatalogCommits .ToDictionary(x => x.CommitId); foreach (var latestCommit in latest.CatalogCommits) { if (!commitIdToCommit.TryGetValue(latestCommit.CommitId, out var existingCommit)) { latestCommit.CatalogPage = existing; context.CatalogCommits.Add(latestCommit); continue; } if (latestCommit.Count != existingCommit.Count || latestCommit.CatalogLeaves.Count != existingCommit.CatalogLeaves.Count) { throw new InvalidOperationException("The number of catalog leaves cannot change in a commit."); } var packageKeyToLeaf = existingCommit .CatalogLeaves .ToDictionary(x => x.PackageKey); foreach (var latestLeaf in latestCommit.CatalogLeaves) { if (!packageKeyToLeaf.TryGetValue(latestLeaf.PackageKey, out var existingLeaf)) { throw new InvalidOperationException("The packages in a commit cannot change."); } if (latestLeaf.Type != existingLeaf.Type) { throw new InvalidOperationException("The type of a catalog leaf cannot change."); } existingLeaf.RelativePath = latestLeaf.RelativePath; } } }
private async Task <CatalogPageEntity> InitializeAsync( string pageUrl, IReadOnlyList <CatalogEntry> leaves, IReadOnlyDictionary <string, long> identityToPackageKey) { await VerifyExpectedPageUrlAsync(pageUrl); var pageEntity = new CatalogPageEntity { Url = pageUrl, CatalogCommits = new List <CatalogCommitEntity>(), }; var commits = leaves .GroupBy(x => x.CommitTimeStamp.ToUniversalTime()); foreach (var commit in commits) { var commitLeaves = commit.ToList(); // This really only every be one, but there is an oddball: // https://api.nuget.org/v3/catalog0/page868.json, timestamp: 2015-04-17T23:24:26.0796162Z var commitId = string.Join(" ", commit .Select(x => Guid.Parse(x.CommitId)) .OrderBy(x => x) .Distinct() .ToList()); var commitEntity = new CatalogCommitEntity { CatalogPage = pageEntity, CommitId = commitId, CommitTimestamp = commit.Key.UtcTicks, CatalogLeaves = new List <CatalogLeafEntity>(), Count = commitLeaves.Count, }; pageEntity.CatalogCommits.Add(commitEntity); foreach (var leaf in commitLeaves) { var identity = $"{leaf.Id}/{leaf.Version.ToNormalizedString()}"; var packageKey = identityToPackageKey[identity]; if (leaf.Types.Count != 1) { throw new InvalidOperationException($"Found a catalog leaf with {leaf.Types.Count} types instead of 1."); } CatalogLeafType type; if (leaf.IsAddOrUpdate) { type = CatalogLeafType.PackageDetails; } else if (leaf.IsDelete) { type = CatalogLeafType.PackageDelete; } else { throw new InvalidOperationException("Unexpected catalog leaf type."); } var leafEntity = new CatalogLeafEntity { CatalogCommit = commitEntity, PackageKey = packageKey, Type = type, }; await VerifyExpectedLeafUrlAsync(leaf, leafEntity); commitEntity.CatalogLeaves.Add(leafEntity); } } return(pageEntity); }