From 1f8a3d91bfdbcc20e870fc22f2c2493fe5dfef48 Mon Sep 17 00:00:00 2001 From: rootdarkarchon Date: Fri, 27 Oct 2023 12:18:01 +0200 Subject: [PATCH] optimize GetAllPairedUnpausedUsers --- .../Hubs/MareHub.Functions.cs | 120 ++- .../Data/MareDbContext.cs | 7 +- .../20231027090903_PausedIndex.Designer.cs | 807 ++++++++++++++++++ .../Migrations/20231027090903_PausedIndex.cs | 27 + .../Migrations/MareDbContextModelSnapshot.cs | 69 +- 5 files changed, 937 insertions(+), 93 deletions(-) create mode 100644 MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.Designer.cs create mode 100644 MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.cs diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs index 0a7889f..0102fee 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs @@ -77,9 +77,8 @@ public partial class MareHub { uid ??= UserUID; - return (await GetAllPairInfo(UserUID).ConfigureAwait(false)) - .Where(u => u.Value.IsSynced && !u.Value.OwnPermissions.IsPaused - && u.Value.OtherPermissions != null && !u.Value.OtherPermissions.IsPaused) + return (await GetBasicPairInfo(UserUID).ConfigureAwait(false)) + .Where(u => u.Value.IsSynced && !u.Value.IsPaused) .Select(u => u.Key).ToList(); } @@ -252,8 +251,8 @@ public partial class MareHub private async Task GetPairInfo(string uid, string otheruid) { - var clientPairs = from cp in _dbContext.ClientPairs.Where(u => u.UserUID == uid && u.OtherUserUID == otheruid) - join cp2 in _dbContext.ClientPairs.Where(u => u.OtherUserUID == uid && u.UserUID == otheruid) + var clientPairs = from cp in _dbContext.ClientPairs.AsNoTracking().Where(u => u.UserUID == uid && u.OtherUserUID == otheruid) + join cp2 in _dbContext.ClientPairs.AsNoTracking().Where(u => u.OtherUserUID == uid && u.UserUID == otheruid) on new { UserUID = cp.UserUID, @@ -275,8 +274,8 @@ public partial class MareHub }; - var groupPairs = from gp in _dbContext.GroupPairs.Where(u => u.GroupUserUID == uid) - join gp2 in _dbContext.GroupPairs.Where(u => u.GroupUserUID == otheruid) + var groupPairs = from gp in _dbContext.GroupPairs.AsNoTracking().Where(u => u.GroupUserUID == uid) + join gp2 in _dbContext.GroupPairs.AsNoTracking().Where(u => u.GroupUserUID == otheruid) on new { GID = gp.GroupGID @@ -294,21 +293,24 @@ public partial class MareHub Synced = true }; - var result = from user in clientPairs.Concat(groupPairs) - join u in _dbContext.Users on user.OtherUserUID equals u.UID - join o in _dbContext.Permissions.Where(u => u.UserUID == uid) + var allPairs = clientPairs.Concat(groupPairs); + + var result = from user in allPairs + join u in _dbContext.Users.AsNoTracking() on user.OtherUserUID equals u.UID + join o in _dbContext.Permissions.AsNoTracking().Where(u => u.UserUID == uid) on new { UserUID = user.UserUID, OtherUserUID = user.OtherUserUID } equals new { UserUID = o.UserUID, OtherUserUID = o.OtherUserUID } into ownperms from ownperm in ownperms.DefaultIfEmpty() - join p in _dbContext.Permissions.Where(u => u.OtherUserUID == uid) + join p in _dbContext.Permissions.AsNoTracking().Where(u => u.OtherUserUID == uid) on new { UserUID = user.OtherUserUID, OtherUserUID = user.UserUID } equals new { UserUID = p.UserUID, OtherUserUID = p.OtherUserUID } into otherperms from otherperm in otherperms.DefaultIfEmpty() where user.UserUID == uid && u.UID == user.OtherUserUID - && ownperm.UserUID == uid + && ownperm.UserUID == user.UserUID && ownperm.OtherUserUID == user.OtherUserUID + && otherperm.OtherUserUID == user.UserUID && otherperm.UserUID == user.OtherUserUID select new { UserUID = user.UserUID, @@ -335,8 +337,8 @@ public partial class MareHub private async Task> GetAllPairInfo(string uid) { - var clientPairs = from cp in _dbContext.ClientPairs.Where(u => u.UserUID == uid) - join cp2 in _dbContext.ClientPairs.Where(u => u.OtherUserUID == uid) + var clientPairs = from cp in _dbContext.ClientPairs.AsNoTracking().Where(u => u.UserUID == uid) + join cp2 in _dbContext.ClientPairs.AsNoTracking().Where(u => u.OtherUserUID == uid) on new { UserUID = cp.UserUID, @@ -358,8 +360,8 @@ public partial class MareHub }; - var groupPairs = from gp in _dbContext.GroupPairs.Where(u => u.GroupUserUID == uid) - join gp2 in _dbContext.GroupPairs.Where(u => u.GroupUserUID != uid) + var groupPairs = from gp in _dbContext.GroupPairs.AsNoTracking().Where(u => u.GroupUserUID == uid) + join gp2 in _dbContext.GroupPairs.AsNoTracking().Where(u => u.GroupUserUID != uid) on new { GID = gp.GroupGID @@ -368,7 +370,6 @@ public partial class MareHub { GID = gp2.GroupGID } - where gp.GroupUserUID == uid select new { UserUID = gp.GroupUserUID, @@ -377,21 +378,24 @@ public partial class MareHub Synced = true }; - var result = from user in clientPairs.Concat(groupPairs) - join u in _dbContext.Users on user.OtherUserUID equals u.UID - join o in _dbContext.Permissions.Where(u => u.UserUID == uid) + var allPairs = clientPairs.Concat(groupPairs); + + var result = from user in allPairs + join u in _dbContext.Users.AsNoTracking() on user.OtherUserUID equals u.UID + join o in _dbContext.Permissions.AsNoTracking().Where(u => u.UserUID == uid) on new { UserUID = user.UserUID, OtherUserUID = user.OtherUserUID } equals new { UserUID = o.UserUID, OtherUserUID = o.OtherUserUID } into ownperms from ownperm in ownperms.DefaultIfEmpty() - join p in _dbContext.Permissions.Where(u => u.OtherUserUID == uid) + join p in _dbContext.Permissions.AsNoTracking().Where(u => u.OtherUserUID == uid) on new { UserUID = user.OtherUserUID, OtherUserUID = user.UserUID } equals new { UserUID = p.UserUID, OtherUserUID = p.OtherUserUID } into otherperms from otherperm in otherperms.DefaultIfEmpty() where user.UserUID == uid && u.UID == user.OtherUserUID - && ownperm.UserUID == uid + && ownperm.UserUID == user.UserUID && ownperm.OtherUserUID == user.OtherUserUID + && otherperm.OtherUserUID == user.UserUID && otherperm.UserUID == user.OtherUserUID select new { UserUID = user.UserUID, @@ -415,5 +419,77 @@ public partial class MareHub }, StringComparer.Ordinal); } + private async Task> GetBasicPairInfo(string uid) + { + var clientPairs = from cp in _dbContext.ClientPairs.AsNoTracking().Where(u => u.UserUID == uid) + join cp2 in _dbContext.ClientPairs.AsNoTracking().Where(u => u.OtherUserUID == uid) + on new + { + UserUID = cp.UserUID, + OtherUserUID = cp.OtherUserUID + } + equals new + { + UserUID = cp2.OtherUserUID, + OtherUserUID = cp2.UserUID + } into joined + from c in joined.DefaultIfEmpty() + where cp.UserUID == uid + select new + { + UserUID = cp.UserUID, + OtherUserUID = cp.OtherUserUID, + Synced = c != null + }; + + + var groupPairs = from gp in _dbContext.GroupPairs.AsNoTracking().Where(u => u.GroupUserUID == uid) + join gp2 in _dbContext.GroupPairs.AsNoTracking().Where(u => u.GroupUserUID != uid) + on new + { + GID = gp.GroupGID + } + equals new + { + GID = gp2.GroupGID + } + select new + { + UserUID = gp.GroupUserUID, + OtherUserUID = gp2.GroupUserUID, + Synced = true + }; + + var allPairs = clientPairs.Concat(groupPairs); + + var result = from user in allPairs + join o in _dbContext.Permissions.AsNoTracking().Where(u => u.UserUID == uid) + on new { UserUID = user.UserUID, OtherUserUID = user.OtherUserUID } + equals new { UserUID = o.UserUID, OtherUserUID = o.OtherUserUID } + into ownperms + from ownperm in ownperms.DefaultIfEmpty() + join p in _dbContext.Permissions.AsNoTracking().Where(u => u.OtherUserUID == uid) + on new { UserUID = user.OtherUserUID, OtherUserUID = user.UserUID } + equals new { UserUID = p.UserUID, OtherUserUID = p.OtherUserUID } + into otherperms + from otherperm in otherperms.DefaultIfEmpty() + where user.UserUID == uid + && ownperm.UserUID == user.UserUID && ownperm.OtherUserUID == user.OtherUserUID + && otherperm.OtherUserUID == user.UserUID && otherperm.UserUID == user.OtherUserUID + select new + { + OtherUserUID = user.OtherUserUID, + Synced = user.Synced, + IsPaused = ownperm.IsPaused || otherperm == null ? true : otherperm.IsPaused + }; + + var resultList = await result.AsNoTracking().ToListAsync().ConfigureAwait(false); + return resultList.GroupBy(g => g.OtherUserUID, StringComparer.Ordinal).ToDictionary(g => g.Key, g => + { + return new BasicUserInfo(g.Max(p => p.Synced), g.First().IsPaused); + }, StringComparer.Ordinal); + } + public record UserInfo(string Alias, bool IndividuallyPaired, bool IsSynced, List GIDs, UserPermissionSet? OwnPermissions, UserPermissionSet? OtherPermissions); + public record BasicUserInfo(bool IsSynced, bool IsPaused); } \ No newline at end of file diff --git a/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs b/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs index 47f975c..e2ca496 100644 --- a/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs +++ b/MareSynchronosServer/MareSynchronosShared/Data/MareDbContext.cs @@ -49,8 +49,6 @@ public class MareDbContext : DbContext public DbSet GroupPairPreferredPermissions { get; set; } public DbSet UserDefaultPreferredPermissions { get; set; } - public IQueryable GetAllPairsForUser(string uid) => FromExpression(() => GetAllPairsForUser(uid)); - protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().ToTable("auth"); @@ -86,6 +84,7 @@ public class MareDbContext : DbContext modelBuilder.Entity().HasKey(u => new { u.UserUID, u.OtherUserUID }); modelBuilder.Entity().HasIndex(c => c.UserUID); modelBuilder.Entity().HasIndex(c => c.OtherUserUID); + modelBuilder.Entity().HasIndex(c => new { c.UserUID, c.OtherUserUID, c.IsPaused }); modelBuilder.Entity().ToTable("group_pair_preferred_permissions"); modelBuilder.Entity().HasKey(u => new { u.UserUID, u.GroupGID }); modelBuilder.Entity().HasIndex(c => c.UserUID); @@ -94,9 +93,5 @@ public class MareDbContext : DbContext modelBuilder.Entity().HasKey(u => u.UserUID); modelBuilder.Entity().HasIndex(u => u.UserUID); modelBuilder.Entity().HasOne(u => u.User); - modelBuilder.HasDbFunction(typeof(MareDbContext).GetMethod(nameof(GetAllPairsForUser), new[] { typeof(string) })) - .HasName("get_all_pairs_for_user"); - modelBuilder.Entity().HasNoKey(); - modelBuilder.Entity().ToTable("user_permission_query", t => t.ExcludeFromMigrations()); } } \ No newline at end of file diff --git a/MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.Designer.cs b/MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.Designer.cs new file mode 100644 index 0000000..f9ead68 --- /dev/null +++ b/MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.Designer.cs @@ -0,0 +1,807 @@ +// +using System; +using MareSynchronosShared.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MareSynchronosServer.Migrations +{ + [DbContext(typeof(MareDbContext))] + [Migration("20231027090903_PausedIndex")] + partial class PausedIndex + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.12") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MareSynchronosShared.Models.Auth", b => + { + b.Property("HashedKey") + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("hashed_key"); + + b.Property("IsBanned") + .HasColumnType("boolean") + .HasColumnName("is_banned"); + + b.Property("PrimaryUserUID") + .HasColumnType("character varying(10)") + .HasColumnName("primary_user_uid"); + + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.HasKey("HashedKey") + .HasName("pk_auth"); + + b.HasIndex("PrimaryUserUID") + .HasDatabaseName("ix_auth_primary_user_uid"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_auth_user_uid"); + + b.ToTable("auth", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Banned", b => + { + b.Property("CharacterIdentification") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("character_identification"); + + b.Property("Reason") + .HasColumnType("text") + .HasColumnName("reason"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("CharacterIdentification") + .HasName("pk_banned_users"); + + b.ToTable("banned_users", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.BannedRegistrations", b => + { + b.Property("DiscordIdOrLodestoneAuth") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("discord_id_or_lodestone_auth"); + + b.HasKey("DiscordIdOrLodestoneAuth") + .HasName("pk_banned_registrations"); + + b.ToTable("banned_registrations", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b => + { + b.Property("UserUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.Property("OtherUserUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("other_user_uid"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("UserUID", "OtherUserUID") + .HasName("pk_client_pairs"); + + b.HasIndex("OtherUserUID") + .HasDatabaseName("ix_client_pairs_other_user_uid"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_client_pairs_user_uid"); + + b.ToTable("client_pairs", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b => + { + b.Property("Hash") + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("hash"); + + b.Property("Size") + .HasColumnType("bigint") + .HasColumnName("size"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.Property("UploadDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("upload_date"); + + b.Property("Uploaded") + .HasColumnType("boolean") + .HasColumnName("uploaded"); + + b.Property("UploaderUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("uploader_uid"); + + b.HasKey("Hash") + .HasName("pk_file_caches"); + + b.HasIndex("UploaderUID") + .HasDatabaseName("ix_file_caches_uploader_uid"); + + b.ToTable("file_caches", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.ForbiddenUploadEntry", b => + { + b.Property("Hash") + .HasMaxLength(40) + .HasColumnType("character varying(40)") + .HasColumnName("hash"); + + b.Property("ForbiddenBy") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("forbidden_by"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("Hash") + .HasName("pk_forbidden_upload_entries"); + + b.ToTable("forbidden_upload_entries", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Group", b => + { + b.Property("GID") + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasColumnName("gid"); + + b.Property("Alias") + .HasMaxLength(50) + .HasColumnType("character varying(50)") + .HasColumnName("alias"); + + b.Property("HashedPassword") + .HasColumnType("text") + .HasColumnName("hashed_password"); + + b.Property("InvitesEnabled") + .HasColumnType("boolean") + .HasColumnName("invites_enabled"); + + b.Property("OwnerUID") + .HasColumnType("character varying(10)") + .HasColumnName("owner_uid"); + + b.Property("PreferDisableAnimations") + .HasColumnType("boolean") + .HasColumnName("prefer_disable_animations"); + + b.Property("PreferDisableSounds") + .HasColumnType("boolean") + .HasColumnName("prefer_disable_sounds"); + + b.Property("PreferDisableVFX") + .HasColumnType("boolean") + .HasColumnName("prefer_disable_vfx"); + + b.HasKey("GID") + .HasName("pk_groups"); + + b.HasIndex("OwnerUID") + .HasDatabaseName("ix_groups_owner_uid"); + + b.ToTable("groups", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupBan", b => + { + b.Property("GroupGID") + .HasColumnType("character varying(20)") + .HasColumnName("group_gid"); + + b.Property("BannedUserUID") + .HasColumnType("character varying(10)") + .HasColumnName("banned_user_uid"); + + b.Property("BannedByUID") + .HasColumnType("character varying(10)") + .HasColumnName("banned_by_uid"); + + b.Property("BannedOn") + .HasColumnType("timestamp with time zone") + .HasColumnName("banned_on"); + + b.Property("BannedReason") + .HasColumnType("text") + .HasColumnName("banned_reason"); + + b.HasKey("GroupGID", "BannedUserUID") + .HasName("pk_group_bans"); + + b.HasIndex("BannedByUID") + .HasDatabaseName("ix_group_bans_banned_by_uid"); + + b.HasIndex("BannedUserUID") + .HasDatabaseName("ix_group_bans_banned_user_uid"); + + b.HasIndex("GroupGID") + .HasDatabaseName("ix_group_bans_group_gid"); + + b.ToTable("group_bans", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupPair", b => + { + b.Property("GroupGID") + .HasColumnType("character varying(20)") + .HasColumnName("group_gid"); + + b.Property("GroupUserUID") + .HasColumnType("character varying(10)") + .HasColumnName("group_user_uid"); + + b.Property("IsModerator") + .HasColumnType("boolean") + .HasColumnName("is_moderator"); + + b.Property("IsPinned") + .HasColumnType("boolean") + .HasColumnName("is_pinned"); + + b.HasKey("GroupGID", "GroupUserUID") + .HasName("pk_group_pairs"); + + b.HasIndex("GroupGID") + .HasDatabaseName("ix_group_pairs_group_gid"); + + b.HasIndex("GroupUserUID") + .HasDatabaseName("ix_group_pairs_group_user_uid"); + + b.ToTable("group_pairs", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b => + { + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.Property("GroupGID") + .HasColumnType("character varying(20)") + .HasColumnName("group_gid"); + + b.Property("DisableAnimations") + .HasColumnType("boolean") + .HasColumnName("disable_animations"); + + b.Property("DisableSounds") + .HasColumnType("boolean") + .HasColumnName("disable_sounds"); + + b.Property("DisableVFX") + .HasColumnType("boolean") + .HasColumnName("disable_vfx"); + + b.Property("IsPaused") + .HasColumnType("boolean") + .HasColumnName("is_paused"); + + b.HasKey("UserUID", "GroupGID") + .HasName("pk_group_pair_preferred_permissions"); + + b.HasIndex("GroupGID") + .HasDatabaseName("ix_group_pair_preferred_permissions_group_gid"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_group_pair_preferred_permissions_user_uid"); + + b.ToTable("group_pair_preferred_permissions", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b => + { + b.Property("GroupGID") + .HasColumnType("character varying(20)") + .HasColumnName("group_gid"); + + b.Property("Invite") + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("invite"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("expiration_date"); + + b.HasKey("GroupGID", "Invite") + .HasName("pk_group_temp_invites"); + + b.HasIndex("GroupGID") + .HasDatabaseName("ix_group_temp_invites_group_gid"); + + b.HasIndex("Invite") + .HasDatabaseName("ix_group_temp_invites_invite"); + + b.ToTable("group_temp_invites", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b => + { + b.Property("DiscordId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)") + .HasColumnName("discord_id"); + + b.Property("HashedLodestoneId") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("hashed_lodestone_id"); + + b.Property("LodestoneAuthString") + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasColumnName("lodestone_auth_string"); + + b.Property("StartedAt") + .HasColumnType("timestamp with time zone") + .HasColumnName("started_at"); + + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.HasKey("DiscordId") + .HasName("pk_lodestone_auth"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_lodestone_auth_user_uid"); + + b.ToTable("lodestone_auth", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.User", b => + { + b.Property("UID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("uid"); + + b.Property("Alias") + .HasMaxLength(15) + .HasColumnType("character varying(15)") + .HasColumnName("alias"); + + b.Property("IsAdmin") + .HasColumnType("boolean") + .HasColumnName("is_admin"); + + b.Property("IsModerator") + .HasColumnType("boolean") + .HasColumnName("is_moderator"); + + b.Property("LastLoggedIn") + .HasColumnType("timestamp with time zone") + .HasColumnName("last_logged_in"); + + b.Property("Timestamp") + .IsConcurrencyToken() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("bytea") + .HasColumnName("timestamp"); + + b.HasKey("UID") + .HasName("pk_users"); + + b.ToTable("users", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b => + { + b.Property("UserUID") + .HasMaxLength(10) + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.Property("DisableGroupAnimations") + .HasColumnType("boolean") + .HasColumnName("disable_group_animations"); + + b.Property("DisableGroupSounds") + .HasColumnType("boolean") + .HasColumnName("disable_group_sounds"); + + b.Property("DisableGroupVFX") + .HasColumnType("boolean") + .HasColumnName("disable_group_vfx"); + + b.Property("DisableIndividualAnimations") + .HasColumnType("boolean") + .HasColumnName("disable_individual_animations"); + + b.Property("DisableIndividualSounds") + .HasColumnType("boolean") + .HasColumnName("disable_individual_sounds"); + + b.Property("DisableIndividualVFX") + .HasColumnType("boolean") + .HasColumnName("disable_individual_vfx"); + + b.Property("IndividualIsSticky") + .HasColumnType("boolean") + .HasColumnName("individual_is_sticky"); + + b.HasKey("UserUID") + .HasName("pk_user_default_preferred_permissions"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_user_default_preferred_permissions_user_uid"); + + b.ToTable("user_default_preferred_permissions", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b => + { + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.Property("OtherUserUID") + .HasColumnType("character varying(10)") + .HasColumnName("other_user_uid"); + + b.Property("DisableAnimations") + .HasColumnType("boolean") + .HasColumnName("disable_animations"); + + b.Property("DisableSounds") + .HasColumnType("boolean") + .HasColumnName("disable_sounds"); + + b.Property("DisableVFX") + .HasColumnType("boolean") + .HasColumnName("disable_vfx"); + + b.Property("IsPaused") + .HasColumnType("boolean") + .HasColumnName("is_paused"); + + b.Property("Sticky") + .HasColumnType("boolean") + .HasColumnName("sticky"); + + b.HasKey("UserUID", "OtherUserUID") + .HasName("pk_user_permission_sets"); + + b.HasIndex("OtherUserUID") + .HasDatabaseName("ix_user_permission_sets_other_user_uid"); + + b.HasIndex("UserUID") + .HasDatabaseName("ix_user_permission_sets_user_uid"); + + b.HasIndex("UserUID", "OtherUserUID", "IsPaused") + .HasDatabaseName("ix_user_permission_sets_user_uid_other_user_uid_is_paused"); + + b.ToTable("user_permission_sets", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b => + { + b.Property("UserUID") + .HasColumnType("character varying(10)") + .HasColumnName("user_uid"); + + b.Property("Base64ProfileImage") + .HasColumnType("text") + .HasColumnName("base64profile_image"); + + b.Property("FlaggedForReport") + .HasColumnType("boolean") + .HasColumnName("flagged_for_report"); + + b.Property("IsNSFW") + .HasColumnType("boolean") + .HasColumnName("is_nsfw"); + + b.Property("ProfileDisabled") + .HasColumnType("boolean") + .HasColumnName("profile_disabled"); + + b.Property("UserDescription") + .HasColumnType("text") + .HasColumnName("user_description"); + + b.HasKey("UserUID") + .HasName("pk_user_profile_data"); + + b.ToTable("user_profile_data", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserProfileDataReport", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ReportDate") + .HasColumnType("timestamp with time zone") + .HasColumnName("report_date"); + + b.Property("ReportReason") + .HasColumnType("text") + .HasColumnName("report_reason"); + + b.Property("ReportedUserUID") + .HasColumnType("character varying(10)") + .HasColumnName("reported_user_uid"); + + b.Property("ReportingUserUID") + .HasColumnType("character varying(10)") + .HasColumnName("reporting_user_uid"); + + b.HasKey("Id") + .HasName("pk_user_profile_data_reports"); + + b.HasIndex("ReportedUserUID") + .HasDatabaseName("ix_user_profile_data_reports_reported_user_uid"); + + b.HasIndex("ReportingUserUID") + .HasDatabaseName("ix_user_profile_data_reports_reporting_user_uid"); + + b.ToTable("user_profile_data_reports", (string)null); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Auth", b => + { + b.HasOne("MareSynchronosShared.Models.User", "PrimaryUser") + .WithMany() + .HasForeignKey("PrimaryUserUID") + .HasConstraintName("fk_auth_users_primary_user_temp_id"); + + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .HasConstraintName("fk_auth_users_user_temp_id1"); + + b.Navigation("PrimaryUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b => + { + b.HasOne("MareSynchronosShared.Models.User", "OtherUser") + .WithMany() + .HasForeignKey("OtherUserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_client_pairs_users_other_user_temp_id2"); + + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_client_pairs_users_user_temp_id3"); + + b.Navigation("OtherUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b => + { + b.HasOne("MareSynchronosShared.Models.User", "Uploader") + .WithMany() + .HasForeignKey("UploaderUID") + .HasConstraintName("fk_file_caches_users_uploader_uid"); + + b.Navigation("Uploader"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.Group", b => + { + b.HasOne("MareSynchronosShared.Models.User", "Owner") + .WithMany() + .HasForeignKey("OwnerUID") + .HasConstraintName("fk_groups_users_owner_temp_id9"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupBan", b => + { + b.HasOne("MareSynchronosShared.Models.User", "BannedBy") + .WithMany() + .HasForeignKey("BannedByUID") + .HasConstraintName("fk_group_bans_users_banned_by_temp_id5"); + + b.HasOne("MareSynchronosShared.Models.User", "BannedUser") + .WithMany() + .HasForeignKey("BannedUserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_group_bans_users_banned_user_temp_id6"); + + b.HasOne("MareSynchronosShared.Models.Group", "Group") + .WithMany() + .HasForeignKey("GroupGID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_group_bans_groups_group_temp_id"); + + b.Navigation("BannedBy"); + + b.Navigation("BannedUser"); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupPair", b => + { + b.HasOne("MareSynchronosShared.Models.Group", "Group") + .WithMany() + .HasForeignKey("GroupGID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_group_pairs_groups_group_temp_id2"); + + b.HasOne("MareSynchronosShared.Models.User", "GroupUser") + .WithMany() + .HasForeignKey("GroupUserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_group_pairs_users_group_user_temp_id8"); + + b.Navigation("Group"); + + b.Navigation("GroupUser"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b => + { + b.HasOne("MareSynchronosShared.Models.Group", "Group") + .WithMany() + .HasForeignKey("GroupGID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_group_pair_preferred_permissions_groups_group_temp_id1"); + + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_group_pair_preferred_permissions_users_user_temp_id7"); + + b.Navigation("Group"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b => + { + b.HasOne("MareSynchronosShared.Models.Group", "Group") + .WithMany() + .HasForeignKey("GroupGID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_group_temp_invites_groups_group_gid"); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b => + { + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .HasConstraintName("fk_lodestone_auth_users_user_uid"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b => + { + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_default_preferred_permissions_users_user_uid"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b => + { + b.HasOne("MareSynchronosShared.Models.User", "OtherUser") + .WithMany() + .HasForeignKey("OtherUserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_permission_sets_users_other_user_uid"); + + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_permission_sets_users_user_uid"); + + b.Navigation("OtherUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b => + { + b.HasOne("MareSynchronosShared.Models.User", "User") + .WithMany() + .HasForeignKey("UserUID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_user_profile_data_users_user_uid"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("MareSynchronosShared.Models.UserProfileDataReport", b => + { + b.HasOne("MareSynchronosShared.Models.User", "ReportedUser") + .WithMany() + .HasForeignKey("ReportedUserUID") + .HasConstraintName("fk_user_profile_data_reports_users_reported_user_uid"); + + b.HasOne("MareSynchronosShared.Models.User", "ReportingUser") + .WithMany() + .HasForeignKey("ReportingUserUID") + .HasConstraintName("fk_user_profile_data_reports_users_reporting_user_uid"); + + b.Navigation("ReportedUser"); + + b.Navigation("ReportingUser"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.cs b/MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.cs new file mode 100644 index 0000000..afdfbdc --- /dev/null +++ b/MareSynchronosServer/MareSynchronosShared/Migrations/20231027090903_PausedIndex.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MareSynchronosServer.Migrations +{ + /// + public partial class PausedIndex : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateIndex( + name: "ix_user_permission_sets_user_uid_other_user_uid_is_paused", + table: "user_permission_sets", + columns: new[] { "user_uid", "other_user_uid", "is_paused" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "ix_user_permission_sets_user_uid_other_user_uid_is_paused", + table: "user_permission_sets"); + } + } +} diff --git a/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs b/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs index 474fc46..2b7a366 100644 --- a/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs +++ b/MareSynchronosServer/MareSynchronosShared/Migrations/MareDbContextModelSnapshot.cs @@ -17,7 +17,7 @@ namespace MareSynchronosServer.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("ProductVersion", "7.0.12") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); @@ -473,70 +473,6 @@ namespace MareSynchronosServer.Migrations b.ToTable("user_default_preferred_permissions", (string)null); }); - modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionQuery", b => - { - b.Property("Alias") - .HasColumnType("text") - .HasColumnName("alias"); - - b.Property("GID") - .HasColumnType("text") - .HasColumnName("gid"); - - b.Property("OtherUserUID") - .HasColumnType("text") - .HasColumnName("other_user_uid"); - - b.Property("OtherpermDisableAnimations") - .HasColumnType("boolean") - .HasColumnName("otherperm_disable_animations"); - - b.Property("OtherpermDisableSounds") - .HasColumnType("boolean") - .HasColumnName("otherperm_disable_sounds"); - - b.Property("OtherpermDisableVFX") - .HasColumnType("boolean") - .HasColumnName("otherperm_disable_vfx"); - - b.Property("OtherpermIsPaused") - .HasColumnType("boolean") - .HasColumnName("otherperm_is_paused"); - - b.Property("OwnPermSticky") - .HasColumnType("boolean") - .HasColumnName("own_perm_sticky"); - - b.Property("OwnpermDisableAnimations") - .HasColumnType("boolean") - .HasColumnName("ownperm_disable_animations"); - - b.Property("OwnpermDisableSounds") - .HasColumnType("boolean") - .HasColumnName("ownperm_disable_sounds"); - - b.Property("OwnpermDisableVFX") - .HasColumnType("boolean") - .HasColumnName("ownperm_disable_vfx"); - - b.Property("OwnpermIsPaused") - .HasColumnType("boolean") - .HasColumnName("ownperm_is_paused"); - - b.Property("Synced") - .HasColumnType("boolean") - .HasColumnName("synced"); - - b.Property("UserUID") - .HasColumnType("text") - .HasColumnName("user_uid"); - - b.ToTable("user_permission_query", null, t => - { - t.ExcludeFromMigrations(); - }); - }); - modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b => { b.Property("UserUID") @@ -576,6 +512,9 @@ namespace MareSynchronosServer.Migrations b.HasIndex("UserUID") .HasDatabaseName("ix_user_permission_sets_user_uid"); + b.HasIndex("UserUID", "OtherUserUID", "IsPaused") + .HasDatabaseName("ix_user_permission_sets_user_uid_other_user_uid_is_paused"); + b.ToTable("user_permission_sets", (string)null); });