Добавлен маппинг для TimeStampedData
Some checks failed
Unit tests / test (push) Failing after 1m6s

This commit is contained in:
Alex Shibalkin 2025-01-20 15:12:40 +05:00
parent a27bd14213
commit 75f6b5b1c3
5 changed files with 199 additions and 12 deletions

View File

@ -39,13 +39,26 @@ public interface ITimestampedSetClient : IDisposable
/// <returns></returns>
Task<IEnumerable<TimestampedSetDto>> Get(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
/// <summary>
/// Диапазон дат за которые есть данные
/// <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>
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
Task<IEnumerable<T>> Get<T>(Guid idDiscriminator, DateTimeOffset? geTimestamp, IEnumerable<string>? columnNames, int skip, int take, CancellationToken token);
/// <summary>
/// Диапазон дат за которые есть данные
/// </summary>
/// <param name="idDiscriminator"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
/// <summary>
///
@ -56,4 +69,14 @@ public interface ITimestampedSetClient : IDisposable
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<TimestampedSetDto>> GetLast(Guid idDiscriminator, IEnumerable<string>? columnNames, int take, CancellationToken token);
/// <summary>
///
/// </summary>
/// <param name="idDiscriminator"></param>
/// <param name="columnNames"></param>
/// <param name="take"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<T>> GetLast<T>(Guid idDiscriminator, IEnumerable<string>? columnNames, int take, CancellationToken token);
}

View File

@ -3,13 +3,18 @@ using DD.Persistence.Client.Clients.Base;
using DD.Persistence.Client.Clients.Interfaces;
using DD.Persistence.Client.Clients.Interfaces.Refit;
using DD.Persistence.Models;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Reflection;
using System.Collections.Concurrent;
namespace DD.Persistence.Client.Clients;
public class TimestampedSetClient : BaseClient, ITimestampedSetClient
{
private readonly IRefitTimestampedSetClient refitTimestampedSetClient;
public TimestampedSetClient(IRefitClientFactory<IRefitTimestampedSetClient> refitTimestampedSetClientFactory, ILogger<TimestampedSetClient> logger) : base(logger)
private readonly ConcurrentDictionary<Guid, TimestampedSetMapperBase> mapperCache = new();
public TimestampedSetClient(IRefitClientFactory<IRefitTimestampedSetClient> refitTimestampedSetClientFactory, ILogger<TimestampedSetClient> logger) : base(logger)
{
this.refitTimestampedSetClient = refitTimestampedSetClientFactory.Create();
}
@ -54,10 +59,34 @@ public class TimestampedSetClient : BaseClient, ITimestampedSetClient
return result;
}
public void Dispose()
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);
}
public async Task<IEnumerable<T>> GetLast<T>(Guid idDiscriminator, IEnumerable<string>? columnNames, int take, CancellationToken token)
{
var data = await GetLast(idDiscriminator, columnNames, take, token);
var mapper = GetMapper<T>(idDiscriminator);
return data.Select(mapper.DeserializeTimeStampedData);
}
private TimestampedSetMapper<T> GetMapper<T>(Guid idDiscriminator)
{
return (TimestampedSetMapper<T>)mapperCache.GetOrAdd(idDiscriminator, name => new TimestampedSetMapper<T>(idDiscriminator));
}
public void Dispose()
{
refitTimestampedSetClient.Dispose();
GC.SuppressFinalize(this);
}
}

View File

@ -11,9 +11,9 @@
<!--Наименование-->
<Title>DD.Persistence.Client</Title>
<!--Версия пакета-->
<VersionPrefix>1.4.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH)).1</VersionPrefix>
<VersionPrefix>1.5.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH)).1</VersionPrefix>
<!--Версия сборки-->
<AssemblyVersion>1.4.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH)).1</AssemblyVersion>
<AssemblyVersion>1.5.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH)).1</AssemblyVersion>
<!--Id пакета-->
<PackageId>DD.Persistence.Client</PackageId>
@ -40,8 +40,8 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.4.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
<AssemblyVersion>1.4.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
<VersionPrefix>1.5.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
<AssemblyVersion>1.5.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
</PropertyGroup>
<ItemGroup>

