Skip to content

Commit 5fc5072

Browse files
authored
Add search response builder abstraction (#698)
Refactors the search implementations to share their response building logic. This reduces the logic in search providers to prepare for supporting the NuGet V2 protocol. Part of #43
1 parent 87ead98 commit 5fc5072

13 files changed

Lines changed: 308 additions & 300 deletions

src/BaGet.Azure/Search/AzureSearchService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public async Task<DependentsResponse> FindDependentsAsync(
161161

162162
var response = await _searchClient.Documents.SearchAsync<PackageDocument>(query, parameters, cancellationToken: cancellationToken);
163163
var results = response.Results
164-
.Select(r => new DependentResult
164+
.Select(r => new PackageDependent
165165
{
166166
Id = r.Document.Id,
167167
Description = r.Document.Description,
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using BaGet.Core;
5+
using Newtonsoft.Json;
6+
7+
namespace BaGet.Azure
8+
{
9+
public static class PackageEntityExtensions
10+
{
11+
public static Package AsPackage(this PackageEntity entity)
12+
{
13+
return new Package
14+
{
15+
Id = entity.Id,
16+
NormalizedVersionString = entity.NormalizedVersion,
17+
OriginalVersionString = entity.OriginalVersion,
18+
19+
// TODO: Convert to System.Text.Json
20+
Authors = JsonConvert.DeserializeObject<string[]>(entity.Authors),
21+
Description = entity.Description,
22+
Downloads = entity.Downloads,
23+
HasReadme = entity.HasReadme,
24+
HasEmbeddedIcon = entity.HasEmbeddedIcon,
25+
IsPrerelease = entity.IsPrerelease,
26+
Language = entity.Language,
27+
Listed = entity.Listed,
28+
MinClientVersion = entity.MinClientVersion,
29+
Published = entity.Published,
30+
RequireLicenseAcceptance = entity.RequireLicenseAcceptance,
31+
SemVerLevel = (SemVerLevel)entity.SemVerLevel,
32+
Summary = entity.Summary,
33+
Title = entity.Title,
34+
ReleaseNotes = entity.ReleaseNotes,
35+
IconUrl = ParseUri(entity.IconUrl),
36+
LicenseUrl = ParseUri(entity.LicenseUrl),
37+
ProjectUrl = ParseUri(entity.ProjectUrl),
38+
RepositoryUrl = ParseUri(entity.RepositoryUrl),
39+
RepositoryType = entity.RepositoryType,
40+
Tags = JsonConvert.DeserializeObject<string[]>(entity.Tags),
41+
Dependencies = ParseDependencies(entity.Dependencies),
42+
PackageTypes = ParsePackageTypes(entity.PackageTypes),
43+
TargetFrameworks = ParseTargetFrameworks(entity.TargetFrameworks),
44+
};
45+
}
46+
47+
private static Uri ParseUri(string input)
48+
{
49+
return string.IsNullOrEmpty(input) ? null : new Uri(input);
50+
}
51+
52+
private static List<PackageDependency> ParseDependencies(string input)
53+
{
54+
// TODO: Convert to System.Text.Json
55+
return JsonConvert.DeserializeObject<List<DependencyModel>>(input)
56+
.Select(e => new PackageDependency
57+
{
58+
Id = e.Id,
59+
VersionRange = e.VersionRange,
60+
TargetFramework = e.TargetFramework,
61+
})
62+
.ToList();
63+
}
64+
65+
private static List<PackageType> ParsePackageTypes(string input)
66+
{
67+
// TODO: Convert to System.Text.Json
68+
return JsonConvert.DeserializeObject<List<PackageTypeModel>>(input)
69+
.Select(e => new PackageType
70+
{
71+
Name = e.Name,
72+
Version = e.Version
73+
})
74+
.ToList();
75+
}
76+
77+
private static List<TargetFramework> ParseTargetFrameworks(string targetFrameworks)
78+
{
79+
// TODO: Convert to System.Text.Json
80+
return JsonConvert.DeserializeObject<List<string>>(targetFrameworks)
81+
.Select(f => new TargetFramework { Moniker = f })
82+
.ToList();
83+
}
84+
}
85+
}

src/BaGet.Azure/Table/TablePackageService.cs

Lines changed: 6 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using BaGet.Core;
77
using Microsoft.Azure.Cosmos.Table;
88
using Microsoft.Extensions.Logging;
9-
using Newtonsoft.Json;
109
using NuGet.Versioning;
1110

1211
namespace BaGet.Azure
@@ -64,7 +63,7 @@ public async Task<bool> AddDownloadAsync(
6463
id.ToLowerInvariant(),
6564
version.ToNormalizedString().ToLowerInvariant());
6665

67-
var result = await _table.ExecuteAsync(operation);
66+
var result = await _table.ExecuteAsync(operation, cancellationToken);
6867
var entity = result.Result as PackageDownloadsEntity;
6968

7069
if (entity == null)
@@ -80,6 +79,7 @@ public async Task<bool> AddDownloadAsync(
8079
catch (StorageException e)
8180
when (attempt < MaxPreconditionFailures && e.IsPreconditionFailedException())
8281
{
82+
attempt++;
8383
_logger.LogWarning(
8484
e,
8585
$"Retrying due to precondition failure, attempt {{Attempt}} of {MaxPreconditionFailures}..",
@@ -111,10 +111,9 @@ public async Task<bool> ExistsAsync(
111111
version.ToNormalizedString().ToLowerInvariant(),
112112
MinimalColumnSet);
113113

114-
var result = await _table.ExecuteAsync(operation, cancellationToken);
115-
var entity = result.Result as PackageEntity;
114+
var execution = await _table.ExecuteAsync(operation, cancellationToken);
116115

117-
return entity != null;
116+
return execution.Result is PackageEntity;
118117
}
119118

120119
public async Task<IReadOnlyList<Package>> FindAsync(string id, bool includeUnlisted, CancellationToken cancellationToken)
@@ -142,7 +141,7 @@ public async Task<IReadOnlyList<Package>> FindAsync(string id, bool includeUnlis
142141
token = segment.ContinuationToken;
143142

144143
// Write out the properties for each entity returned.
145-
results.AddRange(segment.Results.Select(AsPackage));
144+
results.AddRange(segment.Results.Select(r => r.AsPackage()));
146145
}
147146
while (token != null);
148147

@@ -173,7 +172,7 @@ public async Task<Package> FindOrNullAsync(
173172
return null;
174173
}
175174

176-
return AsPackage(entity);
175+
return entity.AsPackage();
177176
}
178177

179178
public async Task<bool> HardDeletePackageAsync(string id, NuGetVersion version, CancellationToken cancellationToken)
@@ -212,72 +211,5 @@ private async Task<bool> TryUpdatePackageAsync(TableOperation operation, Cancell
212211

213212
return true;
214213
}
215-
216-
private Package AsPackage(PackageEntity entity)
217-
{
218-
var targetFrameworks = JsonConvert.DeserializeObject<List<string>>(entity.TargetFrameworks)
219-
.Select(f => new TargetFramework { Moniker = f })
220-
.ToList();
221-
222-
return new Package
223-
{
224-
Id = entity.Id,
225-
NormalizedVersionString = entity.NormalizedVersion,
226-
OriginalVersionString = entity.OriginalVersion,
227-
228-
Authors = JsonConvert.DeserializeObject<string[]>(entity.Authors),
229-
Description = entity.Description,
230-
Downloads = entity.Downloads,
231-
HasReadme = entity.HasReadme,
232-
HasEmbeddedIcon = entity.HasEmbeddedIcon,
233-
IsPrerelease = entity.IsPrerelease,
234-
Language = entity.Language,
235-
Listed = entity.Listed,
236-
MinClientVersion = entity.MinClientVersion,
237-
Published = entity.Published,
238-
RequireLicenseAcceptance = entity.RequireLicenseAcceptance,
239-
SemVerLevel = (SemVerLevel)entity.SemVerLevel,
240-
Summary = entity.Summary,
241-
Title = entity.Title,
242-
ReleaseNotes = entity.ReleaseNotes,
243-
IconUrl = ParseUri(entity.IconUrl),
244-
LicenseUrl = ParseUri(entity.LicenseUrl),
245-
ProjectUrl = ParseUri(entity.ProjectUrl),
246-
RepositoryUrl = ParseUri(entity.RepositoryUrl),
247-
RepositoryType = entity.RepositoryType,
248-
Tags = JsonConvert.DeserializeObject<string[]>(entity.Tags),
249-
Dependencies = ParseDependencies(entity.Dependencies),
250-
PackageTypes = ParsePackageTypes(entity.PackageTypes),
251-
TargetFrameworks = targetFrameworks,
252-
};
253-
}
254-
255-
private Uri ParseUri(string input)
256-
{
257-
return string.IsNullOrEmpty(input) ? null : new Uri(input);
258-
}
259-
260-
private List<PackageDependency> ParseDependencies(string input)
261-
{
262-
return JsonConvert.DeserializeObject<List<DependencyModel>>(input)
263-
.Select(e => new PackageDependency
264-
{
265-
Id = e.Id,
266-
VersionRange = e.VersionRange,
267-
TargetFramework = e.TargetFramework,
268-
})
269-
.ToList();
270-
}
271-
272-
private List<PackageType> ParsePackageTypes(string input)
273-
{
274-
return JsonConvert.DeserializeObject<List<PackageTypeModel>>(input)
275-
.Select(e => new PackageType
276-
{
277-
Name = e.Name,
278-
Version = e.Version
279-
})
280-
.ToList();
281-
}
282214
}
283215
}

0 commit comments

Comments
 (0)