|
|
|
using System.Collections.Concurrent;
|
|
|
|
using System.Linq.Expressions;
|
|
|
|
using System.Reflection;
|
|
|
|
using LiteDB;
|
|
|
|
using LiteDB.Async;
|
|
|
|
|
|
|
|
namespace StabilityMatrix.Core.Extensions;
|
|
|
|
|
|
|
|
// ReSharper disable once InconsistentNaming
|
|
|
|
public static class LiteDBExtensions
|
|
|
|
{
|
|
|
|
private static readonly ConcurrentDictionary<Type, (Type PropertyType, string MemberName, bool IsList)> Mapper =
|
|
|
|
new();
|
|
|
|
|
|
|
|
public static void Register<T, TU>(Expression<Func<T, List<TU>?>> exp, string? collection = null)
|
|
|
|
{
|
|
|
|
var member = (exp.Body is MemberExpression body ? body.Member : null) as PropertyInfo;
|
|
|
|
if (member == null)
|
|
|
|
throw new ArgumentException("Expecting Member Expression");
|
|
|
|
BsonMapper.Global.Entity<T>().DbRef(exp, collection);
|
|
|
|
Mapper.TryAdd(typeof(T), (typeof(TU), member.Name, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void Register<T, TU>(Expression<Func<T, TU?>> exp, string? collection = null)
|
|
|
|
{
|
|
|
|
var member = (exp.Body is MemberExpression body ? body.Member : null) as PropertyInfo;
|
|
|
|
if (member == null)
|
|
|
|
throw new ArgumentException("Expecting Member Expression");
|
|
|
|
BsonMapper.Global.Entity<T>().DbRef(exp, collection);
|
|
|
|
Mapper.TryAdd(typeof(T), (typeof(TU), member.Name, false));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static ILiteCollection<T>? IncludeAll<T>(this ILiteCollection<T> col)
|
|
|
|
{
|
|
|
|
if (!Mapper.ContainsKey(typeof(T)))
|
|
|
|
return null;
|
|
|
|
|
|
|
|
var stringList = new List<string>();
|
|
|
|
var key = typeof(T);
|
|
|
|
var values = new List<string>();
|
|
|
|
var flag = true;
|
|
|
|
while (Mapper.TryGetValue(key, out var tuple))
|
|
|
|
{
|
|
|
|
var str = tuple.MemberName + (tuple.IsList ? "[*]" : "");
|
|
|
|
values.Add(flag ? "$." + str : str);
|
|
|
|
stringList.Add(string.Join(".", values));
|
|
|
|
key = tuple.PropertyType;
|
|
|
|
flag = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return stringList.Aggregate(col, (current, keySelector) => current.Include((BsonExpression)keySelector));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static ILiteCollectionAsync<T> IncludeAll<T>(this ILiteCollectionAsync<T> col)
|
|
|
|
{
|
|
|
|
if (!Mapper.ContainsKey(typeof(T)))
|
|
|
|
return col;
|
|
|
|
|
|
|
|
var stringList = new List<string>();
|
|
|
|
var key = typeof(T);
|
|
|
|
var values = new List<string>();
|
|
|
|
var flag = true;
|
|
|
|
while (Mapper.TryGetValue(key, out var tuple))
|
|
|
|
{
|
|
|
|
var str = tuple.MemberName + (tuple.IsList ? "[*]" : "");
|
|
|
|
values.Add(flag ? "$." + str : str);
|
|
|
|
stringList.Add(string.Join(".", values));
|
|
|
|
key = tuple.PropertyType;
|
|
|
|
flag = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return stringList.Aggregate(col, (current, keySelector) => current.Include((BsonExpression)keySelector));
|
|
|
|
}
|
|
|
|
}
|