using Microsoft.EntityFrameworkCore; using System; using System.Threading; using System.Threading.Tasks; using Data.Extensions; using Data.Models; using Data.Models.Client; using Data.Models.Client.Stats; using Data.Models.Client.Stats.Reference; using Data.Models.Misc; using Data.Models.Server; namespace Data.Context { public abstract class DatabaseContext : DbContext { public DbSet Clients { get; set; } public DbSet Aliases { get; set; } public DbSet AliasLinks { get; set; } public DbSet Penalties { get; set; } public DbSet PenaltyIdentifiers { get; set; } public DbSet EFMeta { get; set; } public DbSet EFChangeHistory { get; set; } #region STATS public DbSet Vector3s { get; set; } public DbSet SnapshotVector3s { get; set; } public DbSet ACSnapshots { get; set; } public DbSet Servers { get; set; } public DbSet ClientKills { get; set; } public DbSet ClientMessages { get; set; } public DbSet ServerStatistics { get; set; } public DbSet HitLocations { get; set; } public DbSet HitStatistics { get; set; } public DbSet Weapons { get; set; } public DbSet WeaponAttachments { get; set; } public DbSet Maps { get; set; } #endregion #region MISC public DbSet InboxMessages { get; set; } public DbSet ServerSnapshots { get;set; } public DbSet ConnectionHistory { get; set; } #endregion private void SetAuditColumns() { return; } public DatabaseContext() { if (!MigrationExtensions.IsMigration) { throw new InvalidOperationException(); } } public DatabaseContext(DbContextOptions options) : base(options) { } protected DatabaseContext(DbContextOptions options) : base(options) { } public override Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default) { SetAuditColumns(); return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); } public override int SaveChanges() { SetAuditColumns(); return base.SaveChanges(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { // make network id unique modelBuilder.Entity(entity => { entity.HasIndex(e => e.NetworkId).IsUnique(); }); modelBuilder.Entity(entity => { entity.HasOne(p => p.Offender) .WithMany(c => c.ReceivedPenalties) .HasForeignKey(c => c.OffenderId) .OnDelete(DeleteBehavior.Restrict); entity.HasOne(p => p.Punisher) .WithMany(p => p.AdministeredPenalties) .HasForeignKey(c => c.PunisherId) .OnDelete(DeleteBehavior.Restrict); entity.Property(p => p.Expires) .IsRequired(false); }); modelBuilder.Entity(entity => { entity.HasMany(e => e.Children) .WithOne(a => a.Link) .HasForeignKey(k => k.LinkId) .OnDelete(DeleteBehavior.Restrict); }); modelBuilder.Entity(ent => { ent.Property(a => a.IPAddress).IsRequired(false); ent.HasIndex(a => a.IPAddress); ent.Property(a => a.Name).HasMaxLength(24); ent.HasIndex(a => a.Name); ent.Property(_alias => _alias.SearchableName).HasMaxLength(24); ent.HasIndex(_alias => _alias.SearchableName); ent.HasIndex(_alias => new {_alias.Name, _alias.IPAddress}); }); modelBuilder.Entity(ent => { ent.HasIndex(_meta => _meta.Key); ent.HasIndex(_meta => _meta.LinkedMetaId); ent.HasOne(_meta => _meta.LinkedMeta) .WithMany() .OnDelete(DeleteBehavior.SetNull); }); modelBuilder.Entity(ent => { ent.HasIndex(identifiers => identifiers.NetworkId); ent.HasIndex(identifiers => identifiers.IPv4Address); }); modelBuilder.Entity(ent => ent.HasIndex(history => history.CreatedDateTime)); // force full name for database conversion modelBuilder.Entity().ToTable("EFClients"); modelBuilder.Entity().ToTable("EFAlias"); modelBuilder.Entity().ToTable("EFAliasLinks"); modelBuilder.Entity().ToTable("EFPenalties"); modelBuilder.Entity().ToTable("EFPenaltyIdentifiers"); modelBuilder.Entity().ToTable(nameof(EFServerSnapshot)); modelBuilder.Entity().ToTable(nameof(EFClientConnectionHistory)); Models.Configuration.StatsModelConfiguration.Configure(modelBuilder); base.OnModelCreating(modelBuilder); } } }