From 77179a5f61adb3b47e0715062ee2bd046fdc24f7 Mon Sep 17 00:00:00 2001 From: Kevin Hahn Date: Wed, 9 Oct 2024 12:26:59 +0700 Subject: [PATCH] simplify IObjectBase interface --- .../Adapter/CustomObjectAdapterTests.cs | 6 +--- .../ObjectBaseTestingHelpers.cs | 11 ++++++ .../Adapters/CustomAdapterProvider.cs | 8 ++--- src/SIL.Harmony/Changes/ChangeContext.cs | 2 +- src/SIL.Harmony/Db/CrdtRepository.cs | 4 +-- src/SIL.Harmony/Db/ObjectSnapshot.cs | 2 +- src/SIL.Harmony/Entities/IObjectBase.cs | 34 +++++++++++-------- 7 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 src/SIL.Harmony.Tests/ObjectBaseTestingHelpers.cs diff --git a/src/SIL.Harmony.Tests/Adapter/CustomObjectAdapterTests.cs b/src/SIL.Harmony.Tests/Adapter/CustomObjectAdapterTests.cs index 1148322..c34d994 100644 --- a/src/SIL.Harmony.Tests/Adapter/CustomObjectAdapterTests.cs +++ b/src/SIL.Harmony.Tests/Adapter/CustomObjectAdapterTests.cs @@ -101,11 +101,7 @@ public DateTimeOffset? DeletedAt set => Obj.DeletedTime = value?.ToUnixTimeSeconds(); } - [JsonIgnore] - public string ObjectTypeName => Obj.TypeName; - - [JsonIgnore] - public Type ObjectType => typeof(MyClass); + public string GetObjectTypeName() => Obj.TypeName; [JsonIgnore] public object DbObject => Obj; diff --git a/src/SIL.Harmony.Tests/ObjectBaseTestingHelpers.cs b/src/SIL.Harmony.Tests/ObjectBaseTestingHelpers.cs new file mode 100644 index 0000000..a25566c --- /dev/null +++ b/src/SIL.Harmony.Tests/ObjectBaseTestingHelpers.cs @@ -0,0 +1,11 @@ +using SIL.Harmony.Entities; + +namespace SIL.Harmony.Tests; + +public static class ObjectBaseTestingHelpers +{ + public static T Is(this IObjectBase obj) where T : class + { + return (T) obj.DbObject; + } +} \ No newline at end of file diff --git a/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs b/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs index 7de660f..53231cc 100644 --- a/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs +++ b/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs @@ -57,7 +57,8 @@ IObjectBase IObjectAdapterProvider.Adapt(object obj) } } -// it's possible to implement this without a Common interface, but it would require the adapter to have 1 property for each object type +// it's possible to implement this without a Common interface +// but it would require the adapter to have 1 property for each object type in order to support deserialization public interface ICustomAdapter : IObjectBase, IPolyType where TSelf : class, ICustomAdapter @@ -65,9 +66,4 @@ public interface ICustomAdapter : IObjectBase, IPolyTyp public static abstract TSelf Create(TCommonInterface obj); static string IPolyType.TypeName => TSelf.AdapterTypeName; public static abstract string AdapterTypeName { get; } - - T IObjectBase.Is() - { - return (T)DbObject; - } } \ No newline at end of file diff --git a/src/SIL.Harmony/Changes/ChangeContext.cs b/src/SIL.Harmony/Changes/ChangeContext.cs index 72104c6..3929999 100644 --- a/src/SIL.Harmony/Changes/ChangeContext.cs +++ b/src/SIL.Harmony/Changes/ChangeContext.cs @@ -19,5 +19,5 @@ internal ChangeContext(Commit commit, SnapshotWorker worker, CrdtConfig crdtConf public async ValueTask GetSnapshot(Guid entityId) => await _worker.GetSnapshot(entityId); public async ValueTask IsObjectDeleted(Guid entityId) => (await GetSnapshot(entityId))?.EntityIsDeleted ?? true; - public IObjectBase Adapt(object obj) => _crdtConfig.ObjectTypeListBuilder.AdapterProvider.Adapt(obj); + internal IObjectBase Adapt(object obj) => _crdtConfig.ObjectTypeListBuilder.AdapterProvider.Adapt(obj); } diff --git a/src/SIL.Harmony/Db/CrdtRepository.cs b/src/SIL.Harmony/Db/CrdtRepository.cs index 88dcb4e..2a4ea39 100644 --- a/src/SIL.Harmony/Db/CrdtRepository.cs +++ b/src/SIL.Harmony/Db/CrdtRepository.cs @@ -173,7 +173,7 @@ public async Task GetObjectBySnapshotId(Guid snapshotId) var snapshot = await Snapshots .DefaultOrder() .LastOrDefaultAsync(s => s.EntityId == objectId && (ignoreChangesAfter == null || s.Commit.DateTime <= ignoreChangesAfter)); - return snapshot?.Entity.Is(); + return (T?) snapshot?.Entity.DbObject; } public IQueryable GetCurrentObjects() where T : class @@ -228,7 +228,7 @@ private async ValueTask SnapshotAdded(ObjectSnapshot objectSnapshot) if (!crdtConfig.Value.EnableProjectedTables) return; if (objectSnapshot.IsRoot && objectSnapshot.EntityIsDeleted) return; //need to check if an entry exists already, even if this is the root commit it may have already been added to the db - var existingEntry = await GetEntityEntry(objectSnapshot.Entity.ObjectType, objectSnapshot.EntityId); + var existingEntry = await GetEntityEntry(objectSnapshot.Entity.DbObject.GetType(), objectSnapshot.EntityId); if (existingEntry is null && objectSnapshot.IsRoot) { //if we don't make a copy first then the entity will be tracked by the context and be modified diff --git a/src/SIL.Harmony/Db/ObjectSnapshot.cs b/src/SIL.Harmony/Db/ObjectSnapshot.cs index c689d2d..53f2e10 100644 --- a/src/SIL.Harmony/Db/ObjectSnapshot.cs +++ b/src/SIL.Harmony/Db/ObjectSnapshot.cs @@ -62,7 +62,7 @@ public ObjectSnapshot(IObjectBase entity, Commit commit, bool isRoot) : this() References = entity.GetReferences(); EntityId = entity.Id; EntityIsDeleted = entity.DeletedAt.HasValue; - TypeName = entity.ObjectTypeName; + TypeName = entity.GetObjectTypeName(); CommitId = commit.Id; Commit = commit; IsRoot = isRoot; diff --git a/src/SIL.Harmony/Entities/IObjectBase.cs b/src/SIL.Harmony/Entities/IObjectBase.cs index cbcbb22..a941712 100644 --- a/src/SIL.Harmony/Entities/IObjectBase.cs +++ b/src/SIL.Harmony/Entities/IObjectBase.cs @@ -8,31 +8,35 @@ public interface IObjectBase Guid Id { get; } DateTimeOffset? DeletedAt { get; set; } - public T Is() - { - return (T)this; - } - - public T? As() where T : class, IObjectBase - { - return this as T; - } - + /// + /// provides the references this object has to other objects, when those objects are deleted + /// will be called to remove the reference + /// + /// public Guid[] GetReferences(); + /// + /// remove a reference to another object, in some cases this may cause this object to be deleted + /// + /// id of the deleted object + /// + /// commit where the reference was removed + /// should be used to set the deleted date for this object + /// public void RemoveReference(Guid id, Commit commit); public IObjectBase Copy(); - public string ObjectTypeName { get; } - public Type ObjectType { get; } + /// + /// the name of the object type, this is used to discriminate between different types of objects in the snapshots table + /// + /// a stable type name of this object, should not change over time + public string GetObjectTypeName(); [JsonIgnore] public object DbObject { get; } - // static string IPolyType.TypeName => throw new NotImplementedException(); } public interface IObjectBase : IObjectBase, IPolyType where TThis : IPolyType { - string IObjectBase.ObjectTypeName => TThis.TypeName; - Type IObjectBase.ObjectType => typeof(TThis); + string IObjectBase.GetObjectTypeName() => TThis.TypeName; static string IPolyType.TypeName => typeof(TThis).Name; [JsonIgnore] object IObjectBase.DbObject => this;