67 lines
2.8 KiB
C#
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;
|
|
}
|
|
}
|