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

Complex forms in miniLcm #1061

Open
wants to merge 23 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
19ef8fe
add LcmDebugger CLI to be able open projects and inspect LCM stuff in…
hahn-kev Sep 23, 2024
dfcf5bb
first pass at what complex forms might look like in miniLcm
hahn-kev Sep 23, 2024
abad0cf
rename EntryType to ComplexEntryType and expose it via a method on th…
hahn-kev Sep 24, 2024
41bd955
add support for variants
hahn-kev Sep 24, 2024
b18c2ee
Merge branch 'develop' into feat/complex-forms
hahn-kev Sep 25, 2024
4b301f0
add crdt support for Complex Forms
hahn-kev Sep 30, 2024
66f99f7
undo ugly hack of putting Sense list on Crdt Entry
hahn-kev Sep 30, 2024
af357b4
add a note when populating the complex forms of an entry
hahn-kev Sep 30, 2024
f1555a2
write tests and support creating entries with complex forms or compon…
hahn-kev Sep 30, 2024
3d9f45c
add complex form type to miniLcm API, ensure complex forms get imported
hahn-kev Sep 30, 2024
786e20b
support updating LCM entry components via the components property
hahn-kev Oct 1, 2024
0fc946e
add support for changing ComplexForms collection directly
hahn-kev Oct 1, 2024
6793913
add support for changing complex form types
hahn-kev Oct 2, 2024
95762f9
add support for changing Components of a complex form
hahn-kev Oct 2, 2024
1c4951d
add support for changing ComplexForms of a component
hahn-kev Oct 2, 2024
5f3b81f
implement complex form type changes via json patch
hahn-kev Oct 2, 2024
37124bf
Merge branch 'develop' into feat/complex-forms
hahn-kev Oct 4, 2024
73dca2f
define custom mapping for MiniLcm.Models.Entry.Senses so that linq2db…
hahn-kev Oct 4, 2024
0b25746
update code to better handle filtering on senses
hahn-kev Oct 4, 2024
58cbdca
revert changes to Entry.Senses
hahn-kev Oct 7, 2024
1b05889
remove variants field from Entry as it's not ready and is out of scope
hahn-kev Oct 7, 2024
1f32678
Merge branch 'develop' into feat/complex-forms
hahn-kev Oct 7, 2024
2652efc
correct some failing tests
hahn-kev Oct 7, 2024
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
7 changes: 7 additions & 0 deletions LexBox.sln
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FwLiteProjectSync", "backen
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FwLiteProjectSync.Tests", "backend\FwLite\FwLiteProjectSync.Tests\FwLiteProjectSync.Tests.csproj", "{5352D1CC-14C5-4589-9389-731F55E4FFDF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LcmDebugger", "backend\LfNext\LcmDebugger\LcmDebugger.csproj", "{5A9011D8-6EC1-4550-BDD7-AFF00DB2B921}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -127,6 +129,10 @@ Global
{5352D1CC-14C5-4589-9389-731F55E4FFDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5352D1CC-14C5-4589-9389-731F55E4FFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5352D1CC-14C5-4589-9389-731F55E4FFDF}.Release|Any CPU.Build.0 = Release|Any CPU
{5A9011D8-6EC1-4550-BDD7-AFF00DB2B921}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A9011D8-6EC1-4550-BDD7-AFF00DB2B921}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A9011D8-6EC1-4550-BDD7-AFF00DB2B921}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A9011D8-6EC1-4550-BDD7-AFF00DB2B921}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -144,6 +150,7 @@ Global
{9001FE0F-DBBF-4A78-9EB9-9B5042CF8A78} = {7B6E21C4-5AF4-4505-B7D9-59A3886C5090}
{2245BAB6-753A-48AE-B929-6D8C35CB9804} = {7B6E21C4-5AF4-4505-B7D9-59A3886C5090}
{5352D1CC-14C5-4589-9389-731F55E4FFDF} = {7B6E21C4-5AF4-4505-B7D9-59A3886C5090}
{5A9011D8-6EC1-4550-BDD7-AFF00DB2B921} = {7B6E21C4-5AF4-4505-B7D9-59A3886C5090}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {440AE83C-6DB0-4F18-B2C1-BCD33F0645B6}
Expand Down
50 changes: 48 additions & 2 deletions backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
using SIL.LCModel.Core.WritingSystems;
using SIL.LCModel.DomainServices;
using SIL.LCModel.Infrastructure;
using EntryType = MiniLcm.EntryType;

namespace FwDataMiniLcmBridge.Api;

public class FwDataMiniLcmApi(Lazy<LcmCache> cacheLazy, bool onCloseSave, ILogger<FwDataMiniLcmApi> logger, FwDataProject project) : ILexboxApi, IDisposable
{
private LcmCache Cache => cacheLazy.Value;
public LcmCache Cache => cacheLazy.Value;
public FwDataProject Project { get; } = project;
public Guid ProjectId => Cache.LangProject.Guid;

Expand All @@ -27,6 +28,7 @@
private ILexExampleSentenceFactory LexExampleSentenceFactory => Cache.ServiceLocator.GetInstance<ILexExampleSentenceFactory>();
private IMoMorphTypeRepository MorphTypeRepository => Cache.ServiceLocator.GetInstance<IMoMorphTypeRepository>();
private IPartOfSpeechRepository PartOfSpeechRepository => Cache.ServiceLocator.GetInstance<IPartOfSpeechRepository>();
private ILexEntryTypeRepository LexEntryTypeRepository => Cache.ServiceLocator.GetInstance<ILexEntryTypeRepository>();
private ICmSemanticDomainRepository SemanticDomainRepository => Cache.ServiceLocator.GetInstance<ICmSemanticDomainRepository>();
private ICmTranslationFactory CmTranslationFactory => Cache.ServiceLocator.GetInstance<ICmTranslationFactory>();
private ICmPossibilityRepository CmPossibilityRepository => Cache.ServiceLocator.GetInstance<ICmPossibilityRepository>();
Expand Down Expand Up @@ -167,7 +169,7 @@
throw new NotImplementedException();
}

