Skip to content

Commit

Permalink
Merge branch 'master' into beta
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/Sitko.Core.App/Json/JsonHelper.cs
#	src/Sitko.Core.Db.Postgres/ModelBuilderExtensions.cs
#	src/Sitko.Core.Repository.Remote/Sitko.Core.Repository.Remote.csproj
#	tests/Sitko.Core.Repository.Remote.Tests/RemoteRepositoryTests.cs
  • Loading branch information
SonicGD committed Jan 7, 2023
2 parents ddcbc07 + d214513 commit 12fd1ce
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 75 deletions.
1 change: 1 addition & 0 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<PackageVersion Include="Serialize.Linq" Version="2.0.0"/>
<PackageVersion Include="MimeMapping" Version="1.0.1.37"/>
<PackageVersion Include="AWSSDK.S3" Version="3.7.101.16"/>
<PackageVersion Include="Remote.Linq.Newtonsoft.Json" Version="7.1.0"/>
</ItemGroup>

<!--Sitko libraries-->
Expand Down
51 changes: 27 additions & 24 deletions src/Sitko.Core.App/Json/JsonHelper.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
using Newtonsoft.Json;
using Serilog;

namespace Sitko.Core.App.Json;

public class JsonHelper
namespace Sitko.Core.App.Json
{
private static JsonSerializerSettings GetJsonSettings(bool throwOnError) =>
new()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
DateParseHandling = DateParseHandling.DateTimeOffset,
TypeNameHandling = TypeNameHandling.Auto,
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead,
Error = (_, e) =>
public class JsonHelper
{
private static JsonSerializerSettings GetJsonSettings(bool throwOnError, bool prettify = false) =>
new()
{
if (!throwOnError)
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
DateParseHandling = DateParseHandling.DateTimeOffset,
TypeNameHandling = TypeNameHandling.Auto,
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead,
Formatting = prettify ? Formatting.Indented : Formatting.None,
Error = (_, e) =>
{
Log.Logger.Error(e.ErrorContext.Error, "Error deserializing json content: {ErrorText}",
e.ErrorContext.Error.ToString());
e.ErrorContext.Handled = true;
if (!throwOnError)
{
Log.Logger.Error(e.ErrorContext.Error, "Error deserializing json content: {ErrorText}",
e.ErrorContext.Error.ToString());
e.ErrorContext.Handled = true;
}
}
}
};
};

public static string SerializeWithMetadata(object obj, bool throwOnError = true) =>
JsonConvert.SerializeObject(obj, GetJsonSettings(throwOnError));
public static string SerializeWithMetadata(object obj, bool throwOnError = true, bool prettify = false) =>
JsonConvert.SerializeObject(obj, GetJsonSettings(throwOnError, prettify));

public static T? DeserializeWithMetadata<T>(string json, bool throwOnError = true) =>
JsonConvert.DeserializeObject<T>(json, GetJsonSettings(throwOnError));
public static T? DeserializeWithMetadata<T>(string json, bool throwOnError = true, bool prettify = false) =>
JsonConvert.DeserializeObject<T>(json, GetJsonSettings(throwOnError, prettify));

public static T? Clone<T>(T? obj, bool throwOnError = true) where T : class =>
obj is null ? null : DeserializeWithMetadata<T>(SerializeWithMetadata(obj, throwOnError), throwOnError)!;
public static T? Clone<T>(T? obj, bool throwOnError = true, bool prettify = false) where T : class =>
obj is null
? null
: DeserializeWithMetadata<T>(SerializeWithMetadata(obj, throwOnError, prettify), throwOnError)!;
}
}

38 changes: 29 additions & 9 deletions src/Sitko.Core.Blazor.MudBlazor/Components/Form/BaseMudForm.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,32 @@
@typeparam TEntity
@inherits Sitko.Core.Blazor.Forms.BaseForm<TEntity>

