Browse Source

Null out sponsorship values when foreign key deleted (#1733)

This allows us to maintain record of sponsorships up
until they are explicitly removed. Fixes issues where removing
sponsorships from organizations with invalid sponsorships would error
pull/1736/head
Matt Gibson 4 years ago committed by GitHub
parent
commit
fa3f1ad0ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/Core/Repositories/EntityFramework/OrganizationRepository.cs
  2. 12
      src/Core/Repositories/EntityFramework/OrganizationUserRepository.cs
  3. 14
      src/Sql/dbo/Stored Procedures/OrganizationSponsorship_OrganizationDeleted.sql
  4. 7
      src/Sql/dbo/Stored Procedures/OrganizationSponsorship_OrganizationUserDeleted.sql
  5. 25
      src/Sql/dbo/Stored Procedures/OrganizationSponsorship_OrganizationUsersDeleted.sql
  6. 86
      util/Migrator/DbScripts/2021-11-23_00_NullOrganizationSponsorshipOnFkDelete.sql

3
src/Core/Repositories/EntityFramework/OrganizationRepository.cs

@ -107,10 +107,9 @@ namespace Bit.Core.Repositories.EntityFramework @@ -107,10 +107,9 @@ namespace Bit.Core.Repositories.EntityFramework
.Where(os =>
os.SponsoringOrganizationId == organization.Id ||
os.SponsoredOrganizationId == organization.Id);
dbContext.RemoveRange(sponsorships.Where(os => os.CloudSponsor));
Guid? UpdatedOrgId(Guid? orgId) => orgId == organization.Id ? null : organization.Id;
foreach (var sponsorship in sponsorships.Where(os => !os.CloudSponsor))
foreach (var sponsorship in sponsorships)
{
sponsorship.SponsoredOrganizationId = UpdatedOrgId(sponsorship.SponsoredOrganizationId);
sponsorship.SponsoringOrganizationId = UpdatedOrgId(sponsorship.SponsoringOrganizationId);

12
src/Core/Repositories/EntityFramework/OrganizationUserRepository.cs

@ -77,7 +77,11 @@ namespace Bit.Core.Repositories.EntityFramework @@ -77,7 +77,11 @@ namespace Bit.Core.Repositories.EntityFramework
var sponsorships = dbContext.OrganizationSponsorships
.Where(os => os.SponsoringOrganizationUserId != default &&
os.SponsoringOrganizationUserId.Value == organizationUserId);
dbContext.RemoveRange(sponsorships);
foreach (var sponsorship in sponsorships)
{
sponsorship.SponsoringOrganizationUserId = null;
}
dbContext.Remove(orgUser);
await dbContext.SaveChangesAsync();
}
@ -92,7 +96,11 @@ namespace Bit.Core.Repositories.EntityFramework @@ -92,7 +96,11 @@ namespace Bit.Core.Repositories.EntityFramework
var sponsorships = dbContext.OrganizationSponsorships
.Where(os => os.SponsoringOrganizationUserId != default &&
organizationUserIds.Contains(os.SponsoringOrganizationUserId ?? default));
dbContext.RemoveRange(sponsorships);
foreach (var sponsorship in sponsorships)
{
sponsorship.SponsoringOrganizationUserId = null;
}
dbContext.RemoveRange(entities);
await dbContext.SaveChangesAsync();
}

14
src/Sql/dbo/Stored Procedures/OrganizationSponsorship_OrganizationDeleted.sql

