using Insight.Infrastructure.Models; using Microsoft.AspNetCore.Http; using MongoDB.Bson; using MongoDB.Bson.Serialization; using MongoDB.Driver; namespace Insight.Infrastructure { public static class MongoCollectionExtensions { private const int _maximumLimit = 100; public static async Task> GetPagedAsync( this IMongoCollection collection, FilterDefinition? filter = null, SortDefinition? sort = null, int offset = 0, int limit = 10, CancellationToken cancellationToken = default) { if (limit > _maximumLimit) throw new InvalidOperationException("invalid limit value > 100"); var query = collection.Find(filter ?? Builders.Filter.Empty); if (sort is not null) query = query.Sort(sort); var data = await query.Skip(offset).Limit(limit).ToListAsync(cancellationToken).ConfigureAwait(false); var total = await collection.EstimatedDocumentCountAsync(null, cancellationToken).ConfigureAwait(false); return new PagedList(data, offset, limit, total); } public static async Task> GetPagedAsync( this IMongoCollection collection, HttpRequest request, HttpResponse response, FilterDefinition? filter = null, SortDefinition? sort = null, int offset = 0, int limit = 10, CancellationToken cancellationToken = default) { var result = await GetPagedAsync(collection, filter, sort, offset, limit, cancellationToken).ConfigureAwait(false); request?.AddPagination(result); response?.AddPagination(result); return result; } public static async Task> GetPagedAsync( this IMongoCollection collection, IAggregateFluent query, int offset = 0, int limit = 10, CancellationToken cancellationToken = default) { if (limit > _maximumLimit) throw new InvalidOperationException("invalid limit value"); var data = await query.Skip(offset).Limit(limit).ToListAsync(cancellationToken).ConfigureAwait(false); var total = await collection.EstimatedDocumentCountAsync(null, cancellationToken).ConfigureAwait(false); return new PagedList(data.Select(x => BsonSerializer.Deserialize(x)), offset, limit, total); } public static async Task> GetPagedAsync( this IMongoCollection collection, HttpRequest request, HttpResponse response, IAggregateFluent query, int offset = 0, int limit = 10, CancellationToken cancellationToken = default) { var result = await GetPagedAsync(collection, query, offset, limit, cancellationToken).ConfigureAwait(false); request?.AddPagination(result); response?.AddPagination(result); return result; } } }