Rename Concelier Source modules to Connector
This commit is contained in:
135
src/StellaOps.Concelier.Connector.Ghsa/Internal/GhsaCursor.cs
Normal file
135
src/StellaOps.Concelier.Connector.Ghsa/Internal/GhsaCursor.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MongoDB.Bson;
|
||||
|
||||
namespace StellaOps.Concelier.Connector.Ghsa.Internal;
|
||||
|
||||
internal sealed record GhsaCursor(
|
||||
DateTimeOffset? LastUpdatedExclusive,
|
||||
DateTimeOffset? CurrentWindowStart,
|
||||
DateTimeOffset? CurrentWindowEnd,
|
||||
int NextPage,
|
||||
IReadOnlyCollection<Guid> PendingDocuments,
|
||||
IReadOnlyCollection<Guid> PendingMappings)
|
||||
{
|
||||
private static readonly IReadOnlyCollection<Guid> EmptyGuidList = Array.Empty<Guid>();
|
||||
|
||||
public static GhsaCursor Empty { get; } = new(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
1,
|
||||
EmptyGuidList,
|
||||
EmptyGuidList);
|
||||
|
||||
public BsonDocument ToBsonDocument()
|
||||
{
|
||||
var document = new BsonDocument
|
||||
{
|
||||
["nextPage"] = NextPage,
|
||||
["pendingDocuments"] = new BsonArray(PendingDocuments.Select(id => id.ToString())),
|
||||
["pendingMappings"] = new BsonArray(PendingMappings.Select(id => id.ToString())),
|
||||
};
|
||||
|
||||
if (LastUpdatedExclusive.HasValue)
|
||||
{
|
||||
document["lastUpdatedExclusive"] = LastUpdatedExclusive.Value.UtcDateTime;
|
||||
}
|
||||
|
||||
if (CurrentWindowStart.HasValue)
|
||||
{
|
||||
document["currentWindowStart"] = CurrentWindowStart.Value.UtcDateTime;
|
||||
}
|
||||
|
||||
if (CurrentWindowEnd.HasValue)
|
||||
{
|
||||
document["currentWindowEnd"] = CurrentWindowEnd.Value.UtcDateTime;
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static GhsaCursor FromBson(BsonDocument? document)
|
||||
{
|
||||
if (document is null || document.ElementCount == 0)
|
||||
{
|
||||
return Empty;
|
||||
}
|
||||
|
||||
var lastUpdatedExclusive = document.TryGetValue("lastUpdatedExclusive", out var lastUpdated)
|
||||
? ParseDate(lastUpdated)
|
||||
: null;
|
||||
var windowStart = document.TryGetValue("currentWindowStart", out var windowStartValue)
|
||||
? ParseDate(windowStartValue)
|
||||
: null;
|
||||
var windowEnd = document.TryGetValue("currentWindowEnd", out var windowEndValue)
|
||||
? ParseDate(windowEndValue)
|
||||
: null;
|
||||
var nextPage = document.TryGetValue("nextPage", out var nextPageValue) && nextPageValue.IsInt32
|
||||
? Math.Max(1, nextPageValue.AsInt32)
|
||||
: 1;
|
||||
|
||||
var pendingDocuments = ReadGuidArray(document, "pendingDocuments");
|
||||
var pendingMappings = ReadGuidArray(document, "pendingMappings");
|
||||
|
||||
return new GhsaCursor(
|
||||
lastUpdatedExclusive,
|
||||
windowStart,
|
||||
windowEnd,
|
||||
nextPage,
|
||||
pendingDocuments,
|
||||
pendingMappings);
|
||||
}
|
||||
|
||||
public GhsaCursor WithPendingDocuments(IEnumerable<Guid> ids)
|
||||
=> this with { PendingDocuments = ids?.Distinct().ToArray() ?? EmptyGuidList };
|
||||
|
||||
public GhsaCursor WithPendingMappings(IEnumerable<Guid> ids)
|
||||
=> this with { PendingMappings = ids?.Distinct().ToArray() ?? EmptyGuidList };
|
||||
|
||||
public GhsaCursor WithLastUpdatedExclusive(DateTimeOffset? timestamp)
|
||||
=> this with { LastUpdatedExclusive = timestamp };
|
||||
|
||||
public GhsaCursor WithCurrentWindowStart(DateTimeOffset? timestamp)
|
||||
=> this with { CurrentWindowStart = timestamp };
|
||||
|
||||
public GhsaCursor WithCurrentWindowEnd(DateTimeOffset? timestamp)
|
||||
=> this with { CurrentWindowEnd = timestamp };
|
||||
|
||||
public GhsaCursor WithNextPage(int page)
|
||||
=> this with { NextPage = page < 1 ? 1 : page };
|
||||
|
||||
private static DateTimeOffset? ParseDate(BsonValue value)
|
||||
{
|
||||
return value.BsonType switch
|
||||
{
|
||||
BsonType.DateTime => DateTime.SpecifyKind(value.ToUniversalTime(), DateTimeKind.Utc),
|
||||
BsonType.String when DateTimeOffset.TryParse(value.AsString, out var parsed) => parsed.ToUniversalTime(),
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
private static IReadOnlyCollection<Guid> ReadGuidArray(BsonDocument document, string field)
|
||||
{
|
||||
if (!document.TryGetValue(field, out var value) || value is not BsonArray array)
|
||||
{
|
||||
return EmptyGuidList;
|
||||
}
|
||||
|
||||
var results = new List<Guid>(array.Count);
|
||||
foreach (var element in array)
|
||||
{
|
||||
if (element is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Guid.TryParse(element.ToString(), out var guid))
|
||||
{
|
||||
results.Add(guid);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user