From fcd2dd380da00c0da53fb46310d8fe12926adb61 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Wed, 10 Jan 2024 11:34:31 +0000 Subject: [PATCH 01/16] [AC-1682] Update FC data migration scripts to clear AccessAll flags and set all Managers to Users --- ...023-12-06_00_AccessAllCollectionGroups.sql | 14 ++-- ...2023-12-06_01_AccessAllCollectionUsers.sql | 65 +++++++++---------- ...02_ManagersEditAssignedCollectionUsers.sql | 12 +++- 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql index d493224821..3ea8ead855 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql @@ -1,10 +1,10 @@ --- Create a temporary table to store the groups with AccessAll = 1 +-- Step 1: Create a temporary table to store the Groups with AccessAll = 1 SELECT [Id] AS [GroupId], [OrganizationId] INTO #TempGroup FROM [dbo].[Group] WHERE [AccessAll] = 1; --- Update existing rows in [dbo].[CollectionGroup] +-- Step 2: Update existing rows in [dbo].[CollectionGroup] UPDATE CG SET CG.[ReadOnly] = 0, @@ -15,7 +15,7 @@ INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] WHERE C.[OrganizationId] = TG.[OrganizationId]; --- Insert new rows into [dbo].[CollectionGroup] +-- Step 3: Insert new rows into [dbo].[CollectionGroup] INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) SELECT C.[Id], TG.[GroupId], 0, 0, 0 FROM [dbo].[Collection] C @@ -23,5 +23,11 @@ FROM [dbo].[Collection] C LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] WHERE CG.[CollectionId] IS NULL; --- Drop the temporary table +-- Step 4: Update [dbo].[Group] to clear AccessAll flag +UPDATE G +SET [AccessAll] = 0 +FROM [dbo].[Group] G +INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + +-- Step 5: Drop the temporary table DROP TABLE #TempGroup; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql index c52cac3d5c..1169dba524 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql @@ -1,45 +1,40 @@ --- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time -SELECT [Id] AS [OrganizationUserId], [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch +-- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 +SELECT [Id] AS [OrganizationUserId], [OrganizationId] INTO #TempOrgUser FROM [dbo].[OrganizationUser] WHERE [AccessAll] = 1; --- Step 2: Get the maximum batch number -DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrgUser); -DECLARE @CurrentBatch INT = 0; - --- Step 3: Process each batch -WHILE @CurrentBatch <= @MaxBatch -BEGIN - -- Update existing rows in [dbo].[CollectionUser] - UPDATE target - SET - target.[ReadOnly] = 0, - target.[HidePasswords] = 0, - target.[Manage] = 0 - FROM [dbo].[CollectionUser] AS target - INNER JOIN ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] AND T.Batch = @CurrentBatch - ) AS source +-- Step 2: Update existing rows in [dbo].[CollectionUser] +UPDATE target +SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 +FROM [dbo].[CollectionUser] AS target +INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] +) AS source ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; - -- Insert new rows into [dbo].[CollectionUser] - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 - FROM ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] AND T.Batch = @CurrentBatch - ) AS source - LEFT JOIN [dbo].[CollectionUser] AS target +-- Step 3: Insert new rows into [dbo].[CollectionUser] +INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) +SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 +FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source +LEFT JOIN [dbo].[CollectionUser] AS target ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] - WHERE target.[CollectionId] IS NULL; +WHERE target.[CollectionId] IS NULL; - -- Move to the next batch - SET @CurrentBatch = @CurrentBatch + 1; -END; +-- Step 4: Update [dbo].[OrganizationUser] to clear AccessAll flag +UPDATE OU +SET [AccessAll] = 0 +FROM [dbo].[OrganizationUser] OU +INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] --- Step 4: Drop the temporary table +-- Step 5: Drop the temporary table DROP TABLE #TempOrgUser; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql index 33a4ce15aa..e5994478da 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql @@ -1,4 +1,4 @@ --- Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission +-- Step 1: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission UPDATE cu SET cu.[ReadOnly] = 0, cu.[HidePasswords] = 0, @@ -9,7 +9,7 @@ INNER JOIN [dbo].[OrganizationUser] ou WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) --- Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access +-- Step 2: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) SELECT cg.[CollectionId], ou.[Id], 0, 0, 1 FROM [dbo].[CollectionGroup] cg @@ -23,3 +23,11 @@ WHERE (ou.[Type] = 3 OR SELECT 1 FROM [dbo].[CollectionUser] cu WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] ) + +-- Step 3: Set all Managers to Users +UPDATE [dbo].[OrganizationUser] +SET [Type] = 2 -- User +WHERE [OrganizationId] = @OrganizationId + AND [Type] = 3; -- Manager + +-- TODO: clear custom permissions JSON? Probably should, but not actually used by any code once we enable FC From 8bf17eb198399866a55ce65db87c2643202473f6 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Wed, 10 Jan 2024 12:34:36 +0000 Subject: [PATCH 02/16] [AC-1682] Updated data migration scripts to bump the account revision date --- ...023-12-06_00_AccessAllCollectionGroups.sql | 24 +++- ...2023-12-06_01_AccessAllCollectionUsers.sql | 24 +++- ...02_ManagersEditAssignedCollectionUsers.sql | 103 +++++++++++++----- 3 files changed, 122 insertions(+), 29 deletions(-) diff --git a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql index 3ea8ead855..fe29bfe0b5 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql @@ -29,5 +29,27 @@ SET [AccessAll] = 0 FROM [dbo].[Group] G INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] --- Step 5: Drop the temporary table +-- Step 5: Bump the account revision date for each unique OrganizationId in #TempGroup +DECLARE @OrganizationId UNIQUEIDENTIFIER + +DECLARE OrgIdCursor CURSOR FOR +SELECT DISTINCT [OrganizationId] +FROM #TempGroup + +OPEN OrgIdCursor +FETCH NEXT FROM OrgIdCursor INTO @OrganizationId + +WHILE (@@FETCH_STATUS = 0) +BEGIN + -- Execute the stored procedure for the current OrganizationId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + + -- Fetch the next OrganizationId + FETCH NEXT FROM OrgIdCursor INTO @OrganizationId +END + +CLOSE OrgIdCursor +DEALLOCATE OrgIdCursor; + +-- Step 6: Drop the temporary table DROP TABLE #TempGroup; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql index 1169dba524..19b97a5ac5 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql @@ -36,5 +36,27 @@ SET [AccessAll] = 0 FROM [dbo].[OrganizationUser] OU INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] --- Step 5: Drop the temporary table +-- Step 5: Bump the account revision date for each unique OrganizationId in #TempOrgUser +DECLARE @OrganizationId UNIQUEIDENTIFIER + +DECLARE OrgIdCursor CURSOR FOR +SELECT DISTINCT [OrganizationId] +FROM #TempOrgUser + +OPEN OrgIdCursor +FETCH NEXT FROM OrgIdCursor INTO @OrganizationId + +WHILE (@@FETCH_STATUS = 0) +BEGIN + -- Execute the stored procedure for the current OrganizationId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + + -- Fetch the next OrganizationId + FETCH NEXT FROM OrgIdCursor INTO @OrganizationId +END + +CLOSE OrgIdCursor +DEALLOCATE OrgIdCursor; + +-- Step 6: Drop the temporary table DROP TABLE #TempOrgUser; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql index e5994478da..736acd0f29 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql @@ -1,33 +1,82 @@ -- Step 1: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission -UPDATE cu -SET cu.[ReadOnly] = 0, - cu.[HidePasswords] = 0, - cu.[Manage] = 1 -FROM [dbo].[CollectionUser] cu -INNER JOIN [dbo].[OrganizationUser] ou - ON cu.[OrganizationUserId] = ou.[Id] -WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND - ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + -- Store the results in a temporary table + SELECT ou.[Id] AS [OrganizationUserId] + INTO #TempStep1 + FROM [dbo].[OrganizationUser] ou + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND + ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); + + -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table + UPDATE cu + SET cu.[ReadOnly] = 0, + cu.[HidePasswords] = 0, + cu.[Manage] = 1 + FROM [dbo].[CollectionUser] cu + INNER JOIN #TempStep1 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; -- Step 2: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access -INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) -SELECT cg.[CollectionId], ou.[Id], 0, 0, 1 -FROM [dbo].[CollectionGroup] cg -INNER JOIN [dbo].[GroupUser] gu - ON cg.GroupId = gu.GroupId -INNER JOIN [dbo].[OrganizationUser] ou - ON gu.OrganizationUserId = ou.[Id] -WHERE (ou.[Type] = 3 OR - (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - AND NOT EXISTS ( - SELECT 1 FROM [dbo].[CollectionUser] cu - WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] - ) + -- Store the results in a temporary table + SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] + INTO #TempStep2 + FROM [dbo].[CollectionGroup] cg + INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ); + + -- Insert rows into [dbo].[CollectionUser] using the temporary table + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 + FROM #TempStep2; -- Step 3: Set all Managers to Users -UPDATE [dbo].[OrganizationUser] -SET [Type] = 2 -- User -WHERE [OrganizationId] = @OrganizationId - AND [Type] = 3; -- Manager + -- Store the results in a temporary table + SELECT [Id] AS [OrganizationUserId] + INTO #TempStep3 + FROM [dbo].[OrganizationUser] + WHERE [Type] = 3; -- Manager --- TODO: clear custom permissions JSON? Probably should, but not actually used by any code once we enable FC + -- Update [dbo].[OrganizationUser] based on the temporary table + UPDATE ou + SET ou.[Type] = 2 -- User + FROM [dbo].[OrganizationUser] ou + INNER JOIN #TempStep3 temp ON ou.[Id] = temp.[OrganizationUserId]; + +-- Step 4: Bump the account revision date for each unique OrganizationUserId in #TempStep1, #TempStep2, and #TempStep3 + -- Join the three temporary tables to get unique OrganizationUserId + SELECT DISTINCT temp1.[OrganizationUserId] + INTO #TempUniqueOrganizationUser + FROM #TempStep1 temp1 + JOIN #TempStep2 temp2 ON temp1.[OrganizationUserId] = temp2.[OrganizationUserId] + JOIN #TempStep3 temp3 ON temp1.[OrganizationUserId] = temp3.[OrganizationUserId]; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempUniqueOrganizationUser + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + +-- Step 5: Clean up temporary tables +DROP TABLE #TempStep1; +DROP TABLE #TempStep2; +DROP TABLE #TempStep3; +DROP TABLE #TempUniqueOrganizationUser; From dfc403243b4f9e80ccc890bcefbaf198d1056dc4 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Wed, 10 Jan 2024 15:05:22 +0000 Subject: [PATCH 03/16] [AC-1682] Created Organization_EnableCollectionEnhancements to migrate organization data for flexible collections --- ...anization_EnableCollectionEnhancements.sql | 132 ++++++++++++++++++ ...anization_EnableCollectionEnhancements.sql | 132 ++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql create mode 100644 util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql diff --git a/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql b/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql new file mode 100644 index 0000000000..926d8eac45 --- /dev/null +++ b/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql @@ -0,0 +1,132 @@ +CREATE PROCEDURE [dbo].[Organization_EnableCollectionEnhancements] + @OrganizationId UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + BEGIN TRY + BEGIN TRANSACTION; + -- Step 1: AccessAll migration for Groups + -- Create a temporary table to store the groups with AccessAll = 1 + SELECT [Id] AS [GroupId], [OrganizationId] + INTO #TempGroup + FROM [dbo].[Group] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; + + -- Update existing rows in [dbo].[CollectionGroup] + UPDATE CG + SET + CG.[ReadOnly] = 0, + CG.[HidePasswords] = 0, + CG.[Manage] = 0 + FROM [dbo].[CollectionGroup] CG + INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] + INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] + WHERE C.[OrganizationId] = TG.[OrganizationId]; + + -- Insert new rows into [dbo].[CollectionGroup] + INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) + SELECT C.[Id], TG.[GroupId], 0, 0, 0 + FROM [dbo].[Collection] C + INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] + LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] + WHERE CG.[CollectionId] IS NULL; + + -- Update Group to clear AccessAll flag + UPDATE G + SET [AccessAll] = 0 + FROM [dbo].[Group] G + INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + + -- Drop the temporary table + DROP TABLE #TempGroup; + + -- Step 2: AccessAll migration for users + -- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 + SELECT [Id] AS [OrganizationUserId], [OrganizationId] + INTO #TempOrgUser + FROM [dbo].[OrganizationUser] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; + + -- Update existing rows in [dbo].[CollectionUser] + UPDATE target + SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 + FROM [dbo].[CollectionUser] AS target + INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; + + -- Insert new rows into [dbo].[CollectionUser] + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 + FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + LEFT JOIN [dbo].[CollectionUser] AS target + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] + WHERE target.[CollectionId] IS NULL; + + -- Update OrganizationUser to clear AccessAll flag + UPDATE OU + SET [AccessAll] = 0 + FROM [dbo].[OrganizationUser] OU + INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] + + -- Drop the temporary table + DROP TABLE #TempOrgUser; + + -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission + UPDATE cu + SET cu.[ReadOnly] = 0, + cu.[HidePasswords] = 0, + cu.[Manage] = 1 + FROM [dbo].[CollectionUser] cu + INNER JOIN [dbo].[OrganizationUser] ou + ON cu.[OrganizationUserId] = ou.[Id] + WHERE ou.[OrganizationId] = @OrganizationId + AND (ou.[Type] = 3 + OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + + -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT cg.[CollectionId], ou.[Id], 0, 0, 1 + FROM [dbo].[CollectionGroup] cg + INNER JOIN [dbo].[GroupUser] gu + ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou + ON gu.OrganizationUserId = ou.[Id] + WHERE ou.[OrganizationId] = @OrganizationId + AND (ou.[Type] = 3 + OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ) + + -- Step 5: Set all Managers to Users + UPDATE [dbo].[OrganizationUser] + SET [Type] = 2 -- User + WHERE [OrganizationId] = @OrganizationId + AND [Type] = 3; -- Manager + + -- Step 6: Bump the account revision dates for all users in the organization + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; +END +GO diff --git a/util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql b/util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql new file mode 100644 index 0000000000..b59b63176d --- /dev/null +++ b/util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql @@ -0,0 +1,132 @@ +CREATE OR ALTER PROCEDURE [dbo].[Organization_EnableCollectionEnhancements] + @OrganizationId UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + BEGIN TRY + BEGIN TRANSACTION; + -- Step 1: AccessAll migration for Groups + -- Create a temporary table to store the groups with AccessAll = 1 + SELECT [Id] AS [GroupId], [OrganizationId] + INTO #TempGroup + FROM [dbo].[Group] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; + + -- Update existing rows in [dbo].[CollectionGroup] + UPDATE CG + SET + CG.[ReadOnly] = 0, + CG.[HidePasswords] = 0, + CG.[Manage] = 0 + FROM [dbo].[CollectionGroup] CG + INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] + INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] + WHERE C.[OrganizationId] = TG.[OrganizationId]; + + -- Insert new rows into [dbo].[CollectionGroup] + INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) + SELECT C.[Id], TG.[GroupId], 0, 0, 0 + FROM [dbo].[Collection] C + INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] + LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] + WHERE CG.[CollectionId] IS NULL; + + -- Update Group to clear AccessAll flag + UPDATE G + SET [AccessAll] = 0 + FROM [dbo].[Group] G + INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + + -- Drop the temporary table + DROP TABLE #TempGroup; + + -- Step 2: AccessAll migration for users + -- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 + SELECT [Id] AS [OrganizationUserId], [OrganizationId] + INTO #TempOrgUser + FROM [dbo].[OrganizationUser] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; + + -- Update existing rows in [dbo].[CollectionUser] + UPDATE target + SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 + FROM [dbo].[CollectionUser] AS target + INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; + + -- Insert new rows into [dbo].[CollectionUser] + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 + FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + LEFT JOIN [dbo].[CollectionUser] AS target + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] + WHERE target.[CollectionId] IS NULL; + + -- Update OrganizationUser to clear AccessAll flag + UPDATE OU + SET [AccessAll] = 0 + FROM [dbo].[OrganizationUser] OU + INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] + + -- Drop the temporary table + DROP TABLE #TempOrgUser; + + -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission + UPDATE cu + SET cu.[ReadOnly] = 0, + cu.[HidePasswords] = 0, + cu.[Manage] = 1 + FROM [dbo].[CollectionUser] cu + INNER JOIN [dbo].[OrganizationUser] ou + ON cu.[OrganizationUserId] = ou.[Id] + WHERE ou.[OrganizationId] = @OrganizationId + AND (ou.[Type] = 3 + OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + + -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT cg.[CollectionId], ou.[Id], 0, 0, 1 + FROM [dbo].[CollectionGroup] cg + INNER JOIN [dbo].[GroupUser] gu + ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou + ON gu.OrganizationUserId = ou.[Id] + WHERE ou.[OrganizationId] = @OrganizationId + AND (ou.[Type] = 3 + OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ) + + -- Step 5: Set all Managers to Users + UPDATE [dbo].[OrganizationUser] + SET [Type] = 2 -- User + WHERE [OrganizationId] = @OrganizationId + AND [Type] = 3; -- Manager + + -- Step 6: Bump the account revision dates for all users in the organization + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; +END +GO From 0d8609a094d0446ce18a2406228a0745df491523 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Wed, 10 Jan 2024 15:29:06 +0000 Subject: [PATCH 04/16] =?UTF-8?q?[AC-1682]=C2=A0Added=20script=20to=20migr?= =?UTF-8?q?ate=20all=20organization=20data=20for=20flexible=20collections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00_AllOrgsEnableCollectionEnhancements.sql | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql diff --git a/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql b/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql new file mode 100644 index 0000000000..fe37747760 --- /dev/null +++ b/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql @@ -0,0 +1,44 @@ +-- This script will enable collection enhancements for all organizations. + +-- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time +SELECT [Id] AS [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch +INTO #TempOrg +FROM [dbo].[Organization]; +-- WHERE [FlexibleCollections] = 0; + +-- Step 2: Get the maximum batch number +DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrg); +DECLARE @CurrentBatch INT = 0; + +-- Step 3: Process each batch +WHILE @CurrentBatch <= @MaxBatch +BEGIN + -- Execute the stored procedure for each OrganizationId in the current batch + DECLARE @OrganizationId UNIQUEIDENTIFIER; + + DECLARE OrgCursor CURSOR FOR + SELECT [OrganizationId] + FROM #TempOrg + WHERE [Batch] = @CurrentBatch; + + OPEN OrgCursor; + + FETCH NEXT FROM OrgCursor INTO @OrganizationId; + + WHILE @@FETCH_STATUS = 0 + BEGIN + -- Execute the stored procedure for the current OrganizationId + EXEC [dbo].[Organization_EnableCollectionEnhancements] @OrganizationId; + + FETCH NEXT FROM OrgCursor INTO @OrganizationId; + END; + + CLOSE OrgCursor; + DEALLOCATE OrgCursor; + + -- Move to the next batch + SET @CurrentBatch = @CurrentBatch + 1; +END; + +-- Step 4: Drop the temporary table +DROP TABLE #TempOrg; From 54cc6fab8f162448446eeb06822e44e97a2b6534 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Wed, 10 Jan 2024 15:29:48 +0000 Subject: [PATCH 05/16] =?UTF-8?q?[AC-1682]=C2=A0Deleted=20old=20data=20mig?= =?UTF-8?q?ration=20scripts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...023-12-06_00_AccessAllCollectionGroups.sql | 55 ------------- ...2023-12-06_01_AccessAllCollectionUsers.sql | 62 -------------- ...02_ManagersEditAssignedCollectionUsers.sql | 82 ------------------- 3 files changed, 199 deletions(-) delete mode 100644 util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql delete mode 100644 util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql delete mode 100644 util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql diff --git a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql deleted file mode 100644 index fe29bfe0b5..0000000000 --- a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql +++ /dev/null @@ -1,55 +0,0 @@ --- Step 1: Create a temporary table to store the Groups with AccessAll = 1 -SELECT [Id] AS [GroupId], [OrganizationId] -INTO #TempGroup -FROM [dbo].[Group] -WHERE [AccessAll] = 1; - --- Step 2: Update existing rows in [dbo].[CollectionGroup] -UPDATE CG -SET - CG.[ReadOnly] = 0, - CG.[HidePasswords] = 0, - CG.[Manage] = 0 - FROM [dbo].[CollectionGroup] CG -INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] -INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] -WHERE C.[OrganizationId] = TG.[OrganizationId]; - --- Step 3: Insert new rows into [dbo].[CollectionGroup] -INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) -SELECT C.[Id], TG.[GroupId], 0, 0, 0 -FROM [dbo].[Collection] C - INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] - LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] -WHERE CG.[CollectionId] IS NULL; - --- Step 4: Update [dbo].[Group] to clear AccessAll flag -UPDATE G -SET [AccessAll] = 0 -FROM [dbo].[Group] G -INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] - --- Step 5: Bump the account revision date for each unique OrganizationId in #TempGroup -DECLARE @OrganizationId UNIQUEIDENTIFIER - -DECLARE OrgIdCursor CURSOR FOR -SELECT DISTINCT [OrganizationId] -FROM #TempGroup - -OPEN OrgIdCursor -FETCH NEXT FROM OrgIdCursor INTO @OrganizationId - -WHILE (@@FETCH_STATUS = 0) -BEGIN - -- Execute the stored procedure for the current OrganizationId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId - - -- Fetch the next OrganizationId - FETCH NEXT FROM OrgIdCursor INTO @OrganizationId -END - -CLOSE OrgIdCursor -DEALLOCATE OrgIdCursor; - --- Step 6: Drop the temporary table -DROP TABLE #TempGroup; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql deleted file mode 100644 index 19b97a5ac5..0000000000 --- a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql +++ /dev/null @@ -1,62 +0,0 @@ --- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 -SELECT [Id] AS [OrganizationUserId], [OrganizationId] -INTO #TempOrgUser -FROM [dbo].[OrganizationUser] -WHERE [AccessAll] = 1; - --- Step 2: Update existing rows in [dbo].[CollectionUser] -UPDATE target -SET - target.[ReadOnly] = 0, - target.[HidePasswords] = 0, - target.[Manage] = 0 -FROM [dbo].[CollectionUser] AS target -INNER JOIN ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] -) AS source - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; - --- Step 3: Insert new rows into [dbo].[CollectionUser] -INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) -SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 -FROM ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source -LEFT JOIN [dbo].[CollectionUser] AS target - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] -WHERE target.[CollectionId] IS NULL; - --- Step 4: Update [dbo].[OrganizationUser] to clear AccessAll flag -UPDATE OU -SET [AccessAll] = 0 -FROM [dbo].[OrganizationUser] OU -INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] - --- Step 5: Bump the account revision date for each unique OrganizationId in #TempOrgUser -DECLARE @OrganizationId UNIQUEIDENTIFIER - -DECLARE OrgIdCursor CURSOR FOR -SELECT DISTINCT [OrganizationId] -FROM #TempOrgUser - -OPEN OrgIdCursor -FETCH NEXT FROM OrgIdCursor INTO @OrganizationId - -WHILE (@@FETCH_STATUS = 0) -BEGIN - -- Execute the stored procedure for the current OrganizationId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId - - -- Fetch the next OrganizationId - FETCH NEXT FROM OrgIdCursor INTO @OrganizationId -END - -CLOSE OrgIdCursor -DEALLOCATE OrgIdCursor; - --- Step 6: Drop the temporary table -DROP TABLE #TempOrgUser; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql deleted file mode 100644 index 736acd0f29..0000000000 --- a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql +++ /dev/null @@ -1,82 +0,0 @@ --- Step 1: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission - -- Store the results in a temporary table - SELECT ou.[Id] AS [OrganizationUserId] - INTO #TempStep1 - FROM [dbo].[OrganizationUser] ou - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND - ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); - - -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table - UPDATE cu - SET cu.[ReadOnly] = 0, - cu.[HidePasswords] = 0, - cu.[Manage] = 1 - FROM [dbo].[CollectionUser] cu - INNER JOIN #TempStep1 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; - --- Step 2: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access - -- Store the results in a temporary table - SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] - INTO #TempStep2 - FROM [dbo].[CollectionGroup] cg - INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId - INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - AND NOT EXISTS ( - SELECT 1 FROM [dbo].[CollectionUser] cu - WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] - ); - - -- Insert rows into [dbo].[CollectionUser] using the temporary table - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 - FROM #TempStep2; - --- Step 3: Set all Managers to Users - -- Store the results in a temporary table - SELECT [Id] AS [OrganizationUserId] - INTO #TempStep3 - FROM [dbo].[OrganizationUser] - WHERE [Type] = 3; -- Manager - - -- Update [dbo].[OrganizationUser] based on the temporary table - UPDATE ou - SET ou.[Type] = 2 -- User - FROM [dbo].[OrganizationUser] ou - INNER JOIN #TempStep3 temp ON ou.[Id] = temp.[OrganizationUserId]; - --- Step 4: Bump the account revision date for each unique OrganizationUserId in #TempStep1, #TempStep2, and #TempStep3 - -- Join the three temporary tables to get unique OrganizationUserId - SELECT DISTINCT temp1.[OrganizationUserId] - INTO #TempUniqueOrganizationUser - FROM #TempStep1 temp1 - JOIN #TempStep2 temp2 ON temp1.[OrganizationUserId] = temp2.[OrganizationUserId] - JOIN #TempStep3 temp3 ON temp1.[OrganizationUserId] = temp3.[OrganizationUserId]; - - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @OrganizationUserId UNIQUEIDENTIFIER - - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempUniqueOrganizationUser - - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @OrganizationUserId - - -- Fetch the next row - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId - END - - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; - --- Step 5: Clean up temporary tables -DROP TABLE #TempStep1; -DROP TABLE #TempStep2; -DROP TABLE #TempStep3; -DROP TABLE #TempUniqueOrganizationUser; From a214c60268847ee84e21606dc1c6a8dab4062082 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 11:55:16 +0000 Subject: [PATCH 06/16] =?UTF-8?q?Revert=20"[AC-1682]=C2=A0Deleted=20old=20?= =?UTF-8?q?data=20migration=20scripts"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 54cc6fab8f162448446eeb06822e44e97a2b6534. --- ...023-12-06_00_AccessAllCollectionGroups.sql | 55 +++++++++++++ ...2023-12-06_01_AccessAllCollectionUsers.sql | 62 ++++++++++++++ ...02_ManagersEditAssignedCollectionUsers.sql | 82 +++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql create mode 100644 util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql create mode 100644 util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql diff --git a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql new file mode 100644 index 0000000000..fe29bfe0b5 --- /dev/null +++ b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql @@ -0,0 +1,55 @@ +-- Step 1: Create a temporary table to store the Groups with AccessAll = 1 +SELECT [Id] AS [GroupId], [OrganizationId] +INTO #TempGroup +FROM [dbo].[Group] +WHERE [AccessAll] = 1; + +-- Step 2: Update existing rows in [dbo].[CollectionGroup] +UPDATE CG +SET + CG.[ReadOnly] = 0, + CG.[HidePasswords] = 0, + CG.[Manage] = 0 + FROM [dbo].[CollectionGroup] CG +INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] +INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] +WHERE C.[OrganizationId] = TG.[OrganizationId]; + +-- Step 3: Insert new rows into [dbo].[CollectionGroup] +INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) +SELECT C.[Id], TG.[GroupId], 0, 0, 0 +FROM [dbo].[Collection] C + INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] + LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] +WHERE CG.[CollectionId] IS NULL; + +-- Step 4: Update [dbo].[Group] to clear AccessAll flag +UPDATE G +SET [AccessAll] = 0 +FROM [dbo].[Group] G +INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + +-- Step 5: Bump the account revision date for each unique OrganizationId in #TempGroup +DECLARE @OrganizationId UNIQUEIDENTIFIER + +DECLARE OrgIdCursor CURSOR FOR +SELECT DISTINCT [OrganizationId] +FROM #TempGroup + +OPEN OrgIdCursor +FETCH NEXT FROM OrgIdCursor INTO @OrganizationId + +WHILE (@@FETCH_STATUS = 0) +BEGIN + -- Execute the stored procedure for the current OrganizationId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + + -- Fetch the next OrganizationId + FETCH NEXT FROM OrgIdCursor INTO @OrganizationId +END + +CLOSE OrgIdCursor +DEALLOCATE OrgIdCursor; + +-- Step 6: Drop the temporary table +DROP TABLE #TempGroup; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql new file mode 100644 index 0000000000..19b97a5ac5 --- /dev/null +++ b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql @@ -0,0 +1,62 @@ +-- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 +SELECT [Id] AS [OrganizationUserId], [OrganizationId] +INTO #TempOrgUser +FROM [dbo].[OrganizationUser] +WHERE [AccessAll] = 1; + +-- Step 2: Update existing rows in [dbo].[CollectionUser] +UPDATE target +SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 +FROM [dbo].[CollectionUser] AS target +INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] +) AS source + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; + +-- Step 3: Insert new rows into [dbo].[CollectionUser] +INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) +SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 +FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source +LEFT JOIN [dbo].[CollectionUser] AS target + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] +WHERE target.[CollectionId] IS NULL; + +-- Step 4: Update [dbo].[OrganizationUser] to clear AccessAll flag +UPDATE OU +SET [AccessAll] = 0 +FROM [dbo].[OrganizationUser] OU +INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] + +-- Step 5: Bump the account revision date for each unique OrganizationId in #TempOrgUser +DECLARE @OrganizationId UNIQUEIDENTIFIER + +DECLARE OrgIdCursor CURSOR FOR +SELECT DISTINCT [OrganizationId] +FROM #TempOrgUser + +OPEN OrgIdCursor +FETCH NEXT FROM OrgIdCursor INTO @OrganizationId + +WHILE (@@FETCH_STATUS = 0) +BEGIN + -- Execute the stored procedure for the current OrganizationId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + + -- Fetch the next OrganizationId + FETCH NEXT FROM OrgIdCursor INTO @OrganizationId +END + +CLOSE OrgIdCursor +DEALLOCATE OrgIdCursor; + +-- Step 6: Drop the temporary table +DROP TABLE #TempOrgUser; diff --git a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql new file mode 100644 index 0000000000..736acd0f29 --- /dev/null +++ b/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql @@ -0,0 +1,82 @@ +-- Step 1: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission + -- Store the results in a temporary table + SELECT ou.[Id] AS [OrganizationUserId] + INTO #TempStep1 + FROM [dbo].[OrganizationUser] ou + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND + ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); + + -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table + UPDATE cu + SET cu.[ReadOnly] = 0, + cu.[HidePasswords] = 0, + cu.[Manage] = 1 + FROM [dbo].[CollectionUser] cu + INNER JOIN #TempStep1 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; + +-- Step 2: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access + -- Store the results in a temporary table + SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] + INTO #TempStep2 + FROM [dbo].[CollectionGroup] cg + INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ); + + -- Insert rows into [dbo].[CollectionUser] using the temporary table + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 + FROM #TempStep2; + +-- Step 3: Set all Managers to Users + -- Store the results in a temporary table + SELECT [Id] AS [OrganizationUserId] + INTO #TempStep3 + FROM [dbo].[OrganizationUser] + WHERE [Type] = 3; -- Manager + + -- Update [dbo].[OrganizationUser] based on the temporary table + UPDATE ou + SET ou.[Type] = 2 -- User + FROM [dbo].[OrganizationUser] ou + INNER JOIN #TempStep3 temp ON ou.[Id] = temp.[OrganizationUserId]; + +-- Step 4: Bump the account revision date for each unique OrganizationUserId in #TempStep1, #TempStep2, and #TempStep3 + -- Join the three temporary tables to get unique OrganizationUserId + SELECT DISTINCT temp1.[OrganizationUserId] + INTO #TempUniqueOrganizationUser + FROM #TempStep1 temp1 + JOIN #TempStep2 temp2 ON temp1.[OrganizationUserId] = temp2.[OrganizationUserId] + JOIN #TempStep3 temp3 ON temp1.[OrganizationUserId] = temp3.[OrganizationUserId]; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempUniqueOrganizationUser + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + +-- Step 5: Clean up temporary tables +DROP TABLE #TempStep1; +DROP TABLE #TempStep2; +DROP TABLE #TempStep3; +DROP TABLE #TempUniqueOrganizationUser; From ee43767c84cbb0457a2744fddbbc9b9696f0d8a7 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 12:15:36 +0000 Subject: [PATCH 07/16] [AC-1682] Modified AccessAllCollectionUsers script to bump revision date by each OrgUser --- ...2023-12-06_01_AccessAllCollectionUsers.sql | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql index 19b97a5ac5..7b663d1bac 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql @@ -36,27 +36,27 @@ SET [AccessAll] = 0 FROM [dbo].[OrganizationUser] OU INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] --- Step 5: Bump the account revision date for each unique OrganizationId in #TempOrgUser -DECLARE @OrganizationId UNIQUEIDENTIFIER +-- Step 5: Bump the account revision date for each unique OrganizationUserId in #TempOrgUser +DECLARE @OrganizationUserId UNIQUEIDENTIFIER -DECLARE OrgIdCursor CURSOR FOR -SELECT DISTINCT [OrganizationId] +DECLARE OrgUserIdCursor CURSOR FOR +SELECT DISTINCT [OrganizationUserId] FROM #TempOrgUser -OPEN OrgIdCursor -FETCH NEXT FROM OrgIdCursor INTO @OrganizationId +OPEN OrgUserIdCursor +FETCH NEXT FROM OrgUserIdCursor INTO @OrganizationUserId WHILE (@@FETCH_STATUS = 0) BEGIN - -- Execute the stored procedure for the current OrganizationId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @OrganizationUserId - -- Fetch the next OrganizationId - FETCH NEXT FROM OrgIdCursor INTO @OrganizationId + -- Fetch the next OrganizationUserId + FETCH NEXT FROM OrgUserIdCursor INTO @OrganizationUserId END -CLOSE OrgIdCursor -DEALLOCATE OrgIdCursor; +CLOSE OrgUserIdCursor +DEALLOCATE OrgUserIdCursor; -- Step 6: Drop the temporary table DROP TABLE #TempOrgUser; From f4450c082c6e2a79940703a29a73c76cbdeba73b Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 13:04:03 +0000 Subject: [PATCH 08/16] [AC-1682] Update data migration script to only enable collection enhancements for organizations that have not yet migrated --- .../2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql b/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql index fe37747760..fa555ee01f 100644 --- a/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql +++ b/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql @@ -1,10 +1,10 @@ --- This script will enable collection enhancements for all organizations. +-- This script will enable collection enhancements for all organizations that have not yet migrated. -- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time SELECT [Id] AS [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch INTO #TempOrg -FROM [dbo].[Organization]; --- WHERE [FlexibleCollections] = 0; +FROM [dbo].[Organization] +WHERE [FlexibleCollections] = 0; -- Step 2: Get the maximum batch number DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrg); @@ -25,7 +25,7 @@ BEGIN FETCH NEXT FROM OrgCursor INTO @OrganizationId; - WHILE @@FETCH_STATUS = 0 + WHILE (@@FETCH_STATUS = 0) BEGIN -- Execute the stored procedure for the current OrganizationId EXEC [dbo].[Organization_EnableCollectionEnhancements] @OrganizationId; From 8cc889554d415e926212b4b6f2cca71afa6ce1c0 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 13:58:45 +0000 Subject: [PATCH 09/16] [AC-1682] Updated AccessAllCollectionGroups migration script to use User_BumpAccountRevisionDateByCollectionId --- ...023-12-06_00_AccessAllCollectionGroups.sql | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql index fe29bfe0b5..e2dcb8dbd9 100644 --- a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql +++ b/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql @@ -29,27 +29,29 @@ SET [AccessAll] = 0 FROM [dbo].[Group] G INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] --- Step 5: Bump the account revision date for each unique OrganizationId in #TempGroup +-- Step 5: Bump the account revision date for each unique CollectionId and OrganizationId +DECLARE @CollectionId UNIQUEIDENTIFIER DECLARE @OrganizationId UNIQUEIDENTIFIER -DECLARE OrgIdCursor CURSOR FOR -SELECT DISTINCT [OrganizationId] -FROM #TempGroup +DECLARE CollectionIdCursor CURSOR FOR +SELECT DISTINCT C.[Id], C.[OrganizationId] +FROM [dbo].[Collection] C +INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] -OPEN OrgIdCursor -FETCH NEXT FROM OrgIdCursor INTO @OrganizationId +OPEN CollectionIdCursor +FETCH NEXT FROM CollectionIdCursor INTO @CollectionId, @OrganizationId WHILE (@@FETCH_STATUS = 0) BEGIN - -- Execute the stored procedure for the current OrganizationId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + -- Execute the stored procedure for the current CollectionId and OrganizationId + EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @CollectionId, @OrganizationId - -- Fetch the next OrganizationId - FETCH NEXT FROM OrgIdCursor INTO @OrganizationId + -- Fetch the next CollectionId and OrganizationId + FETCH NEXT FROM CollectionIdCursor INTO @CollectionId, @OrganizationId END -CLOSE OrgIdCursor -DEALLOCATE OrgIdCursor; +CLOSE CollectionIdCursor +DEALLOCATE CollectionIdCursor; -- Step 6: Drop the temporary table DROP TABLE #TempGroup; From 8a5ea76d8d9ab357f8b5c590a8b7159a9b1313cd Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 14:04:51 +0000 Subject: [PATCH 10/16] [AC-1682] Bumped up the date on data migration scripts --- ...roups.sql => 2024-01-10_00_AccessAllCollectionGroups.sql} | 0 ...nUsers.sql => 2024-01-10_01_AccessAllCollectionUsers.sql} | 0 ...=> 2024-01-10_02_ManagersEditAssignedCollectionUsers.sql} | 0 ...=> 2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql} | 5 +++++ 4 files changed, 5 insertions(+) rename util/Migrator/DbScripts_transition/{2023-12-06_00_AccessAllCollectionGroups.sql => 2024-01-10_00_AccessAllCollectionGroups.sql} (100%) rename util/Migrator/DbScripts_transition/{2023-12-06_01_AccessAllCollectionUsers.sql => 2024-01-10_01_AccessAllCollectionUsers.sql} (100%) rename util/Migrator/DbScripts_transition/{2023-12-06_02_ManagersEditAssignedCollectionUsers.sql => 2024-01-10_02_ManagersEditAssignedCollectionUsers.sql} (100%) rename util/Migrator/DbScripts_transition/{2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql => 2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql} (88%) diff --git a/util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql b/util/Migrator/DbScripts_transition/2024-01-10_00_AccessAllCollectionGroups.sql similarity index 100% rename from util/Migrator/DbScripts_transition/2023-12-06_00_AccessAllCollectionGroups.sql rename to util/Migrator/DbScripts_transition/2024-01-10_00_AccessAllCollectionGroups.sql diff --git a/util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql similarity index 100% rename from util/Migrator/DbScripts_transition/2023-12-06_01_AccessAllCollectionUsers.sql rename to util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql diff --git a/util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql b/util/Migrator/DbScripts_transition/2024-01-10_02_ManagersEditAssignedCollectionUsers.sql similarity index 100% rename from util/Migrator/DbScripts_transition/2023-12-06_02_ManagersEditAssignedCollectionUsers.sql rename to util/Migrator/DbScripts_transition/2024-01-10_02_ManagersEditAssignedCollectionUsers.sql diff --git a/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql b/util/Migrator/DbScripts_transition/2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql similarity index 88% rename from util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql rename to util/Migrator/DbScripts_transition/2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql index fa555ee01f..1df22f2b26 100644 --- a/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql +++ b/util/Migrator/DbScripts_transition/2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql @@ -30,6 +30,11 @@ BEGIN -- Execute the stored procedure for the current OrganizationId EXEC [dbo].[Organization_EnableCollectionEnhancements] @OrganizationId; + -- Update the Organization to set FlexibleCollections = 1 + UPDATE [dbo].[Organization] + SET [FlexibleCollections] = 1 + WHERE [Id] = @OrganizationId; + FETCH NEXT FROM OrgCursor INTO @OrganizationId; END; From 68c586f3c769660baa4eccbab26209549107397c Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 14:40:29 +0000 Subject: [PATCH 11/16] [AC-1682] Added back batching system to AccessAllCollectionUsers data migration script --- ...2024-01-10_01_AccessAllCollectionUsers.sql | 59 +++++++++++-------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql index 7b663d1bac..ac1b81726e 100644 --- a/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql +++ b/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql @@ -1,34 +1,45 @@ --- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 -SELECT [Id] AS [OrganizationUserId], [OrganizationId] +-- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time +SELECT [Id] AS [OrganizationUserId], [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch INTO #TempOrgUser FROM [dbo].[OrganizationUser] WHERE [AccessAll] = 1; --- Step 2: Update existing rows in [dbo].[CollectionUser] -UPDATE target -SET - target.[ReadOnly] = 0, - target.[HidePasswords] = 0, - target.[Manage] = 0 -FROM [dbo].[CollectionUser] AS target -INNER JOIN ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] -) AS source +-- Step 2: Get the maximum batch number +DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrgUser); +DECLARE @CurrentBatch INT = 0; + +-- Step 3: Process each batch +WHILE @CurrentBatch <= @MaxBatch +BEGIN + -- Update existing rows in [dbo].[CollectionUser] + UPDATE target + SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 + FROM [dbo].[CollectionUser] AS target + INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] AND T.Batch = @CurrentBatch + ) AS source ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; --- Step 3: Insert new rows into [dbo].[CollectionUser] -INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) -SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 -FROM ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source -LEFT JOIN [dbo].[CollectionUser] AS target + -- Insert new rows into [dbo].[CollectionUser] + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 + FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] AND T.Batch = @CurrentBatch + ) AS source + LEFT JOIN [dbo].[CollectionUser] AS target ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] -WHERE target.[CollectionId] IS NULL; + WHERE target.[CollectionId] IS NULL; + + -- Move to the next batch + SET @CurrentBatch = @CurrentBatch + 1; +END; -- Step 4: Update [dbo].[OrganizationUser] to clear AccessAll flag UPDATE OU From ba060765770f90ba599836aea41606346b864c28 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 14:41:16 +0000 Subject: [PATCH 12/16] [AC-1682] Added data migration script to set FlexibleCollections = 1 for all orgs --- ...01-10_03_EnableOrgsFlexibleCollections.sql | 28 +++++++++++++++++++ ...4_AllOrgsEnableCollectionEnhancements.sql} | 0 2 files changed, 28 insertions(+) create mode 100644 util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql rename util/Migrator/DbScripts_transition/{2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql => 2024-01-10_04_AllOrgsEnableCollectionEnhancements.sql} (100%) diff --git a/util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql b/util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql new file mode 100644 index 0000000000..061f9a2af9 --- /dev/null +++ b/util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql @@ -0,0 +1,28 @@ +-- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time +SELECT [Id] AS [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch +INTO #TempOrg +FROM [dbo].[Organization] +WHERE [FlexibleCollections] = 0; + +-- Step 2: Get the maximum batch number +DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrg); +DECLARE @CurrentBatch INT = 0; + +-- Step 3: Process each batch +WHILE @CurrentBatch <= @MaxBatch +BEGIN + -- Update existing rows in [dbo].[CollectionUser] + UPDATE target + SET + target.[FlexibleCollections] = 1 + FROM [dbo].[Organization] AS target + INNER JOIN #TempOrg AS source + ON target.[Id] = source.[OrganizationId] + WHERE source.[Batch] = @CurrentBatch; + + -- Move to the next batch + SET @CurrentBatch = @CurrentBatch + 1; +END; + +-- Step 4: Drop the temporary table +DROP TABLE #TempOrg; diff --git a/util/Migrator/DbScripts_transition/2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql b/util/Migrator/DbScripts_transition/2024-01-10_04_AllOrgsEnableCollectionEnhancements.sql similarity index 100% rename from util/Migrator/DbScripts_transition/2024-01-10_03_AllOrgsEnableCollectionEnhancements.sql rename to util/Migrator/DbScripts_transition/2024-01-10_04_AllOrgsEnableCollectionEnhancements.sql From f78e28f037d978e77d3b2c1b82cd77c9891dfc11 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 16:42:30 +0000 Subject: [PATCH 13/16] [AC-1682] Modified data migration script to contain multiple transactions --- ...anization_EnableCollectionEnhancements.sql | 227 +++++++++++-- ...anization_EnableCollectionEnhancements.sql | 132 -------- ...anization_EnableCollectionEnhancements.sql | 299 ++++++++++++++++++ 3 files changed, 496 insertions(+), 162 deletions(-) delete mode 100644 util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql create mode 100644 util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql diff --git a/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql b/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql index 926d8eac45..30ad54131f 100644 --- a/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql +++ b/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql @@ -4,9 +4,9 @@ AS BEGIN SET NOCOUNT ON + -- Step 1: AccessAll migration for Groups BEGIN TRY BEGIN TRANSACTION; - -- Step 1: AccessAll migration for Groups -- Create a temporary table to store the groups with AccessAll = 1 SELECT [Id] AS [GroupId], [OrganizationId] INTO #TempGroup @@ -39,11 +39,48 @@ BEGIN FROM [dbo].[Group] G INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + -- Create a temporary table to store distinct OrganizationUserIds + SELECT DISTINCT GU.[OrganizationUserId] + INTO #TempOrganizationUsers + FROM [dbo].[GroupUser] GU + JOIN #TempGroup TG ON GU.[GroupId] = TG.[GroupId]; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step1OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempOrganizationUsers + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step1OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + -- Drop the temporary table DROP TABLE #TempGroup; + DROP TABLE #TempOrganizationUsers; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; - -- Step 2: AccessAll migration for users - -- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 + -- Step 2: AccessAll migration for users + BEGIN TRY + BEGIN TRANSACTION; + -- Create a temporary table to store the OrganizationUsers with AccessAll = 1 SELECT [Id] AS [OrganizationUserId], [OrganizationId] INTO #TempOrgUser FROM [dbo].[OrganizationUser] @@ -82,46 +119,176 @@ BEGIN FROM [dbo].[OrganizationUser] OU INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step2OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempOrgUser + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step2OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + -- Drop the temporary table DROP TABLE #TempOrgUser; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; - -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission + -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission + BEGIN TRY + BEGIN TRANSACTION; + -- Store the results in a temporary table + SELECT ou.[Id] AS [OrganizationUserId] + INTO #TempStep3 + FROM [dbo].[OrganizationUser] ou + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND + ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); + + -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table UPDATE cu SET cu.[ReadOnly] = 0, cu.[HidePasswords] = 0, cu.[Manage] = 1 FROM [dbo].[CollectionUser] cu - INNER JOIN [dbo].[OrganizationUser] ou - ON cu.[OrganizationUserId] = ou.[Id] - WHERE ou.[OrganizationId] = @OrganizationId - AND (ou.[Type] = 3 - OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + INNER JOIN #TempStep3 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; - -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT cg.[CollectionId], ou.[Id], 0, 0, 1 + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step3OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep3 + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step3OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempStep3; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access + BEGIN TRY + BEGIN TRANSACTION; + -- Store the results in a temporary table + SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] + INTO #TempStep4 FROM [dbo].[CollectionGroup] cg - INNER JOIN [dbo].[GroupUser] gu - ON cg.GroupId = gu.GroupId - INNER JOIN [dbo].[OrganizationUser] ou - ON gu.OrganizationUserId = ou.[Id] - WHERE ou.[OrganizationId] = @OrganizationId - AND (ou.[Type] = 3 - OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - AND NOT EXISTS ( - SELECT 1 FROM [dbo].[CollectionUser] cu - WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] - ) + INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ); - -- Step 5: Set all Managers to Users - UPDATE [dbo].[OrganizationUser] - SET [Type] = 2 -- User - WHERE [OrganizationId] = @OrganizationId - AND [Type] = 3; -- Manager + -- Insert rows into [dbo].[CollectionUser] using the temporary table + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 + FROM #TempStep4; - -- Step 6: Bump the account revision dates for all users in the organization - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step4OrganizationUserId UNIQUEIDENTIFIER + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempStep4 + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step4OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempStep4; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Step 5: Set all Managers to Users + BEGIN TRY + BEGIN TRANSACTION; + -- Store the results in a temporary table + SELECT [Id] AS [OrganizationUserId] + INTO #TempStep5 + FROM [dbo].[OrganizationUser] + WHERE [Type] = 3; -- Manager + + -- Update [dbo].[OrganizationUser] based on the temporary table + UPDATE ou + SET ou.[Type] = 2 -- User + FROM [dbo].[OrganizationUser] ou + INNER JOIN #TempStep5 temp ON ou.[Id] = temp.[OrganizationUserId]; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step5OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep5 + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step5OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempStep5; COMMIT TRANSACTION; END TRY BEGIN CATCH diff --git a/util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql b/util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql deleted file mode 100644 index b59b63176d..0000000000 --- a/util/Migrator/DbScripts/2024-01-10_00_Organization_EnableCollectionEnhancements.sql +++ /dev/null @@ -1,132 +0,0 @@ -CREATE OR ALTER PROCEDURE [dbo].[Organization_EnableCollectionEnhancements] - @OrganizationId UNIQUEIDENTIFIER -AS -BEGIN - SET NOCOUNT ON - - BEGIN TRY - BEGIN TRANSACTION; - -- Step 1: AccessAll migration for Groups - -- Create a temporary table to store the groups with AccessAll = 1 - SELECT [Id] AS [GroupId], [OrganizationId] - INTO #TempGroup - FROM [dbo].[Group] - WHERE [AccessAll] = 1 - AND [OrganizationId] = @OrganizationId; - - -- Update existing rows in [dbo].[CollectionGroup] - UPDATE CG - SET - CG.[ReadOnly] = 0, - CG.[HidePasswords] = 0, - CG.[Manage] = 0 - FROM [dbo].[CollectionGroup] CG - INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] - INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] - WHERE C.[OrganizationId] = TG.[OrganizationId]; - - -- Insert new rows into [dbo].[CollectionGroup] - INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) - SELECT C.[Id], TG.[GroupId], 0, 0, 0 - FROM [dbo].[Collection] C - INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] - LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] - WHERE CG.[CollectionId] IS NULL; - - -- Update Group to clear AccessAll flag - UPDATE G - SET [AccessAll] = 0 - FROM [dbo].[Group] G - INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] - - -- Drop the temporary table - DROP TABLE #TempGroup; - - -- Step 2: AccessAll migration for users - -- Step 1: Create a temporary table to store the OrganizationUsers with AccessAll = 1 - SELECT [Id] AS [OrganizationUserId], [OrganizationId] - INTO #TempOrgUser - FROM [dbo].[OrganizationUser] - WHERE [AccessAll] = 1 - AND [OrganizationId] = @OrganizationId; - - -- Update existing rows in [dbo].[CollectionUser] - UPDATE target - SET - target.[ReadOnly] = 0, - target.[HidePasswords] = 0, - target.[Manage] = 0 - FROM [dbo].[CollectionUser] AS target - INNER JOIN ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; - - -- Insert new rows into [dbo].[CollectionUser] - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 - FROM ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source - LEFT JOIN [dbo].[CollectionUser] AS target - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] - WHERE target.[CollectionId] IS NULL; - - -- Update OrganizationUser to clear AccessAll flag - UPDATE OU - SET [AccessAll] = 0 - FROM [dbo].[OrganizationUser] OU - INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] - - -- Drop the temporary table - DROP TABLE #TempOrgUser; - - -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission - UPDATE cu - SET cu.[ReadOnly] = 0, - cu.[HidePasswords] = 0, - cu.[Manage] = 1 - FROM [dbo].[CollectionUser] cu - INNER JOIN [dbo].[OrganizationUser] ou - ON cu.[OrganizationUserId] = ou.[Id] - WHERE ou.[OrganizationId] = @OrganizationId - AND (ou.[Type] = 3 - OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - - -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT cg.[CollectionId], ou.[Id], 0, 0, 1 - FROM [dbo].[CollectionGroup] cg - INNER JOIN [dbo].[GroupUser] gu - ON cg.GroupId = gu.GroupId - INNER JOIN [dbo].[OrganizationUser] ou - ON gu.OrganizationUserId = ou.[Id] - WHERE ou.[OrganizationId] = @OrganizationId - AND (ou.[Type] = 3 - OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - AND NOT EXISTS ( - SELECT 1 FROM [dbo].[CollectionUser] cu - WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] - ) - - -- Step 5: Set all Managers to Users - UPDATE [dbo].[OrganizationUser] - SET [Type] = 2 -- User - WHERE [OrganizationId] = @OrganizationId - AND [Type] = 3; -- Manager - - -- Step 6: Bump the account revision dates for all users in the organization - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId - - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; -END -GO diff --git a/util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql b/util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql new file mode 100644 index 0000000000..47c0458997 --- /dev/null +++ b/util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql @@ -0,0 +1,299 @@ +CREATE OR ALTER PROCEDURE [dbo].[Organization_EnableCollectionEnhancements] + @OrganizationId UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + -- Step 1: AccessAll migration for Groups + BEGIN TRY + BEGIN TRANSACTION; + -- Create a temporary table to store the groups with AccessAll = 1 + SELECT [Id] AS [GroupId], [OrganizationId] + INTO #TempGroup + FROM [dbo].[Group] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; + + -- Update existing rows in [dbo].[CollectionGroup] + UPDATE CG + SET + CG.[ReadOnly] = 0, + CG.[HidePasswords] = 0, + CG.[Manage] = 0 + FROM [dbo].[CollectionGroup] CG + INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] + INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] + WHERE C.[OrganizationId] = TG.[OrganizationId]; + + -- Insert new rows into [dbo].[CollectionGroup] + INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) + SELECT C.[Id], TG.[GroupId], 0, 0, 0 + FROM [dbo].[Collection] C + INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] + LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] + WHERE CG.[CollectionId] IS NULL; + + -- Update Group to clear AccessAll flag + UPDATE G + SET [AccessAll] = 0 + FROM [dbo].[Group] G + INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + + -- Create a temporary table to store distinct OrganizationUserIds + SELECT DISTINCT GU.[OrganizationUserId] + INTO #TempOrganizationUsers + FROM [dbo].[GroupUser] GU + JOIN #TempGroup TG ON GU.[GroupId] = TG.[GroupId]; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step1OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempOrganizationUsers + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step1OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempGroup; + DROP TABLE #TempOrganizationUsers; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Step 2: AccessAll migration for users + BEGIN TRY + BEGIN TRANSACTION; + -- Create a temporary table to store the OrganizationUsers with AccessAll = 1 + SELECT [Id] AS [OrganizationUserId], [OrganizationId] + INTO #TempOrgUser + FROM [dbo].[OrganizationUser] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; + + -- Update existing rows in [dbo].[CollectionUser] + UPDATE target + SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 + FROM [dbo].[CollectionUser] AS target + INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; + + -- Insert new rows into [dbo].[CollectionUser] + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 + FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + LEFT JOIN [dbo].[CollectionUser] AS target + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] + WHERE target.[CollectionId] IS NULL; + + -- Update OrganizationUser to clear AccessAll flag + UPDATE OU + SET [AccessAll] = 0 + FROM [dbo].[OrganizationUser] OU + INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step2OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempOrgUser + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step2OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempOrgUser; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission + BEGIN TRY + BEGIN TRANSACTION; + -- Store the results in a temporary table + SELECT ou.[Id] AS [OrganizationUserId] + INTO #TempStep3 + FROM [dbo].[OrganizationUser] ou + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND + ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); + + -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table + UPDATE cu + SET cu.[ReadOnly] = 0, + cu.[HidePasswords] = 0, + cu.[Manage] = 1 + FROM [dbo].[CollectionUser] cu + INNER JOIN #TempStep3 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step3OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep3 + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step3OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempStep3; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access + BEGIN TRY + BEGIN TRANSACTION; + -- Store the results in a temporary table + SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] + INTO #TempStep4 + FROM [dbo].[CollectionGroup] cg + INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ); + + -- Insert rows into [dbo].[CollectionUser] using the temporary table + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 + FROM #TempStep4; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step4OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempStep4 + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step4OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempStep4; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Step 5: Set all Managers to Users + BEGIN TRY + BEGIN TRANSACTION; + -- Store the results in a temporary table + SELECT [Id] AS [OrganizationUserId] + INTO #TempStep5 + FROM [dbo].[OrganizationUser] + WHERE [Type] = 3; -- Manager + + -- Update [dbo].[OrganizationUser] based on the temporary table + UPDATE ou + SET ou.[Type] = 2 -- User + FROM [dbo].[OrganizationUser] ou + INNER JOIN #TempStep5 temp ON ou.[Id] = temp.[OrganizationUserId]; + + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step5OrganizationUserId UNIQUEIDENTIFIER + + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep5 + + OPEN UniqueOrgUserIdCursor + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId + + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step5OrganizationUserId + + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + + -- Drop the temporary table + DROP TABLE #TempStep5; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; +END +GO From 3bf1b53536d2b52d04593ffcd8d6f676c58c9be1 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 17:43:39 +0000 Subject: [PATCH 14/16] [AC-1682] Deleted old data migration scripts --- ...024-01-10_00_AccessAllCollectionGroups.sql | 57 ------------- ...0_AllOrgsEnableCollectionEnhancements.sql} | 0 ...2024-01-10_01_AccessAllCollectionUsers.sql | 73 ----------------- ...02_ManagersEditAssignedCollectionUsers.sql | 82 ------------------- ...01-10_03_EnableOrgsFlexibleCollections.sql | 28 ------- 5 files changed, 240 deletions(-) delete mode 100644 util/Migrator/DbScripts_transition/2024-01-10_00_AccessAllCollectionGroups.sql rename util/Migrator/DbScripts_transition/{2024-01-10_04_AllOrgsEnableCollectionEnhancements.sql => 2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql} (100%) delete mode 100644 util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql delete mode 100644 util/Migrator/DbScripts_transition/2024-01-10_02_ManagersEditAssignedCollectionUsers.sql delete mode 100644 util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql diff --git a/util/Migrator/DbScripts_transition/2024-01-10_00_AccessAllCollectionGroups.sql b/util/Migrator/DbScripts_transition/2024-01-10_00_AccessAllCollectionGroups.sql deleted file mode 100644 index e2dcb8dbd9..0000000000 --- a/util/Migrator/DbScripts_transition/2024-01-10_00_AccessAllCollectionGroups.sql +++ /dev/null @@ -1,57 +0,0 @@ --- Step 1: Create a temporary table to store the Groups with AccessAll = 1 -SELECT [Id] AS [GroupId], [OrganizationId] -INTO #TempGroup -FROM [dbo].[Group] -WHERE [AccessAll] = 1; - --- Step 2: Update existing rows in [dbo].[CollectionGroup] -UPDATE CG -SET - CG.[ReadOnly] = 0, - CG.[HidePasswords] = 0, - CG.[Manage] = 0 - FROM [dbo].[CollectionGroup] CG -INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] -INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] -WHERE C.[OrganizationId] = TG.[OrganizationId]; - --- Step 3: Insert new rows into [dbo].[CollectionGroup] -INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) -SELECT C.[Id], TG.[GroupId], 0, 0, 0 -FROM [dbo].[Collection] C - INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] - LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] -WHERE CG.[CollectionId] IS NULL; - --- Step 4: Update [dbo].[Group] to clear AccessAll flag -UPDATE G -SET [AccessAll] = 0 -FROM [dbo].[Group] G -INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] - --- Step 5: Bump the account revision date for each unique CollectionId and OrganizationId -DECLARE @CollectionId UNIQUEIDENTIFIER -DECLARE @OrganizationId UNIQUEIDENTIFIER - -DECLARE CollectionIdCursor CURSOR FOR -SELECT DISTINCT C.[Id], C.[OrganizationId] -FROM [dbo].[Collection] C -INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] - -OPEN CollectionIdCursor -FETCH NEXT FROM CollectionIdCursor INTO @CollectionId, @OrganizationId - -WHILE (@@FETCH_STATUS = 0) -BEGIN - -- Execute the stored procedure for the current CollectionId and OrganizationId - EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @CollectionId, @OrganizationId - - -- Fetch the next CollectionId and OrganizationId - FETCH NEXT FROM CollectionIdCursor INTO @CollectionId, @OrganizationId -END - -CLOSE CollectionIdCursor -DEALLOCATE CollectionIdCursor; - --- Step 6: Drop the temporary table -DROP TABLE #TempGroup; diff --git a/util/Migrator/DbScripts_transition/2024-01-10_04_AllOrgsEnableCollectionEnhancements.sql b/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql similarity index 100% rename from util/Migrator/DbScripts_transition/2024-01-10_04_AllOrgsEnableCollectionEnhancements.sql rename to util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql diff --git a/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql b/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql deleted file mode 100644 index ac1b81726e..0000000000 --- a/util/Migrator/DbScripts_transition/2024-01-10_01_AccessAllCollectionUsers.sql +++ /dev/null @@ -1,73 +0,0 @@ --- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time -SELECT [Id] AS [OrganizationUserId], [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch -INTO #TempOrgUser -FROM [dbo].[OrganizationUser] -WHERE [AccessAll] = 1; - --- Step 2: Get the maximum batch number -DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrgUser); -DECLARE @CurrentBatch INT = 0; - --- Step 3: Process each batch -WHILE @CurrentBatch <= @MaxBatch -BEGIN - -- Update existing rows in [dbo].[CollectionUser] - UPDATE target - SET - target.[ReadOnly] = 0, - target.[HidePasswords] = 0, - target.[Manage] = 0 - FROM [dbo].[CollectionUser] AS target - INNER JOIN ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] AND T.Batch = @CurrentBatch - ) AS source - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; - - -- Insert new rows into [dbo].[CollectionUser] - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 - FROM ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] AND T.Batch = @CurrentBatch - ) AS source - LEFT JOIN [dbo].[CollectionUser] AS target - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] - WHERE target.[CollectionId] IS NULL; - - -- Move to the next batch - SET @CurrentBatch = @CurrentBatch + 1; -END; - --- Step 4: Update [dbo].[OrganizationUser] to clear AccessAll flag -UPDATE OU -SET [AccessAll] = 0 -FROM [dbo].[OrganizationUser] OU -INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] - --- Step 5: Bump the account revision date for each unique OrganizationUserId in #TempOrgUser -DECLARE @OrganizationUserId UNIQUEIDENTIFIER - -DECLARE OrgUserIdCursor CURSOR FOR -SELECT DISTINCT [OrganizationUserId] -FROM #TempOrgUser - -OPEN OrgUserIdCursor -FETCH NEXT FROM OrgUserIdCursor INTO @OrganizationUserId - -WHILE (@@FETCH_STATUS = 0) -BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @OrganizationUserId - - -- Fetch the next OrganizationUserId - FETCH NEXT FROM OrgUserIdCursor INTO @OrganizationUserId -END - -CLOSE OrgUserIdCursor -DEALLOCATE OrgUserIdCursor; - --- Step 6: Drop the temporary table -DROP TABLE #TempOrgUser; diff --git a/util/Migrator/DbScripts_transition/2024-01-10_02_ManagersEditAssignedCollectionUsers.sql b/util/Migrator/DbScripts_transition/2024-01-10_02_ManagersEditAssignedCollectionUsers.sql deleted file mode 100644 index 736acd0f29..0000000000 --- a/util/Migrator/DbScripts_transition/2024-01-10_02_ManagersEditAssignedCollectionUsers.sql +++ /dev/null @@ -1,82 +0,0 @@ --- Step 1: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission - -- Store the results in a temporary table - SELECT ou.[Id] AS [OrganizationUserId] - INTO #TempStep1 - FROM [dbo].[OrganizationUser] ou - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND - ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); - - -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table - UPDATE cu - SET cu.[ReadOnly] = 0, - cu.[HidePasswords] = 0, - cu.[Manage] = 1 - FROM [dbo].[CollectionUser] cu - INNER JOIN #TempStep1 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; - --- Step 2: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access - -- Store the results in a temporary table - SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] - INTO #TempStep2 - FROM [dbo].[CollectionGroup] cg - INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId - INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - AND NOT EXISTS ( - SELECT 1 FROM [dbo].[CollectionUser] cu - WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] - ); - - -- Insert rows into [dbo].[CollectionUser] using the temporary table - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 - FROM #TempStep2; - --- Step 3: Set all Managers to Users - -- Store the results in a temporary table - SELECT [Id] AS [OrganizationUserId] - INTO #TempStep3 - FROM [dbo].[OrganizationUser] - WHERE [Type] = 3; -- Manager - - -- Update [dbo].[OrganizationUser] based on the temporary table - UPDATE ou - SET ou.[Type] = 2 -- User - FROM [dbo].[OrganizationUser] ou - INNER JOIN #TempStep3 temp ON ou.[Id] = temp.[OrganizationUserId]; - --- Step 4: Bump the account revision date for each unique OrganizationUserId in #TempStep1, #TempStep2, and #TempStep3 - -- Join the three temporary tables to get unique OrganizationUserId - SELECT DISTINCT temp1.[OrganizationUserId] - INTO #TempUniqueOrganizationUser - FROM #TempStep1 temp1 - JOIN #TempStep2 temp2 ON temp1.[OrganizationUserId] = temp2.[OrganizationUserId] - JOIN #TempStep3 temp3 ON temp1.[OrganizationUserId] = temp3.[OrganizationUserId]; - - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @OrganizationUserId UNIQUEIDENTIFIER - - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempUniqueOrganizationUser - - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @OrganizationUserId - - -- Fetch the next row - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @OrganizationUserId - END - - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; - --- Step 5: Clean up temporary tables -DROP TABLE #TempStep1; -DROP TABLE #TempStep2; -DROP TABLE #TempStep3; -DROP TABLE #TempUniqueOrganizationUser; diff --git a/util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql b/util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql deleted file mode 100644 index 061f9a2af9..0000000000 --- a/util/Migrator/DbScripts_transition/2024-01-10_03_EnableOrgsFlexibleCollections.sql +++ /dev/null @@ -1,28 +0,0 @@ --- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time -SELECT [Id] AS [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch -INTO #TempOrg -FROM [dbo].[Organization] -WHERE [FlexibleCollections] = 0; - --- Step 2: Get the maximum batch number -DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrg); -DECLARE @CurrentBatch INT = 0; - --- Step 3: Process each batch -WHILE @CurrentBatch <= @MaxBatch -BEGIN - -- Update existing rows in [dbo].[CollectionUser] - UPDATE target - SET - target.[FlexibleCollections] = 1 - FROM [dbo].[Organization] AS target - INNER JOIN #TempOrg AS source - ON target.[Id] = source.[OrganizationId] - WHERE source.[Batch] = @CurrentBatch; - - -- Move to the next batch - SET @CurrentBatch = @CurrentBatch + 1; -END; - --- Step 4: Drop the temporary table -DROP TABLE #TempOrg; From c4ad7d72e8a6c01256bcaa0909151e7891f37a44 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 18:01:11 +0000 Subject: [PATCH 15/16] [AC-1682] Placed temp tables outside transactions --- ...anization_EnableCollectionEnhancements.sql | 484 +++++++++--------- ...anization_EnableCollectionEnhancements.sql | 484 +++++++++--------- 2 files changed, 484 insertions(+), 484 deletions(-) diff --git a/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql b/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql index 30ad54131f..b68ebadf07 100644 --- a/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql +++ b/src/Sql/dbo/Stored Procedures/Organization_EnableCollectionEnhancements.sql @@ -5,295 +5,295 @@ BEGIN SET NOCOUNT ON -- Step 1: AccessAll migration for Groups - BEGIN TRY - BEGIN TRANSACTION; - -- Create a temporary table to store the groups with AccessAll = 1 - SELECT [Id] AS [GroupId], [OrganizationId] - INTO #TempGroup - FROM [dbo].[Group] - WHERE [AccessAll] = 1 - AND [OrganizationId] = @OrganizationId; + -- Create a temporary table to store the groups with AccessAll = 1 + SELECT [Id] AS [GroupId], [OrganizationId] + INTO #TempGroup + FROM [dbo].[Group] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; - -- Update existing rows in [dbo].[CollectionGroup] - UPDATE CG - SET - CG.[ReadOnly] = 0, - CG.[HidePasswords] = 0, - CG.[Manage] = 0 - FROM [dbo].[CollectionGroup] CG - INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] - INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] - WHERE C.[OrganizationId] = TG.[OrganizationId]; + -- Create a temporary table to store distinct OrganizationUserIds + SELECT DISTINCT GU.[OrganizationUserId] + INTO #TempOrganizationUsers + FROM [dbo].[GroupUser] GU + JOIN #TempGroup TG ON GU.[GroupId] = TG.[GroupId]; - -- Insert new rows into [dbo].[CollectionGroup] - INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) - SELECT C.[Id], TG.[GroupId], 0, 0, 0 - FROM [dbo].[Collection] C - INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] - LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] - WHERE CG.[CollectionId] IS NULL; + BEGIN TRY + BEGIN TRANSACTION; + -- Update existing rows in [dbo].[CollectionGroup] + UPDATE CG + SET + CG.[ReadOnly] = 0, + CG.[HidePasswords] = 0, + CG.[Manage] = 0 + FROM [dbo].[CollectionGroup] CG + INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] + INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] + WHERE C.[OrganizationId] = TG.[OrganizationId]; - -- Update Group to clear AccessAll flag - UPDATE G - SET [AccessAll] = 0 - FROM [dbo].[Group] G - INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + -- Insert new rows into [dbo].[CollectionGroup] + INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) + SELECT C.[Id], TG.[GroupId], 0, 0, 0 + FROM [dbo].[Collection] C + INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] + LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] + WHERE CG.[CollectionId] IS NULL; - -- Create a temporary table to store distinct OrganizationUserIds - SELECT DISTINCT GU.[OrganizationUserId] - INTO #TempOrganizationUsers - FROM [dbo].[GroupUser] GU - JOIN #TempGroup TG ON GU.[GroupId] = TG.[GroupId]; + -- Update Group to clear AccessAll flag + UPDATE G + SET [AccessAll] = 0 + FROM [dbo].[Group] G + INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step1OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step1OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempOrganizationUsers + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempOrganizationUsers - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step1OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step1OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempGroup; - DROP TABLE #TempOrganizationUsers; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempGroup; + DROP TABLE #TempOrganizationUsers; -- Step 2: AccessAll migration for users - BEGIN TRY - BEGIN TRANSACTION; - -- Create a temporary table to store the OrganizationUsers with AccessAll = 1 - SELECT [Id] AS [OrganizationUserId], [OrganizationId] - INTO #TempOrgUser - FROM [dbo].[OrganizationUser] - WHERE [AccessAll] = 1 - AND [OrganizationId] = @OrganizationId; + -- Create a temporary table to store the OrganizationUsers with AccessAll = 1 + SELECT [Id] AS [OrganizationUserId], [OrganizationId] + INTO #TempOrgUser + FROM [dbo].[OrganizationUser] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; - -- Update existing rows in [dbo].[CollectionUser] - UPDATE target - SET - target.[ReadOnly] = 0, - target.[HidePasswords] = 0, - target.[Manage] = 0 - FROM [dbo].[CollectionUser] AS target - INNER JOIN ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; + BEGIN TRY + BEGIN TRANSACTION; + -- Update existing rows in [dbo].[CollectionUser] + UPDATE target + SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 + FROM [dbo].[CollectionUser] AS target + INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; - -- Insert new rows into [dbo].[CollectionUser] - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 - FROM ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source - LEFT JOIN [dbo].[CollectionUser] AS target - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] - WHERE target.[CollectionId] IS NULL; + -- Insert new rows into [dbo].[CollectionUser] + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 + FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + LEFT JOIN [dbo].[CollectionUser] AS target + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] + WHERE target.[CollectionId] IS NULL; - -- Update OrganizationUser to clear AccessAll flag - UPDATE OU - SET [AccessAll] = 0 - FROM [dbo].[OrganizationUser] OU - INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] + -- Update OrganizationUser to clear AccessAll flag + UPDATE OU + SET [AccessAll] = 0 + FROM [dbo].[OrganizationUser] OU + INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step2OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step2OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT DISTINCT [OrganizationUserId] - FROM #TempOrgUser + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempOrgUser - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step2OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step2OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempOrgUser; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempOrgUser; -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission - BEGIN TRY - BEGIN TRANSACTION; - -- Store the results in a temporary table - SELECT ou.[Id] AS [OrganizationUserId] - INTO #TempStep3 - FROM [dbo].[OrganizationUser] ou - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND - ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); + -- Store the results in a temporary table + SELECT ou.[Id] AS [OrganizationUserId] + INTO #TempStep3 + FROM [dbo].[OrganizationUser] ou + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND + ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); - -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table - UPDATE cu - SET cu.[ReadOnly] = 0, - cu.[HidePasswords] = 0, - cu.[Manage] = 1 - FROM [dbo].[CollectionUser] cu - INNER JOIN #TempStep3 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; + BEGIN TRY + BEGIN TRANSACTION; + -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table + UPDATE cu + SET cu.[ReadOnly] = 0, + cu.[HidePasswords] = 0, + cu.[Manage] = 1 + FROM [dbo].[CollectionUser] cu + INNER JOIN #TempStep3 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step3OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step3OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempStep3 + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep3 - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step3OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step3OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempStep3; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempStep3; -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access - BEGIN TRY - BEGIN TRANSACTION; - -- Store the results in a temporary table - SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] - INTO #TempStep4 - FROM [dbo].[CollectionGroup] cg - INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId - INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - AND NOT EXISTS ( - SELECT 1 FROM [dbo].[CollectionUser] cu - WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] - ); + -- Store the results in a temporary table + SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] + INTO #TempStep4 + FROM [dbo].[CollectionGroup] cg + INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ); - -- Insert rows into [dbo].[CollectionUser] using the temporary table - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 - FROM #TempStep4; + BEGIN TRY + BEGIN TRANSACTION; + -- Insert rows into [dbo].[CollectionUser] using the temporary table + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 + FROM #TempStep4; - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step4OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step4OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT DISTINCT [OrganizationUserId] - FROM #TempStep4 + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempStep4 - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step4OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step4OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempStep4; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempStep4; -- Step 5: Set all Managers to Users - BEGIN TRY - BEGIN TRANSACTION; - -- Store the results in a temporary table - SELECT [Id] AS [OrganizationUserId] - INTO #TempStep5 - FROM [dbo].[OrganizationUser] - WHERE [Type] = 3; -- Manager + -- Store the results in a temporary table + SELECT [Id] AS [OrganizationUserId] + INTO #TempStep5 + FROM [dbo].[OrganizationUser] + WHERE [Type] = 3; -- Manager - -- Update [dbo].[OrganizationUser] based on the temporary table - UPDATE ou - SET ou.[Type] = 2 -- User - FROM [dbo].[OrganizationUser] ou - INNER JOIN #TempStep5 temp ON ou.[Id] = temp.[OrganizationUserId]; + BEGIN TRY + BEGIN TRANSACTION; + -- Update [dbo].[OrganizationUser] based on the temporary table + UPDATE ou + SET ou.[Type] = 2 -- User + FROM [dbo].[OrganizationUser] ou + INNER JOIN #TempStep5 temp ON ou.[Id] = temp.[OrganizationUserId]; - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step5OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step5OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempStep5 + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep5 - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step5OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step5OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempStep5; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempStep5; END GO diff --git a/util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql b/util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql index 47c0458997..81cf579a14 100644 --- a/util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql +++ b/util/Migrator/DbScripts/2024-01-11_00_Organization_EnableCollectionEnhancements.sql @@ -5,295 +5,295 @@ BEGIN SET NOCOUNT ON -- Step 1: AccessAll migration for Groups - BEGIN TRY - BEGIN TRANSACTION; - -- Create a temporary table to store the groups with AccessAll = 1 - SELECT [Id] AS [GroupId], [OrganizationId] - INTO #TempGroup - FROM [dbo].[Group] - WHERE [AccessAll] = 1 - AND [OrganizationId] = @OrganizationId; + -- Create a temporary table to store the groups with AccessAll = 1 + SELECT [Id] AS [GroupId], [OrganizationId] + INTO #TempGroup + FROM [dbo].[Group] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; - -- Update existing rows in [dbo].[CollectionGroup] - UPDATE CG - SET - CG.[ReadOnly] = 0, - CG.[HidePasswords] = 0, - CG.[Manage] = 0 - FROM [dbo].[CollectionGroup] CG - INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] - INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] - WHERE C.[OrganizationId] = TG.[OrganizationId]; + -- Create a temporary table to store distinct OrganizationUserIds + SELECT DISTINCT GU.[OrganizationUserId] + INTO #TempOrganizationUsers + FROM [dbo].[GroupUser] GU + JOIN #TempGroup TG ON GU.[GroupId] = TG.[GroupId]; - -- Insert new rows into [dbo].[CollectionGroup] - INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) - SELECT C.[Id], TG.[GroupId], 0, 0, 0 - FROM [dbo].[Collection] C - INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] - LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] - WHERE CG.[CollectionId] IS NULL; + BEGIN TRY + BEGIN TRANSACTION; + -- Update existing rows in [dbo].[CollectionGroup] + UPDATE CG + SET + CG.[ReadOnly] = 0, + CG.[HidePasswords] = 0, + CG.[Manage] = 0 + FROM [dbo].[CollectionGroup] CG + INNER JOIN [dbo].[Collection] C ON CG.[CollectionId] = C.[Id] + INNER JOIN #TempGroup TG ON CG.[GroupId] = TG.[GroupId] + WHERE C.[OrganizationId] = TG.[OrganizationId]; - -- Update Group to clear AccessAll flag - UPDATE G - SET [AccessAll] = 0 - FROM [dbo].[Group] G - INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] + -- Insert new rows into [dbo].[CollectionGroup] + INSERT INTO [dbo].[CollectionGroup] ([CollectionId], [GroupId], [ReadOnly], [HidePasswords], [Manage]) + SELECT C.[Id], TG.[GroupId], 0, 0, 0 + FROM [dbo].[Collection] C + INNER JOIN #TempGroup TG ON C.[OrganizationId] = TG.[OrganizationId] + LEFT JOIN [dbo].[CollectionGroup] CG ON CG.[CollectionId] = C.[Id] AND CG.[GroupId] = TG.[GroupId] + WHERE CG.[CollectionId] IS NULL; - -- Create a temporary table to store distinct OrganizationUserIds - SELECT DISTINCT GU.[OrganizationUserId] - INTO #TempOrganizationUsers - FROM [dbo].[GroupUser] GU - JOIN #TempGroup TG ON GU.[GroupId] = TG.[GroupId]; + -- Update Group to clear AccessAll flag + UPDATE G + SET [AccessAll] = 0 + FROM [dbo].[Group] G + INNER JOIN #TempGroup TG ON G.[Id] = TG.[GroupId] - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step1OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step1OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempOrganizationUsers + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempOrganizationUsers - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step1OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step1OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempGroup; - DROP TABLE #TempOrganizationUsers; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step1OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempGroup; + DROP TABLE #TempOrganizationUsers; -- Step 2: AccessAll migration for users - BEGIN TRY - BEGIN TRANSACTION; - -- Create a temporary table to store the OrganizationUsers with AccessAll = 1 - SELECT [Id] AS [OrganizationUserId], [OrganizationId] - INTO #TempOrgUser - FROM [dbo].[OrganizationUser] - WHERE [AccessAll] = 1 - AND [OrganizationId] = @OrganizationId; + -- Create a temporary table to store the OrganizationUsers with AccessAll = 1 + SELECT [Id] AS [OrganizationUserId], [OrganizationId] + INTO #TempOrgUser + FROM [dbo].[OrganizationUser] + WHERE [AccessAll] = 1 + AND [OrganizationId] = @OrganizationId; - -- Update existing rows in [dbo].[CollectionUser] - UPDATE target - SET - target.[ReadOnly] = 0, - target.[HidePasswords] = 0, - target.[Manage] = 0 - FROM [dbo].[CollectionUser] AS target - INNER JOIN ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; + BEGIN TRY + BEGIN TRANSACTION; + -- Update existing rows in [dbo].[CollectionUser] + UPDATE target + SET + target.[ReadOnly] = 0, + target.[HidePasswords] = 0, + target.[Manage] = 0 + FROM [dbo].[CollectionUser] AS target + INNER JOIN ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId]; - -- Insert new rows into [dbo].[CollectionUser] - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 - FROM ( - SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] - FROM [dbo].[Collection] C - INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] - ) AS source - LEFT JOIN [dbo].[CollectionUser] AS target - ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] - WHERE target.[CollectionId] IS NULL; + -- Insert new rows into [dbo].[CollectionUser] + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT source.[CollectionId], source.[OrganizationUserId], 0, 0, 0 + FROM ( + SELECT C.[Id] AS [CollectionId], T.[OrganizationUserId] + FROM [dbo].[Collection] C + INNER JOIN #TempOrgUser T ON C.[OrganizationId] = T.[OrganizationId] + ) AS source + LEFT JOIN [dbo].[CollectionUser] AS target + ON target.[CollectionId] = source.[CollectionId] AND target.[OrganizationUserId] = source.[OrganizationUserId] + WHERE target.[CollectionId] IS NULL; - -- Update OrganizationUser to clear AccessAll flag - UPDATE OU - SET [AccessAll] = 0 - FROM [dbo].[OrganizationUser] OU - INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] + -- Update OrganizationUser to clear AccessAll flag + UPDATE OU + SET [AccessAll] = 0 + FROM [dbo].[OrganizationUser] OU + INNER JOIN #TempOrgUser T ON OU.[Id] = T.[OrganizationUserId] - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step2OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step2OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT DISTINCT [OrganizationUserId] - FROM #TempOrgUser + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempOrgUser - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step2OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step2OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempOrgUser; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step2OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempOrgUser; -- Step 3: Update [dbo].[CollectionUser] with [Manage] = 1 for all users with Manager role or 'EditAssignedCollections' permission - BEGIN TRY - BEGIN TRANSACTION; - -- Store the results in a temporary table - SELECT ou.[Id] AS [OrganizationUserId] - INTO #TempStep3 - FROM [dbo].[OrganizationUser] ou - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND - ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); + -- Store the results in a temporary table + SELECT ou.[Id] AS [OrganizationUserId] + INTO #TempStep3 + FROM [dbo].[OrganizationUser] ou + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND + ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')); - -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table - UPDATE cu - SET cu.[ReadOnly] = 0, - cu.[HidePasswords] = 0, - cu.[Manage] = 1 - FROM [dbo].[CollectionUser] cu - INNER JOIN #TempStep3 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; + BEGIN TRY + BEGIN TRANSACTION; + -- Update [dbo].[CollectionUser] with [Manage] = 1 using the temporary table + UPDATE cu + SET cu.[ReadOnly] = 0, + cu.[HidePasswords] = 0, + cu.[Manage] = 1 + FROM [dbo].[CollectionUser] cu + INNER JOIN #TempStep3 temp ON cu.[OrganizationUserId] = temp.[OrganizationUserId]; - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step3OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step3OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempStep3 + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep3 - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step3OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step3OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempStep3; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step3OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempStep3; -- Step 4: Insert rows to [dbo].[CollectionUser] for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access - BEGIN TRY - BEGIN TRANSACTION; - -- Store the results in a temporary table - SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] - INTO #TempStep4 - FROM [dbo].[CollectionGroup] cg - INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId - INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] - WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) - AND NOT EXISTS ( - SELECT 1 FROM [dbo].[CollectionUser] cu - WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] - ); + -- Store the results in a temporary table + SELECT cg.[CollectionId], ou.[Id] AS [OrganizationUserId] + INTO #TempStep4 + FROM [dbo].[CollectionGroup] cg + INNER JOIN [dbo].[GroupUser] gu ON cg.GroupId = gu.GroupId + INNER JOIN [dbo].[OrganizationUser] ou ON gu.OrganizationUserId = ou.[Id] + WHERE (ou.[Type] = 3 OR (ou.[Permissions] IS NOT NULL AND ISJSON(ou.[Permissions]) > 0 AND JSON_VALUE(ou.[Permissions], '$.editAssignedCollections') = 'true')) + AND NOT EXISTS ( + SELECT 1 FROM [dbo].[CollectionUser] cu + WHERE cu.[CollectionId] = cg.[CollectionId] AND cu.[OrganizationUserId] = ou.[Id] + ); - -- Insert rows into [dbo].[CollectionUser] using the temporary table - INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) - SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 - FROM #TempStep4; + BEGIN TRY + BEGIN TRANSACTION; + -- Insert rows into [dbo].[CollectionUser] using the temporary table + INSERT INTO [dbo].[CollectionUser] ([CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords], [Manage]) + SELECT [CollectionId], [OrganizationUserId], 0, 0, 1 + FROM #TempStep4; - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step4OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step4OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT DISTINCT [OrganizationUserId] - FROM #TempStep4 + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT DISTINCT [OrganizationUserId] + FROM #TempStep4 - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step4OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step4OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempStep4; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step4OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempStep4; -- Step 5: Set all Managers to Users - BEGIN TRY - BEGIN TRANSACTION; - -- Store the results in a temporary table - SELECT [Id] AS [OrganizationUserId] - INTO #TempStep5 - FROM [dbo].[OrganizationUser] - WHERE [Type] = 3; -- Manager + -- Store the results in a temporary table + SELECT [Id] AS [OrganizationUserId] + INTO #TempStep5 + FROM [dbo].[OrganizationUser] + WHERE [Type] = 3; -- Manager - -- Update [dbo].[OrganizationUser] based on the temporary table - UPDATE ou - SET ou.[Type] = 2 -- User - FROM [dbo].[OrganizationUser] ou - INNER JOIN #TempStep5 temp ON ou.[Id] = temp.[OrganizationUserId]; + BEGIN TRY + BEGIN TRANSACTION; + -- Update [dbo].[OrganizationUser] based on the temporary table + UPDATE ou + SET ou.[Type] = 2 -- User + FROM [dbo].[OrganizationUser] ou + INNER JOIN #TempStep5 temp ON ou.[Id] = temp.[OrganizationUserId]; - -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId - DECLARE @Step5OrganizationUserId UNIQUEIDENTIFIER + -- Execute User_BumpAccountRevisionDateByOrganizationUserId for each unique OrganizationUserId + DECLARE @Step5OrganizationUserId UNIQUEIDENTIFIER - DECLARE UniqueOrgUserIdCursor CURSOR FOR - SELECT [OrganizationUserId] - FROM #TempStep5 + DECLARE UniqueOrgUserIdCursor CURSOR FOR + SELECT [OrganizationUserId] + FROM #TempStep5 - OPEN UniqueOrgUserIdCursor - FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationUserId - EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step5OrganizationUserId - - -- Fetch the next row + OPEN UniqueOrgUserIdCursor FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId - END - CLOSE UniqueOrgUserIdCursor - DEALLOCATE UniqueOrgUserIdCursor; + WHILE (@@FETCH_STATUS = 0) + BEGIN + -- Execute the stored procedure for the current OrganizationUserId + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationUserId] @Step5OrganizationUserId - -- Drop the temporary table - DROP TABLE #TempStep5; - COMMIT TRANSACTION; - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION; - THROW; - END CATCH; + -- Fetch the next row + FETCH NEXT FROM UniqueOrgUserIdCursor INTO @Step5OrganizationUserId + END + + CLOSE UniqueOrgUserIdCursor + DEALLOCATE UniqueOrgUserIdCursor; + COMMIT TRANSACTION; + END TRY + BEGIN CATCH + ROLLBACK TRANSACTION; + THROW; + END CATCH; + + -- Drop the temporary table + DROP TABLE #TempStep5; END GO From 96b5278d7cf658114d0b1e5a19c2edd55719bddc Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 11 Jan 2024 18:31:47 +0000 Subject: [PATCH 16/16] [AC-1682] Removed batching from AllOrgsEnableCollectionEnhancements script --- ...00_AllOrgsEnableCollectionEnhancements.sql | 58 ++++++++----------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql b/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql index 1df22f2b26..e13232f7e4 100644 --- a/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql +++ b/util/Migrator/DbScripts_transition/2024-01-10_00_AllOrgsEnableCollectionEnhancements.sql @@ -1,49 +1,37 @@ -- This script will enable collection enhancements for all organizations that have not yet migrated. --- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time -SELECT [Id] AS [OrganizationId], CAST(ROW_NUMBER() OVER(ORDER BY [Id]) / 50000 AS INT) AS Batch +-- Step 1: Insert into a temporary table +SELECT [Id] AS [OrganizationId] INTO #TempOrg FROM [dbo].[Organization] WHERE [FlexibleCollections] = 0; --- Step 2: Get the maximum batch number -DECLARE @MaxBatch INT = (SELECT MAX(Batch) FROM #TempOrg); -DECLARE @CurrentBatch INT = 0; +-- Step 2: Execute the stored procedure for each OrganizationId +DECLARE @OrganizationId UNIQUEIDENTIFIER; --- Step 3: Process each batch -WHILE @CurrentBatch <= @MaxBatch +DECLARE OrgCursor CURSOR FOR +SELECT [OrganizationId] +FROM #TempOrg; + +OPEN OrgCursor; + +FETCH NEXT FROM OrgCursor INTO @OrganizationId; + +WHILE (@@FETCH_STATUS = 0) BEGIN - -- Execute the stored procedure for each OrganizationId in the current batch - DECLARE @OrganizationId UNIQUEIDENTIFIER; + -- Execute the stored procedure for the current OrganizationId + EXEC [dbo].[Organization_EnableCollectionEnhancements] @OrganizationId; - DECLARE OrgCursor CURSOR FOR - SELECT [OrganizationId] - FROM #TempOrg - WHERE [Batch] = @CurrentBatch; - - OPEN OrgCursor; + -- Update the Organization to set FlexibleCollections = 1 + UPDATE [dbo].[Organization] + SET [FlexibleCollections] = 1 + WHERE [Id] = @OrganizationId; FETCH NEXT FROM OrgCursor INTO @OrganizationId; - - WHILE (@@FETCH_STATUS = 0) - BEGIN - -- Execute the stored procedure for the current OrganizationId - EXEC [dbo].[Organization_EnableCollectionEnhancements] @OrganizationId; - - -- Update the Organization to set FlexibleCollections = 1 - UPDATE [dbo].[Organization] - SET [FlexibleCollections] = 1 - WHERE [Id] = @OrganizationId; - - FETCH NEXT FROM OrgCursor INTO @OrganizationId; - END; - - CLOSE OrgCursor; - DEALLOCATE OrgCursor; - - -- Move to the next batch - SET @CurrentBatch = @CurrentBatch + 1; END; --- Step 4: Drop the temporary table +CLOSE OrgCursor; +DEALLOCATE OrgCursor; + +-- Step 3: Drop the temporary table DROP TABLE #TempOrg;