From 9e77090bd4454128a8a108261d31a4a9cafdbd69 Mon Sep 17 00:00:00 2001 From: Schedel Pascal Date: Tue, 9 Jul 2024 10:13:38 +0200 Subject: [PATCH] completely rework IDataProvider - make it more dynamic - prevent incremental method count increase --- OwnChar/Api/ICharacterManager.cs | 4 +- OwnChar/Api/IDataManager.cs | 33 -- OwnChar/Api/IDataProvider.cs | 38 -- OwnChar/Api/IGroupsManager.cs | 6 +- OwnChar/Api/IOwnCharManager.cs | 3 +- OwnChar/Api/IUserManager.cs | 1 + OwnChar/Data/DataManagerActions.cs | 4 +- OwnChar/Data/DataProviderSetAction.cs | 7 + OwnChar/Data/HierarchyProperties.cs | 12 + OwnChar/Data/IDataManager.cs | 19 + OwnChar/Data/IDataProvider.cs | 26 ++ OwnChar/Data/Managers/DefaultDataManager.cs | 192 +++++---- .../JsonFile/JsonFileDataProvider.cs | 369 ++++++++++++------ OwnChar/Manager/Modules/CharacterManager.cs | 17 +- OwnChar/Manager/Modules/GroupsManager.cs | 21 +- OwnChar/Manager/Modules/UserManager.cs | 15 +- OwnChar/Manager/OwnCharManager.cs | 1 + 17 files changed, 486 insertions(+), 282 deletions(-) delete mode 100644 OwnChar/Api/IDataManager.cs delete mode 100644 OwnChar/Api/IDataProvider.cs create mode 100644 OwnChar/Data/DataProviderSetAction.cs create mode 100644 OwnChar/Data/HierarchyProperties.cs create mode 100644 OwnChar/Data/IDataManager.cs create mode 100644 OwnChar/Data/IDataProvider.cs diff --git a/OwnChar/Api/ICharacterManager.cs b/OwnChar/Api/ICharacterManager.cs index d69968c..6b42fee 100644 --- a/OwnChar/Api/ICharacterManager.cs +++ b/OwnChar/Api/ICharacterManager.cs @@ -6,6 +6,6 @@ public interface ICharacterManager Character? CreateCharacter(string? name); Character? CreateCharacter(string? name, Group? destination); bool DeleteCharacter(Character? character); - IEnumerable? GetCharacters(Group? group); - IEnumerable? GetCharacters(UserProfile? profile); + IQueryable? GetCharacters(Group? group); + IQueryable? GetCharacters(UserProfile? profile); } \ No newline at end of file diff --git a/OwnChar/Api/IDataManager.cs b/OwnChar/Api/IDataManager.cs deleted file mode 100644 index b414a51..0000000 --- a/OwnChar/Api/IDataManager.cs +++ /dev/null @@ -1,33 +0,0 @@ -using OwnChar.Data; -using OwnChar.Model; - -namespace OwnChar.Api; - -public interface IDataManager -{ - public delegate void OnActionEventHandler(object sender, OnActionEventArgs e); - public delegate void OnCallbackEventHandler(object sender, OnCallbackEventArgs e); - - event OnActionEventHandler? OnAction; - event OnCallbackEventHandler? OnCallback; - // Login - UserAccount? Login(string username, string password); - bool Logout(UserAccount? account); - - // Action - DataManagerActionResult ExecuteAction(DataManagerAction action, DataManagerActionType actionType, UserAccount currentUser, object? obj, params object?[] parameters); - - //// User management - //UserProfile? GetUserProfile(UserAccount account); - - //// Group management - //UserProfile? GetOwner(UserAccount account, Group group); - //IEnumerable? GetMembers(UserAccount account, Group group); - //bool AddMember(UserAccount account, Group group, UserProfile user); - //bool RemoveMember(UserAccount account, Group group, UserProfile user); - - //// Character management - //UserProfile? GetOwner(UserAccount account, Character group); - //IEnumerable? GetCharacters(UserAccount account, Group group); - //IEnumerable? GetCharacters(UserAccount account, UserProfile profile); -} diff --git a/OwnChar/Api/IDataProvider.cs b/OwnChar/Api/IDataProvider.cs deleted file mode 100644 index 8913ac4..0000000 --- a/OwnChar/Api/IDataProvider.cs +++ /dev/null @@ -1,38 +0,0 @@ -using OwnChar.Model; - -namespace OwnChar.Api; - -public interface IDataProvider -{ - bool IsInitialized(); - void SetInitialized(); - bool SaveDatabase(); - - // Model - abstract T? Create() where T : OwnCharObject; - abstract bool Save(T obj) where T : OwnCharObject; - abstract bool Delete(T obj) where T : OwnCharObject; - virtual IEnumerable? Get() where T : OwnCharObject => Get(null); - abstract IEnumerable? Get(OwnCharObject? context) where T : OwnCharObject; - - // Hierarchy - abstract bool SetParent(UserProfile profile, UserAccount parent); - abstract bool SetParent(Character character, Group parent); - abstract bool SetParent(Property property, Character character); - abstract bool SetOwner(Group group, UserProfile owner); - abstract bool SetOwner(Character group, UserProfile owner); - abstract UserProfile? GetOwner(Group group); - abstract UserProfile? GetOwner(Character character); - - // Collections - abstract bool AddMember(Group group, UserProfile user); - abstract bool RemoveMember(Group group, UserProfile user); - - // Gets - abstract UserAccount? GetUserAccount(string username, string password); - abstract UserProfile? GetUserProfile(string username); - abstract IEnumerable? GetUserAccounts(); - abstract IEnumerable? GetMembers(Group group); - abstract IEnumerable? GetCharacters(Group group); - abstract IEnumerable? GetCharacters(UserProfile jprofile); -} diff --git a/OwnChar/Api/IGroupsManager.cs b/OwnChar/Api/IGroupsManager.cs index 5ed33ae..0c99905 100644 --- a/OwnChar/Api/IGroupsManager.cs +++ b/OwnChar/Api/IGroupsManager.cs @@ -3,10 +3,12 @@ namespace OwnChar.Api; public interface IGroupsManager { + IQueryable? GetGroups(UserProfile? profile); + IQueryable? GetGroups(); bool AddMember(UserProfile? profile, Group? group); Group? CreateGroup(string? name); bool DeleteGroup(Group? group); - bool DeleteMember(UserProfile? profile, Group? group); - IEnumerable? GetMembers(Group? group); + bool RemoveMember(UserProfile? profile, Group? group); + IQueryable? GetMembers(Group? group); UserProfile? GetOwner(Group? group); } \ No newline at end of file diff --git a/OwnChar/Api/IOwnCharManager.cs b/OwnChar/Api/IOwnCharManager.cs index b919611..24ce415 100644 --- a/OwnChar/Api/IOwnCharManager.cs +++ b/OwnChar/Api/IOwnCharManager.cs @@ -1,4 +1,5 @@ -using OwnChar.Model; +using OwnChar.Data; +using OwnChar.Model; using Pilz.Cryptography; namespace OwnChar.Api; diff --git a/OwnChar/Api/IUserManager.cs b/OwnChar/Api/IUserManager.cs index 8db650d..8ff54c7 100644 --- a/OwnChar/Api/IUserManager.cs +++ b/OwnChar/Api/IUserManager.cs @@ -4,6 +4,7 @@ using Pilz.Cryptography; namespace OwnChar.Api; public interface IUserManager { + IQueryable? GetUserAccounts(); UserAccount? CreateUserAccount(string? username, SecureString? password); bool DeleteUserAccount(UserAccount? account); UserProfile? GetOwnUserProfile(); diff --git a/OwnChar/Data/DataManagerActions.cs b/OwnChar/Data/DataManagerActions.cs index 4eee539..135beda 100644 --- a/OwnChar/Data/DataManagerActions.cs +++ b/OwnChar/Data/DataManagerActions.cs @@ -12,12 +12,14 @@ public static class DataManagerActions public static DataManagerAction UserAccount { get; } = new(Get, "useraccount"); public static DataManagerAction Group { get; } = new(Get, "group"); public static DataManagerAction Character { get; } = new(Get, "character"); + public static DataManagerAction Property { get; } = new(Get, "property"); + public static DataManagerAction PropertyCategory { get; } = new(Get, "propertycategory"); } public static class Association { public static DataManagerAction Owner { get; } = new(Associate, "owner"); - public static DataManagerAction Parent { get; } = new(Associate, "parent"); + public static DataManagerAction Profile { get; } = new(Associate, "profile"); public static DataManagerAction Members { get; } = new(Associate, "members"); } } \ No newline at end of file diff --git a/OwnChar/Data/DataProviderSetAction.cs b/OwnChar/Data/DataProviderSetAction.cs new file mode 100644 index 0000000..e9e7d6b --- /dev/null +++ b/OwnChar/Data/DataProviderSetAction.cs @@ -0,0 +1,7 @@ +namespace OwnChar.Data; + +public enum DataProviderSetAction +{ + Set, + Remove, +} diff --git a/OwnChar/Data/HierarchyProperties.cs b/OwnChar/Data/HierarchyProperties.cs new file mode 100644 index 0000000..d636a82 --- /dev/null +++ b/OwnChar/Data/HierarchyProperties.cs @@ -0,0 +1,12 @@ +namespace OwnChar.Data; + +public static class HierarchyProperties +{ + public static string PropProps => "Props"; + public static string PropPropCats => "PropCats"; + public static string PropCharacters => "Characters"; + public static string PropProfile => "Profile"; + public static string PropOwner => "Owner"; + public static string PropMembers => "Members"; + public static string PropGroups => "Groups"; +} diff --git a/OwnChar/Data/IDataManager.cs b/OwnChar/Data/IDataManager.cs new file mode 100644 index 0000000..a520916 --- /dev/null +++ b/OwnChar/Data/IDataManager.cs @@ -0,0 +1,19 @@ +using OwnChar.Model; + +namespace OwnChar.Data; + +public interface IDataManager +{ + public delegate void OnActionEventHandler(object sender, OnActionEventArgs e); + public delegate void OnCallbackEventHandler(object sender, OnCallbackEventArgs e); + + event OnActionEventHandler? OnAction; + event OnCallbackEventHandler? OnCallback; + + // Login + UserAccount? Login(string username, string password); + bool Logout(UserAccount? account); + + // Action + DataManagerActionResult ExecuteAction(DataManagerAction action, DataManagerActionType actionType, UserAccount currentUser, object? obj, params object?[] parameters); +} diff --git a/OwnChar/Data/IDataProvider.cs b/OwnChar/Data/IDataProvider.cs new file mode 100644 index 0000000..b9f6271 --- /dev/null +++ b/OwnChar/Data/IDataProvider.cs @@ -0,0 +1,26 @@ +using OwnChar.Model; + +namespace OwnChar.Data; + +public interface IDataProvider +{ + bool IsInitialized(); + void SetInitialized(); + bool SaveDatabase(); + + // Model + T? Create() where T : OwnCharObject; + bool Save(T obj) where T : OwnCharObject; + bool Delete(T obj) where T : OwnCharObject; + IQueryable? GetAll() where T : OwnCharObject; + + // Hierarchy + bool SetChild(OwnCharObject parent, OwnCharObject? child, string property, DataProviderSetAction action); + T? GetChild(OwnCharObject parent, string property) where T : OwnCharObject; + IQueryable? GetChilds(OwnCharObject parent, string property) where T : OwnCharObject; + T? GetParent(OwnCharObject child, string property) where T : OwnCharObject; + + // Explicite getters + UserAccount? GetUserAccount(string username, string password); + UserProfile? GetUserProfile(string username); +} diff --git a/OwnChar/Data/Managers/DefaultDataManager.cs b/OwnChar/Data/Managers/DefaultDataManager.cs index 639eb96..3d4e6a6 100644 --- a/OwnChar/Data/Managers/DefaultDataManager.cs +++ b/OwnChar/Data/Managers/DefaultDataManager.cs @@ -1,4 +1,4 @@ -using OwnChar.Api; +using OwnChar.Manager.Modules; using OwnChar.Model; namespace OwnChar.Data.Managers; @@ -50,14 +50,21 @@ public class DefaultDataManager : IDataManager // Get if (e.Is(DataManagerActionType.Get)) { - if (e.Is(UserType.User) && e.GetObject(out Group? group)) - return e.SetResult(DataProvider.GetCharacters(group)); + if (e.Is(UserType.User)) + { + if (e.GetObject(out Group? group)) + return e.SetResult(DataProvider.GetChilds(group, HierarchyProperties.PropCharacters)); + if (e.GetObject(out UserProfile? profile)) + return e.SetResult(DataProvider.GetChilds(profile, HierarchyProperties.PropCharacters)); + } + if (e.Is(UserType.Admin)) + return e.SetResult(DataProvider.GetAll()); } // Create else if (e.Is(DataManagerActionType.Set)) { - if (e.Object is Group group && e.GetParam(0, out string? name)) + if (e.GetObject(out Group? group) && e.GetParam(0, out string? name)) return e.SetResult(CreateCharacter(e.CurrentUser, name, group)); } } @@ -68,8 +75,13 @@ public class DefaultDataManager : IDataManager // Get if (e.Is(DataManagerActionType.Get)) { - if (e.Object is UserProfile profile) - return e.SetResult(DataProvider.GetGroups(profile)); + if (e.Is(UserType.User)) + { + if (e.GetObject(out UserProfile? profile)) + return e.SetResult(DataProvider.GetChilds(profile, HierarchyProperties.PropGroups)); + } + if (e.Is(UserType.Admin)) + return e.SetResult(DataProvider.GetAll()); } // Create @@ -87,7 +99,7 @@ public class DefaultDataManager : IDataManager if (e.Is(DataManagerActionType.Get)) { if (e.Is(UserType.Admin)) - return e.SetResult(DataProvider.GetUserAccounts()); + return e.SetResult(DataProvider.GetAll()); } // Create @@ -96,12 +108,44 @@ public class DefaultDataManager : IDataManager if (e.GetParam(0, out string? username) && e.GetParam(1, out string? password)) return e.SetResult(CreateUserAccount(username, password)); } + } + + // Property + else if (e.Is(DataManagerActions.Getter.Property)) + { + // Get + if (e.Is(DataManagerActionType.Get)) + { + if (e.Is(UserType.User) && e.GetObject(out Character? character)) + return e.SetResult(DataProvider.GetChilds(character, HierarchyProperties.PropPropCats)); + } // Create - //else if (e.ActionType == DataManagerActionType.Set( - // return e.SetResult(DataProvider.GetUserAccounts()); + if (e.Is(DataManagerActionType.Set)) + { + if (e.Is(UserType.User) && e.GetObject(out Character? character)) + return e.SetResult(CreateProperty(e.CurrentUser, character)); + } } + //// PropertyCategory + //else if (e.Is(DataManagerActions.Getter.PropertyCategory)) + //{ + // // Get + // if (e.Is(DataManagerActionType.Get)) + // { + // if (e.Is(UserType.User) && e.GetObject(out Character? character)) + // return e.SetResult(DataProvider.GetChilds(character, HierarchyProperties.PropPropCats)); + // } + + // // Create + // if (e.Is(DataManagerActionType.Set)) + // { + // if (e.Is(UserType.User) && e.GetObject(out Character? character)) + // return e.SetResult(CreateProperty(character)); + // } + //} + return false; } @@ -132,6 +176,13 @@ public class DefaultDataManager : IDataManager if (e.Object is UserAccount userAccount) return DeleteUserAccount(userAccount); + // Property + if (e.Object is Property property) + { + if (e.GetParam(0, out Character? paramChar)) + return DeleteProperty(e.CurrentUser, paramChar, property); + } + return false; } @@ -140,31 +191,45 @@ public class DefaultDataManager : IDataManager if (!e.Is(DataManagerActions.Associate)) return false; - if (e.Is(DataManagerActions.Association.Owner)) + if (e.Is(DataManagerActions.Association.Profile)) { - if (e.Object is Group group) + if (e.GetObject(out UserAccount? account)) { - switch (e.ActionType) + if (e.Is(DataManagerActionType.Get)) { - case DataManagerActionType.Get: - return e.SetResultT(DataProvider.GetOwner(group)); - case DataManagerActionType.Set: - if (e.GetParam(0, out UserProfile? profile)) - return DataProvider.SetOwner(group, profile); - break; + if (e.Is(UserType.Admin) || (e.Is(UserType.User) && e.CurrentUser == account)) + return e.SetResult(DataProvider.GetChild(account, HierarchyProperties.PropProfile)); + } + } + } + + else if (e.Is(DataManagerActions.Association.Owner)) + { + if (e.GetObject(out Group? group)) + { + if (e.Is(DataManagerActionType.Get)) + { + if (e.Is(UserType.User)) + return e.SetResultT(DataProvider.GetChild(group, HierarchyProperties.PropOwner)); + } + else if (e.Is(DataManagerActionType.Set)) + { + if (e.Is(UserType.User) && e.GetParam(0, out UserProfile? profile)) + return DataProvider.SetChild(group, profile, HierarchyProperties.PropOwner, DataProviderSetAction.Set); } } - if (e.Object is Character character) + if (e.GetObject(out Character? character)) { - switch (e.ActionType) + if (e.Is(DataManagerActionType.Get)) { - case DataManagerActionType.Get: - return e.SetResultT(DataProvider.GetOwner(character)); - case DataManagerActionType.Set: - if (e.GetParam(0, out UserProfile? profile)) - return DataProvider.SetOwner(character, profile); - break; + if (e.Is(UserType.User)) + return e.SetResultT(DataProvider.GetChild(character, HierarchyProperties.PropOwner)); + } + else if (e.Is(DataManagerActionType.Set)) + { + if (e.Is(UserType.User) && e.GetParam(0, out UserProfile? profile)) + return DataProvider.SetChild(character, profile, HierarchyProperties.PropOwner, DataProviderSetAction.Set); } } } @@ -176,21 +241,21 @@ public class DefaultDataManager : IDataManager { if (!account.HasPermission(UserType.Guest)) return null; - return DataProvider.GetMembers(group); + return DataProvider.GetChilds(group, HierarchyProperties.PropMembers); } public UserProfile? GetOwner(UserAccount account, Group group) { if (!account.HasPermission(UserType.Guest)) return null; - return DataProvider.GetOwner(group); + return DataProvider.GetChild(group, HierarchyProperties.PropOwner); } public UserProfile? GetOwner(UserAccount account, Character character) { if (!account.HasPermission(UserType.Guest)) return null; - return DataProvider.GetOwner(character); + return DataProvider.GetChild(character, HierarchyProperties.PropOwner); } public UserProfile? GetUserProfile(UserAccount account) @@ -224,6 +289,28 @@ public class DefaultDataManager : IDataManager return result; } + protected virtual Property? CreateProperty(UserAccount account, Character character) + { + ArgumentNullException.ThrowIfNull(character, nameof(character)); + + if (!account.HasPermission(UserType.User)) + return null; + + var prop = DataProvider.Create(); + ArgumentNullException.ThrowIfNull(prop, nameof(prop)); + + DataProvider.SetChild(character, prop, HierarchyProperties.PropProps, DataProviderSetAction.Set); + + return prop; + } + + protected virtual bool DeleteProperty(UserAccount account, Character character, Property property) + { + if (GetUserProfile(account) is not UserProfile profile || DataProvider.GetChild(character, HierarchyProperties.PropOwner) is not UserProfile owner || !account.HasPermission(profile == owner ? UserType.User : UserType.Admin)) + return false; + return DataProvider.Delete(property); + } + protected virtual UserAccount? CreateUserAccount(string username, string password) { var account = DataProvider.Create(); @@ -238,10 +325,10 @@ public class DefaultDataManager : IDataManager account.Password = password; profile.Name = username; - DataProvider.SetParent(profile, account); + DataProvider.SetChild(account, profile, HierarchyProperties.PropProfile, DataProviderSetAction.Set); group.IsInternal = true; - DataProvider.SetOwner(group, profile); + DataProvider.SetChild(group, profile, HierarchyProperties.PropOwner, DataProviderSetAction.Set); DataProvider.Save(account); DataProvider.Save(profile); @@ -258,34 +345,6 @@ public class DefaultDataManager : IDataManager return true; } - public IEnumerable? GetCharacters(UserAccount account, Group group) - { - if (!account.HasPermission(UserType.Guest)) - return null; - return DataProvider.GetCharacters(group); - } - - public IEnumerable? GetCharacters(UserAccount account, UserProfile profile) - { - if (!account.HasPermission(UserType.Guest)) - return null; - return DataProvider.GetCharacters(profile); - } - - public bool AddMember(UserAccount account, Group group, UserProfile user) - { - if (GetUserProfile(account) is not UserProfile profile || DataProvider.GetOwner(group) is not UserProfile owner || !account.HasPermission(profile == owner ? UserType.User : UserType.Admin)) - return false; - return DataProvider.AddMember(group, user); - } - - public bool RemoveMember(UserAccount account, Group group, UserProfile user) - { - if (GetUserProfile(account) is not UserProfile profile || DataProvider.GetOwner(group) is not UserProfile owner || !account.HasPermission(profile == owner ? UserType.User : UserType.Admin)) - return false; - return DataProvider.RemoveMember(group, user); - } - protected virtual Group? CreateGroup(UserAccount account, string name) { if (!account.HasPermission(UserType.User) || GetUserProfile(account) is not UserProfile profile || DataProvider.Create() is not Group group) @@ -295,14 +354,14 @@ public class DefaultDataManager : IDataManager DataProvider.Save(group); - DataProvider.SetOwner(group, profile); + DataProvider.SetChild(group, profile, HierarchyProperties.PropOwner, DataProviderSetAction.Set); return group; } protected virtual bool DeleteGroup(UserAccount account, Group group) { - if (GetUserProfile(account) is not UserProfile profile || DataProvider.GetOwner(group) is not UserProfile owner || !account.HasPermission(profile == owner ? UserType.User : UserType.Admin)) + if (GetUserProfile(account) is not UserProfile profile || DataProvider.GetChild(group, HierarchyProperties.PropOwner) is not UserProfile owner || !account.HasPermission(profile == owner ? UserType.User : UserType.Admin)) return false; return DataProvider.Delete(group); } @@ -316,21 +375,18 @@ public class DefaultDataManager : IDataManager DataProvider.Save(character); - DataProvider.SetOwner(character, profile); + DataProvider.SetChild(character, profile, HierarchyProperties.PropOwner, DataProviderSetAction.Set); if (group != null) - DataProvider.SetParent(character, group); + DataProvider.SetChild(group, character, HierarchyProperties.PropCharacters, DataProviderSetAction.Set); return character; } protected virtual bool DeleteCharacter(UserAccount account, Character character) { - if (GetUserProfile(account) is not UserProfile profile || DataProvider.GetOwner(character) is not UserProfile owner || !account.HasPermission(profile == owner ? UserType.User : UserType.Admin)) + if (GetUserProfile(account) is not UserProfile profile || DataProvider.GetChild(character, HierarchyProperties.PropOwner) is not UserProfile owner || !account.HasPermission(profile == owner ? UserType.User : UserType.Admin)) return false; - - DataProvider.Delete(character); - - return true; + return DataProvider.Delete(character); } } diff --git a/OwnChar/Data/Providers/JsonFile/JsonFileDataProvider.cs b/OwnChar/Data/Providers/JsonFile/JsonFileDataProvider.cs index 660f585..3aa2fe1 100644 --- a/OwnChar/Data/Providers/JsonFile/JsonFileDataProvider.cs +++ b/OwnChar/Data/Providers/JsonFile/JsonFileDataProvider.cs @@ -1,13 +1,15 @@ using Newtonsoft.Json; -using OwnChar.Api; using OwnChar.Data.Providers.JsonFile.Model; using OwnChar.Model; using System.Collections; +using System.Linq; namespace OwnChar.Data.Providers.JsonFile; public class JsonFileDataProvider : IDataProvider { + protected readonly Random random = new(); + public JsonFile JsonFile { get; protected set; } public string JsonFilePath { get; protected set; } @@ -33,6 +35,11 @@ public class JsonFileDataProvider : IDataProvider File.WriteAllText(JsonFilePath, JsonConvert.SerializeObject(JsonFile, CreateJsonSerializerSettings())); } + protected int GenerateNewObjectId() + { + return random.Next(); + } + protected virtual JsonSerializerSettings CreateJsonSerializerSettings() { return new JsonSerializerSettings @@ -54,6 +61,12 @@ public class JsonFileDataProvider : IDataProvider JsonFile.IsInitialized = true; } + public bool SaveDatabase() + { + SaveFile(); + return true; + } + public T? Create() where T : OwnCharObject { var t = typeof(T); @@ -74,7 +87,13 @@ public class JsonFileDataProvider : IDataProvider else obj = null; - return obj as T; + if (obj is T objT) + { + objT.Id = GenerateNewObjectId(); + return objT; + } + + return null; } public bool Save(T obj) where T : OwnCharObject @@ -140,89 +159,261 @@ public class JsonFileDataProvider : IDataProvider return false; } - public IEnumerable? Get(OwnCharObject? context) where T : OwnCharObject + public IQueryable? GetAll(OwnCharObject? context) where T : OwnCharObject { var t = typeof(T); - static IEnumerable? asList(IList list) => list as IEnumerable; + static IQueryable? asList(IEnumerable list) => list as IQueryable; - if (t == typeof(Property)) - { - // ... - } - else if (t == typeof(PropertyCategory)) - { - // ... - } - else if (t == typeof(Character)) - { - if (context is JsonGroup group) - return (IEnumerable)group.Characters; - if (context is UserProfile profile) - return (IEnumerable)JsonFile.Characters.Where(n => n.Owner == profile); - return (IEnumerable)JsonFile.Characters; - } + if (t == typeof(Character)) + return asList(JsonFile.Characters); else if (t == typeof(Group)) - { - if (context is UserProfile profile) - return (IEnumerable)JsonFile.Groups.Where(g => g.Owner == profile); - return (IEnumerable)JsonFile.Groups; - } + return asList(JsonFile.Groups); else if (t == typeof(UserAccount)) - return (IEnumerable)JsonFile.UserAccounts; + return asList(JsonFile.UserAccounts); + return null; } - public bool SetParent(UserProfile profile, UserAccount parent) + public bool SetChild(OwnCharObject parent, OwnCharObject? child, string property, DataProviderSetAction action) { - if (parent is JsonUserAccount jaccount && profile is JsonUserProfile jprofile) + // UserAccount + if (parent is JsonUserAccount parentAccount) { - jaccount.Profile = jprofile; - return true; + // User profil + if (property == HierarchyProperties.PropProfile) + { + // Remove + if (child is null || action == DataProviderSetAction.Remove) + { + parentAccount.Profile = null; + return true; + } + + // Set + else if (child is JsonUserProfile childProfile) + { + parentAccount.Profile = childProfile; + return true; + } + } } + + // Group + if (parent is JsonGroup parentGroup) + { + // Characters + if (property == HierarchyProperties.PropCharacters) + { + // Clear + if (child is null && action == DataProviderSetAction.Remove) + { + parentGroup.Characters.Clear(); + return true; + } + + // Add/Remove + else if (child is JsonCharacter childCharacter) + { + // Remove + if (action == DataProviderSetAction.Remove) + { + parentGroup.Characters.Remove(childCharacter); + return true; + } + + // Add + else + { + if (!parentGroup.Characters.Contains(childCharacter)) + parentGroup.Characters.Add(childCharacter); + return true; + } + } + } + + // Members + // ... + + // Owner + if (property == HierarchyProperties.PropOwner) + { + // Remove + if (child is null || action == DataProviderSetAction.Remove) + { + parentGroup.Owner = null; + return true; + } + + // Set + else if (child is JsonUserProfile childProfile) + { + parentGroup.Owner = childProfile; + return true; + } + } + } + + // Character + if (parent is JsonCharacter parentCharacter) + { + // Properties + if (property == HierarchyProperties.PropProps) + { + // Clear + if (child is null && action == DataProviderSetAction.Remove) + { + parentCharacter.Properties.Clear(); + return true; + } + + // Add/Remove + else if (child is JsonProp childProperty) + { + // Remove + if (action == DataProviderSetAction.Remove) + { + parentCharacter.Properties.Remove(childProperty); + return true; + } + + // Add + else + { + if (!parentCharacter.Properties.Contains(childProperty)) + parentCharacter.Properties.Add(childProperty); + return true; + } + } + } + + // Property categories + else if (property == HierarchyProperties.PropPropCats) + { + // Clear + if (child is null && action == DataProviderSetAction.Remove) + { + parentCharacter.PropertyCategories.Clear(); + return true; + } + + // Add/Remove + else if (child is JsonPropCat childPropertyCategory) + { + // Remove + if (action == DataProviderSetAction.Remove) + { + parentCharacter.PropertyCategories.Remove(childPropertyCategory); + return true; + } + + // Add + else + { + if (!parentCharacter.PropertyCategories.Contains(childPropertyCategory)) + parentCharacter.PropertyCategories.Add(childPropertyCategory); + return true; + } + } + } + + // Owner + else if (property == HierarchyProperties.PropOwner) + { + // Remove + if (child is null || action == DataProviderSetAction.Remove) + { + parentCharacter.Owner = null; + return true; + } + + // Set + else if (child is JsonUserProfile childProfile) + { + parentCharacter.Owner = childProfile; + return true; + } + } + } + return false; } - public bool SetParent(Character character, Group parent) + public T? GetParent(OwnCharObject child, string property) where T : OwnCharObject { - if (character is JsonCharacter jcharacter && parent is JsonGroup jgroup) - { - if (!jgroup.Characters.Contains(jcharacter)) - jgroup.Characters.Add(jcharacter); - return true; - } - return false; + throw new NotImplementedException("Not yet implemented as not needed."); } - public bool SetParent(Property property, Character character) + public T? GetChild(OwnCharObject parent, string property) where T : OwnCharObject { - if (property is JsonProp jprop && character is JsonCharacter jcharacter) + // UserAccount + if (parent is JsonUserAccount parentAccount) { - if (!jcharacter.Properties.Contains(jprop)) - jcharacter.Properties.Add(jprop); - return true; + // User profile + if (property == HierarchyProperties.PropProfile) + return parentAccount.Profile as T; } - return false; + + // Group + else if (parent is JsonGroup parentGroup) + { + // Owner + if (property == HierarchyProperties.PropCharacters) + return parentGroup.Owner as T; + } + + // Character + else if (parent is JsonCharacter parentCharacter) + { + // Owner + if (property == HierarchyProperties.PropOwner) + return parentCharacter.Owner as T; + } + + return null; } - public bool SetOwner(Group group, UserProfile owner) + public IQueryable? GetChilds(OwnCharObject parent, string property) where T : OwnCharObject { - if (group is JsonGroup jgroup && owner is JsonUserProfile jprofile) - { - jgroup.Owner = jprofile; - return true; - } - return false; - } + static IQueryable? asList(IEnumerable list) => list as IQueryable; - public bool SetOwner(Character character, UserProfile owner) - { - if (character is JsonCharacter jcharacter && owner is JsonUserProfile jprofile) + // Group + if (parent is JsonGroup parentGroup) { - jcharacter.Owner = jprofile; - return true; + // Characters + if (property == HierarchyProperties.PropCharacters) + return asList(parentGroup.Characters); + + // Members + if (property == HierarchyProperties.PropMembers) + return asList(parentGroup.Members); } - return false; + + // Character + else if (parent is JsonCharacter parentCharacter) + { + // Properties + if (property == HierarchyProperties.PropProps) + return asList(parentCharacter.Properties); + + // Property categories + if (property == HierarchyProperties.PropPropCats) + return asList(parentCharacter.PropertyCategories); + } + + // UserProfile + else if (parent is JsonUserProfile parentUserProfile) + { + // Characters + if (property == HierarchyProperties.PropCharacters) + return asList(JsonFile.Characters.Where(c => c.Owner == parentUserProfile)); + + // Groups + if (property == HierarchyProperties.PropGroups) + return asList(JsonFile.Groups.Where(g => g.Owner == parentUserProfile)); + } + + return null; } public UserAccount? GetUserAccount(string username, string password) @@ -236,66 +427,4 @@ public class JsonFileDataProvider : IDataProvider { return JsonFile.UserAccounts.FirstOrDefault(n => n.Username == username)?.Profile; } - - public IEnumerable? GetMembers(Group group) - { - if (group is JsonGroup jgroup) - return jgroup.Members; - return null; - } - - public UserProfile? GetOwner(Group group) - { - if (group is JsonGroup jgroup) - return jgroup.Owner; - return null; - } - - public UserProfile? GetOwner(Character character) - { - if (character is JsonCharacter jcharacter) - return jcharacter.Owner; - return null; - } - - public IEnumerable? GetCharacters(Group group) - { - if (group is JsonGroup jgroup) - return jgroup.Characters; - return null; - } - - public IEnumerable? GetCharacters(UserProfile profile) - { - if (profile is UserProfile jprofile) - return JsonFile.Characters.Where(n => n.Owner == profile); - return null; - } - - public bool AddMember(Group group, UserProfile user) - { - if (group is JsonGroup jgroup && user is JsonUserProfile jprofile) - { - if (!jgroup.Members.Contains(jprofile)) - jgroup.Members.Add(jprofile); - return true; - } - return false; - } - - public bool RemoveMember(Group group, UserProfile user) - { - if (group is JsonGroup jgroup && user is JsonUserProfile jprofile) - { - jgroup.Members.Remove(jprofile); - return true; - } - return false; - } - - public bool SaveDatabase() - { - SaveFile(); - return true; - } } diff --git a/OwnChar/Manager/Modules/CharacterManager.cs b/OwnChar/Manager/Modules/CharacterManager.cs index 780bda8..5300789 100644 --- a/OwnChar/Manager/Modules/CharacterManager.cs +++ b/OwnChar/Manager/Modules/CharacterManager.cs @@ -1,26 +1,27 @@ using OwnChar.Api; +using OwnChar.Data; using OwnChar.Model; namespace OwnChar.Manager.Modules; public class CharacterManager(OwnCharManager manager) : OwnCharManagerModule(manager), ICharacterManager { - public IEnumerable? GetCharacters(Group? group) + public IQueryable? GetCharacters(Group? group) { Manager.CheckLogin(); if (group != null) - return Manager.DataManager?.GetCharacters(Manager.CurrentUser!, group); + return Manager.DataManager.ExecuteAction(DataManagerActions.Getter.Character, DataManagerActionType.Get, Manager.CurrentUser, group).Result as IQueryable; return null; } - public IEnumerable? GetCharacters(UserProfile? profile) + public IQueryable? GetCharacters(UserProfile? profile) { Manager.CheckLogin(); if (profile != null) - return Manager.DataManager?.GetCharacters(Manager.CurrentUser!, profile); + return Manager.DataManager.ExecuteAction(DataManagerActions.Getter.Character, DataManagerActionType.Get, Manager.CurrentUser, profile).Result as IQueryable; return null; } @@ -33,18 +34,14 @@ public class CharacterManager(OwnCharManager manager) : OwnCharManagerModule(man public Character? CreateCharacter(string? name, Group? destination) { ArgumentException.ThrowIfNullOrWhiteSpace(name, nameof(name)); - Manager.CheckLogin(); - - return Manager.DataManager?.CreateCharacter(Manager.CurrentUser!, name, destination); + return Manager.DataManager.ExecuteAction(DataManagerActions.Getter.PropertyCategory, DataManagerActionType.Set, Manager.CurrentUser, null, name, destination).Result as Character; } public bool DeleteCharacter(Character? character) { ArgumentNullException.ThrowIfNull(character, nameof(character)); - Manager.CheckLogin(); - - return Manager.DataManager?.DeleteCharacter(Manager.CurrentUser!, character) ?? false; + return Manager.DataManager.ExecuteAction(DataManagerActions.Delete, DataManagerActionType.Default, Manager.CurrentUser, character).HasSuccess; } } diff --git a/OwnChar/Manager/Modules/GroupsManager.cs b/OwnChar/Manager/Modules/GroupsManager.cs index ea83c01..73a6359 100644 --- a/OwnChar/Manager/Modules/GroupsManager.cs +++ b/OwnChar/Manager/Modules/GroupsManager.cs @@ -10,14 +10,27 @@ public class GroupsManager(OwnCharManager manager) : OwnCharManagerModule(manage { ArgumentNullException.ThrowIfNull(group, nameof(group)); Manager.CheckLogin(); - return Manager.DataManager.ExecuteAction(DataManagerActions.Association.Members, DataManagerActionType.Get, Manager.CurrentUser, group).HasSuccess; + return Manager.DataManager.ExecuteAction(DataManagerActions.Association.Owner, DataManagerActionType.Get, Manager.CurrentUser, group).Result as UserProfile; } - public IEnumerable? GetMembers(Group? group) + public IQueryable? GetGroups(UserProfile? profile) + { + ArgumentNullException.ThrowIfNull(profile, nameof(profile)); + Manager.CheckLogin(); + return Manager.DataManager.ExecuteAction(DataManagerActions.Getter.Group, DataManagerActionType.Get, Manager.CurrentUser, profile) as IQueryable; + } + + public IQueryable? GetGroups() + { + Manager.CheckLogin(); + return Manager.DataManager.ExecuteAction(DataManagerActions.Getter.Group, DataManagerActionType.Get, Manager.CurrentUser, null) as IQueryable; + } + + public IQueryable? GetMembers(Group? group) { ArgumentNullException.ThrowIfNull(group, nameof(group)); Manager.CheckLogin(); - return Manager.DataManager.ExecuteAction(DataManagerActions.Association.Members, DataManagerActionType.Get, Manager.CurrentUser, group).HasSuccess; + return Manager.DataManager.ExecuteAction(DataManagerActions.Association.Members, DataManagerActionType.Get, Manager.CurrentUser, group).Result as IQueryable; } public bool AddMember(UserProfile? profile, Group? group) @@ -28,7 +41,7 @@ public class GroupsManager(OwnCharManager manager) : OwnCharManagerModule(manage return Manager.DataManager.ExecuteAction(DataManagerActions.Association.Members, DataManagerActionType.Set, Manager.CurrentUser, group, profile).HasSuccess; } - public bool DeleteMember(UserProfile? profile, Group? group) + public bool RemoveMember(UserProfile? profile, Group? group) { ArgumentNullException.ThrowIfNull(profile, nameof(profile)); ArgumentNullException.ThrowIfNull(group, nameof(group)); diff --git a/OwnChar/Manager/Modules/UserManager.cs b/OwnChar/Manager/Modules/UserManager.cs index 2806b41..c3e3b7e 100644 --- a/OwnChar/Manager/Modules/UserManager.cs +++ b/OwnChar/Manager/Modules/UserManager.cs @@ -1,4 +1,5 @@ using OwnChar.Api; +using OwnChar.Data; using OwnChar.Model; using Pilz.Cryptography; @@ -9,20 +10,28 @@ public class UserManager(OwnCharManager manager) : OwnCharManagerModule(manager) public UserProfile? GetOwnUserProfile() { Manager.CheckLogin(); - return Manager.DataManager!.GetUserProfile(Manager.CurrentUser!); + return Manager.DataManager.ExecuteAction(DataManagerActions.Association.Profile, DataManagerActionType.Get, Manager.CurrentUser, Manager.CurrentUser).Result as UserProfile; + } + + public IQueryable? GetUserAccounts() + { + Manager.CheckLogin(); + return Manager.DataManager.ExecuteAction(DataManagerActions.Getter.UserAccount, DataManagerActionType.Get, Manager.CurrentUser, null).Result as IQueryable; } public UserAccount? CreateUserAccount(string? username, SecureString? password) { ArgumentException.ThrowIfNullOrWhiteSpace(username, nameof(username)); ArgumentException.ThrowIfNullOrWhiteSpace(password, nameof(password)); + Manager.CheckLogin(); username = username.Trim().ToLower(); - return Manager.DataManager?.CreateUserAccount(username, Utils.HashPassword(username, password)); + return Manager.DataManager.ExecuteAction(DataManagerActions.Getter.UserAccount, DataManagerActionType.Set, Manager.CurrentUser, null, username, Utils.HashPassword(username, password)).Result as UserAccount; } public bool DeleteUserAccount(UserAccount? account) { ArgumentNullException.ThrowIfNull(account, nameof(account)); - return Manager.DataManager?.DeleteUserAccount(account) ?? false; + Manager.CheckLogin(); + return Manager.DataManager.ExecuteAction(DataManagerActions.Delete, DataManagerActionType.Default, Manager.CurrentUser, account).HasSuccess; } } diff --git a/OwnChar/Manager/OwnCharManager.cs b/OwnChar/Manager/OwnCharManager.cs index 04f6f88..660c905 100644 --- a/OwnChar/Manager/OwnCharManager.cs +++ b/OwnChar/Manager/OwnCharManager.cs @@ -1,5 +1,6 @@ using OwnChar.Api; using OwnChar.Api.Exceptions; +using OwnChar.Data; using OwnChar.Manager.Modules; using OwnChar.Model; using Pilz.Cryptography;