Изменение метода Get к TimestampedValues
All checks were successful
Unit tests / test (push) Successful in 47s
All checks were successful
Unit tests / test (push) Successful in 47s
This commit is contained in:
parent
a3605253d6
commit
8fd16512f3
@ -1,7 +1,6 @@
|
|||||||
using DD.Persistence.Models;
|
using DD.Persistence.Models;
|
||||||
using DD.Persistence.Models.Common;
|
using DD.Persistence.Models.Common;
|
||||||
using DD.Persistence.Services.Interfaces;
|
using DD.Persistence.Services.Interfaces;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
@ -11,15 +10,15 @@ namespace DD.Persistence.API.Controllers;
|
|||||||
/// Хранение наборов данных с отметкой времени.
|
/// Хранение наборов данных с отметкой времени.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
//[Authorize]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class TimestampedValuesController : ControllerBase
|
public class TimestampedValuesController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ITimestampedValuesService timestampedValuesService;
|
private readonly ITimestampedValuesService timestampedValuesService;
|
||||||
|
|
||||||
public TimestampedValuesController(ITimestampedValuesService service)
|
public TimestampedValuesController(ITimestampedValuesService repository)
|
||||||
{
|
{
|
||||||
this.timestampedValuesService = service;
|
this.timestampedValuesService = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -41,26 +40,7 @@ public class TimestampedValuesController : ControllerBase
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="discriminatorId">Дискриминатор (идентификатор) набора</param>
|
/// <param name="discriminatorIds">Набор дискриминаторов</param>
|
||||||
/// <param name="timestampBegin">Фильтр позднее даты</param>
|
|
||||||
/// <param name="columnNames">Фильтр свойств набора</param>
|
|
||||||
/// <param name="skip"></param>
|
|
||||||
/// <param name="take"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
[HttpGet("{discriminatorId}")]
|
|
||||||
[ProducesResponseType(typeof(IEnumerable<TimestampedValuesDto>), (int)HttpStatusCode.OK)]
|
|
||||||
[ProducesResponseType((int)HttpStatusCode.NoContent)]
|
|
||||||
public async Task<ActionResult<IEnumerable<TimestampedValuesDto>>> Get([FromRoute] Guid discriminatorId, DateTimeOffset? timestampBegin, [FromQuery] string[]? columnNames, int skip, int take, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = await timestampedValuesService.Get(discriminatorId, timestampBegin, columnNames, skip, take, token);
|
|
||||||
|
|
||||||
return result.Any() ? Ok(result) : NoContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение данных с фильтрацией для нескольких систем. Значение фильтра null - отключен
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="discriminatorIds">Набор дискриминаторов (идентификаторов)</param>
|
|
||||||
/// <param name="timestampBegin">Фильтр позднее даты</param>
|
/// <param name="timestampBegin">Фильтр позднее даты</param>
|
||||||
/// <param name="columnNames">Фильтр свойств набора</param>
|
/// <param name="columnNames">Фильтр свойств набора</param>
|
||||||
/// <param name="skip"></param>
|
/// <param name="skip"></param>
|
||||||
|
@ -19,22 +19,6 @@ public interface ITimestampedValuesClient : IDisposable
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
Task<int> AddRange(Guid discriminatorId, IEnumerable<TimestampedValuesDto> dtos, CancellationToken token);
|
Task<int> AddRange(Guid discriminatorId, IEnumerable<TimestampedValuesDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получить данные с фильтрацией. Значение фильтра null - отключен
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="discriminatorId">Дискриминатор (идентификатор) набора</param>
|
|
||||||
/// <param name="timestampBegin">Фильтр позднее даты</param>
|
|
||||||
/// <param name="columnNames">Фильтр свойств набора</param>
|
|
||||||
/// <param name="skip"></param>
|
|
||||||
/// <param name="take"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
Task<IEnumerable<TimestampedValuesDto>> Get(Guid discriminatorId,
|
|
||||||
DateTimeOffset? timestampBegin,
|
|
||||||
IEnumerable<string>? columnNames,
|
|
||||||
int skip,
|
|
||||||
int take,
|
|
||||||
CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить данные с фильтрацией для нескольких систем. Значение фильтра null - отключен
|
/// Получить данные с фильтрацией для нескольких систем. Значение фильтра null - отключен
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -99,19 +83,6 @@ public interface ITimestampedValuesClient : IDisposable
|
|||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
Task<DatesRangeDto?> GetDatesRange(Guid discriminatorId, CancellationToken token);
|
Task<DatesRangeDto?> GetDatesRange(Guid discriminatorId, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <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>
|
|
||||||
Task<IEnumerable<T>> Get<T>(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -17,17 +17,6 @@ public interface IRefitTimestampedValuesClient : IRefitClient, IDisposable
|
|||||||
[Post($"{baseUrl}/{{discriminatorId}}")]
|
[Post($"{baseUrl}/{{discriminatorId}}")]
|
||||||
Task<IApiResponse<int>> AddRange(Guid discriminatorId, IEnumerable<TimestampedValuesDto> dtos, CancellationToken token);
|
Task<IApiResponse<int>> AddRange(Guid discriminatorId, IEnumerable<TimestampedValuesDto> dtos, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение данных с фильтрацией для нескольких систем
|
|
||||||
/// </summary>
|
|
||||||
[Get($"{baseUrl}/{{discriminatorId}}")]
|
|
||||||
Task<IApiResponse<IEnumerable<TimestampedValuesDto>>> Get(Guid discriminatorId,
|
|
||||||
DateTimeOffset? timestampBegin,
|
|
||||||
[Query(CollectionFormat.Multi)] IEnumerable<string>? columnNames,
|
|
||||||
int skip,
|
|
||||||
int take,
|
|
||||||
CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение данных с фильтрацией
|
/// Получение данных с фильтрацией
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -31,14 +31,6 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = await ExecuteGetResponse(
|
|
||||||
async () => await refitTimestampedSetClient.Get(discriminatorId, geTimestamp, columnNames, skip, take, token), token);
|
|
||||||
return result!;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
@ -101,15 +93,6 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<IEnumerable<T>> Get<T>(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
|
||||||
{
|
|
||||||
var data = await Get(idDiscriminator, geTimestamp, columnNames, skip, take, token);
|
|
||||||
var mapper = GetMapper<T>(idDiscriminator);
|
|
||||||
|
|
||||||
return data.Select(mapper.DeserializeTimeStampedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<IEnumerable<T>> GetLast<T>(Guid idDiscriminator, int take, CancellationToken token)
|
public async Task<IEnumerable<T>> GetLast<T>(Guid idDiscriminator, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
@ -38,67 +38,67 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
|
|||||||
await AddRange(discriminatorId);
|
await AddRange(discriminatorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[Fact]
|
||||||
|
//public async Task Get_returns_success()
|
||||||
|
//{
|
||||||
|
// //arrange
|
||||||
|
// Cleanup();
|
||||||
|
|
||||||
|
// var discriminatorId = Guid.NewGuid();
|
||||||
|
// discriminatorIds.Append(discriminatorId);
|
||||||
|
|
||||||
|
// //act
|
||||||
|
// var response = await timestampedValuesClient.Get(discriminatorId, null, null, 0, 1, CancellationToken.None);
|
||||||
|
|
||||||
|
// //assert
|
||||||
|
// Assert.Null(response);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//[Fact]
|
||||||
|
|
||||||
|
//public async Task Get_AfterSave_returns_success()
|
||||||
|
//{
|
||||||
|
// //arrange
|
||||||
|
// Cleanup();
|
||||||
|
|
||||||
|
// var discriminatorId = Guid.NewGuid();
|
||||||
|
// discriminatorIds.Append(discriminatorId);
|
||||||
|
|
||||||
|
// var timestampBegin = DateTimeOffset.UtcNow.AddDays(-1);
|
||||||
|
// var columnNames = new List<string>() { "A", "C" };
|
||||||
|
// var skip = 5;
|
||||||
|
// var take = 5;
|
||||||
|
|
||||||
|
// var dtos = await AddRange(discriminatorId);
|
||||||
|
|
||||||
|
// //act
|
||||||
|
// var response = await timestampedValuesClient.Get(discriminatorId, timestampBegin, columnNames, skip, take, CancellationToken.None);
|
||||||
|
|
||||||
|
// //assert
|
||||||
|
// Assert.NotNull(response);
|
||||||
|
// Assert.NotEmpty(response);
|
||||||
|
|
||||||
|
// var actualCount = response.Count();
|
||||||
|
// Assert.Equal(take, actualCount);
|
||||||
|
|
||||||
|
// var actualColumnNames = response.SelectMany(e => e.Values.Keys).Distinct().ToList();
|
||||||
|
// Assert.Equal(columnNames, actualColumnNames);
|
||||||
|
|
||||||
|
// var expectedValueKind = JsonValueKind.Number;
|
||||||
|
// var actualValueKind = ((JsonElement) response.First().Values["A"]).ValueKind;
|
||||||
|
// Assert.Equal(expectedValueKind, actualValueKind);
|
||||||
|
|
||||||
|
// expectedValueKind = JsonValueKind.String;
|
||||||
|
// actualValueKind = ((JsonElement)response.First().Values["C"]).ValueKind;
|
||||||
|
// Assert.Equal(expectedValueKind, actualValueKind);
|
||||||
|
//}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Get_returns_success()
|
public async Task Get_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
var discriminatorId = Guid.NewGuid();
|
|
||||||
discriminatorIds.Append(discriminatorId);
|
|
||||||
|
|
||||||
//act
|
|
||||||
var response = await timestampedValuesClient.Get(discriminatorId, null, null, 0, 1, CancellationToken.None);
|
|
||||||
|
|
||||||
//assert
|
|
||||||
Assert.Null(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
|
|
||||||
public async Task Get_AfterSave_returns_success()
|
|
||||||
{
|
|
||||||
//arrange
|
|
||||||
Cleanup();
|
|
||||||
|
|
||||||
var discriminatorId = Guid.NewGuid();
|
|
||||||
discriminatorIds.Append(discriminatorId);
|
|
||||||
|
|
||||||
var timestampBegin = DateTimeOffset.UtcNow.AddDays(-1);
|
|
||||||
var columnNames = new List<string>() { "A", "C" };
|
|
||||||
var skip = 5;
|
|
||||||
var take = 5;
|
|
||||||
|
|
||||||
var dtos = await AddRange(discriminatorId);
|
|
||||||
|
|
||||||
//act
|
|
||||||
var response = await timestampedValuesClient.Get(discriminatorId, timestampBegin, columnNames, skip, take, CancellationToken.None);
|
|
||||||
|
|
||||||
//assert
|
|
||||||
Assert.NotNull(response);
|
|
||||||
Assert.NotEmpty(response);
|
|
||||||
|
|
||||||
var actualCount = response.Count();
|
|
||||||
Assert.Equal(take, actualCount);
|
|
||||||
|
|
||||||
var actualColumnNames = response.SelectMany(e => e.Values.Keys).Distinct().ToList();
|
|
||||||
Assert.Equal(columnNames, actualColumnNames);
|
|
||||||
|
|
||||||
var expectedValueKind = JsonValueKind.Number;
|
|
||||||
var actualValueKind = ((JsonElement) response.First().Values["A"]).ValueKind;
|
|
||||||
Assert.Equal(expectedValueKind, actualValueKind);
|
|
||||||
|
|
||||||
expectedValueKind = JsonValueKind.String;
|
|
||||||
actualValueKind = ((JsonElement)response.First().Values["C"]).ValueKind;
|
|
||||||
Assert.Equal(expectedValueKind, actualValueKind);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetWithManyDiscriminators_returns_success()
|
|
||||||
{
|
|
||||||
//arrange
|
|
||||||
Cleanup();
|
|
||||||
|
|
||||||
var firstDiscriminatorId = Guid.NewGuid();
|
var firstDiscriminatorId = Guid.NewGuid();
|
||||||
discriminatorIds.Append(firstDiscriminatorId);
|
discriminatorIds.Append(firstDiscriminatorId);
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ public class TimestampedValuesControllerTest : BaseIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetWithManyDiscriminators_AfterSave_returns_success()
|
public async Task Get_AfterSave_returns_success()
|
||||||
{
|
{
|
||||||
//arrange
|
//arrange
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
@ -3,7 +3,6 @@ using DD.Persistence.Models;
|
|||||||
using DD.Persistence.Models.Common;
|
using DD.Persistence.Models.Common;
|
||||||
using DD.Persistence.Repositories;
|
using DD.Persistence.Repositories;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace DD.Persistence.Repository.Repositories;
|
namespace DD.Persistence.Repository.Repositories;
|
||||||
public class TimestampedValuesRepository : ITimestampedValuesRepository
|
public class TimestampedValuesRepository : ITimestampedValuesRepository
|
||||||
@ -38,37 +37,7 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async virtual Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> Get(Guid discriminatorId,
|
public async virtual Task<IDictionary<Guid, IEnumerable<(DateTimeOffset Timestamp, object[] Values)>>> Get(IEnumerable<Guid> discriminatorIds,
|
||||||
DateTimeOffset? timestampBegin,
|
|
||||||
IEnumerable<string>? columnNames,
|
|
||||||
int skip,
|
|
||||||
int take,
|
|
||||||
CancellationToken token)
|
|
||||||
{
|
|
||||||
var query = GetQueryReadOnly()
|
|
||||||
.Where(entity => entity.DiscriminatorId == discriminatorId);
|
|
||||||
|
|
||||||
// Фильтрация по дате
|
|
||||||
if (timestampBegin.HasValue)
|
|
||||||
{
|
|
||||||
query = ApplyGeTimestamp(query, timestampBegin.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
query = query
|
|
||||||
.OrderBy(item => item.Timestamp)
|
|
||||||
.Skip(skip)
|
|
||||||
.Take(take);
|
|
||||||
var entities = await query.ToArrayAsync(token);
|
|
||||||
|
|
||||||
var result = entities.Select(e => Tuple.Create(
|
|
||||||
e.Timestamp,
|
|
||||||
e.Values
|
|
||||||
));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async virtual Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> Get(IEnumerable<Guid> discriminatorIds,
|
|
||||||
DateTimeOffset? timestampBegin,
|
DateTimeOffset? timestampBegin,
|
||||||
IEnumerable<string>? columnNames,
|
IEnumerable<string>? columnNames,
|
||||||
int skip,
|
int skip,
|
||||||
@ -84,28 +53,28 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
|||||||
query = ApplyGeTimestamp(query, timestampBegin.Value);
|
query = ApplyGeTimestamp(query, timestampBegin.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = query
|
// Группировка отсортированных значений по DiscriminatorId
|
||||||
.OrderBy(item => item.Timestamp)
|
var groupQuery = query
|
||||||
.Skip(skip)
|
.GroupBy(e => e.DiscriminatorId)
|
||||||
.Take(take);
|
.Select(g => KeyValuePair.Create(g.Key, g.OrderBy(i => i.Timestamp).Skip(skip).Take(take)));
|
||||||
var entities = await query.ToArrayAsync(token);
|
var entities = await groupQuery.ToArrayAsync(token);
|
||||||
|
|
||||||
var result = entities.Select(e => Tuple.Create(
|
var result = entities.ToDictionary(k => k.Key, v => v.Value.Select(e => (
|
||||||
e.Timestamp,
|
e.Timestamp,
|
||||||
e.Values
|
e.Values
|
||||||
));
|
)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async virtual Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetFirst(Guid discriminatorId, int takeCount, CancellationToken token)
|
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetFirst(Guid discriminatorId, int takeCount, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly()
|
var query = GetQueryReadOnly()
|
||||||
.OrderBy(e => e.Timestamp)
|
.OrderBy(e => e.Timestamp)
|
||||||
.Take(takeCount);
|
.Take(takeCount);
|
||||||
var entities = await query.ToArrayAsync(token);
|
var entities = await query.ToArrayAsync(token);
|
||||||
|
|
||||||
var result = entities.Select(e => Tuple.Create(
|
var result = entities.Select(e => (
|
||||||
e.Timestamp,
|
e.Timestamp,
|
||||||
e.Values
|
e.Values
|
||||||
));
|
));
|
||||||
@ -113,14 +82,14 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async virtual Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetLast(Guid discriminatorId, int takeCount, CancellationToken token)
|
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetLast(Guid discriminatorId, int takeCount, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly()
|
var query = GetQueryReadOnly()
|
||||||
.OrderByDescending(e => e.Timestamp)
|
.OrderByDescending(e => e.Timestamp)
|
||||||
.Take(takeCount);
|
.Take(takeCount);
|
||||||
var entities = await query.ToArrayAsync(token);
|
var entities = await query.ToArrayAsync(token);
|
||||||
|
|
||||||
var result = entities.Select(e => Tuple.Create(
|
var result = entities.Select(e => (
|
||||||
e.Timestamp,
|
e.Timestamp,
|
||||||
e.Values
|
e.Values
|
||||||
));
|
));
|
||||||
@ -129,7 +98,7 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToDo: прореживание должно осуществляться до материализации
|
// ToDo: прореживание должно осуществляться до материализации
|
||||||
public async virtual Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetResampledData(
|
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetResampledData(
|
||||||
Guid discriminatorId,
|
Guid discriminatorId,
|
||||||
DateTimeOffset dateBegin,
|
DateTimeOffset dateBegin,
|
||||||
double intervalSec = 600d,
|
double intervalSec = 600d,
|
||||||
@ -150,13 +119,13 @@ public class TimestampedValuesRepository : ITimestampedValuesRepository
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async virtual Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
|
public async virtual Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
|
||||||
{
|
{
|
||||||
var query = GetQueryReadOnly()
|
var query = GetQueryReadOnly()
|
||||||
.Where(e => e.Timestamp > timestampBegin);
|
.Where(e => e.Timestamp > timestampBegin);
|
||||||
var entities = await query.ToArrayAsync(token);
|
var entities = await query.ToArrayAsync(token);
|
||||||
|
|
||||||
var result = entities.Select(e => Tuple.Create(
|
var result = entities.Select(e => (
|
||||||
e.Timestamp,
|
e.Timestamp,
|
||||||
e.Values
|
e.Values
|
||||||
));
|
));
|
||||||
|
@ -28,14 +28,14 @@ public interface ITimestampedValuesRepository : ISyncRepository, ITimeSeriesBase
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idDiscriminator">Дискриминатор (идентификатор) набора</param>
|
/// <param name="idDiscriminators">Набор дискриминаторов (идентификаторов)</param>
|
||||||
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
||||||
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</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<Tuple<DateTimeOffset, object[]>>> Get(Guid idDiscriminator,
|
Task<IDictionary<Guid, IEnumerable<(DateTimeOffset Timestamp, object[] Values)>>> Get(IEnumerable<Guid> idDiscriminators,
|
||||||
DateTimeOffset? geTimestamp,
|
DateTimeOffset? geTimestamp,
|
||||||
IEnumerable<string>? columnNames,
|
IEnumerable<string>? columnNames,
|
||||||
int skip,
|
int skip,
|
||||||
@ -49,7 +49,7 @@ public interface ITimestampedValuesRepository : ISyncRepository, ITimeSeriesBase
|
|||||||
/// <param name="takeCount">Количество</param>
|
/// <param name="takeCount">Количество</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetFirst(Guid discriminatorId, int takeCount, CancellationToken token);
|
Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetFirst(Guid discriminatorId, int takeCount, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение данных с конца
|
/// Получение данных с конца
|
||||||
@ -58,5 +58,5 @@ public interface ITimestampedValuesRepository : ISyncRepository, ITimeSeriesBase
|
|||||||
/// <param name="takeCount">Количество</param>
|
/// <param name="takeCount">Количество</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetLast(Guid discriminatorId, int takeCount, CancellationToken token);
|
Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetLast(Guid discriminatorId, int takeCount, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public interface ISyncRepository // ToDo: исчерпывающая абстр
|
|||||||
/// <param name="dateBegin">дата начала</param>
|
/// <param name="dateBegin">дата начала</param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetGtDate(Guid discriminatorId, DateTimeOffset dateBegin, CancellationToken token);
|
Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetGtDate(Guid discriminatorId, DateTimeOffset dateBegin, CancellationToken token);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -16,7 +16,7 @@ public interface ITimeSeriesBaseRepository // ToDo: исчерпывающая
|
|||||||
/// <param name="approxPointsCount"></param>
|
/// <param name="approxPointsCount"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<Tuple<DateTimeOffset, object[]>>> GetResampledData(
|
Task<IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> GetResampledData(
|
||||||
Guid discriminatorId,
|
Guid discriminatorId,
|
||||||
DateTimeOffset dateBegin,
|
DateTimeOffset dateBegin,
|
||||||
double intervalSec = 600d,
|
double intervalSec = 600d,
|
||||||
|
@ -25,19 +25,6 @@ public interface ITimestampedValuesService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> Count(Guid discriminatorId, CancellationToken token);
|
Task<int> Count(Guid discriminatorId, CancellationToken token);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получение данных с фильтрацией. Значение фильтра null - отключен
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="discriminatorId">Дискриминатор (идентификатор) набора</param>
|
|
||||||
/// <param name="geTimestamp">Фильтр позднее даты</param>
|
|
||||||
/// <param name="columnNames">Фильтр свойств набора. Можно запросить только некоторые свойства из набора</param>
|
|
||||||
/// <param name="skip"></param>
|
|
||||||
/// <param name="take"></param>
|
|
||||||
/// <param name="token"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<IEnumerable<TimestampedValuesDto>> Get(Guid discriminatorId, DateTimeOffset? geTimestamp,
|
|
||||||
IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получение данных с фильтрацией для нескольких систем. Значение фильтра null - отключен
|
/// Получение данных с фильтрацией для нескольких систем. Значение фильтра null - отключен
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -34,31 +34,12 @@ public class TimestampedValuesService : ITimestampedValuesService
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
|
||||||
{
|
|
||||||
var result = await timestampedValuesRepository.Get(discriminatorId, geTimestamp, columnNames, skip, take, token);
|
|
||||||
|
|
||||||
var dtos = await Materialize(discriminatorId, result, token);
|
|
||||||
|
|
||||||
if (!columnNames.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
dtos = ReduceSetColumnsByNames(dtos, columnNames!);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dtos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
public async Task<IEnumerable<TimestampedValuesDto>> Get(IEnumerable<Guid> discriminatorIds, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token)
|
||||||
{
|
{
|
||||||
var result = await timestampedValuesRepository.Get(discriminatorIds, geTimestamp, columnNames, skip, take, token);
|
var result = await timestampedValuesRepository.Get(discriminatorIds, geTimestamp, columnNames, skip, take, token);
|
||||||
|
|
||||||
List<TimestampedValuesDto> dtos = [];
|
var dtos = await Materialize(result, token);
|
||||||
discriminatorIds.ForEach(async discriminatorId => {
|
|
||||||
var materializeDtos = await Materialize(discriminatorId, result, token);
|
|
||||||
dtos.AddRange(materializeDtos);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!columnNames.IsNullOrEmpty())
|
if (!columnNames.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
@ -73,7 +54,9 @@ public class TimestampedValuesService : ITimestampedValuesService
|
|||||||
{
|
{
|
||||||
var result = await timestampedValuesRepository.GetFirst(discriminatorId, takeCount, token);
|
var result = await timestampedValuesRepository.GetFirst(discriminatorId, takeCount, token);
|
||||||
|
|
||||||
var dtos = await Materialize(discriminatorId, result, token);
|
var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
|
||||||
|
.ToDictionary();
|
||||||
|
var dtos = await Materialize(resultToMaterialize, token);
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
@ -83,7 +66,9 @@ public class TimestampedValuesService : ITimestampedValuesService
|
|||||||
{
|
{
|
||||||
var result = await timestampedValuesRepository.GetLast(discriminatorId, takeCount, token);
|
var result = await timestampedValuesRepository.GetLast(discriminatorId, takeCount, token);
|
||||||
|
|
||||||
var dtos = await Materialize(discriminatorId, result, token);
|
var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
|
||||||
|
.ToDictionary();
|
||||||
|
var dtos = await Materialize(resultToMaterialize, token);
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
@ -98,7 +83,9 @@ public class TimestampedValuesService : ITimestampedValuesService
|
|||||||
{
|
{
|
||||||
var result = await timestampedValuesRepository.GetResampledData(discriminatorId, beginTimestamp, intervalSec, approxPointsCount, token);
|
var result = await timestampedValuesRepository.GetResampledData(discriminatorId, beginTimestamp, intervalSec, approxPointsCount, token);
|
||||||
|
|
||||||
var dtos = await Materialize(discriminatorId, result, token);
|
var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
|
||||||
|
.ToDictionary();
|
||||||
|
var dtos = await Materialize(resultToMaterialize, token);
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
@ -108,7 +95,9 @@ public class TimestampedValuesService : ITimestampedValuesService
|
|||||||
{
|
{
|
||||||
var result = await timestampedValuesRepository.GetGtDate(discriminatorId, beginTimestamp, token);
|
var result = await timestampedValuesRepository.GetGtDate(discriminatorId, beginTimestamp, token);
|
||||||
|
|
||||||
var dtos = await Materialize(discriminatorId, result, token);
|
var resultToMaterialize = new[] { KeyValuePair.Create(discriminatorId, result) }
|
||||||
|
.ToDictionary();
|
||||||
|
var dtos = await Materialize(resultToMaterialize, token);
|
||||||
|
|
||||||
return dtos;
|
return dtos;
|
||||||
}
|
}
|
||||||
@ -132,35 +121,38 @@ public class TimestampedValuesService : ITimestampedValuesService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Преобразовать результат запроса в набор dto
|
/// Преобразовать результат запроса в набор dto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataSchemeId"></param>
|
|
||||||
/// <param name="queryResult"></param>
|
/// <param name="queryResult"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<IEnumerable<TimestampedValuesDto>> Materialize(Guid dataSchemeId, IEnumerable<Tuple<DateTimeOffset, object[]>> queryResult, CancellationToken token)
|
private async Task<IEnumerable<TimestampedValuesDto>> Materialize(IDictionary<Guid, IEnumerable<(DateTimeOffset Timestamp, object[] Values)>> queryResult, CancellationToken token)
|
||||||
{
|
{
|
||||||
var dataScheme = await dataSchemeRepository.Get(dataSchemeId, token);
|
IEnumerable<TimestampedValuesDto> result = [];
|
||||||
if (dataScheme is null)
|
foreach (var keyValuePair in queryResult)
|
||||||
{
|
{
|
||||||
return [];
|
var dataScheme = await dataSchemeRepository.Get(keyValuePair.Key, token);
|
||||||
|
if (dataScheme is null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var tuple in keyValuePair.Value)
|
||||||
|
{
|
||||||
|
var identity = dataScheme!.PropNames;
|
||||||
|
var indexedIdentity = identity
|
||||||
|
.Select((value, index) => new { index, value });
|
||||||
|
|
||||||
|
var dto = new TimestampedValuesDto()
|
||||||
|
{
|
||||||
|
Timestamp = tuple.Timestamp.ToUniversalTime(),
|
||||||
|
Values = indexedIdentity
|
||||||
|
.ToDictionary(x => x.value, x => tuple.Values[x.index])
|
||||||
|
};
|
||||||
|
|
||||||
|
result = result.Append(dto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtos = queryResult.Select(entity =>
|
return result;
|
||||||
{
|
|
||||||
var dto = new TimestampedValuesDto()
|
|
||||||
{
|
|
||||||
Timestamp = entity.Item1.ToUniversalTime()
|
|
||||||
};
|
|
||||||
|
|
||||||
var identity = dataScheme!.PropNames;
|
|
||||||
var indexedIdentity = identity
|
|
||||||
.Select((value, index) => new { index, value });
|
|
||||||
dto.Values = indexedIdentity
|
|
||||||
.ToDictionary(x => x.value, x => entity.Item2[x.index]);
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
});
|
|
||||||
|
|
||||||
return dtos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user