using BLHX.Server.Common.Utils; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using System.Reflection; using System.Text.Json; namespace BLHX.Server.Common.Database { public static class DBManager { public static readonly Logger c = new(nameof(DBManager), ConsoleColor.DarkCyan); public static AccountContext AccountContext { get; } public static PlayerContext PlayerContext { get; } static DBManager() { foreach (var dbCtx in Assembly.GetExecutingAssembly().GetTypes().Where(p => typeof(IBLHXDBContext).IsAssignableFrom(p) && !p.IsInterface)) { var dbPath = (string)dbCtx.GetProperty(nameof(AccountContext.DbPath))!.GetValue(null)!; var saveDir = Path.GetDirectoryName(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, dbPath))!; if (!Directory.Exists(saveDir)) Directory.CreateDirectory(saveDir); } AccountContext = new AccountContext(); PlayerContext = new PlayerContext(); } } enum SavingState { None, Saving, Attempting } public interface IBLHXDBContext { public static abstract string DbPath { get; } public string GetFullDbPath(); } public interface IBLHXDBContext : IBLHXDBContext where TSelf : DbContext { string IBLHXDBContext.GetFullDbPath() => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, (string)typeof(TSelf).GetProperty(nameof(DbPath))!.GetValue(null)!); } public static class PropertyBuilderExtensions { public static PropertyBuilder HasJsonConversion(this PropertyBuilder propertyBuilder) where T : class, new() { ValueConverter converter = new ( v => JsonSerializer.Serialize(v, JsonSerializerOptions.Default), v => JsonSerializer.Deserialize(v, JsonSerializerOptions.Default) ?? new T() ); propertyBuilder.HasConversion(converter); propertyBuilder.Metadata.SetValueConverter(converter); propertyBuilder.HasColumnType("jsonb"); return propertyBuilder; } } }