Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement update and delete apis for ComplexFormTypes and sync them in CrdtFwdataProjectSyncService #1295

Merged
merged 16 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
42 changes: 42 additions & 0 deletions backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
}
await Cache.DoUsingNewOrCurrentUOW("Update WritingSystem",
"Revert WritingSystem",
async () =>

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FwHeadless / publish-fw-headless

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Windows

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 204 in backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Windows

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
var updateProxy = new UpdateWritingSystemProxy(lcmWritingSystem, this)
{
Expand Down Expand Up @@ -377,6 +377,14 @@
{
return ComplexFormTypesFlattened.Select(ToComplexFormType).ToAsyncEnumerable();
}

public Task<ComplexFormType?> GetComplexFormType(Guid id)
{
var lexEntryType = ComplexFormTypesFlattened.SingleOrDefault(c => c.Guid == id);
if (lexEntryType is null) return Task.FromResult<ComplexFormType?>(null);
return Task.FromResult<ComplexFormType?>(ToComplexFormType(lexEntryType));
}

private ComplexFormType ToComplexFormType(ILexEntryType t)
{
return new ComplexFormType() { Id = t.Guid, Name = FromLcmMultiString(t.Name) };
Expand All @@ -400,6 +408,40 @@
return ToComplexFormType(ComplexFormTypesFlattened.Single(c => c.Guid == complexFormType.Id));
}

public Task<ComplexFormType> UpdateComplexFormType(Guid id, UpdateObjectInput<ComplexFormType> update)
{
var type = ComplexFormTypesFlattened.SingleOrDefault(c => c.Guid == id);
if (type is null) throw new NullReferenceException($"unable to find complex form type with id {id}");
UndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW("Update Complex Form Type",
"Revert Complex Form Type",
Cache.ServiceLocator.ActionHandler,
() =>
{
var updateProxy = new UpdateComplexFormTypeProxy(type, null, this);
update.Apply(updateProxy);
});
return Task.FromResult(ToComplexFormType(type));
}

public async Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after)
{
await ComplexFormTypeSync.Sync(before, after, this);
return ToComplexFormType(ComplexFormTypesFlattened.Single(c => c.Guid == after.Id));
}

public async Task DeleteComplexFormType(Guid id)
{
var type = ComplexFormTypesFlattened.SingleOrDefault(c => c.Guid == id);
if (type is null) return;
await Cache.DoUsingNewOrCurrentUOW("Delete Complex Form Type",
"Revert delete",
() =>
{
type.Delete();
return ValueTask.CompletedTask;
});
}

public IAsyncEnumerable<VariantType> GetVariantTypes()
{
return VariantTypes.PossibilitiesOS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,35 @@ namespace FwDataMiniLcmBridge.Api.UpdateProxy;
public record UpdateComplexFormTypeProxy : ComplexFormType
{
private readonly ILexEntryType _lexEntryType;
private readonly ILexEntry _lcmEntry;
private readonly ILexEntry? _lcmEntry;
private readonly FwDataMiniLcmApi _lexboxLcmApi;

[SetsRequiredMembers]
public UpdateComplexFormTypeProxy(ILexEntryType lexEntryType, ILexEntry lcmEntry, FwDataMiniLcmApi lexboxLcmApi)
public UpdateComplexFormTypeProxy(ILexEntryType lexEntryType, ILexEntry? lcmEntry, FwDataMiniLcmApi lexboxLcmApi)
{
_lexEntryType = lexEntryType;
_lcmEntry = lcmEntry;
_lexboxLcmApi = lexboxLcmApi;
Name = new();
Name = base.Name = new();
}

public override Guid Id
{
get => _lexEntryType.Guid;
set
{
if (_lcmEntry is null)
throw new InvalidOperationException("Cannot update complex form type Id on a null entry");
_lexboxLcmApi.RemoveComplexFormType(_lcmEntry, _lexEntryType.Guid);
_lexboxLcmApi.AddComplexFormType(_lcmEntry, value);
}
}

public override required MultiString Name
{
get => new UpdateMultiStringProxy(_lexEntryType.Name, _lexboxLcmApi);
set
{
}
}
}
2 changes: 1 addition & 1 deletion backend/FwLite/FwLiteProjectSync.Tests/Sena3SyncTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private void ShouldAllBeEquivalentTo(Dictionary<Guid, Entry> crdtEntries, Dictio
//by default the first sync is an import, this will skip that so that the sync will actually sync data
private async Task BypassImport()
{
await _syncService.SaveProjectSnapshot(_fwDataApi.Project, new ([], [], []));
await _syncService.SaveProjectSnapshot(_fwDataApi.Project, CrdtFwdataProjectSyncService.ProjectSnapshot.Empty);
}

//this lets us query entries when there is no writing system
Expand Down
14 changes: 14 additions & 0 deletions backend/FwLite/FwLiteProjectSync.Tests/SyncTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -500,4 +500,18 @@ public async Task CanCreateAComplexFormAndItsComponentInOneSync()
//one of the entries will be created first, it will try to create the reference to the other but it won't exist yet
await _fixture.SyncService.Sync(_fixture.CrdtApi, _fixture.FwDataApi);
}

[Fact]
public async Task CanCreateAComplexFormTypeAndSyncsIt()
{
//ensure they are synced so a real sync will happen when we want it to
await _fixture.SyncService.Sync(_fixture.CrdtApi, _fixture.FwDataApi);

var complexFormEntry = await _fixture.CrdtApi.CreateComplexFormType(new() { Name = new() { { "en", "complexFormType" } } });

//one of the entries will be created first, it will try to create the reference to the other but it won't exist yet
await _fixture.SyncService.Sync(_fixture.CrdtApi, _fixture.FwDataApi);

_fixture.FwDataApi.GetComplexFormTypes().ToBlockingEnumerable().Should().ContainEquivalentOf(complexFormEntry);
}
}
16 changes: 14 additions & 2 deletions backend/FwLite/FwLiteProjectSync/CrdtFwdataProjectSyncService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ await SaveProjectSnapshot(fwdataApi.Project,
new ProjectSnapshot(
await fwdataApi.GetEntries().ToArrayAsync(),
await fwdataApi.GetPartsOfSpeech().ToArrayAsync(),
await fwdataApi.GetSemanticDomains().ToArrayAsync()));
await fwdataApi.GetSemanticDomains().ToArrayAsync(),
await fwdataApi.GetComplexFormTypes().ToArrayAsync()));
}
return result;
}
Expand Down Expand Up @@ -72,6 +73,10 @@ private async Task<SyncResult> Sync(IMiniLcmApi crdtApi, IMiniLcmApi fwdataApi,
crdtChanges += await SemanticDomainSync.Sync(currentFwDataSemanticDomains, projectSnapshot.SemanticDomains, crdtApi);
fwdataChanges += await SemanticDomainSync.Sync(await crdtApi.GetSemanticDomains().ToArrayAsync(), currentFwDataSemanticDomains, fwdataApi);

var currentFwDataComplexFormTypes = await fwdataApi.GetComplexFormTypes().ToArrayAsync();
crdtChanges += await ComplexFormTypeSync.Sync(currentFwDataComplexFormTypes, projectSnapshot.ComplexFormTypes, crdtApi);
fwdataChanges += await ComplexFormTypeSync.Sync(await crdtApi.GetComplexFormTypes().ToArrayAsync(), currentFwDataComplexFormTypes, fwdataApi);

var currentFwDataEntries = await fwdataApi.GetEntries().ToArrayAsync();
crdtChanges += await EntrySync.Sync(currentFwDataEntries, projectSnapshot.Entries, crdtApi);
LogDryRun(crdtApi, "crdt");
Expand Down Expand Up @@ -100,7 +105,14 @@ private void LogDryRun(IMiniLcmApi api, string type)
return ((DryRunMiniLcmApi)api).DryRunRecords;
}

