diff --git a/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs b/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs index 058f1d0ba..348754469 100644 --- a/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs +++ b/backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs @@ -914,6 +914,12 @@ public Task DeleteSense(Guid entryId, Guid senseId) return Task.CompletedTask; } + public Task GetExampleSentence(Guid entryId, Guid senseId, Guid id) + { + var lcmExampleSentence = ExampleSentenceRepository.GetObject(id); + return Task.FromResult(lcmExampleSentence is null ? null : FromLexExampleSentence(senseId, lcmExampleSentence)); + } + internal void CreateExampleSentence(ILexSense lexSense, ExampleSentence exampleSentence) { var lexExampleSentence = LexExampleSentenceFactory.Create(exampleSentence.Id, lexSense); @@ -955,6 +961,20 @@ public Task UpdateExampleSentence(Guid entryId, return Task.FromResult(FromLexExampleSentence(senseId, lexExampleSentence)); } + public async Task UpdateExampleSentence(Guid entryId, + Guid senseId, + ExampleSentence before, + ExampleSentence after) + { + await Cache.DoUsingNewOrCurrentUOW("Update Example Sentence", + "Revert Example Sentence", + async () => + { + await ExampleSentenceSync.Sync(entryId, senseId, after, before, this); + }); + return await GetExampleSentence(entryId, senseId, after.Id) ?? throw new NullReferenceException("unable to find example sentence with id " + after.Id); + } + public Task DeleteExampleSentence(Guid entryId, Guid senseId, Guid exampleSentenceId) { var lexExampleSentence = ExampleSentenceRepository.GetObject(exampleSentenceId); diff --git a/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs b/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs index 11635dfa3..21dd0a39c 100644 --- a/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs +++ b/backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs @@ -188,6 +188,11 @@ public Task RemoveSemanticDomainFromSense(Guid senseId, Guid semanticDomainId) return Task.CompletedTask; } + public Task GetExampleSentence(Guid entryId, Guid senseId, Guid id) + { + return api.GetExampleSentence(entryId, senseId, id); + } + public Task CreateExampleSentence(Guid entryId, Guid senseId, ExampleSentence exampleSentence) { DryRunRecords.Add(new DryRunRecord(nameof(CreateExampleSentence), $"Create example sentence {exampleSentence.Sentence}")); @@ -201,11 +206,17 @@ public async Task UpdateExampleSentence(Guid entryId, { DryRunRecords.Add(new DryRunRecord(nameof(UpdateExampleSentence), $"Update example sentence {exampleSentenceId}, changes: {update.Summarize()}")); - var entry = await GetEntry(entryId) ?? - throw new NullReferenceException($"unable to find entry with id {entryId}"); - var sense = entry.Senses.First(s => s.Id == senseId); - var exampleSentence = sense.ExampleSentences.First(s => s.Id == exampleSentenceId); - return exampleSentence; + var exampleSentence = await GetExampleSentence(entryId, senseId, exampleSentenceId); + return exampleSentence ?? throw new NullReferenceException($"unable to find example sentence with id {exampleSentenceId}"); + } + + public Task UpdateExampleSentence(Guid entryId, + Guid senseId, + ExampleSentence before, + ExampleSentence after) + { + DryRunRecords.Add(new DryRunRecord(nameof(UpdateExampleSentence), $"Update example sentence {after.Id}")); + return Task.FromResult(after); } public Task DeleteExampleSentence(Guid entryId, Guid senseId, Guid exampleSentenceId) diff --git a/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs b/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs index ce2bff06f..241c355f3 100644 --- a/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs +++ b/backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs @@ -459,6 +459,14 @@ public async Task CreateExampleSentence(Guid entryId, return await dataModel.GetLatest(exampleSentence.Id) ?? throw new NullReferenceException(); } + public async Task GetExampleSentence(Guid entryId, Guid senseId, Guid id) + { + var exampleSentence = await ExampleSentences.AsTracking(false) + .AsQueryable() + .SingleOrDefaultAsync(e => e.Id == id); + return exampleSentence; + } + public async Task UpdateExampleSentence(Guid entryId, Guid senseId, Guid exampleSentenceId, @@ -470,6 +478,15 @@ public async Task UpdateExampleSentence(Guid entryId, return await dataModel.GetLatest(exampleSentenceId) ?? throw new NullReferenceException(); } + public async Task UpdateExampleSentence(Guid entryId, + Guid senseId, + ExampleSentence before, + ExampleSentence after) + { + await ExampleSentenceSync.Sync(entryId, senseId, after, before, this); + return await GetExampleSentence(entryId, senseId, after.Id) ?? throw new NullReferenceException(); + } + public async Task DeleteExampleSentence(Guid entryId, Guid senseId, Guid exampleSentenceId) { await dataModel.AddChange(ClientId, new DeleteChange(exampleSentenceId)); diff --git a/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs b/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs index de0bc543e..242f45892 100644 --- a/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs +++ b/backend/FwLite/MiniLcm/IMiniLcmReadApi.cs @@ -14,6 +14,7 @@ public interface IMiniLcmReadApi Task GetEntry(Guid id); Task GetPartOfSpeech(Guid id); Task GetSemanticDomain(Guid id); + Task GetExampleSentence(Guid entryId, Guid senseId, Guid id); } public record QueryOptions( diff --git a/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs b/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs index 6608c6335..32d185fef 100644 --- a/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs +++ b/backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs @@ -54,6 +54,10 @@ Task UpdateExampleSentence(Guid entryId, Guid senseId, Guid exampleSentenceId, UpdateObjectInput update); + Task UpdateExampleSentence(Guid entryId, + Guid senseId, + ExampleSentence before, + ExampleSentence after); Task DeleteExampleSentence(Guid entryId, Guid senseId, Guid exampleSentenceId); #endregion diff --git a/backend/FwLite/MiniLcm/SyncHelpers/ExampleSentenceSync.cs b/backend/FwLite/MiniLcm/SyncHelpers/ExampleSentenceSync.cs index 5652e77de..ef2e6cf1a 100644 --- a/backend/FwLite/MiniLcm/SyncHelpers/ExampleSentenceSync.cs +++ b/backend/FwLite/MiniLcm/SyncHelpers/ExampleSentenceSync.cs @@ -22,13 +22,8 @@ public static async Task Sync(Guid entryId, return 1; }; Func> replace = - async (api, beforeExampleSentence, afterExampleSentence) => - { - var updateObjectInput = DiffToUpdate(beforeExampleSentence, afterExampleSentence); - if (updateObjectInput is null) return 0; - await api.UpdateExampleSentence(entryId, senseId, beforeExampleSentence.Id, updateObjectInput); - return 1; - }; + (api, beforeExampleSentence, afterExampleSentence) => + Sync(entryId, senseId, afterExampleSentence, beforeExampleSentence, api); return await DiffCollection.Diff(api, beforeExampleSentences, afterExampleSentences, @@ -37,6 +32,18 @@ public static async Task Sync(Guid entryId, replace); } + public static async Task Sync(Guid entryId, + Guid senseId, + ExampleSentence afterExampleSentence, + ExampleSentence beforeExampleSentence, + IMiniLcmApi api) + { + var updateObjectInput = DiffToUpdate(beforeExampleSentence, afterExampleSentence); + if (updateObjectInput is null) return 0; + await api.UpdateExampleSentence(entryId, senseId, beforeExampleSentence.Id, updateObjectInput); + return 1; + } + public static UpdateObjectInput? DiffToUpdate(ExampleSentence beforeExampleSentence, ExampleSentence afterExampleSentence) { diff --git a/backend/LfClassicData/LfClassicMiniLcmApi.cs b/backend/LfClassicData/LfClassicMiniLcmApi.cs index e762a5440..cc7945e01 100644 --- a/backend/LfClassicData/LfClassicMiniLcmApi.cs +++ b/backend/LfClassicData/LfClassicMiniLcmApi.cs @@ -314,4 +314,15 @@ private static SemanticDomain ToSemanticDomain(Entities.OptionListItem item) if (entry is null) return null; return ToEntry(entry); } + + public async Task GetExampleSentence(Guid entryId, Guid senseId, Guid id) + { + var entry = await Entries.Find(e => e.Guid == entryId).FirstOrDefaultAsync(); + if (entry is null) return null; + var sense = entry.Senses?.FirstOrDefault(s => s?.Guid == senseId); + if (sense is null) return null; + var exampleSentence = sense.Examples?.FirstOrDefault(e => e?.Guid == id); + if (exampleSentence is null) return null; + return ToExampleSentence(sense.Guid, exampleSentence); + } }