using Foxchat.Core; using Foxchat.Core.Database; using Foxchat.Identity.Database.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Npgsql; namespace Foxchat.Identity.Database; public class IdentityContext : IDatabaseContext { private readonly NpgsqlDataSource _dataSource; public DbSet Accounts { get; set; } public DbSet ChatInstances { get; set; } public override DbSet Instance { get; set; } public DbSet Applications { get; set; } public DbSet Tokens { get; set; } public DbSet GuildAccounts { get; set; } public IdentityContext(InstanceConfig config) { var connString = new NpgsqlConnectionStringBuilder(config.Database.Url) { Timeout = config.Database.Timeout ?? 5, MaxPoolSize = config.Database.MaxPoolSize ?? 50, }.ConnectionString; var dataSourceBuilder = new NpgsqlDataSourceBuilder(connString); dataSourceBuilder.UseNodaTime(); _dataSource = dataSourceBuilder.Build(); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .UseNpgsql(_dataSource, o => o.UseNodaTime()) .UseSnakeCaseNamingConvention(); protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) { // ULIDs are stored as UUIDs in the database configurationBuilder.Properties().HaveConversion(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().HasIndex(a => a.Username).IsUnique(); modelBuilder.Entity().HasIndex(a => a.Email).IsUnique(); modelBuilder.Entity().HasIndex(i => i.Domain).IsUnique(); modelBuilder.Entity().HasKey(g => new { g.ChatInstanceId, g.GuildId, g.AccountId }); modelBuilder.Entity().HasIndex(a => a.ClientId).IsUnique(); } } public class DesignTimeIdentityContextFactory : IDesignTimeDbContextFactory { public IdentityContext CreateDbContext(string[] args) { // Read the configuration file var config = new ConfigurationBuilder() .AddConfiguration("identity.ini") .Build() // Get the configuration as our config class .Get() ?? new(); return new IdentityContext(config); } }