<MudEditForm TEntity="TEntity" Entity="Entity" @ref="FormInstance">
<Sitko.Core.Blazor.FluentValidation.FluentValidator/>
<Sitko.Core.Blazor.Forms.FormEditContextCatcher Form="this"/>
@ChildContentFragment
@if (Debug)
{
<MudFormDebug TEntity="TEntity" Form="this"></MudFormDebug>
}
</MudEditForm>
@if (!IsLoading)
{
<MudEditForm TEntity="TEntity" Entity="Entity" @ref="FormInstance">
<Sitko.Core.Blazor.FluentValidation.FluentValidator/>
<Sitko.Core.Blazor.Forms.FormEditContextCatcher Form="this"/>
@ChildContentFragment
@if (Debug)
{
<MudFormDebug TEntity="TEntity" Form="this"></MudFormDebug>
}
</MudEditForm>
}
else
{
<div class="form-loading">
@if (LoadingContent is not null)
{
@LoadingContent
}
else
{
@ChildContentFragment
@if (Debug)
{
<MudFormDebug TEntity="TEntity" Form="this"></MudFormDebug>
}
}
</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public abstract partial class BaseMudForm<TEntity>
where TEntity : class, new()
{
protected abstract RenderFragment ChildContentFragment { get; }
[Parameter] public RenderFragment? LoadingContent { get; set; }
protected MudEditForm<TEntity>? FormInstance { get; set; }
[Inject] public ISnackbar Snackbar { get; set; } = null!;
[Parameter] public bool Debug { get; set; }
Expand Down Expand Up @@ -72,8 +73,9 @@ protected override void OnParametersSet()

public override async Task ResetAsync()
{
await StartLoadingAsync();
await base.ResetAsync();
FormInstance?.Reset();
await StopLoadingAsync();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,32 @@
@typeparam TEntityPk
@typeparam TRepository
@inherits Sitko.Core.Blazor.Forms.BaseRepositoryForm<TEntity, TEntityPk, TRepository>
<MudEditForm TEntity="TEntity" Entity="Entity" @ref="FormInstance">
<Sitko.Core.Blazor.FluentValidation.FluentValidator/>
<Sitko.Core.Blazor.Forms.FormEditContextCatcher Form="this"/>
@ChildContentFragment
@if (Debug)
{
<MudFormDebug TEntity="TEntity" Form="this"></MudFormDebug>
}
</MudEditForm>
@if (!IsLoading)
{
<MudEditForm TEntity="TEntity" Entity="Entity" @ref="FormInstance">
<Sitko.Core.Blazor.FluentValidation.FluentValidator/>
<Sitko.Core.Blazor.Forms.FormEditContextCatcher Form="this"/>
@ChildContentFragment
@if (Debug)
{
<MudFormDebug TEntity="TEntity" Form="this"></MudFormDebug>
}
</MudEditForm>
}
else
{
<div class="form-loading">
@if (LoadingContent is not null)
{
@LoadingContent
}
else
{
@ChildContentFragment
@if (Debug)
{
<MudFormDebug TEntity="TEntity" Form="this"></MudFormDebug>
}
}
</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public abstract partial class BaseMudRepositoryForm<TEntity, TEntityPk, TReposit
[Inject] public ISnackbar Snackbar { get; set; } = null!;
protected abstract RenderFragment ChildContentFragment { get; }

[Parameter] public RenderFragment? LoadingContent { get; set; }

protected override Task NotifySuccessAsync()
{
Snackbar.Add(LocalizationProvider["Entity saved successfully"], Severity.Success);
Expand All @@ -46,8 +48,9 @@ protected override Task NotifyExceptionAsync(Exception ex)

public override async Task ResetAsync()
{
FormInstance!.Reset();
await StartLoadingAsync();
await base.ResetAsync();
await StopLoadingAsync();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public partial class MudFormDebug<TEntity> where TEntity : class, new()
{
[EditorRequired] [Parameter] public BaseForm<TEntity> Form { get; set; } = null!;

private string EntityJson => JsonHelper.SerializeWithMetadata(Form.Entity);
private string EntityJson => JsonHelper.SerializeWithMetadata(Form.Entity, prettify: true);
}

24 changes: 12 additions & 12 deletions src/Sitko.Core.Db.Postgres/ModelBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ public static class ModelBuilderExtensions
(c1, c2) => c1!.Equals(c2),
c => c!.GetHashCode(),
c => JsonHelper.DeserializeWithMetadata<TData>(
JsonHelper.SerializeWithMetadata(c!, throwOnError), throwOnError)!);
JsonHelper.SerializeWithMetadata(c!, throwOnError, false), throwOnError, false)!);
modelBuilder
.Entity<TEntity>()
.Property(getProperty)
.HasColumnType("jsonb")
.HasColumnName(name)
.HasConversion(data => JsonHelper.SerializeWithMetadata(data!, throwOnError),
json => JsonHelper.DeserializeWithMetadata<TData>(json, throwOnError) ?? new TData())
.HasConversion(data => JsonHelper.SerializeWithMetadata(data!, throwOnError, false),
json => JsonHelper.DeserializeWithMetadata<TData>(json, throwOnError, false) ?? new TData())
.Metadata.SetValueComparer(valueComparer);
}

Expand All @@ -36,14 +36,14 @@ public static class ModelBuilderExtensions
#pragma warning restore CS8604
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v!.GetHashCode())),
c => JsonHelper.DeserializeWithMetadata<ICollection<TData>>(
JsonHelper.SerializeWithMetadata(c, throwOnError), throwOnError)!);
JsonHelper.SerializeWithMetadata(c, throwOnError, false), throwOnError, false)!);
modelBuilder
.Entity<TEntity>()
.Property(getProperty)
.HasColumnType("jsonb")
.HasColumnName(name)
.HasConversion(data => JsonHelper.SerializeWithMetadata(data, throwOnError),
json => JsonHelper.DeserializeWithMetadata<ICollection<TData>>(json, throwOnError) ??
.HasConversion(data => JsonHelper.SerializeWithMetadata(data, throwOnError, false),
json => JsonHelper.DeserializeWithMetadata<ICollection<TData>>(json, throwOnError, false) ??
new List<TData>())
.Metadata.SetValueComparer(valueComparer);
}
Expand All @@ -58,14 +58,14 @@ public static class ModelBuilderExtensions
#pragma warning restore CS8604
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v!.GetHashCode())),
c => JsonHelper.DeserializeWithMetadata<TData[]>(
JsonHelper.SerializeWithMetadata(c, throwOnError), throwOnError)!);
JsonHelper.SerializeWithMetadata(c, throwOnError, false), throwOnError, false)!);
modelBuilder
.Entity<TEntity>()
.Property(getProperty)
.HasColumnType("jsonb")
.HasColumnName(name)
.HasConversion(data => JsonHelper.SerializeWithMetadata(data, throwOnError),
json => JsonHelper.DeserializeWithMetadata<TData[]>(json, throwOnError) ?? Array.Empty<TData>())
.HasConversion(data => JsonHelper.SerializeWithMetadata(data, throwOnError, false),
json => JsonHelper.DeserializeWithMetadata<TData[]>(json, throwOnError, false) ?? Array.Empty<TData>())
.Metadata.SetValueComparer(valueComparer);
}

