using Microsoft.EntityFrameworkCore; using Npgsql; namespace RegexBot.Data; /// /// Represents a database connection using the settings defined in the bot's global configuration. /// public class BotDatabaseContext : DbContext { private static readonly string _connectionString; static BotDatabaseContext() { // Get our own config loaded just for the SQL stuff var conf = new InstanceConfig(); _connectionString = new NpgsqlConnectionStringBuilder() { #if DEBUG IncludeErrorDetail = true, #endif Host = conf.SqlHost ?? "localhost", // default to localhost Database = conf.SqlDatabase, Username = conf.SqlUsername, Password = conf.SqlPassword }.ToString(); } /// /// Retrieves the user cache. /// public DbSet UserCache { get; set; } = null!; /// /// Retrieves the guild user cache. /// public DbSet GuildUserCache { get; set; } = null!; /// /// Retrieves the guild message cache. /// public DbSet GuildMessageCache { get; set; } = null!; /// /// Retrieves the moderator logs. /// public DbSet ModLogs { get; set; } = null!; /// protected sealed override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .UseNpgsql(_connectionString) .UseSnakeCaseNamingConvention(); /// protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity(entity => entity.Property(e => e.Discriminator).HasMaxLength(4).IsFixedLength()); modelBuilder.Entity(e => { e.HasKey(p => new { p.GuildId, p.UserId }); e.Property(p => p.FirstSeenTime).HasDefaultValueSql("now()"); e.HasOne(entry => entry.User) .WithMany(u => u.Guilds) .HasForeignKey(entry => entry.UserId); e.Navigation(entry => entry.User).AutoInclude(); }); modelBuilder.Entity(e => e.Property(p => p.CreatedAt).HasDefaultValueSql("now()")); modelBuilder.HasPostgresEnum(); modelBuilder.Entity(e => { e.Property(p => p.Timestamp).HasDefaultValueSql("now()"); e.HasOne(entry => entry.User) .WithMany(gu => gu.Logs) .HasForeignKey(entry => new { entry.GuildId, entry.UserId }); e.Navigation(entry => entry.User).AutoInclude(); }); modelBuilder.Entity(e => { e.HasOne(entry => entry.Author) .WithMany(gu => gu.Messages) .HasForeignKey(cgm => new { cgm.GuildId, cgm.AuthorId }) .HasPrincipalKey(cgu => new { cgu.GuildId, cgu.UserId }); e.Navigation(entry => entry.Author).AutoInclude(); }); } }