Add TimestampedSetRepository #2
@ -2,11 +2,14 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Persistence.Models;
|
using Persistence.Models;
|
||||||
using Persistence.Repositories;
|
using Persistence.Repositories;
|
||||||
using Persistence.Repository.Repositories;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace Persistence.API.Controllers;
|
namespace Persistence.API.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Хранение наборов данных с отметкой времени.
|
||||||
|
/// Не оптимизировано под большие данные.
|
||||||
|
/// </summary>
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/[controller]/{idDiscriminator}")]
|
[Route("api/[controller]/{idDiscriminator}")]
|
||||||
@ -19,6 +22,14 @@ public class TimestampedSetController : ControllerBase
|
|||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Записать новые данные
|
||||||
|
/// Предполагается что данные с одним дискриминатором имеют одинаковую структуру
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <param name="sets"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns>кол-во затронутых записей</returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> InsertRange([FromRoute]Guid idDiscriminator, [FromBody]IEnumerable<TimestampedSetDto> sets, CancellationToken token)
|
public async Task<IActionResult> InsertRange([FromRoute]Guid idDiscriminator, [FromBody]IEnumerable<TimestampedSetDto> sets, CancellationToken token)
|
||||||
@ -27,22 +38,46 @@ public class TimestampedSetController : ControllerBase
|
|||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
||||||
|
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||||
|
/// <param name="skip"></param>
|
||||||
|
/// <param name="take"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, [FromQuery]IEnumerable<string>? props, int skip, int take, CancellationToken token)
|
public async Task<IActionResult> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, [FromQuery]IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await repository.Get(idDiscriminator, geTimestamp, props, skip, take, token);
|
var result = await repository.Get(idDiscriminator, geTimestamp, columnNames, skip, take, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить последние данные
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||||
|
/// <param name="take"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns>Фильтрованный набор данных с сортировкой по отметке времени</returns>
|
||||||
[HttpGet("last")]
|
[HttpGet("last")]
|
||||||
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(IEnumerable<TimestampedSetDto>), (int)HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> GetLast(Guid idDiscriminator, [FromQuery]IEnumerable<string>? props, int take, CancellationToken token)
|
public async Task<IActionResult> GetLast(Guid idDiscriminator, [FromQuery]IEnumerable<string>? columnNames, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await repository.GetLast(idDiscriminator, props, take, token);
|
var result = await repository.GetLast(idDiscriminator, columnNames, take, token);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Диапазон дат за которые есть данные
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns>Дата первой и последней записи</returns>
|
||||||
[HttpGet("datesRange")]
|
[HttpGet("datesRange")]
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
||||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||||
@ -52,8 +87,14 @@ public class TimestampedSetController : ControllerBase
|
|||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Количество записей по указанному набору в БД. Для пагинации.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[HttpGet("count")]
|
[HttpGet("count")]
|
||||||
[ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
||||||
public async Task<IActionResult> Count(Guid idDiscriminator, CancellationToken token)
|
public async Task<IActionResult> Count(Guid idDiscriminator, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
@ -2,22 +2,61 @@
|
|||||||
using Refit;
|
using Refit;
|
||||||
|
|
||||||
namespace Persistence.Client.Clients;
|
namespace Persistence.Client.Clients;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Клиент для работы с репозиторием для хранения разных наборов данных рядов.
|
||||||
|
/// idDiscriminator - идентифицирует конкретный набор данных, прим.: циклы измерения АСИБР, или отчет о DrillTest.
|
||||||
|
/// idDiscriminator формируют клиенты и только им известно что они обозначают.
|
||||||
|
/// Так как данные приходят редко, то их прореживания для построения графиков не предусмотрено.
|
||||||
|
/// </summary>
|
||||||
public interface ITimestampedSetClient
|
public interface ITimestampedSetClient
|
||||||
{
|
{
|
||||||
private const string baseUrl = "/api/TimestampedSet/{idDiscriminator}";
|
private const string baseUrl = "/api/TimestampedSet/{idDiscriminator}";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Добавление новых данных
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <param name="sets"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[Post(baseUrl)]
|
[Post(baseUrl)]
|
||||||
Task<IApiResponse<int>> InsertRange(Guid idDiscriminator, IEnumerable<TimestampedSetDto> sets);
|
Task<IApiResponse<int>> InsertRange(Guid idDiscriminator, IEnumerable<TimestampedSetDto> sets);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
||||||
|
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||||
|
/// <param name="skip"></param>
|
||||||
|
/// <param name="take"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[Get(baseUrl)]
|
[Get(baseUrl)]
|
||||||
Task<IApiResponse<IEnumerable<TimestampedSetDto>>> Get(Guid idDiscriminator, [Query] DateTimeOffset? geTimestamp, [Query] IEnumerable<string>? props, int skip, int take);
|
Task<IApiResponse<IEnumerable<TimestampedSetDto>>> Get(Guid idDiscriminator, [Query] DateTimeOffset? geTimestamp, [Query] IEnumerable<string>? columnNames, int skip, int take);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получить последние данные
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||||
|
/// <param name="take"></param>
|
||||||
|
/// <returns></returns>
|
||||||
[Get($"{baseUrl}/last")]
|
[Get($"{baseUrl}/last")]
|
||||||
Task<IApiResponse<IEnumerable<TimestampedSetDto>>> GetLast(Guid idDiscriminator, [Query] IEnumerable<string>? props, int take);
|
Task<IApiResponse<IEnumerable<TimestampedSetDto>>> GetLast(Guid idDiscriminator, [Query] IEnumerable<string>? columnNames, int take);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Количество записей по указанному набору в БД. Для пагинации.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <returns></returns>
|
||||||
[Get($"{baseUrl}/count")]
|
[Get($"{baseUrl}/count")]
|
||||||
Task<IApiResponse<int>> Count(Guid idDiscriminator);
|
Task<IApiResponse<int>> Count(Guid idDiscriminator);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Диапазон дат за которые есть данные
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
|
/// <returns></returns>
|
||||||
[Get($"{baseUrl}/datesRange")]
|
[Get($"{baseUrl}/datesRange")]
|
||||||
Task<IApiResponse<DatesRangeDto?>> GetDatesRange(Guid idDiscriminator);
|
Task<IApiResponse<DatesRangeDto?>> GetDatesRange(Guid idDiscriminator);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ public class TimestampedSetRepository : ITimestampedSetRepository
|
|||||||
return db.SaveChangesAsync(token);
|
return db.SaveChangesAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TimestampedSetDto>> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? props, int skip, int take, CancellationToken token)
|
public async Task<IEnumerable<TimestampedSetDto>> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var dbSet = db.Set<TimestampedSet>();
|
var dbSet = db.Set<TimestampedSet>();
|
||||||
var query = dbSet.Where(entity => entity.IdDiscriminator == idDiscriminator);
|
var query = dbSet.Where(entity => entity.IdDiscriminator == idDiscriminator);
|
||||||
@ -43,13 +43,13 @@ public class TimestampedSetRepository : ITimestampedSetRepository
|
|||||||
|
|
||||||
var data = await Materialize(query, token);
|
var data = await Materialize(query, token);
|
||||||
|
|
||||||
if (props is not null && props.Any())
|
if (columnNames is not null && columnNames.Any())
|
||||||
data = ApplyPropsFilter(data, props);
|
data = ReduceSetColumnsByNames(data, columnNames);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<TimestampedSetDto>> GetLast(Guid idDiscriminator, IEnumerable<string>? props, int take, CancellationToken token)
|
public async Task<IEnumerable<TimestampedSetDto>> GetLast(Guid idDiscriminator, IEnumerable<string>? columnNames, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var dbSet = db.Set<TimestampedSet>();
|
var dbSet = db.Set<TimestampedSet>();
|
||||||
var query = dbSet.Where(entity => entity.IdDiscriminator == idDiscriminator);
|
var query = dbSet.Where(entity => entity.IdDiscriminator == idDiscriminator);
|
||||||
@ -60,8 +60,8 @@ public class TimestampedSetRepository : ITimestampedSetRepository
|
|||||||
|
|
||||||
var data = await Materialize(query, token);
|
var data = await Materialize(query, token);
|
||||||
|
|
||||||
if (props is not null && props.Any())
|
if (columnNames is not null && columnNames.Any())
|
||||||
data = ApplyPropsFilter(data, props);
|
data = ReduceSetColumnsByNames(data, columnNames);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -107,13 +107,13 @@ public class TimestampedSetRepository : ITimestampedSetRepository
|
|||||||
return query.Where(entity => entity.Timestamp >= geTimestampUtc);
|
return query.Where(entity => entity.Timestamp >= geTimestampUtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<TimestampedSetDto> ApplyPropsFilter(IEnumerable<TimestampedSetDto> query, IEnumerable<string> props)
|
private static IEnumerable<TimestampedSetDto> ReduceSetColumnsByNames(IEnumerable<TimestampedSetDto> query, IEnumerable<string> columnNames)
|
||||||
{
|
{
|
||||||
var newQuery = query
|
var newQuery = query
|
||||||
.Select(entity => new TimestampedSetDto(
|
.Select(entity => new TimestampedSetDto(
|
||||||
entity.Timestamp,
|
entity.Timestamp,
|
||||||
entity.Set
|
entity.Set
|
||||||
.Where(prop => props.Contains(prop.Key))
|
.Where(prop => columnNames.Contains(prop.Key))
|
||||||
.ToDictionary(prop => prop.Key, prop => prop.Value)
|
.ToDictionary(prop => prop.Key, prop => prop.Value)
|
||||||
));
|
));
|
||||||
return newQuery;
|
return newQuery;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
namespace Persistence.Repositories;
|
namespace Persistence.Repositories;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Репозиторий для хранения разных наборов данных временных рядов.
|
/// Репозиторий для хранения разных наборов данных рядов.
|
||||||
/// idDiscriminator - идентифицирует конкретный набор данных, прим.: циклы измерения АСИБР, или отчет о DrillTest.
|
/// idDiscriminator - идентифицирует конкретный набор данных, прим.: циклы измерения АСИБР, или отчет о DrillTest.
|
||||||
/// idDiscriminator формируют клиенты и только им известно что они обозначают.
|
/// idDiscriminator формируют клиенты и только им известно что они обозначают.
|
||||||
/// Так как данные приходят редко, то их прореживания для построения графиков не предусмотрено.
|
/// Так как данные приходят редко, то их прореживания для построения графиков не предусмотрено.
|
||||||
@ -13,7 +13,7 @@ public interface ITimestampedSetRepository
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Количество записей по указанному набору в БД. Для пагинации.
|
/// Количество записей по указанному набору в БД. Для пагинации.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> Count(Guid idDiscriminator, CancellationToken token);
|
Task<int> Count(Guid idDiscriminator, CancellationToken token);
|
||||||
@ -23,17 +23,17 @@ public interface ITimestampedSetRepository
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
||||||
/// <param name="props">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||||
/// <param name="skip"></param>
|
/// <param name="skip"></param>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<TimestampedSetDto>> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? props, int skip, int take, CancellationToken token);
|
Task<IEnumerable<TimestampedSetDto>> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Диапазон дат за которые есть данные
|
/// Диапазон дат за которые есть данные
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator"></param>
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
|
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
|
||||||
@ -42,11 +42,11 @@ public interface ITimestampedSetRepository
|
|||||||
/// Получить последние данные
|
/// Получить последние данные
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
||||||
/// <param name="props">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<TimestampedSetDto>> GetLast(Guid idDiscriminator, IEnumerable<string>? props, int take, CancellationToken token);
|
Task<IEnumerable<TimestampedSetDto>> GetLast(Guid idDiscriminator, IEnumerable<string>? columnNames, int take, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Добавление новых данных
|
/// Добавление новых данных
|
||||||
|
Loading…
Reference in New Issue
Block a user