Merge branch 'master' into TimestampedValuesRepository
Some checks failed
Unit tests / test (push) Failing after 57s
Some checks failed
Unit tests / test (push) Failing after 57s
This commit is contained in:
commit
1e0bae5435
@ -1,10 +1,10 @@
|
||||
{
|
||||
"DbConnection": {
|
||||
"Host": "postgres",
|
||||
"Host": "localhost",
|
||||
"Port": 5432,
|
||||
"Database": "persistence",
|
||||
"Username": "postgres",
|
||||
"Password": "postgres"
|
||||
"Password": "q"
|
||||
},
|
||||
"NeedUseKeyCloak": false,
|
||||
"AuthUser": {
|
||||
|
@ -77,4 +77,28 @@ public interface ITimestampedValuesClient : IDisposable
|
||||
/// <param name="discriminatorId">Дискриминатор (идентификатор) набора</param>
|
||||
/// <param name="token"></param>
|
||||
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>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <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, int take, CancellationToken token);
|
||||
}
|
@ -4,6 +4,7 @@ using DD.Persistence.Client.Clients.Interfaces.Refit;
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace DD.Persistence.Client.Clients;
|
||||
|
||||
@ -18,6 +19,9 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
|
||||
this.refitTimestampedSetClient = refitTimestampedSetClientFactory.Create();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
private readonly ConcurrentDictionary<Guid, TimestampedSetMapperBase> mapperCache = new();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<int> AddRange(Guid discriminatorId, IEnumerable<TimestampedValuesDto> sets, CancellationToken token)
|
||||
{
|
||||
@ -89,6 +93,30 @@ public class TimestampedValuesClient : BaseClient, ITimestampedValuesClient
|
||||
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/>
|
||||
public async Task<IEnumerable<T>> GetLast<T>(Guid idDiscriminator, int take, CancellationToken token)
|
||||
{
|
||||
var data = await GetLast(idDiscriminator, take, token);
|
||||
var mapper = GetMapper<T>(idDiscriminator);
|
||||
|
||||
return data.Select(mapper.DeserializeTimeStampedData);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
private TimestampedSetMapper<T> GetMapper<T>(Guid idDiscriminator)
|
||||
{
|
||||
return (TimestampedSetMapper<T>)mapperCache.GetOrAdd(idDiscriminator, name => new TimestampedSetMapper<T>(idDiscriminator));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
|
@ -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>
|
||||
|
135
DD.Persistence.Client/TimestampedSetMapper.cs
Normal file
135
DD.Persistence.Client/TimestampedSetMapper.cs
Normal 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(TimestampedValuesDto 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(TimestampedValuesDto data)
|
||||
{
|
||||
return DeserializeTimeStampedData(data)!;
|
||||
}
|
||||
|
||||
public T DeserializeTimeStampedData(TimestampedValuesDto data)
|
||||
{
|
||||
|
||||
if (entityType.IsValueType)
|
||||
return MapStruct(data);
|
||||
else
|
||||
return MapClass(data);
|
||||
}
|
||||
|
||||
private T MapClass(TimestampedValuesDto data)
|
||||
{
|
||||
var entity = (T)RuntimeHelpers.GetUninitializedObject(typeof(T));
|
||||
foreach (var (propertyName, value) in data.Values)
|
||||
{
|
||||
if (value is JsonElement jsonElement)
|
||||
SetPropertyValueFromJson(ref entity, propertyName, jsonElement);
|
||||
}
|
||||
SetPropertyValue(ref entity, "Timestamp", data.Timestamp);
|
||||
return entity;
|
||||
}
|
||||
|
||||
private T MapStruct(TimestampedValuesDto data)
|
||||
{
|
||||
var entity = Activator.CreateInstance<T>();
|
||||
object boxedEntity = entity!;
|
||||
foreach (var (propertyName, value) in data.Values)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user