using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore; namespace Content.Server.Database { public abstract class ServerDbContext : DbContext { /// /// The "dotnet ef" CLI tool uses the parameter-less constructor. /// When that happens we want to supply the via . /// To use the context within the application, the options need to be passed the constructor instead. /// protected readonly bool InitializedWithOptions; public ServerDbContext() { } public ServerDbContext(DbContextOptions options) : base(options) { InitializedWithOptions = true; } public DbSet Preference { get; set; } = null!; public DbSet Profile { get; set; } = null!; public DbSet AssignedUserId { get; set; } = null!; protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() .HasIndex(p => p.UserId) .IsUnique(); modelBuilder.Entity() .HasIndex(p => new {p.Slot, PrefsId = p.PreferenceId}) .IsUnique(); modelBuilder.Entity() .HasIndex(p => new {HumanoidProfileId = p.ProfileId, p.AntagName}) .IsUnique(); modelBuilder.Entity() .HasIndex(p => p.UserName) .IsUnique(); // Can't have two usernames with the same user ID. modelBuilder.Entity() .HasIndex(p => p.UserId) .IsUnique(); } } [Table("preference")] public class Preference { // NOTE: on postgres there SHOULD be an FK ensuring that the selected character slot always exists. // I had to use a migration to implement it and as a result its creation is a finicky mess. // Because if I let EFCore know about it it would explode on a circular reference. // Also it has to be DEFERRABLE INITIALLY DEFERRED so that insertion of new preferences works. // Also I couldn't figure out how to create it on SQLite. [Column("preference_id")] public int Id { get; set; } [Column("user_id")] public Guid UserId { get; set; } [Column("selected_character_slot")] public int SelectedCharacterSlot { get; set; } public List Profiles { get; } = new List(); } [Table("profile")] public class Profile { [Column("profile_id")] public int Id { get; set; } [Column("slot")] public int Slot { get; set; } [Column("char_name")] public string CharacterName { get; set; } = null!; [Column("age")] public int Age { get; set; } [Column("sex")] public string Sex { get; set; } = null!; [Column("hair_name")] public string HairName { get; set; } = null!; [Column("hair_color")] public string HairColor { get; set; } = null!; [Column("facial_hair_name")] public string FacialHairName { get; set; } = null!; [Column("facial_hair_color")] public string FacialHairColor { get; set; } = null!; [Column("eye_color")] public string EyeColor { get; set; } = null!; [Column("skin_color")] public string SkinColor { get; set; } = null!; public List Jobs { get; } = new List(); public List Antags { get; } = new List(); [Column("pref_unavailable")] public DbPreferenceUnavailableMode PreferenceUnavailable { get; set; } [Column("preference_id")] public int PreferenceId { get; set; } public Preference Preference { get; set; } = null!; } [Table("job")] public class Job { [Column("job_id")] public int Id { get; set; } public Profile Profile { get; set; } = null!; [Column("profile_id")] public int ProfileId { get; set; } [Column("job_name")] public string JobName { get; set; } = null!; [Column("priority")] public DbJobPriority Priority { get; set; } } public enum DbJobPriority { // These enum values HAVE to match the ones in JobPriority in Shared. Never = 0, Low = 1, Medium = 2, High = 3 } [Table("antag")] public class Antag { [Column("antag_id")] public int Id { get; set; } public Profile Profile { get; set; } = null!; [Column("profile_id")] public int ProfileId { get; set; } [Column("antag_name")] public string AntagName { get; set; } = null!; } public enum DbPreferenceUnavailableMode { // These enum values HAVE to match the ones in PreferenceUnavailableMode in Shared. StayInLobby = 0, SpawnAsOverflow, } [Table("assigned_user_id")] public class AssignedUserId { [Column("assigned_user_id_id")] public int Id { get; set; } [Column("user_name")] public string UserName { get; set; } = null!; [Column("user_id")] public Guid UserId { get; set; } } }