public record ProjectSnapshot(Entry[] Entries, PartOfSpeech[] PartsOfSpeech, SemanticDomain[] SemanticDomains);
public record ProjectSnapshot(
Entry[] Entries,
PartOfSpeech[] PartsOfSpeech,
SemanticDomain[] SemanticDomains,
ComplexFormType[] ComplexFormTypes)
{
internal static ProjectSnapshot Empty { get; } = new([], [], [], []);
}

private async Task<ProjectSnapshot?> GetProjectSnapshot(FwDataProject project)
{
Expand Down
24 changes: 24 additions & 0 deletions backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,37 @@ public IAsyncEnumerable<ComplexFormType> GetComplexFormTypes()
return api.GetComplexFormTypes();
}

public Task<ComplexFormType?> GetComplexFormType(Guid id)
{
return api.GetComplexFormType(id);
}


public Task<ComplexFormType> CreateComplexFormType(ComplexFormType complexFormType)
{
DryRunRecords.Add(new DryRunRecord(nameof(CreateComplexFormType),
$"Create complex form type {complexFormType.Name}"));
return Task.FromResult(complexFormType);
}

public async Task<ComplexFormType> UpdateComplexFormType(Guid id, UpdateObjectInput<ComplexFormType> update)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateComplexFormType), $"Update complex form type {id}"));
return await GetComplexFormType(id) ?? throw new NullReferenceException($"unable to find complex form type with id {id}");
}

public Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after)
{
DryRunRecords.Add(new DryRunRecord(nameof(UpdateComplexFormType), $"Update complex form type {after.Id}"));
return Task.FromResult(after);
}

public Task DeleteComplexFormType(Guid id)
{
DryRunRecords.Add(new DryRunRecord(nameof(DeleteComplexFormType), $"Delete complex form type {id}"));
return Task.CompletedTask;
}

public IAsyncEnumerable<Entry> GetEntries(QueryOptions? options = null)
{
return api.GetEntries(options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
DerivedType: JsonPatchChange<SemanticDomain>,
TypeDiscriminator: jsonPatch:SemanticDomain
},
{
DerivedType: JsonPatchChange<ComplexFormType>,
TypeDiscriminator: jsonPatch:ComplexFormType
},
{
DerivedType: DeleteChange<Entry>,
TypeDiscriminator: delete:Entry
Expand Down
4 changes: 3 additions & 1 deletion backend/FwLite/LcmCrdt.Tests/EntityCopyMethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public static IEnumerable<object[]> GetEntityTypes()
typeof(ExampleSentence),
typeof(WritingSystem),
typeof(PartOfSpeech),
typeof(SemanticDomain)
typeof(SemanticDomain),
typeof(ComplexFormType)
];
return types.Select(t => new object[] { t });
}
Expand All @@ -37,6 +38,7 @@ public void EntityCopyMethodShouldCopyAllFields(Type type)
type.IsAssignableTo(typeof(IObjectWithId)).Should().BeTrue();
var entity = (IObjectWithId) AutoFaker.Generate(type);
var copy = entity.Copy();
//todo this does not detect a deep copy, but it should as that breaks stuff
copy.Should().BeEquivalentTo(entity, options => options.IncludingAllRuntimeProperties());
}
}
22 changes: 22 additions & 0 deletions backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace LcmCrdt;

public class CrdtMiniLcmApi(DataModel dataModel, CurrentProjectService projectService, LcmCrdtDbContext dbContext, MiniLcmValidators validators) : IMiniLcmApi

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FwHeadless / publish-fw-headless

Parameter 'dbContext' is unread.

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

Parameter 'dbContext' is unread.

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

Parameter 'dbContext' is unread.

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

Parameter 'dbContext' is unread.

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

Parameter 'dbContext' is unread.

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Mac

Parameter 'dbContext' is unread.

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Windows

Parameter 'dbContext' is unread.

Check warning on line 18 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Windows