Expand All @@ -80,14 +80,14 @@ public static class ModelBuilderExtensions
#pragma warning restore CS8604
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v!.GetHashCode())),
c => JsonHelper.DeserializeWithMetadata<TEnumerable>(
JsonHelper.SerializeWithMetadata(c, throwOnError), throwOnError)!);
JsonHelper.SerializeWithMetadata(c, throwOnError, false), throwOnError, false)!);
modelBuilder
.Entity<TEntity>()
.Property(getProperty)
.HasColumnType("jsonb")
.HasColumnName(name)
.HasConversion(data => JsonHelper.SerializeWithMetadata(data, throwOnError),
json => JsonHelper.DeserializeWithMetadata<TEnumerable>(json, throwOnError) ??
.HasConversion(data => JsonHelper.SerializeWithMetadata(data, throwOnError,false),
json => JsonHelper.DeserializeWithMetadata<TEnumerable>(json, throwOnError,false) ??
new TEnumerable())
.Metadata.SetValueComparer(valueComparer);
}
Expand Down
39 changes: 26 additions & 13 deletions src/Sitko.Core.Repository.Remote/SerializedQuery.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
using System.Linq.Expressions;
using Serialize.Linq.Serializers;
using Newtonsoft.Json;
using Remote.Linq;
using Remote.Linq.Newtonsoft.Json;

namespace Sitko.Core.Repository.Remote;

