SET ANSI_NULLS ON; GO SET QUOTED_IDENTIFIER ON; GO CREATE OR ALTER PROCEDURE dbo.ProjectHardDelete_PrepareDependencies @ProjectID int, @UserID int, @AllowActiveProject bit = 0 AS BEGIN SET NOCOUNT ON; IF NOT EXISTS ( SELECT 1 FROM dbo.Projects p INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID WHERE p.ProjectID = @ProjectID AND pua.UserID = @UserID AND pua.AccessRole = N'Owner' AND pua.IsActive = 1 ) THROW 52001, 'Project was not found for this owner.', 1; IF @AllowActiveProject = 0 AND EXISTS (SELECT 1 FROM dbo.Projects WHERE ProjectID = @ProjectID AND IsArchived = 0) THROW 52002, 'Only archived projects can be permanently deleted.', 1; DECLARE @BookIDs TABLE (BookID int NOT NULL PRIMARY KEY); DECLARE @ChapterIDs TABLE (ChapterID int NOT NULL PRIMARY KEY); DECLARE @SceneIDs TABLE (SceneID int NOT NULL PRIMARY KEY); DECLARE @StoryIntelligenceRunIDs TABLE (StoryIntelligenceRunID int NOT NULL PRIMARY KEY); DECLARE @StoryIntelligenceChapterResultIDs TABLE (ChapterResultID int NOT NULL PRIMARY KEY); DECLARE @StoryIntelligenceSceneResultIDs TABLE (SceneResultID int NOT NULL PRIMARY KEY); DECLARE @ImportSessionIDs TABLE (ImportSessionID int NOT NULL PRIMARY KEY); DECLARE @CharacterIntelligenceProfileIDs TABLE (CharacterIntelligenceProfileID int NOT NULL PRIMARY KEY); INSERT @BookIDs (BookID) SELECT BookID FROM dbo.Books WHERE ProjectID = @ProjectID; INSERT @ChapterIDs (ChapterID) SELECT c.ChapterID FROM dbo.Chapters c INNER JOIN @BookIDs b ON b.BookID = c.BookID; INSERT @SceneIDs (SceneID) SELECT s.SceneID FROM dbo.Scenes s INNER JOIN @ChapterIDs c ON c.ChapterID = s.ChapterID; INSERT @ImportSessionIDs (ImportSessionID) SELECT StoryIntelligenceBookPipelineID FROM dbo.StoryIntelligenceBookPipelines pipeline WHERE pipeline.ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = pipeline.BookID); INSERT @StoryIntelligenceRunIDs (StoryIntelligenceRunID) SELECT DISTINCT r.StoryIntelligenceRunID FROM dbo.StoryIntelligenceRuns r WHERE r.ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = r.BookID) OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = r.ChapterID) OR EXISTS (SELECT 1 FROM @SceneIDs s INNER JOIN dbo.Scenes scene ON scene.SceneID = s.SceneID WHERE scene.ImportRunID = r.StoryIntelligenceRunID); INSERT @StoryIntelligenceChapterResultIDs (ChapterResultID) SELECT DISTINCT cr.ChapterResultID FROM dbo.StoryIntelligenceChapterResults cr WHERE cr.ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @StoryIntelligenceRunIDs r WHERE r.StoryIntelligenceRunID = cr.StoryIntelligenceRunID) OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = cr.BookID) OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = cr.ChapterID); INSERT @StoryIntelligenceSceneResultIDs (SceneResultID) SELECT DISTINCT sr.SceneResultID FROM dbo.StoryIntelligenceSceneResults sr WHERE sr.ProjectID = @ProjectID OR EXISTS (SELECT 1 FROM @StoryIntelligenceRunIDs r WHERE r.StoryIntelligenceRunID = sr.StoryIntelligenceRunID) OR EXISTS (SELECT 1 FROM @StoryIntelligenceChapterResultIDs cr WHERE cr.ChapterResultID = sr.ChapterResultID) OR EXISTS (SELECT 1 FROM @BookIDs b WHERE b.BookID = sr.BookID) OR EXISTS (SELECT 1 FROM @ChapterIDs c WHERE c.ChapterID = sr.ChapterID) OR EXISTS (SELECT 1 FROM @SceneIDs s WHERE s.SceneID = sr.SceneID); INSERT @CharacterIntelligenceProfileIDs (CharacterIntelligenceProfileID) SELECT DISTINCT profile.CharacterIntelligenceProfileID FROM dbo.CharacterIntelligenceProfiles profile WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs sessionIDs WHERE sessionIDs.ImportSessionID = profile.ImportSessionID) OR EXISTS (SELECT 1 FROM @StoryIntelligenceSceneResultIDs resultIDs WHERE resultIDs.SceneResultID = profile.LastUpdatedSceneResultID); DELETE suggestion FROM dbo.SceneCharacterSuggestions suggestion LEFT JOIN @SceneIDs scene ON scene.SceneID = suggestion.SceneID LEFT JOIN dbo.Characters characterRows ON characterRows.CharacterID = suggestion.CharacterID WHERE scene.SceneID IS NOT NULL OR characterRows.ProjectID = @ProjectID; DELETE suggestion FROM dbo.SceneLocationSuggestions suggestion LEFT JOIN @SceneIDs scene ON scene.SceneID = suggestion.SceneID LEFT JOIN dbo.Locations locationRows ON locationRows.LocationID = suggestion.LocationID WHERE scene.SceneID IS NOT NULL OR locationRows.ProjectID = @ProjectID; DELETE suggestion FROM dbo.SceneAssetSuggestions suggestion LEFT JOIN @SceneIDs scene ON scene.SceneID = suggestion.SceneID LEFT JOIN dbo.StoryAssets assetRows ON assetRows.StoryAssetID = suggestion.AssetID WHERE scene.SceneID IS NOT NULL OR assetRows.ProjectID = @ProjectID; DELETE sceneAssets FROM dbo.WordCompanionSceneAssets sceneAssets LEFT JOIN @SceneIDs scene ON scene.SceneID = sceneAssets.SceneID LEFT JOIN dbo.StoryAssets assetRows ON assetRows.StoryAssetID = sceneAssets.StoryAssetID WHERE scene.SceneID IS NOT NULL OR assetRows.ProjectID = @ProjectID; DELETE sceneLocations FROM dbo.WordCompanionSceneLocations sceneLocations LEFT JOIN @SceneIDs scene ON scene.SceneID = sceneLocations.SceneID LEFT JOIN dbo.Locations locationRows ON locationRows.LocationID = sceneLocations.LocationID WHERE scene.SceneID IS NOT NULL OR locationRows.ProjectID = @ProjectID; DELETE evidence FROM dbo.CharacterIntelligenceEvidenceEvents evidence WHERE EXISTS (SELECT 1 FROM @CharacterIntelligenceProfileIDs profileIDs WHERE profileIDs.CharacterIntelligenceProfileID = evidence.CharacterIntelligenceProfileID) OR EXISTS (SELECT 1 FROM @StoryIntelligenceSceneResultIDs resultIDs WHERE resultIDs.SceneResultID = evidence.SceneResultID); DELETE profileRows FROM dbo.CharacterIntelligenceProfiles profileRows WHERE EXISTS (SELECT 1 FROM @CharacterIntelligenceProfileIDs profileIDs WHERE profileIDs.CharacterIntelligenceProfileID = profileRows.CharacterIntelligenceProfileID); DELETE FROM dbo.StoryMemoryIllustrationAssignments WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryIllustrationAssignments.ImportSessionID); DELETE FROM dbo.StoryMemoryIllustrationDemands WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryIllustrationDemands.ImportSessionID); DELETE FROM dbo.StoryMemoryRelationships WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryRelationships.ImportSessionID); DELETE FROM dbo.StoryMemoryCharacterAttributes WHERE EXISTS ( SELECT 1 FROM dbo.StoryMemoryCharacters c INNER JOIN @ImportSessionIDs ids ON ids.ImportSessionID = c.ImportSessionID WHERE c.StoryMemoryCharacterID = StoryMemoryCharacterAttributes.StoryMemoryCharacterID ); DELETE FROM dbo.StoryMemoryCharacterAliases WHERE EXISTS ( SELECT 1 FROM dbo.StoryMemoryCharacters c INNER JOIN @ImportSessionIDs ids ON ids.ImportSessionID = c.ImportSessionID WHERE c.StoryMemoryCharacterID = StoryMemoryCharacterAliases.StoryMemoryCharacterID ); DELETE FROM dbo.StoryMemoryAssets WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryAssets.ImportSessionID); DELETE FROM dbo.StoryMemoryLocations WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryLocations.ImportSessionID); DELETE FROM dbo.StoryMemoryCharacters WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryCharacters.ImportSessionID); DELETE FROM dbo.StoryMemoryProcessedSceneResults WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryProcessedSceneResults.ImportSessionID) OR EXISTS (SELECT 1 FROM @StoryIntelligenceSceneResultIDs resultIDs WHERE resultIDs.SceneResultID = StoryMemoryProcessedSceneResults.SceneResultID); DELETE FROM dbo.StoryMemoryImportPreferences WHERE EXISTS (SELECT 1 FROM @ImportSessionIDs ids WHERE ids.ImportSessionID = StoryMemoryImportPreferences.ImportSessionID); END; GO DECLARE @ProjectHardDeleteDefinition nvarchar(max) = OBJECT_DEFINITION(OBJECT_ID(N'dbo.ProjectHardDelete_ForOwner')); IF @ProjectHardDeleteDefinition IS NOT NULL AND @ProjectHardDeleteDefinition NOT LIKE N'%ProjectHardDelete_PrepareDependencies%' BEGIN SET @ProjectHardDeleteDefinition = REPLACE ( @ProjectHardDeleteDefinition, N' BEGIN TRANSACTION;', N' BEGIN TRANSACTION; EXEC dbo.ProjectHardDelete_PrepareDependencies @ProjectID = @ProjectID, @UserID = @UserID, @AllowActiveProject = 0;' ); IF @ProjectHardDeleteDefinition NOT LIKE N'%ProjectHardDelete_PrepareDependencies%' THROW 52012, 'Project hard-delete dependency cleanup call was not inserted.', 1; DECLARE @CreateIndex int = CHARINDEX(N'CREATE', @ProjectHardDeleteDefinition); DECLARE @ProcedureIndex int = CHARINDEX(N'PROCEDURE', @ProjectHardDeleteDefinition); IF @CreateIndex = 0 OR @ProcedureIndex = 0 OR @ProcedureIndex <= @CreateIndex THROW 52013, 'Project hard-delete procedure definition could not be patched.', 1; SET @ProjectHardDeleteDefinition = STUFF ( @ProjectHardDeleteDefinition, @CreateIndex, @ProcedureIndex - @CreateIndex, N'ALTER ' ); EXEC sys.sp_executesql @ProjectHardDeleteDefinition; END; GO IF OBJECT_DEFINITION(OBJECT_ID(N'dbo.ProjectHardDelete_ForOwner')) NOT LIKE N'%ProjectHardDelete_PrepareDependencies%' THROW 52014, 'Project hard-delete procedure does not call dependency cleanup.', 1; GO