< Summary

Information
Class: MRA.Infrastructure.Database.Providers.MongoDbDatabase
Assembly: MRA.Infrastructure
File(s): D:\a\MiguelRomerART\MiguelRomerART\MRA.Infrastructure\Database\Providers\MongoDbDatabase.cs
Line coverage
10%
Covered lines: 6
Uncovered lines: 49
Coverable lines: 55
Total lines: 129
Line coverage: 10.9%
Branch coverage
0%
Covered branches: 0
Total branches: 14
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Database()0%2040%
InitializeMongoDb()100%210%
RegisterBsonClass(...)0%620%
GetAllDocumentsAsync()0%620%
GetDocumentAsync()0%620%
GetDocumentType(...)100%210%
DocumentExistsAsync()100%210%
SetDocumentAsync()0%2040%
DeleteDocumentAsync()100%210%

File(s)

D:\a\MiguelRomerART\MiguelRomerART\MRA.Infrastructure\Database\Providers\MongoDbDatabase.cs

#LineLine coverage
 1using DnsClient.Internal;
 2using Microsoft.Extensions.Logging;
 3using MongoDB.Bson;
 4using MongoDB.Bson.Serialization;
 5using MongoDB.Driver;
 6using MRA.Infrastructure.Settings;
 7using MRA.Infrastructure.Database.Documents.Interfaces;
 8using MRA.Infrastructure.Database.Documents.MongoDb;
 9using MRA.Infrastructure.Database.Providers.Interfaces;
 10
 11namespace MRA.Infrastructure.Database.Providers;
 12
 13public class MongoDbDatabase : IDocumentsDatabase
 14{
 15    internal const string ID_FIELD = "_id";
 16
 17    private readonly AppSettings _appConfiguration;
 18    private readonly DocumentTypeRegistry _typeRegistry;
 19    private readonly ILogger<MongoDbDatabase> _logger;
 20
 121    private readonly object _initLock = new object();
 22    private static IMongoDatabase? _database = null;
 23
 24    private IMongoDatabase Database
 25    {
 26        get
 27        {
 028            if (_database == null)
 29            {
 030                lock (_initLock)
 31                {
 032                    if (_database == null)
 33                    {
 034                        InitializeMongoDb();
 35                    }
 036                }
 37            }
 38
 039            return _database;
 40        }
 41    }
 42
 143    public MongoDbDatabase(AppSettings appConfig, ILogger<MongoDbDatabase> logger)
 44    {
 145        _appConfiguration = appConfig;
 146        _logger = logger;
 147        _typeRegistry = new DocumentTypeRegistry(appConfig);
 148    }
 49
 50    private void InitializeMongoDb()
 51    {
 052        _logger.LogInformation("Initializing MongoDb Database. Registering document classes.");
 053        RegisterBsonClass(typeof(InspirationMongoDocument));
 054        RegisterBsonClass(typeof(DrawingMongoDocument));
 055        RegisterBsonClass(typeof(CollectionMongoDocument));
 56
 057        var mongoClient = new MongoClient(_appConfiguration.AzureCosmosDb.ConnectionString);
 058        _database = mongoClient.GetDatabase(_appConfiguration.AzureCosmosDb.DatabaseName);
 059    }
 60
 61    private void RegisterBsonClass(Type documentType)
 62    {
 063        if (!BsonClassMap.IsClassMapRegistered(documentType))
 64        {
 065            var classMap = new BsonClassMap(documentType);
 066            classMap.AutoMap();
 067            classMap.SetIgnoreExtraElements(true);
 068            BsonClassMap.RegisterClassMap(classMap);
 69        }
 070    }
 71
 72    public async Task<IEnumerable<IDocument>> GetAllDocumentsAsync<IDocument>(string collection)
 73    {
 074        var mongoCollection = Database.GetCollection<object>(collection);
 075        var documents = await mongoCollection.Find(FilterDefinition<object>.Empty).ToListAsync();
 76
 077        var deserializedDocuments = new List<IDocument>();
 078        foreach (var doc in documents)
 79        {
 080            var deserialized = (IDocument)BsonSerializer.Deserialize(doc.ToBson(), GetDocumentType(collection));
 081            deserializedDocuments.Add(deserialized);
 82        }
 83
 084        return deserializedDocuments;
 085    }
 86
 87    public async Task<IDocument> GetDocumentAsync<IDocument>(string collection, string documentId)
 88    {
 089        var mongoCollection = Database.GetCollection<object>(collection);
 90
 091        var filter = Builders<object>.Filter.Eq(ID_FIELD, documentId);
 092        var document = await mongoCollection.Find(filter).FirstOrDefaultAsync();
 93
 094        if (document == null)
 095            return default;
 96
 097        return (IDocument)BsonSerializer.Deserialize(document.ToBson(), GetDocumentType(collection));
 098    }
 99
 0100    private Type GetDocumentType(string collection) => _typeRegistry.GetDocumentType(collection);
 101
 102
 103    public async Task<bool> DocumentExistsAsync(string collection, string documentId)
 104    {
 0105        var mongoCollection = Database.GetCollection<object>(collection);
 0106        var filter = Builders<object>.Filter.Eq(ID_FIELD, documentId);
 0107        return await mongoCollection.Find(filter).AnyAsync();
 0108    }
 109
 110    public async Task<bool> SetDocumentAsync(string collection, string documentId, IDocument document)
 111    {
 0112        if(document is not IMongoDocument mongoDocument)
 113        {
 0114            throw new InvalidOperationException($"Document type mismatch. Can't save to MongoDb");
 115        }
 116
 0117        var result = await mongoDocument.SetDocumentAsync(Database, collection, documentId);
 0118        return result.ModifiedCount > 0 || result.UpsertedId != null;
 0119    }
 120
 121    public async Task<bool> DeleteDocumentAsync(string collection, string id)
 122    {
 0123        var mongoCollection = Database.GetCollection<object>(collection);
 0124        var filter = Builders<object>.Filter.Eq(ID_FIELD, id);
 0125        var result = await mongoCollection.DeleteOneAsync(filter);
 126
 0127        return result.DeletedCount > 0;
 0128    }
 129}