View File

@ -0,0 +1,135 @@
using DD.Persistence.Models;
using System.Collections.Concurrent;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.Json;
namespace DD.Persistence.Client;
internal abstract class TimestampedSetMapperBase
{
public abstract object Map(TimestampedSetDto data);
}
internal class TimestampedSetMapper<T> : TimestampedSetMapperBase
{
private readonly Type entityType = typeof(T);
public Guid IdDiscriminator { get; }
private readonly ConcurrentDictionary<string, PropertyInfo?> PropertyCache = new();
public TimestampedSetMapper(Guid idDiscriminator)
{
IdDiscriminator = idDiscriminator;
}
public override object Map(TimestampedSetDto data)
{
return DeserializeTimeStampedData(data)!;
}
public T DeserializeTimeStampedData(TimestampedSetDto data)
{
if (entityType.IsValueType)
return MapStruct(data);
else
return MapClass(data);
}
private T MapClass(TimestampedSetDto data)
{
var entity = (T)RuntimeHelpers.GetUninitializedObject(typeof(T));
foreach (var (propertyName, value) in data.Set)
{
if (value is JsonElement jsonElement)
SetPropertyValueFromJson(ref entity, propertyName, jsonElement);
}
SetPropertyValue(ref entity, "Timestamp", data.Timestamp);
return entity;
}
private T MapStruct(TimestampedSetDto data)
{
var entity = Activator.CreateInstance<T>();
object boxedEntity = entity!;
foreach (var (propertyName, value) in data.Set)
{
if (value is JsonElement jsonElement)
SetPropertyValueForStructFromJson(ref boxedEntity, propertyName, jsonElement);
}
SetPropertyValueForStruct(ref boxedEntity, "Timestamp", data.Timestamp);
return (T)boxedEntity;
}
private void SetPropertyValueForStructFromJson(ref object entity, string propertyName, JsonElement element)
{
var property = GetPropertyInfo(propertyName);
if (property is null)
return;
try
{
var value = element.Deserialize(property.PropertyType);
property.SetValue(entity, value);
}
catch (Exception ex)
{
}
}
private void SetPropertyValueForStruct(ref object entity, string propertyName, object value)
{
var property = GetPropertyInfo(propertyName);
if (property is null)
return;
try
{
var convertedValue = Convert.ChangeType(value, property.PropertyType);
property.SetValue(entity, convertedValue);
}
catch (Exception ex)
{
}
}
private void SetPropertyValueFromJson(ref T entity, string propertyName, JsonElement jsonElement)
{
var property = GetPropertyInfo(propertyName);
if (property is null)
return;
try
{
var value = jsonElement.Deserialize(property.PropertyType);
property.SetValue(entity, value);
}
catch (Exception ex)
{
}
}
private void SetPropertyValue(ref T entity, string propertyName, object value)
{
var property = GetPropertyInfo(propertyName);
if (property is null)
return;
try
{
var convertedValue = Convert.ChangeType(value, property.PropertyType);
property.SetValue(entity, convertedValue);
}
catch (Exception ex)
{
}
}
private PropertyInfo? GetPropertyInfo(string propertyName)
{
return PropertyCache.GetOrAdd(propertyName, name => entityType.GetProperty(name));
}
}

View File

@ -11,9 +11,9 @@
<!--Наименование-->
<Title>DD.Persistence.Models</Title>
<!--Версия пакета-->
<VersionPrefix>1.2.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
<VersionPrefix>1.3.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</VersionPrefix>
<!--Версия сборки-->
<AssemblyVersion>1.2.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
<AssemblyVersion>1.3.$([System.DateTime]::UtcNow.ToString(yyMM.ddHH))</AssemblyVersion>
<!--Id пакета-->
<PackageId>DD.Persistence.Models</PackageId>