@ -9,23 +9,13 @@ BEGIN @@ -9,23 +9,13 @@ BEGIN
SET
[SponsoringOrganizationId] = NULL
WHERE
[SponsoringOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
[SponsoringOrganizationId] = @OrganizationId
UPDATE
[dbo].[OrganizationSponsorship]
SET
[SponsoredOrganizationId] = NULL
WHERE
[SponsoredOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
DELETE
FROM
[dbo].[OrganizationSponsorship]
WHERE
[CloudSponsor] = 1 AND
([SponsoredOrganizationId] = @OrganizationId OR
[SponsoringOrganizationId] = @OrganizationId)
[SponsoredOrganizationId] = @OrganizationId
END
GO

7
src/Sql/dbo/Stored Procedures/OrganizationSponsorship_OrganizationUserDeleted.sql

@ -4,9 +4,12 @@ AS @@ -4,9 +4,12 @@ AS
BEGIN
SET NOCOUNT ON
DELETE
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship]
[dbo].[OrganizationSponsorship] OS
WHERE
[SponsoringOrganizationUserId] = @OrganizationUserId
END

25
src/Sql/dbo/Stored Procedures/OrganizationSponsorship_OrganizationUsersDeleted.sql

@ -4,22 +4,13 @@ AS @@ -4,22 +4,13 @@ AS
BEGIN
SET NOCOUNT ON
DECLARE @BatchSize AS INT;
SET @BatchSize = 100;
WHILE @BatchSize > 0
BEGIN
BEGIN TRANSACTION OrganizationSponsorship_DeleteOUs
DELETE TOP(@BatchSize) OS
FROM
[dbo].[OrganizationSponsorship] OS
INNER JOIN
@SponsoringOrganizationUserIds I ON I.Id = OS.SponsoringOrganizationUserId
SET @BatchSize = @@ROWCOUNT
COMMIT TRANSACTION OrganizationSponsorship_DeleteOUs
END
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship] OS
INNER JOIN
@SponsoringOrganizationUserIds I ON I.Id = OS.SponsoringOrganizationUserId
END
GO

86
util/Migrator/DbScripts/2021-11-23_00_NullOrganizationSponsorshipOnFkDelete.sql

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
-- OrganizationSponsorship_OrganizationDeleted
IF OBJECT_ID('[dbo].[OrganizationSponsorship_OrganizationDeleted]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationSponsorship_OrganizationDeleted]
END
GO
CREATE PROCEDURE [dbo].[OrganizationSponsorship_OrganizationDeleted]
@OrganizationId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
UPDATE
[dbo].[OrganizationSponsorship]
SET
[SponsoringOrganizationId] = NULL
WHERE
[SponsoringOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
UPDATE
[dbo].[OrganizationSponsorship]
SET
[SponsoredOrganizationId] = NULL
WHERE
[SponsoredOrganizationId] = @OrganizationId AND
[CloudSponsor] = 0
DELETE
FROM
[dbo].[OrganizationSponsorship]
WHERE
[CloudSponsor] = 1 AND
([SponsoredOrganizationId] = @OrganizationId OR
[SponsoringOrganizationId] = @OrganizationId)
END
GO
-- OrganizationSponsorship_OrganizationUserDeleted
IF OBJECT_ID('[dbo].[OrganizationSponsorship_OrganizationUserDeleted]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUserDeleted]
END
GO
CREATE PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUserDeleted]
@OrganizationUserId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship] OS
WHERE
[SponsoringOrganizationUserId] = @OrganizationUserId
END
GO
-- OrganizationSponsorship_OrganizationUsersDeleted
IF OBJECT_ID('[dbo].[OrganizationSponsorship_OrganizationUsersDeleted]') IS NOT NULL
BEGIN
DROP PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUsersDeleted]
END
GO
CREATE PROCEDURE [dbo].[OrganizationSponsorship_OrganizationUsersDeleted]
@SponsoringOrganizationUserIds [dbo].[GuidIdArray] READONLY
AS
BEGIN
SET NOCOUNT ON
UPDATE
OS
SET
[SponsoringOrganizationUserId] = NULL
FROM
[dbo].[OrganizationSponsorship] OS
INNER JOIN
@SponsoringOrganizationUserIds I ON I.Id = OS.SponsoringOrganizationUserId
END
GO
Loading…
Cancel
Save