Files
git.stella-ops.org/src/StellaOps.Feedser.Storage.Mongo/Documents/DocumentStore.cs

67 lines
2.8 KiB
C#

using Microsoft.Extensions.Logging;
using MongoDB.Driver;
namespace StellaOps.Feedser.Storage.Mongo.Documents;
public sealed class DocumentStore : IDocumentStore
{
private readonly IMongoCollection<DocumentDocument> _collection;
private readonly ILogger<DocumentStore> _logger;
public DocumentStore(IMongoDatabase database, ILogger<DocumentStore> logger)
{
_collection = (database ?? throw new ArgumentNullException(nameof(database)))
.GetCollection<DocumentDocument>(MongoStorageDefaults.Collections.Document);
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<DocumentRecord> UpsertAsync(DocumentRecord record, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(record);
var document = DocumentDocumentExtensions.FromRecord(record);
var filter = Builders<DocumentDocument>.Filter.Eq(x => x.SourceName, record.SourceName)
& Builders<DocumentDocument>.Filter.Eq(x => x.Uri, record.Uri);
var options = new FindOneAndReplaceOptions<DocumentDocument>
{
IsUpsert = true,
ReturnDocument = ReturnDocument.After,
};
var replaced = await _collection.FindOneAndReplaceAsync(filter, document, options, cancellationToken).ConfigureAwait(false);
_logger.LogDebug("Upserted document {Source}/{Uri}", record.SourceName, record.Uri);
return (replaced ?? document).ToRecord();
}
public async Task<DocumentRecord?> FindBySourceAndUriAsync(string sourceName, string uri, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(sourceName);
ArgumentException.ThrowIfNullOrEmpty(uri);
var filter = Builders<DocumentDocument>.Filter.Eq(x => x.SourceName, sourceName)
& Builders<DocumentDocument>.Filter.Eq(x => x.Uri, uri);
var document = await _collection.Find(filter).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
return document?.ToRecord();
}
public async Task<DocumentRecord?> FindAsync(Guid id, CancellationToken cancellationToken)
{
var document = await _collection.Find(x => x.Id == id).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
return document?.ToRecord();
}
public async Task<bool> UpdateStatusAsync(Guid id, string status, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(status);
var update = Builders<DocumentDocument>.Update
.Set(x => x.Status, status)
.Set(x => x.LastModified, DateTime.UtcNow);
var result = await _collection.UpdateOneAsync(x => x.Id == id, update, cancellationToken: cancellationToken).ConfigureAwait(false);
return result.MatchedCount > 0;
}
}