public record SerializedQuery<TEntity> where TEntity : class
{
private readonly ExpressionSerializer serializer = new(new JsonSerializer());
private readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings().ConfigureRemoteLinq();

public SerializedQuery(SerializedQueryData? data = null) => Data = data ?? new SerializedQueryData();

public SerializedQueryData Data { get; }

private string Serialize(Expression expression) =>
JsonConvert.SerializeObject(expression.ToRemoteLinqExpression(), serializerSettings);

private T Deserialize<T>(string json) where T : Expression
{
var exp = JsonConvert.DeserializeObject<global::Remote.Linq.Expressions.Expression>(json, serializerSettings)!;
return (T)exp.ToLinqExpression();
}

public Expression<Func<TEntity, TValue>> SelectExpression<TValue>() => Data.SelectExpressionString is null
? throw new InvalidOperationException("Empty select expression")
: (Expression<Func<TEntity, TValue>>)serializer.DeserializeText(Data.SelectExpressionString);
: Deserialize<Expression<Func<TEntity, TValue>>>(Data.SelectExpressionString);

public SerializedQuery<TEntity> SetSelectExpression(Expression selectExpression)
{
Data.SelectExpressionString = serializer.SerializeText(selectExpression);
Data.SelectExpressionString =
Serialize(selectExpression);
return this;
}

Expand All @@ -34,7 +46,7 @@ public SerializedQuery<TEntity> AddWhereExpressions(IEnumerable<Expression<Func<

public SerializedQuery<TEntity> AddWhereExpression(Expression<Func<TEntity, bool>> expression)
{
Data.Where.Add(serializer.SerializeText(expression));
Data.Where.Add(Serialize(expression));
return this;
}

Expand Down Expand Up @@ -68,7 +80,7 @@ public SerializedQuery<TEntity> AddOrderByExpressions(IEnumerable<Expression<Fun

public SerializedQuery<TEntity> AddOrderByExpression(Expression<Func<TEntity, object>> expression)
{
Data.OrderBy.Add(serializer.SerializeText(expression));
Data.OrderBy.Add(Serialize(expression));
return this;
}

Expand All @@ -85,7 +97,7 @@ public SerializedQuery<TEntity> AddOrderByExpression(Expression<Func<TEntity, ob

public SerializedQuery<TEntity> AddOrderByDescendingExpression(Expression<Func<TEntity, object>> expression)
{
Data.OrderByDescending.Add(serializer.SerializeText(expression));
Data.OrderByDescending.Add(Serialize(expression));
return this;
}

Expand Down Expand Up @@ -132,8 +144,8 @@ public void Apply(IRepositoryQuery<TEntity> query)
{
foreach (var expressionNode in Data.Where)
{
var ex = serializer.DeserializeText(expressionNode);
query.Where((Expression<Func<TEntity, bool>>)ex);
var ex = Deserialize<Expression<Func<TEntity, bool>>>(expressionNode);
query.Where(ex);
}

foreach (var (whereStr, values) in Data.WhereByString)
Expand All @@ -150,14 +162,14 @@ public void Apply(IRepositoryQuery<TEntity> query)

foreach (var expressionNode in Data.OrderBy)
{
var ex = serializer.DeserializeText(expressionNode);
query.OrderBy((Expression<Func<TEntity, object>>)ex);
var ex = Deserialize<Expression<Func<TEntity, object>>>(expressionNode);
query.OrderBy(ex);
}

foreach (var expressionNode in Data.OrderByDescending)
{
var ex = serializer.DeserializeText(expressionNode);
query.OrderByDescending((Expression<Func<TEntity, object>>)ex);
var ex = Deserialize<Expression<Func<TEntity, object>>>(expressionNode);
query.OrderByDescending(ex);
}

foreach (var (propertyName, isDescending) in Data.OrderByString)
Expand All @@ -182,3 +194,4 @@ public void Apply(IRepositoryQuery<TEntity> query)
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CompareNETObjects" />
<PackageReference Include="Serialize.Linq" />
<PackageReference Include="Remote.Linq.Newtonsoft.Json" />
</ItemGroup>
</Project>
Loading

0 comments on commit 12fd1ce

Please sign in to comment.