diff --git a/DD.Persistence.API/Controllers/TimestampedValuesController.cs b/DD.Persistence.API/Controllers/TimestampedValuesController.cs
index 2b0b245..c4d498b 100644
--- a/DD.Persistence.API/Controllers/TimestampedValuesController.cs
+++ b/DD.Persistence.API/Controllers/TimestampedValuesController.cs
@@ -15,26 +15,26 @@ namespace DD.Persistence.API.Controllers;
[Route("api/[controller]/{discriminatorId}")]
public class TimestampedValuesController : ControllerBase
{
- private readonly ITimestampedValuesRepository repository;
+ private readonly ITimestampedValuesRepository timestampedValuesRepository;
public TimestampedValuesController(ITimestampedValuesRepository repository)
{
- this.repository = repository;
+ this.timestampedValuesRepository = repository;
}
///
- /// Записать новые данные
+ /// Записать новые данные.
/// Предполагается что данные с одним дискриминатором имеют одинаковую структуру
///
/// Дискриминатор (идентификатор) набора
- ///
+ ///
///
- /// кол-во затронутых записей
[HttpPost]
- [ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
- public async Task AddRange([FromRoute] Guid discriminatorId, [FromBody] IEnumerable sets, CancellationToken token)
+ [ProducesResponseType(typeof(int), (int)HttpStatusCode.Created)]
+ public async Task AddRange([FromRoute] Guid discriminatorId, [FromBody] IEnumerable dtos, CancellationToken token)
{
- var result = await repository.AddRange(discriminatorId, sets, token);
+ var result = await timestampedValuesRepository.AddRange(discriminatorId, dtos, token);
+
return Ok(result);
}
@@ -42,81 +42,100 @@ public class TimestampedValuesController : ControllerBase
/// Получение данных с фильтрацией. Значение фильтра null - отключен
///
/// Дискриминатор (идентификатор) набора
- /// Фильтр позднее даты
- /// Фильтр свойств набора. Можно запросить только некоторые свойства из набора
+ /// Фильтр позднее даты
+ /// Фильтр свойств набора
///
///
///
- /// Фильтрованный набор данных с сортировкой по отметке времени
[HttpGet]
- [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
- public async Task Get([FromRoute] Guid discriminatorId, DateTimeOffset? geTimestamp, [FromQuery] IEnumerable? columnNames, int skip, int take, CancellationToken token)
+ public async Task>> Get([FromRoute] Guid discriminatorId, DateTimeOffset? timestampBegin, [FromQuery] string[]? columnNames, int skip, int take, CancellationToken token)
{
- var result = await repository.Get(discriminatorId, geTimestamp, columnNames, skip, take, token);
- return Ok(result);
+ var result = await timestampedValuesRepository.Get(discriminatorId, timestampBegin, columnNames, skip, take, token);
+
+ return result.Any() ? Ok(result) : NoContent();
}
///
- /// Получить последние данные
+ /// Получить данные, начиная с заданной отметки времени
+ ///
+ /// Дискриминатор (идентификатор) набора
+ /// Фильтр позднее даты
+ ///
+ [HttpGet("gtdate")]
+ public async Task>> GetGtDate([FromRoute] Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
+ {
+ var result = await timestampedValuesRepository.GetGtDate(discriminatorId, timestampBegin, token);
+
+ return result.Any() ? Ok(result) : NoContent();
+ }
+
+ ///
+ /// Получить данные c начала
///
/// Дискриминатор (идентификатор) набора
- /// Фильтр свойств набора. Можно запросить только некоторые свойства из набора
///
///
- /// Фильтрованный набор данных с сортировкой по отметке времени
- [HttpGet("last")]
- [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
- public async Task GetLast([FromRoute] Guid discriminatorId, [FromQuery] IEnumerable? columnNames, int take, CancellationToken token)
+ [HttpGet("first")]
+ public async Task>> GetFirst([FromRoute] Guid discriminatorId, int take, CancellationToken token)
{
- var result = await repository.GetLast(discriminatorId, columnNames, take, token);
- return Ok(result);
+ var result = await timestampedValuesRepository.GetFirst(discriminatorId, take, token);
+
+ return result.Any() ? Ok(result) : NoContent();
}
///
- /// Диапазон дат за которые есть данные
- ///
- ///
- ///
- /// Дата первой и последней записи
- [HttpGet("datesRange")]
- [ProducesResponseType(typeof(DatesRangeDto), (int)HttpStatusCode.OK)]
- [ProducesResponseType((int)HttpStatusCode.NoContent)]
- public async Task GetDatesRange([FromRoute] Guid discriminatorId, CancellationToken token)
- {
- var result = await repository.GetDatesRange(discriminatorId, token);
- return Ok(result);
- }
-
- ///
- /// Количество записей по указанному набору в БД. Для пагинации.
+ /// Получить данные c конца
///
/// Дискриминатор (идентификатор) набора
+ ///
///
- ///
- [HttpGet("count")]
- [ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
- [ProducesResponseType((int)HttpStatusCode.NoContent)]
- public async Task Count([FromRoute] Guid discriminatorId, CancellationToken token)
+ [HttpGet("last")]
+ public async Task>> GetLast([FromRoute] Guid discriminatorId, int take, CancellationToken token)
{
- var result = await repository.Count(discriminatorId, token);
- return Ok(result);
+ var result = await timestampedValuesRepository.GetLast(discriminatorId, take, token);
+
+ return result.Any() ? Ok(result) : NoContent();
}
///
/// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
///
- ///
- ///
+ /// Дискриминатор (идентификатор) набора
+ /// Фильтр позднее даты
///
///
///
- ///
[HttpGet("resampled")]
- [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)]
- [ProducesResponseType((int)HttpStatusCode.NoContent)]
- public async Task GetResampledData([FromRoute] Guid discriminatorId, DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
+ public async Task>> GetResampledData([FromRoute] Guid discriminatorId, DateTimeOffset timestampBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default)
{
- var result = await repository.GetResampledData(discriminatorId, dateBegin, intervalSec, approxPointsCount, token);
+ var result = await timestampedValuesRepository.GetResampledData(discriminatorId, timestampBegin, intervalSec, approxPointsCount, token);
+
+ return result.Any() ? Ok(result) : NoContent();
+ }
+
+ ///
+ /// Получить количество записей по указанному набору в БД. Для пагинации
+ ///
+ /// Дискриминатор (идентификатор) набора
+ ///
+ [HttpGet("count")]
+ public async Task> Count([FromRoute] Guid discriminatorId, CancellationToken token)
+ {
+ var result = await timestampedValuesRepository.Count(discriminatorId, token);
+
+ return Ok(result);
+ }
+
+ ///
+ /// Получить диапазон дат, в пределах которых хранятся даные
+ ///
+ ///
+ ///
+ [HttpGet("datesRange")]
+ public async Task> GetDatesRange([FromRoute] Guid discriminatorId, CancellationToken token)
+ {
+ var result = await timestampedValuesRepository.GetDatesRange(discriminatorId, token);
+
return Ok(result);
}
}
diff --git a/DD.Persistence.Client/Clients/Base/BaseClient.cs b/DD.Persistence.Client/Clients/Base/BaseClient.cs
index 3b13cdb..f9bcdd7 100644
--- a/DD.Persistence.Client/Clients/Base/BaseClient.cs
+++ b/DD.Persistence.Client/Clients/Base/BaseClient.cs
@@ -12,13 +12,13 @@ public abstract class BaseClient
this.logger = logger;
}
- public async Task ExecuteGetResponse(Func>> getMethod, CancellationToken token)
+ public async Task ExecuteGetResponse(Func>> getMethod, CancellationToken token)
{
var response = await getMethod.Invoke().WaitAsync(token);
if (response.IsSuccessStatusCode)
{
- return response.Content;
+ return response.Content!;
}
var exception = response.GetPersistenceException();
diff --git a/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs b/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
index ea1f576..23f1ddf 100644
--- a/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/Interfaces/ITimestampedValuesClient.cs
@@ -10,61 +10,71 @@ namespace DD.Persistence.Client.Clients.Interfaces;
///
public interface ITimestampedValuesClient : IDisposable
{
- ///
- /// Записать новые данные
- ///
- ///
- ///
- ///
- ///
- Task AddRange(Guid discriminatorId, IEnumerable sets, CancellationToken token);
-
- ///
- /// Количество записей по указанному набору в БД. Для пагинации
- ///
- ///
- ///
- ///
- Task Count(Guid discriminatorId, CancellationToken token);
-
- ///
- /// Получение данных с фильтрацией. Значение фильтра null - отключен
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token);
-
- ///
- /// Диапазон дат за которые есть данные
- ///
- ///
- ///
- ///
- Task GetDatesRange(Guid discriminatorId, CancellationToken token);
+ ///
+ /// Записать новые данные
+ /// Предполагается что данные с одним дискриминатором имеют одинаковую структуру
+ ///
+ /// Дискриминатор (идентификатор) набора
+ ///
+ ///
+ Task AddRange(Guid discriminatorId, IEnumerable dtos, CancellationToken token);
///
- /// Получить последние данные
+ /// Получить данные с фильтрацией. Значение фильтра null - отключен
///
- ///
- ///
+ /// Дискриминатор (идентификатор) набора
+ /// Фильтр позднее даты
+ /// Фильтр свойств набора
+ ///
///
///
- ///
- Task> GetLast(Guid discriminatorId, IEnumerable? columnNames, int take, CancellationToken token);
+ Task> Get(Guid discriminatorId, DateTimeOffset? timestampBegin, IEnumerable? columnNames, int skip, int take, CancellationToken token);
///
- /// Получить список объектов с прореживанием, удовлетворяющий диапазону дат
+ /// Получить данные, начиная с заданной отметки времени
///
- ///
- ///
+ /// Дискриминатор (идентификатор) набора
+ /// Фильтр позднее даты
+ ///
+ Task> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token);
+
+ ///
+ /// Получить данные с начала
+ ///
+ /// Дискриминатор (идентификатор) набора
+ ///
+ ///
+ Task> GetFirst(Guid discriminatorId, int take, CancellationToken token);
+
+ ///
+ /// Получить данные с конца
+ ///
+ /// Дискриминатор (идентификатор) набора
+ ///
+ ///
+ Task> GetLast(Guid discriminatorId, int take, CancellationToken token);
+
+ ///
+ /// Получить данные с прореживанием, удовлетворяющем диапазону дат
+ ///
+ /// Дискриминатор (идентификатор) набора
+ ///
///
///
///
- ///
- Task> GetResampledData(Guid discriminatorId, DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default);
+ Task> GetResampledData(Guid discriminatorId, DateTimeOffset timestampBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default);
+
+ ///
+ /// Количество записей по указанному набору в БД. Для пагинации
+ ///
+ /// Дискриминатор (идентификатор) набора
+ ///
+ Task Count(Guid discriminatorId, CancellationToken token);
+
+ ///
+ /// Диапазон дат, в пределах которых осуществляется хранение данных
+ ///
+ /// Дискриминатор (идентификатор) набора
+ ///
+ Task GetDatesRange(Guid discriminatorId, CancellationToken token);
}
\ No newline at end of file
diff --git a/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitClient.cs b/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitClient.cs
index 9568a51..4a140e0 100644
--- a/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitClient.cs
+++ b/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitClient.cs
@@ -5,6 +5,10 @@ using System.Text;
using System.Threading.Tasks;
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
+
+///
+/// Базовый Refit интерфейс
+///
public interface IRefitClient
{
}
diff --git a/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs b/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs
index 2515a57..bd94136 100644
--- a/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/Interfaces/Refit/IRefitTimestampedValuesClient.cs
@@ -4,25 +4,58 @@ using Refit;
namespace DD.Persistence.Client.Clients.Interfaces.Refit;
+///
+/// Refit интерфейс для TimestampedValuesController
+///
public interface IRefitTimestampedValuesClient : IRefitClient, IDisposable
{
private const string baseUrl = "/api/TimestampedValues/{discriminatorId}";
+ ///
+ /// Записать новые данные
+ ///
[Post(baseUrl)]
- Task> AddRange(Guid discriminatorId, IEnumerable sets, CancellationToken token);
+ Task> AddRange(Guid discriminatorId, IEnumerable dtos, CancellationToken token);
+ ///
+ /// Получение данных с фильтрацией
+ ///
[Get(baseUrl)]
- Task>> Get(Guid discriminatorId, [Query] DateTimeOffset? geTimestamp, [Query] IEnumerable? columnNames, int skip, int take, CancellationToken token);
+ Task>> Get(Guid discriminatorId, DateTimeOffset? timestampBegin, [Query(CollectionFormat.Multi)] IEnumerable? columnNames, int skip, int take, CancellationToken token);
+ ///
+ /// Получить данные, начиная с заданной отметки времени
+ ///
+ [Get($"{baseUrl}/gtdate")]
+ Task>> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token);
+
+ ///
+ /// Получить данные c начала
+ ///
+ [Get($"{baseUrl}/first")]
+ Task>> GetFirst(Guid discriminatorId, int take, CancellationToken token);
+
+ ///
+ /// Получить данные c конца
+ ///
[Get($"{baseUrl}/last")]
- Task>> GetLast(Guid discriminatorId, [Query] IEnumerable? columnNames, int take, CancellationToken token);
+ Task>> GetLast(Guid discriminatorId, int take, CancellationToken token);
+ ///
+ /// Получить список объектов с прореживанием, удовлетворяющий диапазону временных отметок
+ ///
+ [Get($"{baseUrl}/resampled")]
+ Task>> GetResampledData(Guid discriminatorId, DateTimeOffset timestampBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default);
+
+ ///
+ /// Получить количество записей по указанному набору в БД. Для пагинации
+ ///
[Get($"{baseUrl}/count")]
Task> Count(Guid discriminatorId, CancellationToken token);
+ ///
+ /// Получить диапазон дат, в пределах которых хранятся даные
+ ///
[Get($"{baseUrl}/datesRange")]
Task> GetDatesRange(Guid discriminatorId, CancellationToken token);
-
- [Get($"{baseUrl}/resampled")]
- Task>> GetResampledData(Guid discriminatorId, DateTimeOffset dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default);
}
diff --git a/DD.Persistence.Client/Clients/TimestampedValuesClient.cs b/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
index d32e9b9..19fce3f 100644
--- a/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
+++ b/DD.Persistence.Client/Clients/TimestampedValuesClient.cs
@@ -1,20 +1,24 @@
-using Microsoft.Extensions.Logging;
-using DD.Persistence.Client.Clients.Base;
+using DD.Persistence.Client.Clients.Base;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client.Clients.Interfaces.Refit;
using DD.Persistence.Models;
using DD.Persistence.Models.Common;
+using Microsoft.Extensions.Logging;
namespace DD.Persistence.Client.Clients;
+
+///
public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
{
private readonly IRefitTimestampedValuesClient refitTimestampedSetClient;
+ ///
public TimestampedValuesClient(IRefitClientFactory refitTimestampedSetClientFactory, ILogger logger) : base(logger)
{
this.refitTimestampedSetClient = refitTimestampedSetClientFactory.Create();
}
+ ///
public async Task AddRange(Guid discriminatorId, IEnumerable sets, CancellationToken token)
{
var result = await ExecutePostResponse(
@@ -23,38 +27,42 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
return result;
}
+ ///
public async Task> Get(Guid discriminatorId, DateTimeOffset? geTimestamp, IEnumerable? columnNames, int skip, int take, CancellationToken token)
{
var result = await ExecuteGetResponse(
async () => await refitTimestampedSetClient.Get(discriminatorId, geTimestamp, columnNames, skip, take, token), token);
+ return result;
+ }
- return result!;
- }
+ ///
+ public async Task> GetGtDate(Guid discriminatorId, DateTimeOffset timestampBegin, CancellationToken token)
+ {
+ var result = await ExecuteGetResponse(
+ async () => await refitTimestampedSetClient.GetGtDate(discriminatorId, timestampBegin, token), token);
- public async Task> GetLast(Guid discriminatorId, IEnumerable? columnNames, int take, CancellationToken token)
+ return result;
+ }
+
+ ///
+ public async Task> GetFirst(Guid discriminatorId, int take, CancellationToken token)
+ {
+ var result = await ExecuteGetResponse(
+ async () => await refitTimestampedSetClient.GetFirst(discriminatorId, take, token), token);
+
+ return result;
+ }
+
+ ///
+ public async Task> GetLast(Guid discriminatorId, int take, CancellationToken token)
{
var result = await ExecuteGetResponse(
- async () => await refitTimestampedSetClient.GetLast(discriminatorId, columnNames, take, token), token);
+ async () => await refitTimestampedSetClient.GetLast(discriminatorId, take, token), token);
- return result!;
- }
-
- public async Task Count(Guid discriminatorId, CancellationToken token)
- {
- var result = await ExecuteGetResponse(
- async () => await refitTimestampedSetClient.Count(discriminatorId, token), token);
-
- return result;
- }
-
- public async Task GetDatesRange(Guid discriminatorId, CancellationToken token)
- {
- var result = await ExecuteGetResponse(
- async () => await refitTimestampedSetClient.GetDatesRange(discriminatorId, token), token);
-
- return result;
+ return result;
}
+ ///
public async Task> GetResampledData(Guid discriminatorId, DateTimeOffset dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default)
{
var result = await ExecuteGetResponse(
@@ -63,6 +71,25 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
return result;
}
+ ///
+ public async Task Count(Guid discriminatorId, CancellationToken token)
+ {
+ var result = await ExecuteGetResponse(
+ async () => await refitTimestampedSetClient.Count(discriminatorId, token), token);
+
+ return result;
+ }
+
+ ///
+ public async Task GetDatesRange(Guid discriminatorId, CancellationToken token)
+ {
+ var result = await ExecuteGetResponse(
+ async () => await refitTimestampedSetClient.GetDatesRange(discriminatorId, token), token);
+
+ return result;
+ }
+
+ ///
public void Dispose()
{
refitTimestampedSetClient.Dispose();
diff --git a/DD.Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs b/DD.Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs
index 51afc02..7974470 100644
--- a/DD.Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs
+++ b/DD.Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs
@@ -15,7 +15,7 @@ namespace DD.Persistence.IntegrationTests.Controllers
{
public class TechMessagesControllerTest : BaseIntegrationTest
{
- private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DataSourceSystem).FullName}CacheKey";
+ private static readonly string SystemCacheKey = $"{typeof(DataSourceSystem).FullName}CacheKey";
private readonly ITechMessagesClient techMessagesClient;
private readonly IMemoryCache memoryCache;
public TechMessagesControllerTest(WebAppFactoryFixture factory) : base(factory)
diff --git a/DD.Persistence.IntegrationTests/Controllers/TimestampedSetControllerTest.cs b/DD.Persistence.IntegrationTests/Controllers/TimestampedSetControllerTest.cs
deleted file mode 100644
index 97882e5..0000000
--- a/DD.Persistence.IntegrationTests/Controllers/TimestampedSetControllerTest.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using DD.Persistence.Client;
-using DD.Persistence.Client.Clients.Interfaces;
-using DD.Persistence.Models;
-using Xunit;
-using DD.Persistence.Client.Clients.Interfaces.Refit;
-using DD.Persistence.Client.Clients;
-using Microsoft.Extensions.Logging;
-using System.Text.Json;
-using System.Text;
-using Microsoft.Extensions.Primitives;
-using System.Dynamic;
-using Newtonsoft.Json.Linq;
-
-namespace DD.Persistence.IntegrationTests.Controllers;
-public class TimestampedSetControllerTest : BaseIntegrationTest
-{
- private readonly ITimestampedValuesClient client;
-
- public TimestampedSetControllerTest(WebAppFactoryFixture factory) : base(factory)
- {
- var refitClientFactory = scope.ServiceProvider
- .GetRequiredService>();
- var logger = scope.ServiceProvider.GetRequiredService>();
-
- client = scope.ServiceProvider
- .GetRequiredService();
- }
-
- [Fact]
- public async Task InsertRange()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- IEnumerable testSets = Generate(10, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
-
- // act
- var response = await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
-
- // assert
- Assert.Equal(testSets.Count(), response);
- }
-
- [Fact]
- public async Task Get_without_filter()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- int count = 10;
- IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
- await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
-
- // act
- var response = await client.Get(idDiscriminator, null, null, 0, int.MaxValue, CancellationToken.None);
-
- // assert
- Assert.NotNull(response);
- Assert.Equal(count, response.Count());
- }
-
- [Fact]
- public async Task Get_with_filter_props()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- int count = 10;
- IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
- await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
- string[] props = ["A"];
-
- // act
- var response = await client.Get(idDiscriminator, null, props, 0, int.MaxValue, new CancellationToken());
-
- // assert
- Assert.NotNull(response);
- Assert.Equal(count, response.Count());
- foreach (var item in response)
- {
- Assert.Single(item.Values!);
- var kv = item.Values!.First();
- Assert.Equal("A", ((KeyValuePair) kv).Key);
- }
- }
-
- [Fact]
- public async Task Get_geDate()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- int count = 10;
- var dateMin = DateTimeOffset.Now;
- var dateMax = DateTimeOffset.Now.AddSeconds(count);
- IEnumerable testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
- var insertResponse = await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
- var tail = testSets.OrderBy(t => t.Timestamp).Skip(count / 2).Take(int.MaxValue);
- var geDate = tail.First().Timestamp;
- var tolerance = TimeSpan.FromSeconds(1);
- var expectedCount = tail.Count();
-
- // act
- var response = await client.Get(idDiscriminator, geDate, null, 0, int.MaxValue, CancellationToken.None);
-
- // assert
- Assert.NotNull(response);
- Assert.Equal(expectedCount, response.Count());
- var minDate = response.Min(t => t.Timestamp);
- Assert.Equal(geDate, geDate, tolerance);
- }
-
- [Fact]
- public async Task Get_with_skip_take()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- int count = 10;
- IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
- await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
- var expectedCount = count / 2;
-
- // act
- var response = await client.Get(idDiscriminator, null, null, 2, expectedCount, new CancellationToken());
-
- // assert
- Assert.NotNull(response);
- Assert.Equal(expectedCount, response.Count());
- }
-
-
- [Fact]
- public async Task Get_with_big_skip_take()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- var expectedCount = 1;
- int count = 10 + expectedCount;
- IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
- await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
-
- // act
- var response = await client.Get(idDiscriminator, null, null, count - expectedCount, count, new CancellationToken());
-
- // assert
- Assert.NotNull(response);
- Assert.Equal(expectedCount, response.Count());
- }
-
- [Fact]
- public async Task GetLast()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- int count = 10;
- IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
- await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
- var expectedCount = 8;
-
- // act
- var response = await client.GetLast(idDiscriminator, null, expectedCount, new CancellationToken());
-
- // assert
- Assert.NotNull(response);
- Assert.Equal(expectedCount, response.Count());
- }
-
- [Fact]
- public async Task GetDatesRange()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- int count = 10;
- var dateMin = DateTimeOffset.Now;
- var dateMax = DateTimeOffset.Now.AddSeconds(count - 1);
- IEnumerable testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
- await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
- var tolerance = TimeSpan.FromSeconds(1);
-
- // act
- var response = await client.GetDatesRange(idDiscriminator, new CancellationToken());
-
- // assert
- Assert.NotNull(response);
- Assert.Equal(dateMin, response.From, tolerance);
- Assert.Equal(dateMax, response.To, tolerance);
- }
-
- [Fact]
- public async Task Count()
- {
- // arrange
- Guid idDiscriminator = Guid.NewGuid();
- int count = 144;
- IEnumerable testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
- await client.AddRange(idDiscriminator, testSets, CancellationToken.None);
-
- // act
- var response = await client.Count(idDiscriminator, new CancellationToken());
-
- // assert
- Assert.Equal(count, response);
- }
-
- private static IEnumerable Generate(int n, DateTimeOffset from)
- {
- var result = new List();
- for (int i = 0; i < n; i++)
- {
- var t = new object[] {
- new { A = i },
- new { B = i * 1.1 },
- new { C = $"Any{i}" },
- new { D = DateTimeOffset.Now }
- };
- string jsonString = JsonSerializer.Serialize(t);
- var values = JsonSerializer.Deserialize