using Microsoft.Extensions.Options; using MongoDB.Driver; using Supercell.GUT.Server.Database.Document; using Supercell.GUT.Server.Database.Options; namespace Supercell.GUT.Server.Database; public class DatabaseManager { private const string IdentifierCounterCollection = "t_id_counter"; private static readonly FindOneAndUpdateOptions s_counterUpdateOptions = new() { ReturnDocument = ReturnDocument.After }; private readonly DatabaseOptions _options; private readonly MongoClient _client; private readonly IMongoDatabase _database; private readonly IMongoCollection _idCounters; public DatabaseManager(IOptions options) { _options = options.Value; _client = new MongoClient(_options.MongoConnectionString); _database = _client.GetDatabase(_options.DatabaseName); _idCounters = _database.GetCollection(IdentifierCounterCollection); } public IMongoCollection GetCollection(string collectionName) where TDatabaseDocument : IDatabaseDocument { return _database.GetCollection(collectionName); } public async Task GetNextLowIdAsync(string counterName) { var cursor = await _idCounters.FindAsync(doc => doc.CounterName == counterName); if (!cursor.Any()) { await _idCounters.InsertOneAsync(new IdentifierCounterDocument { CounterName = counterName, CurrentLowId = 0 }); } IdentifierCounterDocument? document = await _idCounters.FindOneAndUpdateAsync( x => x.CounterName == counterName, Builders.Update.Inc(nameof(IdentifierCounterDocument.CurrentLowId), 1), s_counterUpdateOptions); return document.CurrentLowId; } }