From 080cd99c2dc321e9c5b45f815fb600a7569c54f0 Mon Sep 17 00:00:00 2001 From: Loporrit <141286461+loporrit@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:35:31 +0000 Subject: [PATCH] db factory Co-authored-by: Stanley Dimant --- .../MareSynchronosServer/Hubs/MareHub.Chat.cs | 6 +- .../Hubs/MareHub.Functions.cs | 66 +++++------ .../Hubs/MareHub.Groups.cs | 110 +++++++++--------- .../MareSynchronosServer/Hubs/MareHub.User.cs | 48 ++++---- .../MareSynchronosServer/Hubs/MareHub.cs | 24 +++- .../MareSynchronosServer/Startup.cs | 9 ++ 6 files changed, 143 insertions(+), 120 deletions(-) diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Chat.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Chat.cs index efbe490..19eaefc 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Chat.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Chat.cs @@ -27,9 +27,9 @@ public partial class MareHub var (userExists, groupPair) = await TryValidateUserInGroup(dto.GID, UserUID).ConfigureAwait(false); if (!userExists) return; - var group = await _dbContext.Groups.AsNoTracking().SingleAsync(g => g.GID == dto.GID).ConfigureAwait(false); - var sender = await _dbContext.Users.AsNoTracking().SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); - var groupPairs = await _dbContext.GroupPairs.AsNoTracking().Include(p => p.GroupUser).Where(p => p.GroupGID == dto.Group.GID).ToListAsync().ConfigureAwait(false); + var group = await DbContext.Groups.AsNoTracking().SingleAsync(g => g.GID == dto.GID).ConfigureAwait(false); + var sender = await DbContext.Users.AsNoTracking().SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.AsNoTracking().Include(p => p.GroupUser).Where(p => p.GroupGID == dto.Group.GID).ToListAsync().ConfigureAwait(false); if (group == null || sender == null) return; diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs index dd2fa89..2ecbcc8 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs @@ -20,26 +20,26 @@ public partial class MareHub private async Task DeleteUser(User user) { - var ownPairData = await _dbContext.ClientPairs.Where(u => u.User.UID == user.UID).ToListAsync().ConfigureAwait(false); - var auth = await _dbContext.Auth.SingleAsync(u => u.UserUID == user.UID).ConfigureAwait(false); - var lodestone = await _dbContext.LodeStoneAuth.SingleOrDefaultAsync(a => a.User.UID == user.UID).ConfigureAwait(false); - var groupPairs = await _dbContext.GroupPairs.Where(g => g.GroupUserUID == user.UID).ToListAsync().ConfigureAwait(false); - var userProfileData = await _dbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.UID).ConfigureAwait(false); - var bannedEntries = await _dbContext.GroupBans.Where(u => u.BannedUserUID == user.UID).ToListAsync().ConfigureAwait(false); + var ownPairData = await DbContext.ClientPairs.Where(u => u.User.UID == user.UID).ToListAsync().ConfigureAwait(false); + var auth = await DbContext.Auth.SingleAsync(u => u.UserUID == user.UID).ConfigureAwait(false); + var lodestone = await DbContext.LodeStoneAuth.SingleOrDefaultAsync(a => a.User.UID == user.UID).ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.Where(g => g.GroupUserUID == user.UID).ToListAsync().ConfigureAwait(false); + var userProfileData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.UID).ConfigureAwait(false); + var bannedEntries = await DbContext.GroupBans.Where(u => u.BannedUserUID == user.UID).ToListAsync().ConfigureAwait(false); if (lodestone != null) { - _dbContext.Remove(lodestone); + DbContext.Remove(lodestone); } if (userProfileData != null) { - _dbContext.Remove(userProfileData); + DbContext.Remove(userProfileData); } - _dbContext.ClientPairs.RemoveRange(ownPairData); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); - var otherPairData = await _dbContext.ClientPairs.Include(u => u.User) + DbContext.ClientPairs.RemoveRange(ownPairData); + await DbContext.SaveChangesAsync().ConfigureAwait(false); + var otherPairData = await DbContext.ClientPairs.Include(u => u.User) .Where(u => u.OtherUser.UID == user.UID).AsNoTracking().ToListAsync().ConfigureAwait(false); foreach (var pair in otherPairData) { @@ -53,19 +53,19 @@ public partial class MareHub _mareMetrics.IncCounter(MetricsAPI.CounterUsersRegisteredDeleted, 1); - _dbContext.GroupBans.RemoveRange(bannedEntries); - _dbContext.ClientPairs.RemoveRange(otherPairData); - _dbContext.Users.Remove(user); - _dbContext.Auth.Remove(auth); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.GroupBans.RemoveRange(bannedEntries); + DbContext.ClientPairs.RemoveRange(otherPairData); + DbContext.Users.Remove(user); + DbContext.Auth.Remove(auth); + await DbContext.SaveChangesAsync().ConfigureAwait(false); } private async Task> GetAllPairedClientsWithPauseState(string? uid = null) { uid ??= UserUID; - var query = await (from userPair in _dbContext.ClientPairs - join otherUserPair in _dbContext.ClientPairs on userPair.OtherUserUID equals otherUserPair.UserUID + var query = await (from userPair in DbContext.ClientPairs + join otherUserPair in DbContext.ClientPairs on userPair.OtherUserUID equals otherUserPair.UserUID where otherUserPair.OtherUserUID == uid && userPair.UserUID == uid select new { @@ -75,8 +75,8 @@ public partial class MareHub PauseStateOther = otherUserPair.IsPaused, }) .Union( - (from userGroupPair in _dbContext.GroupPairs - join otherGroupPair in _dbContext.GroupPairs on userGroupPair.GroupGID equals otherGroupPair.GroupGID + (from userGroupPair in DbContext.GroupPairs + join otherGroupPair in DbContext.GroupPairs on userGroupPair.GroupGID equals otherGroupPair.GroupGID where userGroupPair.GroupUserUID == uid && otherGroupPair.GroupUserUID != uid @@ -141,7 +141,7 @@ public partial class MareHub private async Task> SendOfflineToAllPairedUsers() { var usersToSendDataTo = await GetAllPairedUnpausedUsers().ConfigureAwait(false); - var self = await _dbContext.Users.AsNoTracking().SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); + var self = await DbContext.Users.AsNoTracking().SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); await Clients.Users(usersToSendDataTo).Client_UserSendOffline(new(self.ToUserData())).ConfigureAwait(false); return usersToSendDataTo; @@ -150,7 +150,7 @@ public partial class MareHub private async Task> SendOnlineToAllPairedUsers() { var usersToSendDataTo = await GetAllPairedUnpausedUsers().ConfigureAwait(false); - var self = await _dbContext.Users.AsNoTracking().SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); + var self = await DbContext.Users.AsNoTracking().SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); await Clients.Users(usersToSendDataTo).Client_UserSendOnline(new(self.ToUserData(), UserCharaIdent)).ConfigureAwait(false); return usersToSendDataTo; @@ -163,7 +163,7 @@ public partial class MareHub if (isOwnerResult.ReferredGroup == null) return (false, null); - var groupPairSelf = await _dbContext.GroupPairs.SingleOrDefaultAsync(g => g.GroupGID == gid && g.GroupUserUID == UserUID).ConfigureAwait(false); + var groupPairSelf = await DbContext.GroupPairs.SingleOrDefaultAsync(g => g.GroupGID == gid && g.GroupUserUID == UserUID).ConfigureAwait(false); if (groupPairSelf == null || !groupPairSelf.IsModerator) return (false, null); return (true, isOwnerResult.ReferredGroup); @@ -171,7 +171,7 @@ public partial class MareHub private async Task<(bool isValid, Group ReferredGroup)> TryValidateOwner(string gid) { - var group = await _dbContext.Groups.SingleOrDefaultAsync(g => g.GID == gid).ConfigureAwait(false); + var group = await DbContext.Groups.SingleOrDefaultAsync(g => g.GID == gid).ConfigureAwait(false); if (group == null) return (false, null); return (string.Equals(group.OwnerUID, UserUID, StringComparison.Ordinal), group); @@ -181,7 +181,7 @@ public partial class MareHub { uid ??= UserUID; - var groupPair = await _dbContext.GroupPairs.Include(c => c.GroupUser) + var groupPair = await DbContext.GroupPairs.Include(c => c.GroupUser) .SingleOrDefaultAsync(g => g.GroupGID == gid && (g.GroupUserUID == uid || g.GroupUser.Alias == uid)).ConfigureAwait(false); if (groupPair == null) return (false, null); @@ -218,13 +218,13 @@ public partial class MareHub var (exists, groupPair) = await TryValidateUserInGroup(dto.Group.GID, userUid).ConfigureAwait(false); if (!exists) return; - var group = await _dbContext.Groups.SingleOrDefaultAsync(g => g.GID == dto.Group.GID).ConfigureAwait(false); + var group = await DbContext.Groups.SingleOrDefaultAsync(g => g.GID == dto.Group.GID).ConfigureAwait(false); - var groupPairs = await _dbContext.GroupPairs.Where(p => p.GroupGID == group.GID).ToListAsync().ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.Where(p => p.GroupGID == group.GID).ToListAsync().ConfigureAwait(false); var groupPairsWithoutSelf = groupPairs.Where(p => !string.Equals(p.GroupUserUID, userUid, StringComparison.Ordinal)).ToList(); - _dbContext.GroupPairs.Remove(groupPair); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.GroupPairs.Remove(groupPair); + await DbContext.SaveChangesAsync().ConfigureAwait(false); await Clients.User(userUid).Client_GroupDelete(new GroupDto(group.ToGroupData())).ConfigureAwait(false); @@ -235,17 +235,17 @@ public partial class MareHub { _logger.LogCallInfo(MareHubLogger.Args(dto, "Deleted")); - _dbContext.Groups.Remove(group); + DbContext.Groups.Remove(group); } else { - var groupHasMigrated = await SharedDbFunctions.MigrateOrDeleteGroup(_dbContext, group, groupPairsWithoutSelf, _maxExistingGroupsByUser).ConfigureAwait(false); + var groupHasMigrated = await SharedDbFunctions.MigrateOrDeleteGroup(DbContext, group, groupPairsWithoutSelf, _maxExistingGroupsByUser).ConfigureAwait(false); if (groupHasMigrated.Item1) { _logger.LogCallInfo(MareHubLogger.Args(dto, "Migrated", groupHasMigrated.Item2)); - var user = await _dbContext.Users.SingleAsync(u => u.UID == groupHasMigrated.Item2).ConfigureAwait(false); + var user = await DbContext.Users.SingleAsync(u => u.UID == groupHasMigrated.Item2).ConfigureAwait(false); await Clients.Users(groupPairsWithoutSelf.Select(p => p.GroupUserUID)).Client_GroupSendInfo(new GroupInfoDto(group.ToGroupData(), user.ToUserData(), group.GetGroupPermissions())).ConfigureAwait(false); @@ -263,7 +263,7 @@ public partial class MareHub } } - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs index bc4db5e..835e257 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs @@ -38,8 +38,8 @@ public partial class MareHub GroupGID = dto.Group.GID, }; - _dbContext.Add(ban); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.Add(ban); + await DbContext.SaveChangesAsync().ConfigureAwait(false); await GroupRemoveUser(dto).ConfigureAwait(false); @@ -59,9 +59,9 @@ public partial class MareHub group.DisableAnimations = dto.Permissions.HasFlag(GroupPermissions.DisableAnimations); group.DisableVFX = dto.Permissions.HasFlag(GroupPermissions.DisableVFX); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); - var groupPairs = _dbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToList(); + var groupPairs = DbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToList(); await Clients.Users(groupPairs).Client_GroupChangePermissions(new GroupPermissionDto(dto.Group, dto.Permissions)).ConfigureAwait(false); } @@ -79,13 +79,13 @@ public partial class MareHub groupPair.IsPaused = dto.GroupPairPermissions.IsPaused(); groupPair.DisableVFX = dto.GroupPairPermissions.IsDisableVFX(); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); - var groupPairs = _dbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == dto.Group.GID).ToList(); + var groupPairs = DbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == dto.Group.GID).ToList(); await Clients.Users(groupPairs.Select(p => p.GroupUserUID)).Client_GroupPairChangePermissions(dto).ConfigureAwait(false); var allUserPairs = await GetAllPairedClientsWithPauseState().ConfigureAwait(false); - var self = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); + var self = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); if (wasPaused == groupPair.IsPaused) return; @@ -129,20 +129,20 @@ public partial class MareHub var (isInGroup, newOwnerPair) = await TryValidateUserInGroup(dto.Group.GID, dto.User.UID).ConfigureAwait(false); if (!isInGroup) return; - var ownedShells = await _dbContext.Groups.CountAsync(g => g.OwnerUID == dto.User.UID).ConfigureAwait(false); + var ownedShells = await DbContext.Groups.CountAsync(g => g.OwnerUID == dto.User.UID).ConfigureAwait(false); if (ownedShells >= _maxExistingGroupsByUser) return; - var prevOwner = await _dbContext.GroupPairs.SingleOrDefaultAsync(g => g.GroupGID == dto.Group.GID && g.GroupUserUID == UserUID).ConfigureAwait(false); + var prevOwner = await DbContext.GroupPairs.SingleOrDefaultAsync(g => g.GroupGID == dto.Group.GID && g.GroupUserUID == UserUID).ConfigureAwait(false); prevOwner.IsPinned = false; group.Owner = newOwnerPair.GroupUser; group.Alias = null; newOwnerPair.IsPinned = true; newOwnerPair.IsModerator = false; - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); - var groupPairs = await _dbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).AsNoTracking().ToListAsync().ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).AsNoTracking().ToListAsync().ConfigureAwait(false); await Clients.Users(groupPairs).Client_GroupSendInfo(new GroupInfoDto(group.ToGroupData(), newOwnerPair.GroupUser.ToUserData(), group.GetGroupPermissions())).ConfigureAwait(false); } @@ -158,7 +158,7 @@ public partial class MareHub _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); group.HashedPassword = StringUtils.Sha256String(dto.Password); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); return true; } @@ -171,7 +171,7 @@ public partial class MareHub var (hasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false); if (!hasRights) return; - var groupPairs = await _dbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == dto.Group.GID).ToListAsync().ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == dto.Group.GID).ToListAsync().ConfigureAwait(false); await Clients.Users(groupPairs.Where(p => !p.IsPinned && !p.IsModerator).Select(g => g.GroupUserUID)).Client_GroupDelete(new GroupDto(group.ToGroupData())).ConfigureAwait(false); @@ -179,8 +179,8 @@ public partial class MareHub var notPinned = groupPairs.Where(g => !g.IsPinned && !g.IsModerator).ToList(); - _dbContext.GroupPairs.RemoveRange(notPinned); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.GroupPairs.RemoveRange(notPinned); + await DbContext.SaveChangesAsync().ConfigureAwait(false); foreach (var pair in notPinned) { @@ -202,15 +202,15 @@ public partial class MareHub public async Task GroupCreate() { _logger.LogCallInfo(); - var existingGroupsByUser = await _dbContext.Groups.CountAsync(u => u.OwnerUID == UserUID).ConfigureAwait(false); - var existingJoinedGroups = await _dbContext.GroupPairs.CountAsync(u => u.GroupUserUID == UserUID).ConfigureAwait(false); + var existingGroupsByUser = await DbContext.Groups.CountAsync(u => u.OwnerUID == UserUID).ConfigureAwait(false); + var existingJoinedGroups = await DbContext.GroupPairs.CountAsync(u => u.GroupUserUID == UserUID).ConfigureAwait(false); if (existingGroupsByUser >= _maxExistingGroupsByUser || existingJoinedGroups >= _maxJoinedGroupsByUser) { throw new System.Exception($"Max groups for user is {_maxExistingGroupsByUser}, max joined groups is {_maxJoinedGroupsByUser}."); } var gid = StringUtils.GenerateRandomString(9); - while (await _dbContext.Groups.AnyAsync(g => g.GID == "LSS-" + gid).ConfigureAwait(false)) + while (await DbContext.Groups.AnyAsync(g => g.GID == "LSS-" + gid).ConfigureAwait(false)) { gid = StringUtils.GenerateRandomString(9); } @@ -236,11 +236,11 @@ public partial class MareHub IsPinned = true, }; - await _dbContext.Groups.AddAsync(newGroup).ConfigureAwait(false); - await _dbContext.GroupPairs.AddAsync(initialPair).ConfigureAwait(false); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.Groups.AddAsync(newGroup).ConfigureAwait(false); + await DbContext.GroupPairs.AddAsync(initialPair).ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); - var self = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); + var self = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(newGroup.ToGroupData(), self.ToUserData(), GroupPermissions.NoneSet, GroupUserPermissions.NoneSet, GroupUserInfo.None)) .ConfigureAwait(false); @@ -259,7 +259,7 @@ public partial class MareHub var (hasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false); if (!hasRights) return new(); - var existingInvites = await _dbContext.GroupTempInvites.Where(g => g.GroupGID == group.GID).ToListAsync().ConfigureAwait(false); + var existingInvites = await DbContext.GroupTempInvites.Where(g => g.GroupGID == group.GID).ToListAsync().ConfigureAwait(false); for (int i = 0; i < amount; i++) { @@ -283,8 +283,8 @@ public partial class MareHub }); } - _dbContext.GroupTempInvites.AddRange(tempInvites); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.GroupTempInvites.AddRange(tempInvites); + await DbContext.SaveChangesAsync().ConfigureAwait(false); return inviteCodes; } @@ -298,10 +298,10 @@ public partial class MareHub _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); - var groupPairs = await _dbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).ToListAsync().ConfigureAwait(false); - _dbContext.RemoveRange(groupPairs); - _dbContext.Remove(group); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).ToListAsync().ConfigureAwait(false); + DbContext.RemoveRange(groupPairs); + DbContext.Remove(group); + await DbContext.SaveChangesAsync().ConfigureAwait(false); await Clients.Users(groupPairs.Select(g => g.GroupUserUID)).Client_GroupDelete(new GroupDto(group.ToGroupData())).ConfigureAwait(false); @@ -316,7 +316,7 @@ public partial class MareHub var (userHasRights, group) = await TryValidateGroupModeratorOrOwner(dto.GID).ConfigureAwait(false); if (!userHasRights) return new List(); - var banEntries = await _dbContext.GroupBans.Include(b => b.BannedUser).Where(g => g.GroupGID == dto.Group.GID).AsNoTracking().ToListAsync().ConfigureAwait(false); + var banEntries = await DbContext.GroupBans.Include(b => b.BannedUser).Where(g => g.GroupGID == dto.Group.GID).AsNoTracking().ToListAsync().ConfigureAwait(false); List bannedGroupUsers = banEntries.Select(b => new BannedGroupUserDto(group.ToGroupData(), b.BannedUser.ToUserData(), b.BannedReason, b.BannedOn, @@ -334,14 +334,14 @@ public partial class MareHub _logger.LogCallInfo(MareHubLogger.Args(dto.Group)); - var group = await _dbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid).ConfigureAwait(false); + var group = await DbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid).ConfigureAwait(false); var groupGid = group?.GID ?? string.Empty; - var existingPair = await _dbContext.GroupPairs.AsNoTracking().SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.GroupUserUID == UserUID).ConfigureAwait(false); + var existingPair = await DbContext.GroupPairs.AsNoTracking().SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.GroupUserUID == UserUID).ConfigureAwait(false); var hashedPw = StringUtils.Sha256String(dto.Password); - var existingUserCount = await _dbContext.GroupPairs.AsNoTracking().CountAsync(g => g.GroupGID == groupGid).ConfigureAwait(false); - var joinedGroups = await _dbContext.GroupPairs.CountAsync(g => g.GroupUserUID == UserUID).ConfigureAwait(false); - var isBanned = await _dbContext.GroupBans.AnyAsync(g => g.GroupGID == groupGid && g.BannedUserUID == UserUID).ConfigureAwait(false); - var oneTimeInvite = await _dbContext.GroupTempInvites.SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.Invite == hashedPw).ConfigureAwait(false); + var existingUserCount = await DbContext.GroupPairs.AsNoTracking().CountAsync(g => g.GroupGID == groupGid).ConfigureAwait(false); + var joinedGroups = await DbContext.GroupPairs.CountAsync(g => g.GroupUserUID == UserUID).ConfigureAwait(false); + var isBanned = await DbContext.GroupBans.AnyAsync(g => g.GroupGID == groupGid && g.BannedUserUID == UserUID).ConfigureAwait(false); + var oneTimeInvite = await DbContext.GroupTempInvites.SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.Invite == hashedPw).ConfigureAwait(false); if (group == null || (!string.Equals(group.HashedPassword, hashedPw, StringComparison.Ordinal) && oneTimeInvite == null) @@ -355,7 +355,7 @@ public partial class MareHub if (oneTimeInvite != null) { _logger.LogCallInfo(MareHubLogger.Args(aliasOrGid, "TempInvite", oneTimeInvite.Invite)); - _dbContext.Remove(oneTimeInvite); + DbContext.Remove(oneTimeInvite); } GroupPair newPair = new() @@ -367,16 +367,16 @@ public partial class MareHub DisableVFX = false }; - await _dbContext.GroupPairs.AddAsync(newPair).ConfigureAwait(false); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.GroupPairs.AddAsync(newPair).ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); _logger.LogCallInfo(MareHubLogger.Args(aliasOrGid, "Success")); await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(group.ToGroupData(), group.Owner.ToUserData(), group.GetGroupPermissions(), newPair.GetGroupPairPermissions(), newPair.GetGroupPairUserInfo())).ConfigureAwait(false); - var self = _dbContext.Users.Single(u => u.UID == UserUID); + var self = DbContext.Users.Single(u => u.UID == UserUID); - var groupPairs = await _dbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == group.GID && p.GroupUserUID != UserUID).ToListAsync().ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == group.GID && p.GroupUserUID != UserUID).ToListAsync().ConfigureAwait(false); await Clients.Users(groupPairs.Select(p => p.GroupUserUID)) .Client_GroupPairJoined(new GroupPairFullInfoDto(group.ToGroupData(), self.ToUserData(), newPair.GetGroupPairUserInfo(), newPair.GetGroupPairPermissions())).ConfigureAwait(false); @@ -420,7 +420,7 @@ public partial class MareHub var (hasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false); if (!hasRights) return -1; - var allGroupUsers = await _dbContext.GroupPairs.Include(p => p.GroupUser).Include(p => p.Group) + var allGroupUsers = await DbContext.GroupPairs.Include(p => p.GroupUser).Include(p => p.Group) .Where(g => g.GroupGID == dto.Group.GID) .ToListAsync().ConfigureAwait(false); var usersToPrune = allGroupUsers.Where(p => !p.IsPinned && !p.IsModerator @@ -430,7 +430,7 @@ public partial class MareHub if (!execute) return usersToPrune.Count(); - _dbContext.GroupPairs.RemoveRange(usersToPrune); + DbContext.GroupPairs.RemoveRange(usersToPrune); foreach (var pair in usersToPrune) { @@ -438,7 +438,7 @@ public partial class MareHub .Client_GroupPairLeft(new GroupPairDto(dto.Group, pair.GroupUser.ToUserData())).ConfigureAwait(false); } - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); return usersToPrune.Count(); } @@ -457,10 +457,10 @@ public partial class MareHub if (groupPair.IsModerator || string.Equals(group.OwnerUID, dto.User.UID, StringComparison.Ordinal)) return; _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); - _dbContext.GroupPairs.Remove(groupPair); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.GroupPairs.Remove(groupPair); + await DbContext.SaveChangesAsync().ConfigureAwait(false); - var groupPairs = _dbContext.GroupPairs.Where(p => p.GroupGID == group.GID).AsNoTracking().ToList(); + var groupPairs = DbContext.GroupPairs.Where(p => p.GroupGID == group.GID).AsNoTracking().ToList(); await Clients.Users(groupPairs.Select(p => p.GroupUserUID)).Client_GroupPairLeft(dto).ConfigureAwait(false); var userIdent = await GetUserIdent(dto.User.UID).ConfigureAwait(false); @@ -505,9 +505,9 @@ public partial class MareHub userPair.IsModerator = false; } - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); - var groupPairs = await _dbContext.GroupPairs.AsNoTracking().Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToListAsync().ConfigureAwait(false); + var groupPairs = await DbContext.GroupPairs.AsNoTracking().Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToListAsync().ConfigureAwait(false); await Clients.Users(groupPairs).Client_GroupPairChangeUserInfo(new GroupPairUserInfoDto(dto.Group, dto.User, userPair.GetGroupPairUserInfo())).ConfigureAwait(false); } @@ -516,7 +516,7 @@ public partial class MareHub { _logger.LogCallInfo(); - var groups = await _dbContext.GroupPairs.Include(g => g.Group).Include(g => g.Group.Owner).Where(g => g.GroupUserUID == UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false); + var groups = await DbContext.GroupPairs.Include(g => g.Group).Include(g => g.Group.Owner).Where(g => g.GroupUserUID == UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false); return groups.Select(g => new GroupFullInfoDto(g.Group.ToGroupData(), g.Group.Owner.ToUserData(), g.Group.GetGroupPermissions(), g.GetGroupPairPermissions(), g.GetGroupPairUserInfo())).ToList(); @@ -530,8 +530,8 @@ public partial class MareHub var (inGroup, _) = await TryValidateUserInGroup(dto.Group.GID).ConfigureAwait(false); if (!inGroup) return new List(); - var group = await _dbContext.Groups.SingleAsync(g => g.GID == dto.Group.GID).ConfigureAwait(false); - var allPairs = await _dbContext.GroupPairs.Include(g => g.GroupUser).Where(g => g.GroupGID == dto.Group.GID && g.GroupUserUID != UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false); + var group = await DbContext.Groups.SingleAsync(g => g.GID == dto.Group.GID).ConfigureAwait(false); + var allPairs = await DbContext.GroupPairs.Include(g => g.GroupUser).Where(g => g.GroupGID == dto.Group.GID && g.GroupUserUID != UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false); return allPairs.Select(p => new GroupPairFullInfoDto(group.ToGroupData(), p.GroupUser.ToUserData(), p.GetGroupPairUserInfo(), p.GetGroupPairPermissions())).ToList(); } @@ -543,11 +543,11 @@ public partial class MareHub var (userHasRights, _) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false); if (!userHasRights) return; - var banEntry = await _dbContext.GroupBans.SingleOrDefaultAsync(g => g.GroupGID == dto.Group.GID && g.BannedUserUID == dto.User.UID).ConfigureAwait(false); + var banEntry = await DbContext.GroupBans.SingleOrDefaultAsync(g => g.GroupGID == dto.Group.GID && g.BannedUserUID == dto.User.UID).ConfigureAwait(false); if (banEntry == null) return; - _dbContext.Remove(banEntry); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.Remove(banEntry); + await DbContext.SaveChangesAsync().ConfigureAwait(false); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); } diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs index 0fbee6f..77bcd96 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs @@ -30,7 +30,7 @@ public partial class MareHub if (string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal) || string.IsNullOrWhiteSpace(dto.User.UID)) return; // grab other user, check if it exists and if a pair already exists - var otherUser = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == uid || u.Alias == uid).ConfigureAwait(false); + var otherUser = await DbContext.Users.SingleOrDefaultAsync(u => u.UID == uid || u.Alias == uid).ConfigureAwait(false); if (otherUser == null) { await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Warning, $"Cannot pair with {dto.User.UID}, UID does not exist").ConfigureAwait(false); @@ -44,7 +44,7 @@ public partial class MareHub } var existingEntry = - await _dbContext.ClientPairs.AsNoTracking() + await DbContext.ClientPairs.AsNoTracking() .FirstOrDefaultAsync(p => p.User.UID == UserUID && p.OtherUserUID == otherUser.UID).ConfigureAwait(false); @@ -55,7 +55,7 @@ public partial class MareHub } // grab self create new client pair and save - var user = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); + var user = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); @@ -65,8 +65,8 @@ public partial class MareHub OtherUser = otherUser, User = user, }; - await _dbContext.ClientPairs.AddAsync(wl).ConfigureAwait(false); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.ClientPairs.AddAsync(wl).ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); // get the opposite entry of the client pair var otherEntry = OppositeEntry(otherUser.UID); @@ -97,8 +97,8 @@ public partial class MareHub { _logger.LogCallInfo(); - var userEntry = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); - var secondaryUsers = await _dbContext.Auth.Include(u => u.User).Where(u => u.PrimaryUserUID == UserUID).Select(c => c.User).ToListAsync().ConfigureAwait(false); + var userEntry = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false); + var secondaryUsers = await DbContext.Auth.Include(u => u.User).Where(u => u.PrimaryUserUID == UserUID).Select(c => c.User).ToListAsync().ConfigureAwait(false); foreach (var user in secondaryUsers) { await DeleteUser(user).ConfigureAwait(false); @@ -126,8 +126,8 @@ public partial class MareHub _logger.LogCallInfo(); var query = - from userToOther in _dbContext.ClientPairs - join otherToUser in _dbContext.ClientPairs + from userToOther in DbContext.ClientPairs + join otherToUser in DbContext.ClientPairs on new { user = userToOther.UserUID, @@ -186,7 +186,7 @@ public partial class MareHub return new UserProfileDto(user.User, false, null, null, "Due to the pause status you cannot access this users profile."); } - var data = await _dbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.User.UID).ConfigureAwait(false); + var data = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.User.UID).ConfigureAwait(false); if (data == null) return new UserProfileDto(user.User, false, null, null, null); if (data.FlaggedForReport) return new UserProfileDto(user.User, true, null, null, "This profile is flagged for report and pending evaluation"); @@ -277,14 +277,14 @@ public partial class MareHub // check if client pair even exists ClientPair callerPair = - await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false); + await DbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false); if (callerPair == null) return; bool callerHadPaused = callerPair.IsPaused; // delete from database, send update info to users pair list - _dbContext.ClientPairs.Remove(callerPair); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.ClientPairs.Remove(callerPair); + await DbContext.SaveChangesAsync().ConfigureAwait(false); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); @@ -334,14 +334,14 @@ public partial class MareHub { _logger.LogCallInfo(MareHubLogger.Args(dto)); - UserProfileDataReport report = await _dbContext.UserProfileReports.SingleOrDefaultAsync(u => u.ReportedUserUID == dto.User.UID && u.ReportingUserUID == UserUID).ConfigureAwait(false); + UserProfileDataReport report = await DbContext.UserProfileReports.SingleOrDefaultAsync(u => u.ReportedUserUID == dto.User.UID && u.ReportingUserUID == UserUID).ConfigureAwait(false); if (report != null) { await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "You already reported this profile and it's pending validation").ConfigureAwait(false); return; } - UserProfileData profile = await _dbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID).ConfigureAwait(false); + UserProfileData profile = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID).ConfigureAwait(false); if (profile == null) { await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "This user has no profile").ConfigureAwait(false); @@ -358,9 +358,9 @@ public partial class MareHub profile.FlaggedForReport = true; - await _dbContext.UserProfileReports.AddAsync(reportToAdd).ConfigureAwait(false); + await DbContext.UserProfileReports.AddAsync(reportToAdd).ConfigureAwait(false); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); var allPairedUsers = await GetAllPairedUnpausedUsers(dto.User.UID).ConfigureAwait(false); var pairs = await GetOnlineUsers(allPairedUsers).ConfigureAwait(false); @@ -375,7 +375,7 @@ public partial class MareHub _logger.LogCallInfo(MareHubLogger.Args(dto)); if (string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) return; - ClientPair pair = await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false); + ClientPair pair = await DbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false); if (pair == null) return; var pauseChange = pair.IsPaused != dto.Permissions.IsPaused(); @@ -384,8 +384,8 @@ public partial class MareHub pair.DisableAnimations = dto.Permissions.IsDisableAnimations(); pair.DisableSounds = dto.Permissions.IsDisableSounds(); pair.DisableVFX = dto.Permissions.IsDisableVFX(); - _dbContext.Update(pair); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + DbContext.Update(pair); + await DbContext.SaveChangesAsync().ConfigureAwait(false); _logger.LogCallInfo(MareHubLogger.Args(dto, "Success")); @@ -424,7 +424,7 @@ public partial class MareHub if (!string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) throw new HubException("Cannot modify profile data for anyone but yourself"); - var existingData = await _dbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID).ConfigureAwait(false); + var existingData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID).ConfigureAwait(false); if (existingData?.FlaggedForReport ?? false) { @@ -488,10 +488,10 @@ public partial class MareHub IsNSFW = dto.IsNSFW ?? false }; - await _dbContext.UserProfileData.AddAsync(userProfileData).ConfigureAwait(false); + await DbContext.UserProfileData.AddAsync(userProfileData).ConfigureAwait(false); } - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false); var pairs = await GetOnlineUsers(allPairedUsers).ConfigureAwait(false); @@ -510,5 +510,5 @@ public partial class MareHub private static partial Regex UrlRegex(); private ClientPair OppositeEntry(string otherUID) => - _dbContext.ClientPairs.AsNoTracking().SingleOrDefault(w => w.User.UID == otherUID && w.OtherUser.UID == UserUID); + DbContext.ClientPairs.AsNoTracking().SingleOrDefault(w => w.User.UID == otherUID && w.OtherUser.UID == UserUID); } \ No newline at end of file diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs index 5fbfdb6..37e2c9b 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs @@ -11,6 +11,7 @@ using MareSynchronosShared.Services; using MareSynchronosShared.Utils.Configuration; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; +using Microsoft.EntityFrameworkCore; using StackExchange.Redis.Extensions.Core.Abstractions; namespace MareSynchronosServer.Hubs; @@ -22,7 +23,6 @@ public partial class MareHub : Hub, IMareHub private readonly SystemInfoService _systemInfoService; private readonly IHttpContextAccessor _contextAccessor; private readonly MareHubLogger _logger; - private readonly MareDbContext _dbContext; private readonly string _shardName; private readonly int _maxExistingGroupsByUser; private readonly int _maxJoinedGroupsByUser; @@ -30,9 +30,13 @@ public partial class MareHub : Hub, IMareHub private readonly IRedisDatabase _redis; private readonly Uri _fileServerAddress; private readonly Version _expectedClientVersion; + private readonly int _maxCharaDataByUser; + + private readonly Lazy _dbContextLazy; + private MareDbContext DbContext => _dbContextLazy.Value; public MareHub(MareMetrics mareMetrics, - MareDbContext mareDbContext, ILogger logger, SystemInfoService systemInfoService, + IDbContextFactory mareDbContextFactory, ILogger logger, SystemInfoService systemInfoService, IConfigurationService configuration, IHttpContextAccessor contextAccessor, IRedisDatabase redisDb) { @@ -47,7 +51,17 @@ public partial class MareHub : Hub, IMareHub _contextAccessor = contextAccessor; _redis = redisDb; _logger = new MareHubLogger(this, logger); - _dbContext = mareDbContext; + _dbContextLazy = new Lazy(() => mareDbContextFactory.CreateDbContext()); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + DbContext.Dispose(); + } + + base.Dispose(disposing); } [Authorize(Policy = "Identified")] @@ -59,9 +73,9 @@ public partial class MareHub : Hub, IMareHub await Clients.Caller.Client_UpdateSystemInfo(_systemInfoService.SystemInfoDto).ConfigureAwait(false); - var dbUser = _dbContext.Users.SingleOrDefault(f => f.UID == UserUID); + var dbUser = DbContext.Users.SingleOrDefault(f => f.UID == UserUID); dbUser.LastLoggedIn = DateTime.UtcNow; - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await DbContext.SaveChangesAsync().ConfigureAwait(false); await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Information, "Welcome to Loporrit, Current Online Users: " + _systemInfoService.SystemInfoDto.OnlineUsers).ConfigureAwait(false); diff --git a/MareSynchronosServer/MareSynchronosServer/Startup.cs b/MareSynchronosServer/MareSynchronosServer/Startup.cs index eebe181..cf685a2 100644 --- a/MareSynchronosServer/MareSynchronosServer/Startup.cs +++ b/MareSynchronosServer/MareSynchronosServer/Startup.cs @@ -239,6 +239,15 @@ public class Startup }).UseSnakeCaseNamingConvention(); options.EnableThreadSafetyChecks(false); }, mareConfig.GetValue(nameof(MareConfigurationBase.DbContextPoolSize), 1024)); + services.AddDbContextFactory(options => + { + options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"), builder => + { + builder.MigrationsHistoryTable("_efmigrationshistory", "public"); + builder.MigrationsAssembly("MareSynchronosShared"); + }).UseSnakeCaseNamingConvention(); + options.EnableThreadSafetyChecks(false); + }); } private static void ConfigureMetrics(IServiceCollection services)