using audit_logs.Models.AppSettings; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; using audit_logs.Utils; using audit_logs.Repositories.Interfaces; using Serilog; namespace audit.Repositories; public abstract class MongoRepository : IMongoRepository { protected readonly IMongoDatabase _db; protected MongoRepository(IOptions dbSettings) { _db = MongoDbHostBuilderExtension.GetMongoDB(dbSettings); } protected MongoRepository(IMongoDatabase database) { _db = database; } public abstract string GetCollectionName(); protected IMongoCollection? _collection; public IMongoCollection Collection { get { if (_collection == null) { var collectionName = GetCollectionName(); if(!this.CollectionExists(collectionName)) _db.CreateCollection(collectionName); _collection = _db.GetCollection(collectionName); _ = CreateIndexes(); } return _collection; } set { _collection = value; } } public virtual Task CreateIndexes() { return Task.CompletedTask; } public virtual async Task InsertOneAsync(T obj) { try { await Collection.InsertOneAsync(obj); } catch (Exception ex) { Console.WriteLine("An error occurred: {ExMessage}", ex.Message); } } public virtual async Task InsertManyAsync(List obj) { try { InsertManyOptions options = new() { IsOrdered = false}; await Collection.InsertManyAsync(obj, options); } catch (Exception ex) { Log.Error("An error occurred: {ExMessage}", ex.Message); } } public async Task UpdateOneAsync(ObjectId id, T obj) { try { var filter = Builders.Filter.Eq("_id", id); await Collection.ReplaceOneAsync(filter, obj, new ReplaceOptions { IsUpsert = true }); } catch (Exception ex) { Log.Error( "Error updating id: {Id}. Exception:{Ex}, stackTrace: {Trace}", id.ToString() , ex.Message, ex.StackTrace); } } protected async Task UpdateManyObjectIdAsync(string nameId, ObjectId id, ObjectId oldId) { try { var update = Builders.Update.Set(nameId, id); var filter = Builders.Filter.Eq(nameId, oldId); await Collection.UpdateManyAsync(filter, update); } catch (Exception ex) { Log.Error("An error occurred: {ExMessage}", ex.Message); } } public async Task DeleteAsync(ObjectId id) { try { var filter = Builders.Filter.Eq("_id", id); return await Collection.FindOneAndDeleteAsync(filter); } catch (Exception ex) { Log.Error("An error occurred: {ExMessage}", ex.Message); return default; } } protected async Task DeleteAsync(string id) { try { var filter = Builders.Filter.Eq("_id", id); return await Collection.FindOneAndDeleteAsync(filter); } catch (Exception ex) { Log.Error("An error occurred: {ExMessage}", ex.Message); return default; } } private bool CollectionExists(string collectionName) { try { var filter = new BsonDocument("name", collectionName); var options = new ListCollectionNamesOptions { Filter = filter }; return _db.ListCollectionNames(options).Any(); } catch (Exception ex) { Log.Error("An error occurred: {ExMessage}", ex.Message); return false; } } public async Task> GetPaginatedAsync(int pageNumber, int pageSize,FilterDefinition? filter = null,SortDefinition sort=null) { if (pageNumber <= 0) throw new ArgumentException("Page number must be greater than 0.", nameof(pageNumber)); if (pageSize <= 0) throw new ArgumentException("Page size must be greater than 0.", nameof(pageSize)); filter ??= FilterDefinition.Empty; // Usa un filtro vacío si no se proporcionó ninguno try { return await Collection .Find(filter) .Skip((pageNumber - 1) * pageSize) .Sort(sort) .Limit(pageSize) .ToListAsync(); } catch (Exception ex) { Log.Error("Error retrieving paginated data: {ExMessage}", ex.Message); return Enumerable.Empty(); } } public async Task CountDocumentsAsync(FilterDefinition? filter = null) { filter ??= FilterDefinition.Empty; // Usa un filtro vacío porsi no se pasa como parametro return await Collection.CountDocumentsAsync(filter); } }