using System.Collections.Concurrent; using HermesSocketLibrary.db; using HermesSocketLibrary.Requests.Messages; using HermesSocketServer.Store.Internal; namespace HermesSocketServer.Store { public class GroupStore : AutoSavedStore { public static readonly string[] AUTO_GENERATED_GROUP_NAMES = ["everyone", "subscribers", "vip", "moderators", "broadcaster"]; private IDictionary _chatters; private readonly string _userId; private readonly Database _database; private readonly ServerConfiguration _configuration; private readonly Serilog.ILogger _logger; public IDictionary Chatters { get => _chatters; } public GroupStore(string userId, DatabaseTable table, Database database, ServerConfiguration configuration, Serilog.ILogger logger) : base(table, database, logger) { _userId = userId; _database = database; _logger = logger; _configuration = configuration; _chatters = new ConcurrentDictionary(); } public override async Task Load() { var groups = new List<(string, string)>(); var data = new Dictionary() { { "user", _userId } }; string sql = $"SELECT id, name, priority FROM \"Group\" WHERE \"userId\" = @user"; await _database.Execute(sql, data, (reader) => { var id = reader.GetGuid(0).ToString(); var name = reader.GetString(1); _store.Add(id, new Group() { Id = id, UserId = _userId, Name = name, Priority = reader.GetInt32(2), }); groups.Add((id, name)); }); _logger.Information($"Loaded {_store.Count} groups from database."); // Load Chatter Groups var chatterGroupTable = _configuration.Database.Tables["ChatterGroup"]; var groupChatters = groups.Select(group => new ChatterGroupStore(_userId, group.Item1, chatterGroupTable, _database, _logger)).ToArray(); List tasks = new List(); for (var i = 0; i < groups.Count; i++) { var store = groupChatters[i]; if (AUTO_GENERATED_GROUP_NAMES.All(n => n != groups[i].Item2)) tasks.Add(store.Load()); _chatters.Add(store.GroupId, store); } await Task.WhenAll(tasks); } public override async Task Save() { List tasks = _chatters.Values.Select(c => c.Save()).ToList(); tasks.Add(base.Save()); await Task.WhenAll(base.Save()); } protected override void OnInitialAdd(string key, Group value) { ArgumentException.ThrowIfNullOrWhiteSpace(key, nameof(key)); ArgumentNullException.ThrowIfNull(value, nameof(value)); ArgumentException.ThrowIfNullOrWhiteSpace(value.UserId, nameof(value.UserId)); ArgumentException.ThrowIfNullOrWhiteSpace(value.Name, nameof(value.Name)); ArgumentNullException.ThrowIfNull(value.Priority, nameof(value.Priority)); } protected override void OnInitialModify(string key, Group oldValue, Group newValue) { ArgumentNullException.ThrowIfNull(newValue, nameof(newValue)); ArgumentException.ThrowIfNullOrWhiteSpace(newValue.UserId, nameof(newValue.UserId)); ArgumentException.ThrowIfNullOrWhiteSpace(newValue.Name, nameof(newValue.Name)); ArgumentNullException.ThrowIfNull(newValue.Priority, nameof(newValue.Priority)); ArgumentOutOfRangeException.ThrowIfNotEqual(oldValue.UserId, newValue.UserId, nameof(oldValue.UserId)); if (AUTO_GENERATED_GROUP_NAMES.Any(s => s == oldValue.Name)) ArgumentOutOfRangeException.ThrowIfNotEqual(oldValue.Name, newValue.Name, nameof(oldValue.Name)); } protected override void OnPostRemove(string key, Group value) { } } }