using System.Collections.Immutable; using HermesSocketLibrary.db; using HermesSocketServer.Models; namespace HermesSocketServer.Store { public class PolicyStore : GroupSaveStore { private readonly string _userId; private readonly Database _database; private readonly Serilog.ILogger _logger; private readonly GroupSaveSqlGenerator _generator; public PolicyStore(string userId, Database database, Serilog.ILogger logger) : base(logger) { _userId = userId; _database = database; _logger = logger; var ctp = new Dictionary { { "id", "Id" }, { "userId", "UserId" }, { "groupId", "GroupId" }, { "path", "Path" }, { "count", "Usage" }, { "timespan", "Span" }, }; _generator = new GroupSaveSqlGenerator(ctp, _logger); } public override async Task Load() { var data = new Dictionary() { { "user", _userId } }; string sql = $"SELECT id, \"groupId\", path, count, timespan FROM \"GroupPermissionPolicy\" WHERE \"userId\" = @user"; await _database.Execute(sql, data, (reader) => { var id = reader.GetGuid(0); _store.Add(id.ToString(), new PolicyMessage() { Id = id, UserId = _userId, GroupId = reader.GetGuid(1), Path = reader.GetString(2), Usage = reader.GetInt32(3), Span = reader.GetInt32(4), }); }); _logger.Information($"Loaded {_store.Count} policies from database."); } protected override void OnInitialAdd(string key, PolicyMessage value) { } protected override void OnInitialModify(string key, PolicyMessage value) { } protected override void OnInitialRemove(string key) { } public override async Task Save() { int count = 0; string sql = string.Empty; ImmutableList? list = null; if (_added.Any()) { lock (_lock) { list = _added.ToImmutableList(); _added.Clear(); } count = list.Count; sql = _generator.GeneratePreparedInsertSql("GroupPermissionPolicy", count, ["id", "userId", "groupId", "path", "count", "timespan"]); _logger.Debug($"GroupPermissionPolicy - Adding {count} rows to database: {sql}"); var values = list.Select(id => _store[id]).Where(v => v != null); await _generator.DoPreparedStatement(_database, sql, values, ["id", "userId", "groupId", "path", "count", "timespan"]); } if (_modified.Any()) { lock (_lock) { list = _modified.ToImmutableList(); _modified.Clear(); } count = list.Count; sql = _generator.GeneratePreparedUpdateSql("GroupPermissionPolicy", count, ["id"], ["userId", "groupId", "path", "count", "timespan"]); _logger.Debug($"GroupPermissionPolicy - Modifying {count} rows in database: {sql}"); var values = list.Select(id => _store[id]).Where(v => v != null); await _generator.DoPreparedStatement(_database, sql, values, ["id", "userId", "groupId", "path", "count", "timespan"]); } if (_deleted.Any()) { lock (_lock) { list = _deleted.ToImmutableList(); _deleted.Clear(); } count = list.Count; sql = _generator.GeneratePreparedDeleteSql("GroupPermissionPolicy", count, ["id"]); _logger.Debug($"GroupPermissionPolicy - Deleting {count} rows from database: {sql}"); await _generator.DoPreparedStatementRaw(_database, sql, list.Select(id => new Guid(id)), ["id"]); } } } }