Skip to content

Commit 5207421

Browse files
authored
Allow getting objects of type via IChangeContext (#41)
* allow changes to get all entities of a given type to use for constraint checks
1 parent 4af7d83 commit 5207421

File tree

4 files changed

+44
-6
lines changed

4 files changed

+44
-6
lines changed

src/SIL.Harmony.Core/IChangeContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ public interface IChangeContext
1414
public async ValueTask<bool> IsObjectDeleted(Guid entityId) => (await GetSnapshot(entityId))?.EntityIsDeleted ?? true;
1515
internal IObjectBase Adapt(object obj);
1616
IAsyncEnumerable<object> GetObjectsReferencing(Guid entityId, bool includeDeleted = false);
17+
IAsyncEnumerable<T> GetObjectsOfType<T>(string jsonTypeName, bool includeDeleted = false) where T : class;
1718
}

src/SIL.Harmony.Sample/Changes/SetTagChange.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,26 @@ public class SetTagChange(Guid entityId, string text) : Change<Tag>(entityId), I
88
{
99
public string Text { get; } = text;
1010

11-
public override ValueTask<Tag> NewEntity(Commit commit, IChangeContext context)
11+
public override async ValueTask<Tag> NewEntity(Commit commit, IChangeContext context)
1212
{
13-
return new(new Tag()
13+
var tagExists = await context.GetObjectsOfType<Tag>(nameof(Tag)).AnyAsync(t => t.Text == Text);
14+
return new Tag()
1415
{
1516
Id = EntityId,
16-
Text = Text
17-
});
17+
Text = Text,
18+
DeletedAt = tagExists ? commit.DateTime : null
19+
};
1820
}
1921

2022

21-
public override ValueTask ApplyChange(Tag entity, IChangeContext context)
23+
public override async ValueTask ApplyChange(Tag entity, IChangeContext context)
2224
{
25+
if (entity.Text == Text) return;
26+
var tagExists = await context.GetObjectsOfType<Tag>(nameof(Tag)).AnyAsync(t => t.Id != EntityId && t.Text == Text);
27+
if (tagExists)
28+
{
29+
entity.DeletedAt = context.Commit.DateTime;
30+
}
2331
entity.Text = Text;
24-
return ValueTask.CompletedTask;
2532
}
2633
}

src/SIL.Harmony.Tests/DataModelReferenceTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,26 @@ await AddCommitsViaSync([
150150
def.Should().NotBeNull();
151151
def.DeletedAt.Should().NotBeNull();
152152
}
153+
154+
[Fact]
155+
public async Task CanCreate2TagsWithTheSameNameOutOfOrder()
156+
{
157+
var tagText = "tag1";
158+
var commitA = await WriteNextChange(SetTag(Guid.NewGuid(), tagText));
159+
//represents someone syncing in a tag with the same name
160+
await WriteChangeBefore(commitA, SetTag(Guid.NewGuid(), tagText));
161+
DataModel.QueryLatest<Tag>().Where(t => t.Text == tagText).Should().ContainSingle();
162+
}
163+
164+
[Fact]
165+
public async Task CanUpdateTagWithTheSameNameOutOfOrder()
166+
{
167+
var tagText = "tag1";
168+
var renameTagId = Guid.NewGuid();
169+
await WriteNextChange(SetTag(renameTagId, "tag2"));
170+
var commitA = await WriteNextChange(SetTag(Guid.NewGuid(), tagText));
171+
//represents someone syncing in a tag with the same name
172+
await WriteNextChange(SetTag(renameTagId, tagText));
173+
DataModel.QueryLatest<Tag>().Where(t => t.Text == tagText).Should().ContainSingle();
174+
}
153175
}

src/SIL.Harmony/Changes/ChangeContext.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,13 @@ public IAsyncEnumerable<object> GetObjectsReferencing(Guid entityId, bool includ
2525
{
2626
return _worker.GetSnapshotsReferencing(entityId, includeDeleted).Select(s => s.Entity.DbObject);
2727
}
28+
29+
public IAsyncEnumerable<T> GetObjectsOfType<T>(string jsonTypeName, bool includeDeleted = false) where T : class
30+
{
31+
return _worker.GetSnapshotsWhere(s => (includeDeleted || !s.EntityIsDeleted) && s.TypeName == jsonTypeName)
32+
.Select(s => s.Entity.DbObject)
33+
.OfType<T>();
34+
}
35+
2836
IObjectBase IChangeContext.Adapt(object obj) => _crdtConfig.ObjectTypeListBuilder.Adapt(obj);
2937
}

0 commit comments

Comments
 (0)