2021-03-06 05:36:36 +01:00
|
|
|
#nullable enable
|
2019-08-22 13:44:06 +02:00
|
|
|
using System.Threading;
|
2017-09-27 07:18:09 +02:00
|
|
|
using System.Threading.Tasks;
|
2020-11-17 13:46:23 +01:00
|
|
|
using BTCPayServer.Abstractions.Contracts;
|
2020-06-28 10:55:27 +02:00
|
|
|
using BTCPayServer.Data;
|
2019-08-22 13:44:06 +02:00
|
|
|
using BTCPayServer.Events;
|
2017-09-27 07:18:09 +02:00
|
|
|
using Microsoft.EntityFrameworkCore;
|
2021-07-27 14:08:54 +02:00
|
|
|
using Microsoft.Extensions.Caching.Memory;
|
2017-09-27 07:18:09 +02:00
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
|
|
namespace BTCPayServer.Services
|
|
|
|
{
|
2020-10-21 14:02:20 +02:00
|
|
|
public class SettingsRepository : ISettingsRepository
|
2017-10-27 10:53:04 +02:00
|
|
|
{
|
2020-06-29 05:07:48 +02:00
|
|
|
private readonly ApplicationDbContextFactory _ContextFactory;
|
2019-08-22 13:44:06 +02:00
|
|
|
private readonly EventAggregator _EventAggregator;
|
2021-07-27 14:08:54 +02:00
|
|
|
private readonly IMemoryCache _memoryCache;
|
2019-08-22 13:44:06 +02:00
|
|
|
|
2021-07-27 14:08:54 +02:00
|
|
|
public SettingsRepository(ApplicationDbContextFactory contextFactory, EventAggregator eventAggregator, IMemoryCache memoryCache)
|
2017-10-27 10:53:04 +02:00
|
|
|
{
|
|
|
|
_ContextFactory = contextFactory;
|
2019-08-22 13:44:06 +02:00
|
|
|
_EventAggregator = eventAggregator;
|
2021-07-27 14:08:54 +02:00
|
|
|
_memoryCache = memoryCache;
|
2017-10-27 10:53:04 +02:00
|
|
|
}
|
2017-09-27 07:18:09 +02:00
|
|
|
|
2021-03-06 05:36:36 +01:00
|
|
|
public async Task<T?> GetSettingAsync<T>(string? name = null) where T : class
|
2017-10-27 10:53:04 +02:00
|
|
|
{
|
2021-03-06 05:36:36 +01:00
|
|
|
name ??= typeof(T).FullName ?? string.Empty;
|
2021-07-27 14:08:54 +02:00
|
|
|
return await _memoryCache.GetOrCreateAsync(GetCacheKey(name), async entry =>
|
2017-10-27 10:53:04 +02:00
|
|
|
{
|
2021-07-27 14:08:54 +02:00
|
|
|
await using var ctx = _ContextFactory.CreateContext();
|
2017-10-27 10:53:04 +02:00
|
|
|
var data = await ctx.Settings.Where(s => s.Id == name).FirstOrDefaultAsync();
|
2021-07-27 14:08:54 +02:00
|
|
|
return data == null ? default : Deserialize<T>(data.Value);
|
|
|
|
});
|
2017-10-27 10:53:04 +02:00
|
|
|
}
|
2021-03-06 05:36:36 +01:00
|
|
|
public async Task UpdateSetting<T>(T obj, string? name = null) where T : class
|
2017-10-27 10:53:04 +02:00
|
|
|
{
|
2021-07-27 14:08:54 +02:00
|
|
|
name ??= typeof(T).FullName ?? string.Empty;
|
|
|
|
await using (var ctx = _ContextFactory.CreateContext())
|
2017-10-27 10:53:04 +02:00
|
|
|
{
|
2020-12-28 11:10:53 +01:00
|
|
|
var settings = UpdateSettingInContext<T>(ctx, obj, name);
|
2017-10-27 10:53:04 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
await ctx.SaveChangesAsync();
|
|
|
|
}
|
|
|
|
catch (DbUpdateException)
|
|
|
|
{
|
|
|
|
ctx.Entry(settings).State = EntityState.Added;
|
|
|
|
await ctx.SaveChangesAsync();
|
|
|
|
}
|
|
|
|
}
|
2021-12-31 08:59:02 +01:00
|
|
|
_memoryCache.Set(GetCacheKey(name), obj);
|
2019-08-22 13:44:06 +02:00
|
|
|
_EventAggregator.Publish(new SettingsChanged<T>()
|
2018-04-18 09:07:16 +02:00
|
|
|
{
|
2022-04-24 05:19:34 +02:00
|
|
|
Settings = obj,
|
|
|
|
SettingsName = name
|
2019-08-22 13:44:06 +02:00
|
|
|
});
|
2020-12-28 11:10:53 +01:00
|
|
|
}
|
|
|
|
|
2021-03-06 05:36:36 +01:00
|
|
|
public SettingData UpdateSettingInContext<T>(ApplicationDbContext ctx, T obj, string? name = null) where T : class
|
2020-12-28 11:10:53 +01:00
|
|
|
{
|
2021-03-06 05:36:36 +01:00
|
|
|
name ??= obj.GetType().FullName ?? string.Empty;
|
2021-07-27 14:08:54 +02:00
|
|
|
_memoryCache.Remove(GetCacheKey(name));
|
2021-12-31 08:59:02 +01:00
|
|
|
var settings = new SettingData { Id = name, Value = Serialize(obj) };
|
2020-12-28 11:10:53 +01:00
|
|
|
ctx.Attach(settings);
|
|
|
|
ctx.Entry(settings).State = EntityState.Modified;
|
|
|
|
return settings;
|
2017-10-27 10:53:04 +02:00
|
|
|
}
|
2017-09-27 07:18:09 +02:00
|
|
|
|
2021-10-18 08:00:38 +02:00
|
|
|
private T? Deserialize<T>(string value) where T : class
|
2017-10-27 10:53:04 +02:00
|
|
|
{
|
|
|
|
return JsonConvert.DeserializeObject<T>(value);
|
|
|
|
}
|
2017-09-27 07:18:09 +02:00
|
|
|
|
2017-10-27 10:53:04 +02:00
|
|
|
private string Serialize<T>(T obj)
|
|
|
|
{
|
|
|
|
return JsonConvert.SerializeObject(obj);
|
|
|
|
}
|
2020-06-28 10:55:27 +02:00
|
|
|
|
2021-07-27 14:08:54 +02:00
|
|
|
private string GetCacheKey(string name)
|
|
|
|
{
|
|
|
|
return $"{nameof(SettingsRepository)}_{name}";
|
|
|
|
}
|
|
|
|
|
2021-03-06 05:36:36 +01:00
|
|
|
public async Task<T> WaitSettingsChanged<T>(CancellationToken cancellationToken = default) where T : class
|
2018-04-18 09:07:16 +02:00
|
|
|
{
|
2019-08-22 13:44:06 +02:00
|
|
|
return (await _EventAggregator.WaitNext<SettingsChanged<T>>(cancellationToken)).Settings;
|
2018-04-18 09:07:16 +02:00
|
|
|
}
|
2017-10-27 10:53:04 +02:00
|
|
|
}
|
2017-09-27 07:18:09 +02:00
|
|
|
}
|