using Sonex.Data.Database; namespace Sonex.Data.Records; public sealed class AccountPreferenceRecord { private static readonly object CacheLock = new(); private static readonly Dictionary CacheStore = new(StringComparer.OrdinalIgnoreCase); public string Key { get; set; } = string.Empty; public string Value { get; set; } = string.Empty; public static IReadOnlyDictionary Cache { get { lock (CacheLock) { return new Dictionary(CacheStore, StringComparer.OrdinalIgnoreCase); } } } public static Task> GetAll() { return DB.QueryListAsync( "SELECT \"key\" AS Key, \"value\" AS Value FROM sonex.account_preferences_get();"); } public static async Task> LoadAllToCache() { var result = await GetAll().ConfigureAwait(false); if (!result.Success) return result; lock (CacheLock) { CacheStore.Clear(); foreach (var item in result.Items) { if (string.IsNullOrWhiteSpace(item.Key)) continue; CacheStore[item.Key] = item.Value ?? string.Empty; } } return result; } public Task> Save() { if (string.IsNullOrWhiteSpace(Key)) { return Task.FromResult(new DB.SingleResult { Success = false, Item = false, ErrorMessage = "Preference key cannot be empty." }); } var safeKey = Key.Trim(); var safeValue = Value ?? string.Empty; return SaveInternalAsync(safeKey, safeValue); } public static Task> Update(string key, string value) { if (string.IsNullOrWhiteSpace(key)) { return Task.FromResult(new DB.SingleResult { Success = false, Item = false, ErrorMessage = "Preference key cannot be empty." }); } return SaveInternalAsync(key.Trim(), value ?? string.Empty); } public static void SetCachedValue(string key, string value) { if (string.IsNullOrWhiteSpace(key)) return; lock (CacheLock) { CacheStore[key.Trim()] = value ?? string.Empty; } } public static bool TryGetCachedValue(string key, out string value) { value = string.Empty; if (string.IsNullOrWhiteSpace(key)) return false; lock (CacheLock) { if (!CacheStore.TryGetValue(key.Trim(), out var cachedValue)) return false; value = cachedValue; return true; } } private static async Task> SaveInternalAsync(string key, string value) { var result = await DB.QuerySingleAsync( "SELECT sonex.account_preferences_update(@Key, @Value);", new { Key = key, Value = value }).ConfigureAwait(false); if (result.Success && result.Item == true) SetCachedValue(key, value); return result; } }