Parameter 'dbContext' is unread.
{
private Guid ClientId { get; } = projectService.ProjectData.ClientId;
public ProjectData ProjectData => projectService.ProjectData;
Expand Down Expand Up @@ -163,6 +163,11 @@
return ComplexFormTypes.AsAsyncEnumerable();
}

public async Task<ComplexFormType?> GetComplexFormType(Guid id)
{
return await ComplexFormTypes.SingleOrDefaultAsync(c => c.Id == id);
}

public async Task<ComplexFormType> CreateComplexFormType(ComplexFormType complexFormType)
{
await validators.ValidateAndThrow(complexFormType);
Expand All @@ -171,6 +176,23 @@
return await ComplexFormTypes.SingleAsync(c => c.Id == complexFormType.Id);
}

public async Task<ComplexFormType> UpdateComplexFormType(Guid id, UpdateObjectInput<ComplexFormType> update)
{
await dataModel.AddChange(ClientId, new JsonPatchChange<ComplexFormType>(id, update.Patch));
return await GetComplexFormType(id) ?? throw new NullReferenceException($"unable to find complex form type with id {id}");
}

public async Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after)
{
await ComplexFormTypeSync.Sync(before, after, this);
return await GetComplexFormType(after.Id) ?? throw new NullReferenceException($"unable to find complex form type with id {after.Id}");
}

public async Task DeleteComplexFormType(Guid id)
{
await dataModel.AddChange(ClientId, new DeleteChange<ComplexFormType>(id));
}

public async Task<ComplexFormComponent> CreateComplexFormComponent(ComplexFormComponent complexFormComponent)
{
var existing = await ComplexFormComponents.SingleOrDefaultAsync(c =>
Expand Down Expand Up @@ -337,7 +359,7 @@
]);
return await GetEntry(entry.Id) ?? throw new NullReferenceException();

async IAsyncEnumerable<AddEntryComponentChange> ToComplexFormComponents(IList<ComplexFormComponent> complexFormComponents)

Check warning on line 362 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Build FW Lite and run tests

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 362 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 362 in backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs

View workflow job for this annotation

GitHub Actions / Publish FW Lite app for Windows

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
foreach (var complexFormComponent in complexFormComponents)
{
Expand Down
1 change: 1 addition & 0 deletions backend/FwLite/LcmCrdt/LcmCrdtKernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ public static void ConfigureCrdt(CrdtConfig config)
.Add<JsonPatchChange<WritingSystem>>()
.Add<JsonPatchChange<PartOfSpeech>>()
.Add<JsonPatchChange<SemanticDomain>>()
.Add<JsonPatchChange<ComplexFormType>>()
.Add<DeleteChange<Entry>>()
.Add<DeleteChange<Sense>>()
.Add<DeleteChange<ExampleSentence>>()
Expand Down
19 changes: 19 additions & 0 deletions backend/FwLite/MiniLcm.Tests/ComplexFormComponentTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,25 @@ public async Task CreateComplexFormType_Works()
types.Should().ContainSingle(t => t.Id == complexFormType.Id);
}

[Fact]
public async Task UpdateComplexFormType_Works()
{
var complexFormType = new ComplexFormType() { Id = Guid.NewGuid(), Name = new() { { "en", "test" } } };
await Api.CreateComplexFormType(complexFormType);
var updatedComplexFormType = await Api.UpdateComplexFormType(complexFormType.Id, new UpdateObjectInput<ComplexFormType>().Set(c => c.Name["en"], "updated"));
updatedComplexFormType.Name["en"].Should().Be("updated");
}

[Fact]
public async Task UpdateComplexFormTypeSync_Works()
{
var complexFormType = new ComplexFormType() { Id = Guid.NewGuid(), Name = new() { { "en", "test" } } };
await Api.CreateComplexFormType(complexFormType);
var afterFormType = complexFormType with { Name = new() { { "en", "updated" } } };
var actualFormType = await Api.UpdateComplexFormType(complexFormType, afterFormType);
actualFormType.Should().BeEquivalentTo(afterFormType, options => options.Excluding(c => c.Id));
}

