diff --git a/MumbleApi/Database/DataContext.cs b/MumbleApi/Database/DataContext.cs index c707e38..52e6712 100644 --- a/MumbleApi/Database/DataContext.cs +++ b/MumbleApi/Database/DataContext.cs @@ -42,26 +42,31 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .WithOne(p => p.Creator) .OnDelete(DeleteBehavior.Cascade); + modelBuilder + .Entity() + .HasIndex(u => u.Username) + .IsUnique(); + modelBuilder .Entity() .ToTable(t => t.HasCheckConstraint( "chk_avatar_type", - @"(avatar_url is null and avatar_media_type is null) or (avatar_url is not null and avatar_media_type is not null)")); + "(avatar_url is null and avatar_media_type is null) or (avatar_url is not null and avatar_media_type is not null)")); modelBuilder .Entity() .ToTable(t => t.HasCheckConstraint( "chk_media_data", - @"(media_url is null and media_type is null) or (media_url is not null and media_type is not null)")); + "(media_url is null and media_type is null) or (media_url is not null and media_type is not null)")); modelBuilder .Entity() .ToTable(t => t.HasCheckConstraint( "chk_post_content", - @"(media_url is not null and media_type is not null) or text is not null")); + "(media_url is not null and media_type is not null) or text is not null")); modelBuilder .Entity() diff --git a/MumbleApi/Migrations/20240125091156_MakeUsernameUnique.Designer.cs b/MumbleApi/Migrations/20240125091156_MakeUsernameUnique.Designer.cs new file mode 100644 index 0000000..16301ca --- /dev/null +++ b/MumbleApi/Migrations/20240125091156_MakeUsernameUnique.Designer.cs @@ -0,0 +1,238 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using MumbleApi.Database; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MumbleApi.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20240125091156_MakeUsernameUnique")] + partial class MakeUsernameUnique + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MumbleApi.Entities.Follow", b => + { + b.Property("FollowerId") + .HasColumnType("text") + .HasColumnName("follower_id"); + + b.Property("FolloweeId") + .HasColumnType("text") + .HasColumnName("followee_id"); + + b.HasKey("FollowerId", "FolloweeId") + .HasName("pk_follows"); + + b.HasIndex("FolloweeId") + .HasDatabaseName("ix_follows_followee_id"); + + b.ToTable("follows", (string)null); + }); + + modelBuilder.Entity("MumbleApi.Entities.Like", b => + { + b.Property("PostId") + .HasColumnType("text") + .HasColumnName("post_id"); + + b.Property("UserId") + .HasColumnType("text") + .HasColumnName("user_id"); + + b.HasKey("PostId", "UserId") + .HasName("pk_likes"); + + b.HasIndex("UserId") + .HasDatabaseName("ix_likes_user_id"); + + b.ToTable("likes", (string)null); + }); + + modelBuilder.Entity("MumbleApi.Entities.Post", b => + { + b.Property("Id") + .HasColumnType("text") + .HasColumnName("id"); + + b.Property("CreatorId") + .IsRequired() + .HasColumnType("text") + .HasColumnName("creator_id"); + + b.Property("Deleted") + .HasColumnType("timestamp with time zone") + .HasColumnName("deleted"); + + b.Property("MediaType") + .HasColumnType("text") + .HasColumnName("media_type"); + + b.Property("MediaUrl") + .HasColumnType("text") + .HasColumnName("media_url"); + + b.Property("ParentId") + .HasColumnType("text") + .HasColumnName("parent_id"); + + b.Property("Text") + .HasColumnType("text") + .HasColumnName("text"); + + b.HasKey("Id") + .HasName("pk_posts"); + + b.HasIndex("CreatorId") + .HasDatabaseName("ix_posts_creator_id"); + + b.HasIndex("ParentId") + .HasDatabaseName("ix_posts_parent_id"); + + b.ToTable("posts", null, t => + { + t.HasCheckConstraint("chk_media_data", "(media_url is null and media_type is null) or (media_url is not null and media_type is not null)"); + + t.HasCheckConstraint("chk_post_content", "(media_url is not null and media_type is not null) or text is not null"); + }); + }); + + modelBuilder.Entity("MumbleApi.Entities.User", b => + { + b.Property("Id") + .HasColumnType("text") + .HasColumnName("id"); + + b.Property("AvatarMediaType") + .HasColumnType("text") + .HasColumnName("avatar_media_type"); + + b.Property("AvatarUrl") + .HasColumnType("text") + .HasColumnName("avatar_url"); + + b.Property("Firstname") + .IsRequired() + .HasColumnType("text") + .HasColumnName("firstname"); + + b.Property("Lastname") + .IsRequired() + .HasColumnType("text") + .HasColumnName("lastname"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text") + .HasColumnName("username"); + + b.HasKey("Id") + .HasName("pk_users"); + + b.HasIndex("Username") + .IsUnique() + .HasDatabaseName("ix_users_username"); + + b.ToTable("users", null, t => + { + t.HasCheckConstraint("chk_avatar_type", "(avatar_url is null and avatar_media_type is null) or (avatar_url is not null and avatar_media_type is not null)"); + }); + }); + + modelBuilder.Entity("MumbleApi.Entities.Follow", b => + { + b.HasOne("MumbleApi.Entities.User", "Followee") + .WithMany("Followees") + .HasForeignKey("FolloweeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_follows_users_followee_id"); + + b.HasOne("MumbleApi.Entities.User", "Follower") + .WithMany("Followers") + .HasForeignKey("FollowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_follows_users_follower_id"); + + b.Navigation("Followee"); + + b.Navigation("Follower"); + }); + + modelBuilder.Entity("MumbleApi.Entities.Like", b => + { + b.HasOne("MumbleApi.Entities.Post", "Post") + .WithMany("Likes") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_likes_posts_post_id"); + + b.HasOne("MumbleApi.Entities.User", "User") + .WithMany("Likes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_likes_users_user_id"); + + b.Navigation("Post"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MumbleApi.Entities.Post", b => + { + b.HasOne("MumbleApi.Entities.User", "Creator") + .WithMany("Posts") + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_posts_users_creator_id"); + + b.HasOne("MumbleApi.Entities.Post", "Parent") + .WithMany("Replies") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("fk_posts_posts_parent_id"); + + b.Navigation("Creator"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("MumbleApi.Entities.Post", b => + { + b.Navigation("Likes"); + + b.Navigation("Replies"); + }); + + modelBuilder.Entity("MumbleApi.Entities.User", b => + { + b.Navigation("Followees"); + + b.Navigation("Followers"); + + b.Navigation("Likes"); + + b.Navigation("Posts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MumbleApi/Migrations/20240125091156_MakeUsernameUnique.cs b/MumbleApi/Migrations/20240125091156_MakeUsernameUnique.cs new file mode 100644 index 0000000..c9583b5 --- /dev/null +++ b/MumbleApi/Migrations/20240125091156_MakeUsernameUnique.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MumbleApi.Migrations +{ + /// + public partial class MakeUsernameUnique : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateIndex( + name: "ix_users_username", + table: "users", + column: "username", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "ix_users_username", + table: "users"); + } + } +} diff --git a/MumbleApi/Migrations/DataContextModelSnapshot.cs b/MumbleApi/Migrations/DataContextModelSnapshot.cs index d691286..a71cf4d 100644 --- a/MumbleApi/Migrations/DataContextModelSnapshot.cs +++ b/MumbleApi/Migrations/DataContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("ProductVersion", "8.0.1") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); @@ -140,6 +140,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id") .HasName("pk_users"); + b.HasIndex("Username") + .IsUnique() + .HasDatabaseName("ix_users_username"); + b.ToTable("users", null, t => { t.HasCheckConstraint("chk_avatar_type", "(avatar_url is null and avatar_media_type is null) or (avatar_url is not null and avatar_media_type is not null)");