PlotDirector/PlotLine/Sql/009_Phase1H_SceneDependenciesAndMoves.sql
2026-06-01 09:03:59 +01:00

306 lines
12 KiB
Transact-SQL

SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF COL_LENGTH('dbo.SceneDependencies', 'ProjectID') IS NULL
BEGIN
ALTER TABLE dbo.SceneDependencies ADD ProjectID int NULL;
END;
GO
UPDATE sd
SET ProjectID = b.ProjectID
FROM dbo.SceneDependencies sd
INNER JOIN dbo.Scenes s ON s.SceneID = sd.SourceSceneID
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
INNER JOIN dbo.Books b ON b.BookID = c.BookID
WHERE sd.ProjectID IS NULL;
GO
IF COL_LENGTH('dbo.SceneDependencies', 'IsHardDependency') IS NULL
BEGIN
ALTER TABLE dbo.SceneDependencies ADD IsHardDependency bit NOT NULL CONSTRAINT DF_SceneDependencies_IsHardDependency DEFAULT 0;
END;
GO
MERGE dbo.SceneDependencyTypes AS target
USING (VALUES
(N'Must Occur Before', 10), (N'Emotional Setup', 20), (N'Reveal Setup', 30), (N'Action Consequence', 40),
(N'Travel Dependency', 50), (N'Relationship Dependency', 60), (N'Knowledge Dependency', 70), (N'Object Dependency', 80),
(N'Location Dependency', 90), (N'Time Dependency', 100)
) AS source (TypeName, SortOrder)
ON target.TypeName = source.TypeName
WHEN NOT MATCHED THEN INSERT (TypeName, SortOrder) VALUES (source.TypeName, source.SortOrder);
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependencyLookup_All
AS
BEGIN
SET NOCOUNT ON;
SELECT SceneDependencyTypeID, TypeName, SortOrder, IsActive
FROM dbo.SceneDependencyTypes
WHERE IsActive = 1
ORDER BY SortOrder;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependency_Save
@SceneDependencyID int = NULL,
@ProjectID int = NULL,
@SourceSceneID int,
@TargetSceneID int,
@SceneDependencyTypeID int,
@Description nvarchar(max) = NULL,
@IsHardDependency bit = 0
AS
BEGIN
SET NOCOUNT ON;
IF @ProjectID IS NULL
BEGIN
SELECT @ProjectID = b.ProjectID
FROM dbo.Scenes s
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
INNER JOIN dbo.Books b ON b.BookID = c.BookID
WHERE s.SceneID = @SourceSceneID;
END;
IF @SourceSceneID = @TargetSceneID
RETURN;
IF @SceneDependencyID IS NULL OR @SceneDependencyID = 0
BEGIN
INSERT dbo.SceneDependencies (ProjectID, SourceSceneID, TargetSceneID, SceneDependencyTypeID, Description, IsHardDependency)
VALUES (@ProjectID, @SourceSceneID, @TargetSceneID, @SceneDependencyTypeID, @Description, @IsHardDependency);
SELECT CAST(SCOPE_IDENTITY() AS int);
RETURN;
END;
UPDATE dbo.SceneDependencies
SET SourceSceneID = @SourceSceneID,
TargetSceneID = @TargetSceneID,
SceneDependencyTypeID = @SceneDependencyTypeID,
Description = @Description,
IsHardDependency = @IsHardDependency,
UpdatedDate = SYSUTCDATETIME()
WHERE SceneDependencyID = @SceneDependencyID;
SELECT @SceneDependencyID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependency_Archive
@SceneDependencyID int
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.SceneDependencies
SET IsArchived = 1, UpdatedDate = SYSUTCDATETIME()
WHERE SceneDependencyID = @SceneDependencyID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependency_ListByScene
@SceneID int
AS
BEGIN
SET NOCOUNT ON;
SELECT sd.SceneDependencyID, sd.ProjectID, sd.SourceSceneID, sd.TargetSceneID, sd.SceneDependencyTypeID,
sdt.TypeName AS SceneDependencyTypeName, sd.Description, sd.IsHardDependency, sd.CreatedDate, sd.UpdatedDate, sd.IsArchived,
sourceOrder.BookID AS SourceBookID, sourceOrder.BookTitle AS SourceBookTitle, sourceOrder.ChapterID AS SourceChapterID,
sourceOrder.ChapterNumber AS SourceChapterNumber, sourceOrder.SceneNumber AS SourceSceneNumber, sourceOrder.SceneTitle AS SourceSceneTitle,
targetOrder.BookID AS TargetBookID, targetOrder.BookTitle AS TargetBookTitle, targetOrder.ChapterID AS TargetChapterID,
targetOrder.ChapterNumber AS TargetChapterNumber, targetOrder.SceneNumber AS TargetSceneNumber, targetOrder.SceneTitle AS TargetSceneTitle,
CASE WHEN sd.TargetSceneID = @SceneID THEN N'DependsOn' ELSE N'Dependent' END AS DependencyDirection
FROM dbo.SceneDependencies sd
INNER JOIN dbo.SceneDependencyTypes sdt ON sdt.SceneDependencyTypeID = sd.SceneDependencyTypeID
INNER JOIN dbo.NarrativeSceneOrder sourceOrder ON sourceOrder.SceneID = sd.SourceSceneID
INNER JOIN dbo.NarrativeSceneOrder targetOrder ON targetOrder.SceneID = sd.TargetSceneID
WHERE sd.IsArchived = 0 AND @SceneID IN (sd.SourceSceneID, sd.TargetSceneID)
ORDER BY DependencyDirection, sourceOrder.GlobalSceneIndex, targetOrder.GlobalSceneIndex;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependency_ListByProject
@ProjectID int,
@BookID int = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT sd.SceneDependencyID, sd.ProjectID, sd.SourceSceneID, sd.TargetSceneID, sd.SceneDependencyTypeID,
sdt.TypeName AS SceneDependencyTypeName, sd.Description, sd.IsHardDependency, sd.CreatedDate, sd.UpdatedDate, sd.IsArchived,
sourceOrder.BookID AS SourceBookID, sourceOrder.BookTitle AS SourceBookTitle, sourceOrder.ChapterID AS SourceChapterID,
sourceOrder.ChapterNumber AS SourceChapterNumber, sourceOrder.SceneNumber AS SourceSceneNumber, sourceOrder.SceneTitle AS SourceSceneTitle,
targetOrder.BookID AS TargetBookID, targetOrder.BookTitle AS TargetBookTitle, targetOrder.ChapterID AS TargetChapterID,
targetOrder.ChapterNumber AS TargetChapterNumber, targetOrder.SceneNumber AS TargetSceneNumber, targetOrder.SceneTitle AS TargetSceneTitle
FROM dbo.SceneDependencies sd
INNER JOIN dbo.SceneDependencyTypes sdt ON sdt.SceneDependencyTypeID = sd.SceneDependencyTypeID
INNER JOIN dbo.NarrativeSceneOrder sourceOrder ON sourceOrder.SceneID = sd.SourceSceneID
INNER JOIN dbo.NarrativeSceneOrder targetOrder ON targetOrder.SceneID = sd.TargetSceneID
WHERE sd.IsArchived = 0 AND sd.ProjectID = @ProjectID AND (@BookID IS NULL OR targetOrder.BookID = @BookID OR sourceOrder.BookID = @BookID)
ORDER BY sourceOrder.GlobalSceneIndex, targetOrder.GlobalSceneIndex;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependency_Counts
@ProjectID int,
@BookID int = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT scene.SceneID, COUNT(*) AS DependencyCount
FROM dbo.NarrativeSceneOrder scene
INNER JOIN dbo.SceneDependencies sd ON scene.SceneID IN (sd.SourceSceneID, sd.TargetSceneID) AND sd.IsArchived = 0
WHERE scene.ProjectID = @ProjectID AND (@BookID IS NULL OR scene.BookID = @BookID)
GROUP BY scene.SceneID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.ChapterOption_ListByProject
@ProjectID int
AS
BEGIN
SET NOCOUNT ON;
SELECT c.ChapterID, b.BookID, b.BookTitle, b.BookNumber, c.ChapterNumber, c.ChapterTitle, c.SortOrder
FROM dbo.Chapters c
INNER JOIN dbo.Books b ON b.BookID = c.BookID
WHERE b.ProjectID = @ProjectID AND b.IsArchived = 0 AND c.IsArchived = 0
ORDER BY b.SortOrder, b.BookNumber, c.SortOrder, c.ChapterNumber;
END;
GO
CREATE OR ALTER PROCEDURE dbo.Scene_NormalizeSortOrder
@ChapterID int
AS
BEGIN
SET NOCOUNT ON;
;WITH ordered AS
(
SELECT SceneID, ROW_NUMBER() OVER (ORDER BY SortOrder, SceneNumber, SceneID) AS rn
FROM dbo.Scenes
WHERE ChapterID = @ChapterID AND IsArchived = 0
)
UPDATE s
SET SortOrder = ordered.rn * 10, UpdatedDate = SYSUTCDATETIME()
FROM dbo.Scenes s
INNER JOIN ordered ON ordered.SceneID = s.SceneID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.Scene_RenumberChapter
@ChapterID int
AS
BEGIN
SET NOCOUNT ON;
;WITH ordered AS
(
SELECT SceneID, ROW_NUMBER() OVER (ORDER BY SortOrder, SceneNumber, SceneID) AS rn
FROM dbo.Scenes
WHERE ChapterID = @ChapterID AND IsArchived = 0
)
UPDATE s
SET SceneNumber = ordered.rn, SortOrder = ordered.rn * 10, UpdatedDate = SYSUTCDATETIME()
FROM dbo.Scenes s
INNER JOIN ordered ON ordered.SceneID = s.SceneID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.Chapter_RenumberBook
@BookID int
AS
BEGIN
SET NOCOUNT ON;
;WITH ordered AS
(
SELECT ChapterID, ROW_NUMBER() OVER (ORDER BY SortOrder, ChapterNumber, ChapterID) AS rn
FROM dbo.Chapters
WHERE BookID = @BookID AND IsArchived = 0
)
UPDATE c
SET ChapterNumber = ordered.rn, SortOrder = ordered.rn * 10, UpdatedDate = SYSUTCDATETIME()
FROM dbo.Chapters c
INNER JOIN ordered ON ordered.ChapterID = c.ChapterID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneMovePreview_Get
@SceneID int,
@TargetChapterID int,
@Position nvarchar(20) = N'End'
AS
BEGIN
SET NOCOUNT ON;
SELECT s.SceneID, s.SceneNumber, s.SceneTitle, s.ChapterID AS SourceChapterID, sourceChapter.ChapterNumber AS SourceChapterNumber,
sourceChapter.ChapterTitle AS SourceChapterTitle, sourceBook.BookID AS SourceBookID, sourceBook.BookTitle AS SourceBookTitle,
@TargetChapterID AS TargetChapterID, targetChapter.ChapterNumber AS TargetChapterNumber, targetChapter.ChapterTitle AS TargetChapterTitle,
targetBook.BookID AS TargetBookID, targetBook.BookTitle AS TargetBookTitle, @Position AS Position,
(SELECT COUNT(*) FROM dbo.SceneDependencies WHERE IsArchived = 0 AND @SceneID IN (SourceSceneID, TargetSceneID)) AS DependencyCount,
(SELECT COUNT(*) FROM dbo.ContinuityWarnings WHERE IsDismissed = 0 AND IsIntentional = 0 AND SceneID = @SceneID) AS ActiveWarningCount
FROM dbo.Scenes s
INNER JOIN dbo.Chapters sourceChapter ON sourceChapter.ChapterID = s.ChapterID
INNER JOIN dbo.Books sourceBook ON sourceBook.BookID = sourceChapter.BookID
INNER JOIN dbo.Chapters targetChapter ON targetChapter.ChapterID = @TargetChapterID
INNER JOIN dbo.Books targetBook ON targetBook.BookID = targetChapter.BookID
WHERE s.SceneID = @SceneID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.Scene_MoveToChapter
@SceneID int,
@TargetChapterID int,
@Position nvarchar(20) = N'End',
@Renumber bit = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SourceChapterID int = (SELECT ChapterID FROM dbo.Scenes WHERE SceneID = @SceneID);
DECLARE @NewSortOrder int;
IF @Position = N'Start'
SELECT @NewSortOrder = ISNULL(MIN(SortOrder), 10) - 5 FROM dbo.Scenes WHERE ChapterID = @TargetChapterID AND IsArchived = 0;
ELSE
SELECT @NewSortOrder = ISNULL(MAX(SortOrder), 0) + 10 FROM dbo.Scenes WHERE ChapterID = @TargetChapterID AND IsArchived = 0 AND SceneID <> @SceneID;
UPDATE dbo.Scenes
SET ChapterID = @TargetChapterID, SortOrder = @NewSortOrder, UpdatedDate = SYSUTCDATETIME()
WHERE SceneID = @SceneID;
EXEC dbo.Scene_NormalizeSortOrder @SourceChapterID;
EXEC dbo.Scene_NormalizeSortOrder @TargetChapterID;
IF @Renumber = 1
BEGIN
EXEC dbo.Scene_RenumberChapter @SourceChapterID;
EXEC dbo.Scene_RenumberChapter @TargetChapterID;
END;
SELECT @SceneID;
END;
GO
CREATE OR ALTER PROCEDURE dbo.SceneDependency_FinaliseWarnings
@ProjectID int,
@BookID int = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ErrorSeverityID int = (SELECT WarningSeverityID FROM dbo.WarningSeverities WHERE SeverityName = N'Error');
DECLARE @WarningSeverityID int = (SELECT WarningSeverityID FROM dbo.WarningSeverities WHERE SeverityName = N'Warning');
DECLARE @WarningTypeID int = (SELECT WarningTypeID FROM dbo.WarningTypes WHERE TypeName = N'Scene Dependency Broken');
UPDATE cw
SET WarningSeverityID = CASE WHEN sd.IsHardDependency = 1 THEN @ErrorSeverityID ELSE @WarningSeverityID END,
Message = CONCAT(N'Possible scene order issue: ''', sourceOrder.SceneTitle, N''' is now after ''', targetOrder.SceneTitle, N'''.'),
Details = COALESCE(sd.Description, cw.Details),
LastDetectedDate = SYSUTCDATETIME()
FROM dbo.ContinuityWarnings cw
INNER JOIN dbo.SceneDependencies sd ON sd.SceneDependencyID = cw.EntityID
INNER JOIN dbo.NarrativeSceneOrder sourceOrder ON sourceOrder.SceneID = sd.SourceSceneID
INNER JOIN dbo.NarrativeSceneOrder targetOrder ON targetOrder.SceneID = sd.TargetSceneID
WHERE cw.ProjectID = @ProjectID
AND cw.WarningTypeID = @WarningTypeID
AND cw.EntityType = N'SceneDependency'
AND (@BookID IS NULL OR cw.BookID = @BookID);
END;
GO