Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions src/SIL.Harmony/Db/EntityConfig/ChangeEntityConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,45 @@

namespace SIL.Harmony.Db.EntityConfig;

public class ChangeEntityConfig(JsonSerializerOptions jsonSerializerOptions) : IEntityTypeConfiguration<ChangeEntity<IChange>>
public class ChangeEntityConfig(JsonSerializerOptions jsonSerializerOptions)
: IEntityTypeConfiguration<ChangeEntity<IChange>>
{
public ChangeEntityConfig() : this(JsonSerializerOptions.Default)
{
}

public void Configure(EntityTypeBuilder<ChangeEntity<IChange>> builder)
{
builder.ToTable("ChangeEntities");
builder.HasKey(c => new { c.CommitId, c.Index });
builder.Property(c => c.Change)
.HasColumnType("jsonb")
.HasConversion(
change => JsonSerializer.Serialize(change, jsonSerializerOptions),
json => DeserializeChange(json)
);
var changeProperty = builder.Property(c => c.Change)
.HasColumnType("jsonb");
if (EF.IsDesignTime)
{
changeProperty
.HasConversion(
change => SerializeChange(change, null),
json => DeserializeChange(json, null)
);
}
else
{
changeProperty
.HasConversion(
change => SerializeChange(change, jsonSerializerOptions),
json => DeserializeChange(json, jsonSerializerOptions)
);
}
}

private IChange DeserializeChange(string json)
public static IChange DeserializeChange(string json, JsonSerializerOptions? jsonSerializerOptions)
{
return JsonSerializer.Deserialize<IChange>(json, jsonSerializerOptions) ??
throw new SerializationException("Could not deserialize Change: " + json);
}

public static string SerializeChange(IChange change, JsonSerializerOptions? jsonSerializerOptions)
{
return JsonSerializer.Serialize(change, jsonSerializerOptions);
}
}
17 changes: 15 additions & 2 deletions src/SIL.Harmony/Db/EntityConfig/CommitEntityConfig.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Runtime.Serialization;
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using SIL.Harmony.Changes;

namespace SIL.Harmony.Db.EntityConfig;

Expand All @@ -24,11 +26,22 @@ public void Configure(EntityTypeBuilder<Commit> builder)
builder.Property(c => c.Metadata)
.HasColumnType("jsonb")
.HasConversion(
m => JsonSerializer.Serialize(m, (JsonSerializerOptions?)null),
json => JsonSerializer.Deserialize<CommitMetadata>(json, (JsonSerializerOptions?)null) ?? new()
m => Serialize(m, null),
json => Deserialize(json, null) ?? new()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding EF.IsDesignTime conditional logic to match other config classes

Other entity configurations (ChangeEntityConfig and SnapshotEntityConfig) conditionally apply serialization options based on whether EF is in design-time mode. This file should follow the same pattern for consistency.

-                m => Serialize(m, null),
-                json => Deserialize(json, null) ?? new()
+                var metadataProperty = builder.Property(c => c.Metadata)
+                    .HasColumnType("jsonb");
+                if (EF.IsDesignTime)
+                {
+                    metadataProperty.HasConversion(
+                        m => Serialize(m, null),
+                        json => Deserialize(json, null) ?? new()
+                    );
+                }
+                else
+                {
+                    metadataProperty.HasConversion(
+                        m => Serialize(m, jsonSerializerOptions),
+                        json => Deserialize(json, jsonSerializerOptions) ?? new()
+                    );
+                }

Committable suggestion skipped: line range outside the PR's diff.

);
builder.HasMany(c => c.ChangeEntities)
.WithOne()
.HasForeignKey(c => c.CommitId);
}

public static CommitMetadata Deserialize(string json, JsonSerializerOptions? jsonSerializerOptions)
{
return JsonSerializer.Deserialize<CommitMetadata>(json, jsonSerializerOptions) ??
throw new SerializationException("Could not deserialize CommitMetadata: " + json);
}

public static string Serialize(CommitMetadata commitMetadata, JsonSerializerOptions? jsonSerializerOptions)
{
return JsonSerializer.Serialize(commitMetadata, jsonSerializerOptions);
}
}
27 changes: 21 additions & 6 deletions src/SIL.Harmony/Db/EntityConfig/SnapshotEntityConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,32 @@ public void Configure(EntityTypeBuilder<ObjectSnapshot> builder)
.HasOne(s => s.Commit)
.WithMany(c => c.Snapshots)
.HasForeignKey(s => s.CommitId);
builder.Property(s => s.Entity)
.HasColumnType("jsonb")
.HasConversion(
entry => JsonSerializer.Serialize(entry, jsonSerializerOptions),
json => DeserializeObject(json)
var entityProperty = builder.Property(s => s.Entity)
.HasColumnType("jsonb");
if (EF.IsDesignTime)
{
entityProperty.HasConversion(
entry => Serialize(entry, null),
json => DeserializeObject(json, null)
);
}
else
{
entityProperty.HasConversion(
entry => Serialize(entry, jsonSerializerOptions),
json => DeserializeObject(json, jsonSerializerOptions)
);
}
}

private IObjectBase DeserializeObject(string json)
public static IObjectBase DeserializeObject(string json, JsonSerializerOptions? jsonSerializerOptions)
{
return JsonSerializer.Deserialize<IObjectBase>(json, jsonSerializerOptions) ??
throw new SerializationException($"Could not deserialize Entry: {json}");
}

public static string Serialize(IObjectBase change, JsonSerializerOptions? jsonSerializerOptions)
{
return JsonSerializer.Serialize(change, jsonSerializerOptions);
}
}