185 lines
7.9 KiB
C#
185 lines
7.9 KiB
C#
using adas_core.Application.Exceptions;
|
|
using adas_core.Application.Repositories.Interfaces;
|
|
using adas_core.Domain.Models.AppSettings;
|
|
using adas_core.Domain.Models.Filter;
|
|
using adas_core.Domain.Models.MongoModels;
|
|
using Microsoft.Extensions.Options;
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using Serilog;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace adas_core.Infrastructure.Repositories;
|
|
|
|
/// <summary>
|
|
/// Repository implementation for managing <see cref="LightBeacon"/> entities in MongoDB.
|
|
/// Provides CRUD operations and query capabilities specific to light beacons.
|
|
/// </summary>
|
|
public class LightBeaconRepository : MongoRepository<LightBeacon>, ILightBeaconRepository
|
|
{
|
|
private readonly ApiSettings _apiSettings;
|
|
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="LightBeaconRepository"/> class.
|
|
/// </summary>
|
|
/// <param name="database">The MongoDB database instance used to access the collection.</param>
|
|
/// <param name="apiSettings">The application API settings containing configuration values, including the collection name.</param>
|
|
public LightBeaconRepository(IMongoDatabase database, IOptions<ApiSettings> apiSettings) : base(database)
|
|
{
|
|
_apiSettings = apiSettings.Value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the name of the MongoDB collection used to store light beacons.
|
|
/// </summary>
|
|
/// <returns>The collection name retrieved from the API settings.</returns>
|
|
public override string GetCollectionName()
|
|
{
|
|
return _apiSettings.LightBeacons;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves a list of light beacons whose identifiers are contained in the provided list of configuration relay identifiers.
|
|
/// </summary>
|
|
/// <param name="configurationRelayList">A list of <see cref="ObjectId"/> values representing the relay identifiers to filter by.</param>
|
|
/// <returns>A <see cref="List{LightBeacon}"/> containing the matching light beacons. Returns an empty list if no matches are found.</returns>
|
|
public List<LightBeacon> GetLightBeaconInList(List<ObjectId> configurationRelayList)
|
|
{
|
|
var filterBuilder = Builders<LightBeacon>.Filter;
|
|
|
|
var filter = filterBuilder.And(
|
|
filterBuilder.In(r => r.Id, configurationRelayList));
|
|
|
|
return Collection.Find(filter).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asynchronously retrieves a light beacon by its unique identifier.
|
|
/// </summary>
|
|
/// <param name="relayId">The <see cref="ObjectId"/> of the relay (light beacon) to retrieve.</param>
|
|
/// <returns>
|
|
/// A <see cref="Task{LightBeacon}"/> representing the asynchronous operation.
|
|
/// The task result contains the <see cref="LightBeacon"/> if found; otherwise, <see langword="null"/>.
|
|
/// </returns>
|
|
public async Task<LightBeacon?> GetById(ObjectId relayId)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<LightBeacon>.Filter.Eq(x => x.Id, relayId);
|
|
var result = await Collection.FindAsync(filter, null);
|
|
return result.FirstOrDefault();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error("Exception trying to get relay by id: {id}. Exception {e}", relayId, e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asynchronously retrieves a light beacon by its name.
|
|
/// </summary>
|
|
/// <param name="requestRelayName">The name of the relay (light beacon) to search for. Can be <see langword="null"/>.</param>
|
|
/// <returns>
|
|
/// A <see cref="Task{LightBeacon}"/> representing the asynchronous operation.
|
|
/// The task result contains the <see cref="LightBeacon"/> if found; otherwise, <see langword="null"/>.
|
|
/// </returns>
|
|
public async Task<LightBeacon?> GetByName(string? requestRelayName)
|
|
{
|
|
var filterBuilder = Builders<LightBeacon>.Filter;
|
|
|
|
var filter = filterBuilder.Eq(r => r.Name, requestRelayName);
|
|
|
|
return await Collection.Find(filter).FirstOrDefaultAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asynchronously inserts a new light beacon into the database and returns the inserted entity.
|
|
/// </summary>
|
|
/// <param name="beacon">The <see cref="LightBeacon"/> instance to insert.</param>
|
|
/// <returns>
|
|
/// A <see cref="Task{LightBeacon}"/> representing the asynchronous operation.
|
|
/// The task result contains the inserted <see cref="LightBeacon"/> if successful; otherwise, <see langword="null"/> if the operation fails.
|
|
/// </returns>
|
|
public async Task<LightBeacon?> InsertOneAsyncAndReturn(LightBeacon beacon)
|
|
{
|
|
try
|
|
{
|
|
await Collection.InsertOneAsync(beacon);
|
|
return beacon;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex.Message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves a paginated, sorted, and filtered set of light beacons based on the provided pagination filter.
|
|
/// Results are sorted ascending by name. When a text filter is provided, a case-insensitive regex match is performed on the name field.
|
|
/// </summary>
|
|
/// <param name="filter">The <see cref="PaginationFilter"/> containing pagination and filtering criteria.</param>
|
|
/// <returns>
|
|
/// An <see cref="IFindFluent{LightBeacon, LightBeacon}"/> instance that can be used to further refine and execute the query.
|
|
/// </returns>
|
|
/// <exception cref="BadRequestException">Thrown when the text filter exceeds 100 characters in length.</exception>
|
|
public IFindFluent<LightBeacon, LightBeacon> GetPaginatedRelays(PaginationFilter filter)
|
|
{
|
|
var filterBuilder = Builders<LightBeacon>.Filter;
|
|
var sort = Builders<LightBeacon>.Sort.Ascending("name");
|
|
var filters = new List<FilterDefinition<LightBeacon>>();
|
|
|
|
if (filter.FilteredRequest == null)
|
|
return CreateFindFluent(filters, sort);
|
|
|
|
if (!string.IsNullOrWhiteSpace(filter.FilteredRequest.Text))
|
|
{
|
|
var textFilter = filter.FilteredRequest.Text;
|
|
|
|
if (textFilter.Length > 100)
|
|
throw new BadRequestException("Text filter too long");
|
|
|
|
var textFilterEscaped = Regex.Escape(textFilter);
|
|
|
|
filters.Add(
|
|
filterBuilder.Regex(
|
|
p => p.Name,
|
|
new BsonRegularExpression(textFilterEscaped, "i")
|
|
)
|
|
);
|
|
}
|
|
|
|
return CreateFindFluent(filters, sort);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Searches for light beacons whose name matches the specified text.
|
|
/// </summary>
|
|
/// <param name="textToSearch">The text to search for within light beacon names.</param>
|
|
/// <returns>
|
|
/// A <see cref="Task{List{LightBeacon}}"/> representing the asynchronous operation,
|
|
/// containing a list of matching <see cref="LightBeacon"/> objects.
|
|
/// </returns>
|
|
/// <exception cref="NotImplementedException">This method is not yet implemented.</exception>
|
|
public Task<List<LightBeacon>> GetSearchByName(string textToSearch)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an <see cref="IFindFluent{LightBeacon, LightBeacon}"/> instance by combining the provided filter definitions
|
|
/// and applying the specified sort order. If no filters are provided, an empty filter is used.
|
|
/// </summary>
|
|
/// <param name="filters">A list of <see cref="FilterDefinition{LightBeacon}"/> to be combined into the query.</param>
|
|
/// <param name="sort">The <see cref="SortDefinition{LightBeacon}"/> defining the sort order of the results.</param>
|
|
/// <returns>An <see cref="IFindFluent{LightBeacon, LightBeacon}"/> instance representing the constructed query.</returns>
|
|
private IFindFluent<LightBeacon, LightBeacon> CreateFindFluent(List<FilterDefinition<LightBeacon>> filters, SortDefinition<LightBeacon> sort)
|
|
{
|
|
var combinedFilter = filters.Any()
|
|
? Builders<LightBeacon>.Filter.And(filters)
|
|
: Builders<LightBeacon>.Filter.Empty;
|
|
return Collection.Find(combinedFilter).Sort(sort);
|
|
}
|
|
} |