using CommunityToolkit.Mvvm.ComponentModel; using Sonex.DBWrapper; using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using Logger = Sonex.Client.Helpers.Logger; namespace Sonex.Client.Models; public partial class AccountPreferencesModel : ObservableObject { [ObservableProperty] private string key = string.Empty; [ObservableProperty] private string value = string.Empty; private static readonly object _cacheLock = new(); private static readonly Dictionary _cache = new(StringComparer.OrdinalIgnoreCase); public static IReadOnlyDictionary Cache { get { lock (_cacheLock) { return new Dictionary(_cache, StringComparer.OrdinalIgnoreCase); } } } public static async Task> GetAll() { try { return await DB.QueryListAsync( "SELECT \"key\" AS Key, \"value\" AS Value FROM sonex.account_preferences_get();"); } catch (Exception ex) { Logger.Error( ex, source: nameof(AccountPreferencesModel), operation: nameof(GetAll)); return new DB.Result { Success = false, ErrorMessage = ex.Message, ErrorStackTrace = ex.StackTrace }; } } public static async Task> LoadAllToCache() { try { var result = await GetAll(); if (!result.Success) { return result; } lock (_cacheLock) { _cache.Clear(); foreach (var item in result.Items) { if (string.IsNullOrWhiteSpace(item.Key)) { continue; } _cache[item.Key] = item.Value ?? string.Empty; } } return result; } catch (Exception ex) { Logger.Error( ex, source: nameof(AccountPreferencesModel), operation: nameof(LoadAllToCache)); return new DB.Result { Success = false, ErrorMessage = ex.Message, ErrorStackTrace = ex.StackTrace }; } } public static async Task> Update(string key, string value) { if (string.IsNullOrWhiteSpace(key)) { return new DB.SingleResult { Success = false, Item = false, ErrorMessage = "Preference key cannot be empty." }; } try { var safeKey = key.Trim(); var safeValue = value ?? string.Empty; var result = await DB.QuerySingleAsync( "SELECT sonex.account_preferences_update(@Key, @Value);", new { Key = safeKey, Value = safeValue }); if (result.Success && result.Item == true) { SetCachedValue(safeKey, safeValue); } return result; } catch (Exception ex) { Logger.Error( ex, source: nameof(AccountPreferencesModel), operation: nameof(Update)); return new DB.SingleResult { Success = false, Item = false, ErrorMessage = ex.Message, ErrorStackTrace = ex.StackTrace }; } } public static void SetCachedValue(string key, string value) { if (string.IsNullOrWhiteSpace(key)) { return; } var safeKey = key.Trim(); var safeValue = value ?? string.Empty; lock (_cacheLock) { _cache[safeKey] = safeValue; } } public static bool TryGetCachedValue(string key, out string value) { value = string.Empty; if (string.IsNullOrWhiteSpace(key)) { return false; } lock (_cacheLock) { return _cache.TryGetValue(key.Trim(), out value); } } }