public async IAsyncEnumerable<PartOfSpeech> GetPartsOfSpeech()

Check warning on line 172 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.
{
foreach (var partOfSpeech in PartOfSpeechRepository.AllInstances().OrderBy(p => p.Name.BestAnalysisAlternative.Text))
{
Expand All @@ -175,7 +177,7 @@
}
}

public async Task CreatePartOfSpeech(PartOfSpeech partOfSpeech)

Check warning on line 180 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.
{
if (partOfSpeech.Id == default) partOfSpeech.Id = Guid.NewGuid();
UndoableUnitOfWorkHelper.Do("Create Part of Speech",
Expand All @@ -189,7 +191,7 @@
});
}

public async IAsyncEnumerable<SemanticDomain> GetSemanticDomains()

Check warning on line 194 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.
{
foreach (var semanticDomain in SemanticDomainRepository.AllInstances().OrderBy(p => p.Abbreviation.UiString))
{
Expand All @@ -202,7 +204,7 @@
}
}

public async Task CreateSemanticDomain(SemanticDomain semanticDomain)

Check warning on line 207 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.
{
if (semanticDomain.Id == Guid.Empty) semanticDomain.Id = Guid.NewGuid();
UndoableUnitOfWorkHelper.Do("Create Semantic Domain",
Expand Down Expand Up @@ -231,7 +233,51 @@
LexemeForm = FromLcmMultiString(entry.LexemeFormOA.Form),
CitationForm = FromLcmMultiString(entry.CitationForm),
LiteralMeaning = FromLcmMultiString(entry.LiteralMeaning),
Senses = entry.AllSenses.Select(FromLexSense).ToList()
Senses = entry.AllSenses.Select(FromLexSense).ToList(),
ComplexForm = ToComplexForm(entry)
};
}

private ComplexForm? ToComplexForm(ILexEntry entry)
{
var complexEntryRef = entry.ComplexFormEntryRefs.SingleOrDefault();
hahn-kev marked this conversation as resolved.
Show resolved Hide resolved
if (complexEntryRef is null) return null;
return new ComplexForm
{
Id = complexEntryRef.Guid,
Components =
[
..complexEntryRef.ComponentLexemesRS.Select(o => o switch
{
ILexEntry e => ToEntryReference(e),
ILexSense s => ToSenseReference(s),
_ => throw new NotSupportedException($"object type {o.ClassName} not supported")
})
],
Types =
[
..complexEntryRef.ComplexEntryTypesRS.Select(t =>
new EntryType() { Id = t.Guid, Name = FromLcmMultiString(t.Name), })
]
};
}

private EntryReference ToEntryReference(ILexEntry entry)
{
return new EntryReference
{
EntryId = entry.Guid,
Headword = entry.HeadWord.Text
};
}

private EntryReference ToSenseReference(ILexSense sense)
{
return new EntryReference
{
EntryId = sense.Entry.Guid,
SenseId = sense.Guid,
Headword = sense.Entry.HeadWord.Text,
};
}

Expand Down Expand Up @@ -285,7 +331,7 @@
return GetEntries(null, options);
}

public async IAsyncEnumerable<Entry> GetEntries(

Check warning on line 334 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.
Func<ILexEntry, bool>? predicate, QueryOptions? options = null)
{
var entries = EntriesRepository.AllInstances();
Expand Down
21 changes: 21 additions & 0 deletions backend/FwLite/MiniLcm/Entry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class Entry : IObjectWithId
public virtual IList<Sense> Senses { get; set; } = [];

public virtual MultiString Note { get; set; } = new();
public virtual ComplexForm? ComplexForm { get; set; }

public bool MatchesQuery(string query) =>
LexemeForm.SearchValue(query)
Expand All @@ -25,3 +26,23 @@ public string Headword()
return word?.Trim() ?? "(Unknown)";
}
}

public class EntryReference
{
public required Guid EntryId { get; set; }
public Guid? SenseId { get; set; } = null;
public required string Headword { get; set; }
}

public class ComplexForm
{
public IList<EntryReference> Components { get; set; } = [];
public IList<EntryType> Types { get; set; } = [];
public Guid Id { get; set; }
}

public class EntryType
{
public required Guid Id { get; set; }
public required MultiString Name { get; set; }
}
18 changes: 18 additions & 0 deletions backend/LfNext/LcmDebugger/LcmDebugger.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\FwLite\FwDataMiniLcmBridge\FwDataMiniLcmBridge.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>

</Project>
15 changes: 15 additions & 0 deletions backend/LfNext/LcmDebugger/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// See https://aka.ms/new-console-template for more information

using FwDataMiniLcmBridge;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder();
builder.Services.AddFwDataBridge();

var app = builder.Build();

var fwDataFactory = app.Services.GetRequiredService<FwDataFactory>();
var miniLcmApi = fwDataFactory.GetFwDataMiniLcmApi("fruit", false);
await miniLcmApi.GetEntries().ToArrayAsync();
var complexEntryTypesOa = miniLcmApi.Cache.LangProject.LexDbOA.ComplexEntryTypesOA;
Loading