[Fact]
public async Task AddComplexFormType_Works()
{
Expand Down
1 change: 1 addition & 0 deletions backend/FwLite/MiniLcm/IMiniLcmReadApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public interface IMiniLcmReadApi
IAsyncEnumerable<PartOfSpeech> GetPartsOfSpeech();
IAsyncEnumerable<SemanticDomain> GetSemanticDomains();
IAsyncEnumerable<ComplexFormType> GetComplexFormTypes();
Task<ComplexFormType?> GetComplexFormType(Guid id);
IAsyncEnumerable<Entry> GetEntries(QueryOptions? options = null);
IAsyncEnumerable<Entry> SearchEntries(string query, QueryOptions? options = null);
Task<Entry?> GetEntry(Guid id);
Expand Down
3 changes: 3 additions & 0 deletions backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Task<WritingSystem> UpdateWritingSystem(WritingSystemId id,
#endregion

Task<ComplexFormType> CreateComplexFormType(ComplexFormType complexFormType);
Task<ComplexFormType> UpdateComplexFormType(Guid id, UpdateObjectInput<ComplexFormType> update);
Task<ComplexFormType> UpdateComplexFormType(ComplexFormType before, ComplexFormType after);
Task DeleteComplexFormType(Guid id);

#region Entry
Task<Entry> CreateEntry(Entry entry);
Expand Down
4 changes: 2 additions & 2 deletions backend/FwLite/MiniLcm/Models/ComplexFormType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
public record ComplexFormType : IObjectWithId
{
public virtual Guid Id { get; set; }
public required MultiString Name { get; set; }
public virtual required MultiString Name { get; set; }

public DateTimeOffset? DeletedAt { get; set; }

Expand All @@ -19,6 +19,6 @@ public void RemoveReference(Guid id, DateTimeOffset time)

public IObjectWithId Copy()
{
return new ComplexFormType { Id = Id, Name = Name, DeletedAt = DeletedAt };
return new ComplexFormType { Id = Id, Name = Name.Copy(), DeletedAt = DeletedAt };
}
}
47 changes: 47 additions & 0 deletions backend/FwLite/MiniLcm/SyncHelpers/ComplexFormTypeSync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using MiniLcm.Models;
using SystemTextJsonPatch;

namespace MiniLcm.SyncHelpers;

public static class ComplexFormTypeSync
{
public static async Task<int> Sync(ComplexFormType[] afterComplexFormTypes,
ComplexFormType[] beforeComplexFormTypes,
IMiniLcmApi api)
{
return await DiffCollection.Diff(api,
beforeComplexFormTypes,
afterComplexFormTypes,
complexFormType => complexFormType.Id,
static async (api, afterComplexFormType) =>
{
await api.CreateComplexFormType(afterComplexFormType);
return 1;
},
static async (api, beforeComplexFormType) =>
{
await api.DeleteComplexFormType(beforeComplexFormType.Id);
return 1;
},
static (api, beforeComplexFormType, afterComplexFormType) => Sync(beforeComplexFormType, afterComplexFormType, api));
}

public static async Task<int> Sync(ComplexFormType before,
ComplexFormType after,
IMiniLcmApi api)
{
var updateObjectInput = ComplexFormTypeDiffToUpdate(before, after);
if (updateObjectInput is not null) await api.UpdateComplexFormType(after.Id, updateObjectInput);
return updateObjectInput is null ? 0 : 1;
}

public static UpdateObjectInput<ComplexFormType>? ComplexFormTypeDiffToUpdate(ComplexFormType before, ComplexFormType after)
{
JsonPatchDocument<ComplexFormType> patchDocument = new();
patchDocument.Operations.AddRange(MultiStringDiff.GetMultiStringDiff<ComplexFormType>(nameof(ComplexFormType.Name),
before.Name,
after.Name));
if (patchDocument.Operations.Count == 0) return null;
return new UpdateObjectInput<ComplexFormType>(patchDocument);
}
}
Loading