mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-04-30 03:22:04 -04:00
156 lines
5.3 KiB
C#
156 lines
5.3 KiB
C#
using KfChatDotNetBot.Models.DbModels;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Runtime.Caching;
|
|
using System.Text.Json;
|
|
using NLog;
|
|
|
|
namespace KfChatDotNetBot.Settings;
|
|
|
|
public static class SettingsProvider
|
|
{
|
|
public static async Task<Setting> GetValueAsync(string key, bool caseInsensitive = false, bool bypassCache = false)
|
|
{
|
|
var logger = LogManager.GetCurrentClassLogger();
|
|
var cache = MemoryCache.Default;
|
|
if (!bypassCache && cache.Contains(key))
|
|
{
|
|
var cachedSetting = cache.Get(key) as SettingDbModel;
|
|
if (cachedSetting == null)
|
|
{
|
|
logger.Error($"Caught a null in spite of the cache supposedly containing {key}");
|
|
throw new Exception("Cached Setting entry was null");
|
|
}
|
|
var value = cachedSetting.Value;
|
|
if (cachedSetting.Value == "null") value = null;
|
|
return new Setting(value, cachedSetting, true);
|
|
}
|
|
await using var db = new ApplicationDbContext();
|
|
logger.Trace($"Retrieving value for {key}");
|
|
|
|
SettingDbModel? setting;
|
|
if (caseInsensitive)
|
|
{
|
|
// String comparison doesn't work on EF core if I recall correctly
|
|
#pragma warning disable CA1862
|
|
setting = await db.Settings.FirstOrDefaultAsync(s => s.Key.ToLower() == key.ToLower());
|
|
#pragma warning restore CA1862
|
|
}
|
|
else
|
|
{
|
|
setting = await db.Settings.FirstOrDefaultAsync(s => s.Key == key);
|
|
}
|
|
if (setting == null)
|
|
{
|
|
logger.Debug($"{key} does not exist, throwing KeyNotFoundException");
|
|
throw new KeyNotFoundException($"{key} does not exist");
|
|
}
|
|
|
|
cache.Set(key, setting, new CacheItemPolicy {AbsoluteExpiration = DateTimeOffset.UtcNow.AddSeconds(setting.CacheDuration)});
|
|
|
|
if (setting.Value == "null")
|
|
{
|
|
logger.Debug($"{key}'s value is null so returning SettingValue(null)");
|
|
return new Setting(null, setting, false);
|
|
}
|
|
|
|
if (setting.IsSecret)
|
|
{
|
|
logger.Info($"Cache Miss! Returning secret of length '{setting.Value?.Length}' for {key}");
|
|
|
|
}
|
|
else
|
|
{
|
|
logger.Info($"Cache Miss! Returning '{setting.Value}' for {key}");
|
|
|
|
}
|
|
return new Setting(setting.Value, setting, false);
|
|
}
|
|
|
|
public static async Task<Dictionary<string, Setting>> GetMultipleValuesAsync(string[] keys, bool caseInsensitive = false, bool bypassCache = false)
|
|
{
|
|
var logger = LogManager.GetCurrentClassLogger();
|
|
logger.Trace($"Getting values for keys {string.Join(", ", keys)}");
|
|
|
|
var values = new Dictionary<string, Setting>();
|
|
foreach (var key in keys)
|
|
{
|
|
values.Add(key, await GetValueAsync(key, caseInsensitive, bypassCache));
|
|
}
|
|
|
|
return values;
|
|
}
|
|
|
|
public static async Task SetValueAsync(string key, object? value)
|
|
{
|
|
var logger = LogManager.GetCurrentClassLogger();
|
|
await using var db = new ApplicationDbContext();
|
|
string stringValue;
|
|
if (value == null)
|
|
{
|
|
stringValue = "null";
|
|
}
|
|
else if (value is string)
|
|
{
|
|
stringValue = (string)value;
|
|
}
|
|
else
|
|
{
|
|
stringValue = (string)Convert.ChangeType(value, TypeCode.String);
|
|
}
|
|
logger.Debug($"Setting {key} to {stringValue}");
|
|
|
|
var setting = await db.Settings.FirstOrDefaultAsync(s => s.Key == key);
|
|
if (setting == null)
|
|
{
|
|
logger.Debug($"{key} does not exist, throwing KeyNotFoundException()");
|
|
throw new KeyNotFoundException();
|
|
}
|
|
|
|
setting.Value = stringValue;
|
|
await db.SaveChangesAsync();
|
|
var cache = MemoryCache.Default;
|
|
if (cache.Contains(key)) cache.Remove(key);
|
|
}
|
|
|
|
public static async Task SetValueAsJsonObjectAsync<T>(string key, T data)
|
|
{
|
|
var logger = LogManager.GetCurrentClassLogger();
|
|
await using var db = new ApplicationDbContext();
|
|
logger.Debug($"Building data for {key}");
|
|
var value = JsonSerializer.Serialize(data);
|
|
|
|
logger.Debug($"Setting {key} to {value}");
|
|
|
|
var setting = await db.Settings.FirstOrDefaultAsync(s => s.Key == key);
|
|
if (setting == null)
|
|
{
|
|
logger.Debug($"{key} does not exist, throwing KeyNotFoundException()");
|
|
throw new KeyNotFoundException();
|
|
}
|
|
|
|
setting.Value = value;
|
|
await db.SaveChangesAsync();
|
|
var cache = MemoryCache.Default;
|
|
if (cache.Contains(key)) cache.Remove(key);
|
|
}
|
|
|
|
public static async Task SetValueAsBooleanAsync(string key, bool value)
|
|
{
|
|
var logger = LogManager.GetCurrentClassLogger();
|
|
await using var db = new ApplicationDbContext();
|
|
logger.Debug($"Setting {key} to {value}");
|
|
|
|
var setting = await db.Settings.FirstOrDefaultAsync(s => s.Key == key);
|
|
if (setting == null)
|
|
{
|
|
logger.Debug($"{key} does not exist, throwing KeyNotFoundException()");
|
|
throw new KeyNotFoundException();
|
|
}
|
|
|
|
setting.Value = value ? "true" : "false";
|
|
|
|
await db.SaveChangesAsync();
|
|
var cache = MemoryCache.Default;
|
|
if (cache.Contains(key)) cache.Remove(key);
|
|
}
|
|
} |