445 lines
20 KiB
Transact-SQL
445 lines
20 KiB
Transact-SQL
SET ANSI_NULLS ON;
|
|
GO
|
|
SET QUOTED_IDENTIFIER ON;
|
|
GO
|
|
|
|
/*
|
|
Timeline-focused performance pass.
|
|
|
|
Scope:
|
|
- Keep the initial Timeline page from loading full character/asset lane data
|
|
just to render scene-card summaries.
|
|
- Keep project/book filters as early as possible inside heavy Timeline queries.
|
|
- Add narrow supporting indexes for the Timeline warning, character, asset,
|
|
and scene-overview paths.
|
|
*/
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_ContinuityWarnings_TimelineActiveList' AND object_id = OBJECT_ID(N'dbo.ContinuityWarnings'))
|
|
BEGIN
|
|
CREATE INDEX IX_ContinuityWarnings_TimelineActiveList
|
|
ON dbo.ContinuityWarnings(ProjectID, BookID, WarningSeverityID, WarningTypeID, SceneID, LastDetectedDate DESC, ContinuityWarningID DESC)
|
|
INCLUDE (ValidationRunID, ChapterID, EntityType, EntityID, Message, Details, CreatedDate)
|
|
WHERE IsDismissed = 0 AND IsIntentional = 0;
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_ContinuityWarnings_TimelineList' AND object_id = OBJECT_ID(N'dbo.ContinuityWarnings'))
|
|
BEGIN
|
|
CREATE INDEX IX_ContinuityWarnings_TimelineList
|
|
ON dbo.ContinuityWarnings(ProjectID, BookID, SceneID, EntityType, EntityID, WarningTypeID, WarningSeverityID)
|
|
INCLUDE (IsDismissed, IsIntentional, LastDetectedDate, ValidationRunID, ChapterID, Message, Details, CreatedDate);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneCharacters_SceneID_TimelineOverview' AND object_id = OBJECT_ID(N'dbo.SceneCharacters'))
|
|
BEGIN
|
|
CREATE INDEX IX_SceneCharacters_SceneID_TimelineOverview
|
|
ON dbo.SceneCharacters(SceneID, CharacterID)
|
|
INCLUDE (SceneCharacterID, RoleInSceneTypeID, PresenceTypeID, LocationID, EntryLocationID, ExitLocationID, AppearanceNotes, OutfitDescription, PhysicalCondition, EmotionalState, KnowledgeNotes, CreatedDate, UpdatedDate);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Books_Project_Active_Timeline' AND object_id = OBJECT_ID(N'dbo.Books'))
|
|
BEGIN
|
|
CREATE INDEX IX_Books_Project_Active_Timeline
|
|
ON dbo.Books(ProjectID, IsArchived, BookID)
|
|
INCLUDE (BookTitle, Subtitle, SortOrder, BookNumber);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Chapters_Book_Active_Timeline' AND object_id = OBJECT_ID(N'dbo.Chapters'))
|
|
BEGIN
|
|
CREATE INDEX IX_Chapters_Book_Active_Timeline
|
|
ON dbo.Chapters(BookID, IsArchived, ChapterID)
|
|
INCLUDE (ChapterNumber, ChapterTitle, SortOrder);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Scenes_Chapter_Active_Timeline' AND object_id = OBJECT_ID(N'dbo.Scenes'))
|
|
BEGIN
|
|
CREATE INDEX IX_Scenes_Chapter_Active_Timeline
|
|
ON dbo.Scenes(ChapterID, IsArchived, SceneID)
|
|
INCLUDE (SceneNumber, SceneTitle, SortOrder, POVCharacterID, PrimaryLocationID, RevisionStatusID);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_StoryAssets_Project_TimelineList' AND object_id = OBJECT_ID(N'dbo.StoryAssets'))
|
|
BEGIN
|
|
CREATE INDEX IX_StoryAssets_Project_TimelineList
|
|
ON dbo.StoryAssets(ProjectID, IsArchived, Importance DESC, AssetName)
|
|
INCLUDE (AssetKindID, CurrentStateID, CurrentLocationID, IsResolved, ShowInQuickAddBar, ImagePath, ThumbnailPath, CreatedDate, UpdatedDate);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_AssetEvents_SceneID_TimelineOverview' AND object_id = OBJECT_ID(N'dbo.AssetEvents'))
|
|
BEGIN
|
|
CREATE INDEX IX_AssetEvents_SceneID_TimelineOverview
|
|
ON dbo.AssetEvents(SceneID, StoryAssetID, UpdatedDate DESC)
|
|
INCLUDE (AssetEventTypeID, EventTitle);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_AssetStates_Active_Project_Sort' AND object_id = OBJECT_ID(N'dbo.AssetStates'))
|
|
BEGIN
|
|
CREATE INDEX IX_AssetStates_Active_Project_Sort
|
|
ON dbo.AssetStates(IsActive, ProjectID, SortOrder)
|
|
INCLUDE (AssetKindID, StateName, Description, IsResolvedState);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_CharacterAttributeTypes_Active_Project_Sort' AND object_id = OBJECT_ID(N'dbo.CharacterAttributeTypes'))
|
|
BEGIN
|
|
CREATE INDEX IX_CharacterAttributeTypes_Active_Project_Sort
|
|
ON dbo.CharacterAttributeTypes(IsActive, ProjectID, SortOrder)
|
|
INCLUDE (AttributeName, DataType, IsNormallyStable);
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.ContinuityWarning_List
|
|
@ProjectID int,
|
|
@BookID int = NULL,
|
|
@SceneID int = NULL,
|
|
@EntityType nvarchar(80) = NULL,
|
|
@EntityID int = NULL,
|
|
@WarningTypeID int = NULL,
|
|
@WarningSeverityID int = NULL,
|
|
@IncludeDismissed bit = 0,
|
|
@IncludeIntentional bit = 0
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
IF @IncludeDismissed = 0 AND @IncludeIntentional = 0
|
|
BEGIN
|
|
SELECT cw.ContinuityWarningID, cw.ValidationRunID, cw.ProjectID, cw.BookID, b.BookTitle, b.Subtitle AS BookSubtitle,
|
|
cw.ChapterID, c.ChapterNumber, c.ChapterTitle, cw.SceneID, s.SceneNumber, s.SceneTitle, cw.EntityType,
|
|
cw.EntityID, cw.WarningTypeID, wt.TypeName AS WarningTypeName, cw.WarningSeverityID, ws.SeverityName,
|
|
cw.Message, cw.Details, cw.IsDismissed, cw.IsIntentional, cw.CreatedDate, cw.LastDetectedDate
|
|
FROM dbo.ContinuityWarnings cw
|
|
INNER JOIN dbo.WarningTypes wt ON wt.WarningTypeID = cw.WarningTypeID
|
|
INNER JOIN dbo.WarningSeverities ws ON ws.WarningSeverityID = cw.WarningSeverityID
|
|
LEFT JOIN dbo.Books b ON b.BookID = cw.BookID
|
|
LEFT JOIN dbo.Chapters c ON c.ChapterID = cw.ChapterID
|
|
LEFT JOIN dbo.Scenes s ON s.SceneID = cw.SceneID
|
|
WHERE cw.ProjectID = @ProjectID
|
|
AND cw.IsDismissed = 0
|
|
AND cw.IsIntentional = 0
|
|
AND (@BookID IS NULL OR cw.BookID = @BookID)
|
|
AND (@SceneID IS NULL OR cw.SceneID = @SceneID)
|
|
AND (@EntityType IS NULL OR cw.EntityType = @EntityType)
|
|
AND (@EntityID IS NULL OR cw.EntityID = @EntityID)
|
|
AND (@WarningTypeID IS NULL OR cw.WarningTypeID = @WarningTypeID)
|
|
AND (@WarningSeverityID IS NULL OR cw.WarningSeverityID = @WarningSeverityID)
|
|
ORDER BY ws.SortOrder DESC, cw.LastDetectedDate DESC, cw.ContinuityWarningID DESC
|
|
OPTION (RECOMPILE);
|
|
|
|
RETURN;
|
|
END;
|
|
|
|
SELECT cw.ContinuityWarningID, cw.ValidationRunID, cw.ProjectID, cw.BookID, b.BookTitle, b.Subtitle AS BookSubtitle,
|
|
cw.ChapterID, c.ChapterNumber, c.ChapterTitle, cw.SceneID, s.SceneNumber, s.SceneTitle, cw.EntityType,
|
|
cw.EntityID, cw.WarningTypeID, wt.TypeName AS WarningTypeName, cw.WarningSeverityID, ws.SeverityName,
|
|
cw.Message, cw.Details, cw.IsDismissed, cw.IsIntentional, cw.CreatedDate, cw.LastDetectedDate
|
|
FROM dbo.ContinuityWarnings cw
|
|
INNER JOIN dbo.WarningTypes wt ON wt.WarningTypeID = cw.WarningTypeID
|
|
INNER JOIN dbo.WarningSeverities ws ON ws.WarningSeverityID = cw.WarningSeverityID
|
|
LEFT JOIN dbo.Books b ON b.BookID = cw.BookID
|
|
LEFT JOIN dbo.Chapters c ON c.ChapterID = cw.ChapterID
|
|
LEFT JOIN dbo.Scenes s ON s.SceneID = cw.SceneID
|
|
WHERE cw.ProjectID = @ProjectID
|
|
AND (@BookID IS NULL OR cw.BookID = @BookID)
|
|
AND (@SceneID IS NULL OR cw.SceneID = @SceneID)
|
|
AND (@EntityType IS NULL OR cw.EntityType = @EntityType)
|
|
AND (@EntityID IS NULL OR cw.EntityID = @EntityID)
|
|
AND (@WarningTypeID IS NULL OR cw.WarningTypeID = @WarningTypeID)
|
|
AND (@WarningSeverityID IS NULL OR cw.WarningSeverityID = @WarningSeverityID)
|
|
AND (@IncludeDismissed = 1 OR cw.IsDismissed = 0)
|
|
AND (@IncludeIntentional = 1 OR cw.IsIntentional = 0)
|
|
ORDER BY ws.SortOrder DESC, cw.LastDetectedDate DESC, cw.ContinuityWarningID DESC
|
|
OPTION (RECOMPILE);
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.StoryAsset_ListByProject
|
|
@ProjectID int
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
CREATE TABLE #ProjectLocationPaths
|
|
(
|
|
LocationID int NOT NULL PRIMARY KEY,
|
|
LocationName nvarchar(200) NOT NULL,
|
|
LocationPath nvarchar(max) NOT NULL
|
|
);
|
|
|
|
;WITH ProjectLocationTree AS
|
|
(
|
|
SELECT LocationID, LocationName, CAST(LocationName AS nvarchar(max)) AS LocationPath
|
|
FROM dbo.Locations
|
|
WHERE ProjectID = @ProjectID AND ParentLocationID IS NULL AND IsArchived = 0
|
|
|
|
UNION ALL
|
|
|
|
SELECT child.LocationID, child.LocationName, CAST(parent.LocationPath + N' > ' + child.LocationName AS nvarchar(max)) AS LocationPath
|
|
FROM dbo.Locations child
|
|
INNER JOIN ProjectLocationTree parent ON parent.LocationID = child.ParentLocationID
|
|
WHERE child.ProjectID = @ProjectID AND child.IsArchived = 0
|
|
)
|
|
INSERT #ProjectLocationPaths (LocationID, LocationName, LocationPath)
|
|
SELECT LocationID, LocationName, LocationPath
|
|
FROM ProjectLocationTree;
|
|
|
|
SELECT sa.StoryAssetID, sa.ProjectID, sa.AssetName, sa.AssetKindID, ak.KindName, sa.Description, sa.Importance,
|
|
sa.CurrentStateID, ast.StateName AS CurrentStateName, sa.CurrentLocationID,
|
|
location.LocationName AS CurrentLocationName, location.LocationPath AS CurrentLocationPath,
|
|
sa.IsResolved, sa.ShowInQuickAddBar, sa.ImagePath, sa.ThumbnailPath, sa.CreatedDate, sa.UpdatedDate, sa.IsArchived
|
|
FROM dbo.StoryAssets sa
|
|
INNER JOIN dbo.AssetKinds ak ON ak.AssetKindID = sa.AssetKindID
|
|
LEFT JOIN dbo.AssetStates ast ON ast.AssetStateID = sa.CurrentStateID
|
|
LEFT JOIN #ProjectLocationPaths location ON location.LocationID = sa.CurrentLocationID
|
|
WHERE sa.ProjectID = @ProjectID
|
|
AND sa.IsArchived = 0
|
|
ORDER BY sa.Importance DESC, sa.AssetName;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.AssetLookup_All
|
|
@ProjectID int = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
SELECT AssetKindID, KindName, SortOrder, IsActive FROM dbo.AssetKinds WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT AssetStateID, ProjectID, AssetKindID, StateName, SortOrder, Description, IsResolvedState, IsActive
|
|
FROM dbo.AssetStates
|
|
WHERE IsActive = 1
|
|
AND (@ProjectID IS NULL OR ProjectID IS NULL OR ProjectID = @ProjectID)
|
|
ORDER BY SortOrder;
|
|
SELECT AssetEventTypeID, TypeName, MarkerText, SortOrder, IsActive FROM dbo.AssetEventTypes WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT AssetDependencyTypeID, TypeName, SortOrder, IsValidatingDependency, IsActive FROM dbo.AssetDependencyTypes WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT AssetCustodyEventTypeID, TypeName, SortOrder, IsActive FROM dbo.AssetCustodyEventTypes WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT CustodyRoleID, RoleName, SortOrder, IsActive FROM dbo.CustodyRoles WHERE IsActive = 1 ORDER BY SortOrder;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterLookup_All
|
|
@ProjectID int = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
SELECT CharacterRoleInSceneTypeID, TypeName, SortOrder, IsActive FROM dbo.CharacterRoleInSceneTypes WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT PresenceTypeID, TypeName, SortOrder, IsActive FROM dbo.PresenceTypes WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT CharacterAttributeTypeID, ProjectID, AttributeName, DataType, IsNormallyStable, SortOrder, IsActive
|
|
FROM dbo.CharacterAttributeTypes
|
|
WHERE IsActive = 1
|
|
AND (@ProjectID IS NULL OR ProjectID IS NULL OR ProjectID = @ProjectID)
|
|
ORDER BY SortOrder;
|
|
SELECT KnowledgeStateID, StateName, SortOrder, IsActive FROM dbo.KnowledgeStates WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT rt.RelationshipTypeID, rt.TypeName, rt.IsPermanentDefault, rt.SortOrder, rt.IsActive,
|
|
rt.RelationshipCategoryID, rc.CategoryName AS RelationshipCategoryName, rc.SortOrder AS CategorySortOrder
|
|
FROM dbo.RelationshipTypes rt
|
|
LEFT JOIN dbo.RelationshipCategories rc ON rc.RelationshipCategoryID = rt.RelationshipCategoryID
|
|
WHERE rt.IsActive = 1
|
|
ORDER BY COALESCE(rc.SortOrder, 900), rt.SortOrder, rt.TypeName;
|
|
SELECT RelationshipStateID, StateName, SortOrder, IsActive FROM dbo.RelationshipStates WHERE IsActive = 1 ORDER BY SortOrder;
|
|
SELECT RelationshipCategoryID, CategoryName, SortOrder, IsActive FROM dbo.RelationshipCategories WHERE IsActive = 1 ORDER BY SortOrder, CategoryName;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterTimeline_GetByProject
|
|
@ProjectID int,
|
|
@BookID int = NULL
|
|
WITH RECOMPILE
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
CREATE TABLE #TimelineScenes
|
|
(
|
|
SceneID int NOT NULL PRIMARY KEY,
|
|
SceneNumber decimal(9,2) NOT NULL,
|
|
SceneTitle nvarchar(200) NOT NULL,
|
|
ChapterNumber decimal(9,2) NOT NULL,
|
|
BookTitle nvarchar(200) NOT NULL,
|
|
BookSubtitle nvarchar(200) NULL,
|
|
BookSortOrder int NOT NULL,
|
|
ChapterSortOrder int NOT NULL,
|
|
SceneSortOrder int NOT NULL
|
|
);
|
|
|
|
INSERT #TimelineScenes (SceneID, SceneNumber, SceneTitle, ChapterNumber, BookTitle, BookSubtitle, BookSortOrder, ChapterSortOrder, SceneSortOrder)
|
|
SELECT s.SceneID, s.SceneNumber, s.SceneTitle, ch.ChapterNumber, b.BookTitle, b.Subtitle, b.SortOrder, ch.SortOrder, s.SortOrder
|
|
FROM dbo.Books b
|
|
INNER JOIN dbo.Chapters ch ON ch.BookID = b.BookID
|
|
INNER JOIN dbo.Scenes s ON s.ChapterID = ch.ChapterID
|
|
WHERE b.ProjectID = @ProjectID
|
|
AND b.IsArchived = 0
|
|
AND ch.IsArchived = 0
|
|
AND s.IsArchived = 0
|
|
AND (@BookID IS NULL OR b.BookID = @BookID);
|
|
|
|
CREATE TABLE #TimelineCharacters
|
|
(
|
|
CharacterID int NOT NULL PRIMARY KEY,
|
|
ProjectID int NOT NULL,
|
|
CharacterName nvarchar(200) NOT NULL,
|
|
ShortName nvarchar(100) NULL,
|
|
Sex nvarchar(50) NULL,
|
|
BirthDate date NULL,
|
|
AgeAtSeriesStart int NULL,
|
|
AgeReferenceSceneID int NULL,
|
|
Height nvarchar(50) NULL,
|
|
EyeColour nvarchar(50) NULL,
|
|
CharacterImportance int NULL,
|
|
ShowInQuickAddBar bit NOT NULL,
|
|
DefaultDescription nvarchar(max) NULL,
|
|
CreatedDate datetime2 NOT NULL,
|
|
UpdatedDate datetime2 NOT NULL,
|
|
IsArchived bit NOT NULL
|
|
);
|
|
|
|
INSERT #TimelineCharacters (CharacterID, ProjectID, CharacterName, ShortName, Sex, BirthDate, AgeAtSeriesStart, AgeReferenceSceneID, Height, EyeColour, CharacterImportance, ShowInQuickAddBar, DefaultDescription, CreatedDate, UpdatedDate, IsArchived)
|
|
SELECT CharacterID, ProjectID, CharacterName, ShortName, Sex, BirthDate, AgeAtSeriesStart, AgeReferenceSceneID,
|
|
Height, EyeColour, CharacterImportance, ShowInQuickAddBar, DefaultDescription, CreatedDate, UpdatedDate, IsArchived
|
|
FROM dbo.Characters
|
|
WHERE ProjectID = @ProjectID AND IsArchived = 0;
|
|
|
|
CREATE TABLE #ProjectLocationPaths
|
|
(
|
|
LocationID int NOT NULL PRIMARY KEY,
|
|
LocationName nvarchar(200) NOT NULL,
|
|
LocationPath nvarchar(max) NOT NULL
|
|
);
|
|
|
|
;WITH ProjectLocationTree AS
|
|
(
|
|
SELECT LocationID, LocationName, CAST(LocationName AS nvarchar(max)) AS LocationPath
|
|
FROM dbo.Locations
|
|
WHERE ProjectID = @ProjectID AND ParentLocationID IS NULL AND IsArchived = 0
|
|
|
|
UNION ALL
|
|
|
|
SELECT child.LocationID, child.LocationName, CAST(parent.LocationPath + N' > ' + child.LocationName AS nvarchar(max)) AS LocationPath
|
|
FROM dbo.Locations child
|
|
INNER JOIN ProjectLocationTree parent ON parent.LocationID = child.ParentLocationID
|
|
WHERE child.ProjectID = @ProjectID AND child.IsArchived = 0
|
|
)
|
|
INSERT #ProjectLocationPaths (LocationID, LocationName, LocationPath)
|
|
SELECT LocationID, LocationName, LocationPath
|
|
FROM ProjectLocationTree;
|
|
|
|
SELECT CharacterID, ProjectID, CharacterName, ShortName, Sex, BirthDate, AgeAtSeriesStart, AgeReferenceSceneID,
|
|
Height, EyeColour, CharacterImportance, ShowInQuickAddBar, DefaultDescription, CreatedDate, UpdatedDate, IsArchived
|
|
FROM #TimelineCharacters
|
|
ORDER BY ISNULL(CharacterImportance, 0) DESC, CharacterName;
|
|
|
|
SELECT sc.SceneCharacterID, sc.SceneID, sc.CharacterID, c.ProjectID, c.CharacterName, c.ShortName, c.BirthDate, c.AgeAtSeriesStart,
|
|
sc.RoleInSceneTypeID, role.TypeName AS RoleInSceneTypeName, sc.PresenceTypeID, presence.TypeName AS PresenceTypeName,
|
|
sc.LocationID, location.LocationName, location.LocationPath, sc.EntryLocationID, entry.LocationName AS EntryLocationName,
|
|
sc.ExitLocationID, exitLocation.LocationName AS ExitLocationName, sc.AppearanceNotes, sc.OutfitDescription,
|
|
sc.PhysicalCondition, sc.EmotionalState, sc.KnowledgeNotes, s.SceneNumber, s.SceneTitle, s.ChapterNumber, s.BookTitle, s.BookSubtitle,
|
|
sc.CreatedDate, sc.UpdatedDate
|
|
FROM #TimelineScenes s
|
|
INNER JOIN dbo.SceneCharacters sc ON sc.SceneID = s.SceneID
|
|
INNER JOIN #TimelineCharacters c ON c.CharacterID = sc.CharacterID
|
|
LEFT JOIN dbo.CharacterRoleInSceneTypes role ON role.CharacterRoleInSceneTypeID = sc.RoleInSceneTypeID
|
|
LEFT JOIN dbo.PresenceTypes presence ON presence.PresenceTypeID = sc.PresenceTypeID
|
|
LEFT JOIN #ProjectLocationPaths location ON location.LocationID = sc.LocationID
|
|
LEFT JOIN #ProjectLocationPaths entry ON entry.LocationID = sc.EntryLocationID
|
|
LEFT JOIN #ProjectLocationPaths exitLocation ON exitLocation.LocationID = sc.ExitLocationID
|
|
ORDER BY s.BookSortOrder, s.ChapterSortOrder, s.SceneSortOrder, c.CharacterName;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.Timeline_SceneOverviews
|
|
@ProjectID int,
|
|
@BookID int = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
CREATE TABLE #TimelineScenes
|
|
(
|
|
SceneID int NOT NULL PRIMARY KEY,
|
|
BookSortOrder int NOT NULL,
|
|
ChapterSortOrder int NOT NULL,
|
|
SceneSortOrder int NOT NULL
|
|
);
|
|
|
|
INSERT #TimelineScenes (SceneID, BookSortOrder, ChapterSortOrder, SceneSortOrder)
|
|
SELECT s.SceneID, b.SortOrder, c.SortOrder, s.SortOrder
|
|
FROM dbo.Books b
|
|
INNER JOIN dbo.Chapters c ON c.BookID = b.BookID
|
|
INNER JOIN dbo.Scenes s ON s.ChapterID = c.ChapterID
|
|
WHERE b.ProjectID = @ProjectID
|
|
AND b.IsArchived = 0
|
|
AND c.IsArchived = 0
|
|
AND s.IsArchived = 0
|
|
AND (@BookID IS NULL OR b.BookID = @BookID);
|
|
|
|
CREATE TABLE #ProjectLocationPaths
|
|
(
|
|
LocationID int NOT NULL PRIMARY KEY,
|
|
LocationName nvarchar(200) NOT NULL,
|
|
LocationPath nvarchar(max) NOT NULL
|
|
);
|
|
|
|
;WITH ProjectLocationTree AS
|
|
(
|
|
SELECT LocationID, LocationName, CAST(LocationName AS nvarchar(max)) AS LocationPath
|
|
FROM dbo.Locations
|
|
WHERE ProjectID = @ProjectID AND ParentLocationID IS NULL AND IsArchived = 0
|
|
|
|
UNION ALL
|
|
|
|
SELECT child.LocationID, child.LocationName, CAST(parent.LocationPath + N' > ' + child.LocationName AS nvarchar(max)) AS LocationPath
|
|
FROM dbo.Locations child
|
|
INNER JOIN ProjectLocationTree parent ON parent.LocationID = child.ParentLocationID
|
|
WHERE child.ProjectID = @ProjectID AND child.IsArchived = 0
|
|
)
|
|
INSERT #ProjectLocationPaths (LocationID, LocationName, LocationPath)
|
|
SELECT LocationID, LocationName, LocationPath
|
|
FROM ProjectLocationTree;
|
|
|
|
SELECT ts.SceneID,
|
|
sc.CharacterID,
|
|
ch.CharacterName,
|
|
CONVERT(bit, CASE WHEN role.TypeName LIKE N'%POV%' THEN 1 ELSE 0 END) AS IsPov,
|
|
CONVERT(int, NULL) AS StoryAssetID,
|
|
CONVERT(nvarchar(200), NULL) AS AssetName,
|
|
CONVERT(int, NULL) AS AssetImportance,
|
|
CONVERT(nvarchar(100), NULL) AS AssetEventTypeName,
|
|
location.LocationPath AS LocationName
|
|
FROM #TimelineScenes ts
|
|
INNER JOIN dbo.SceneCharacters sc ON sc.SceneID = ts.SceneID
|
|
INNER JOIN dbo.Characters ch ON ch.CharacterID = sc.CharacterID AND ch.ProjectID = @ProjectID AND ch.IsArchived = 0
|
|
LEFT JOIN dbo.CharacterRoleInSceneTypes role ON role.CharacterRoleInSceneTypeID = sc.RoleInSceneTypeID
|
|
LEFT JOIN #ProjectLocationPaths location ON location.LocationID = sc.LocationID
|
|
|
|
UNION ALL
|
|
|
|
SELECT SceneID, CharacterID, CharacterName, IsPov, StoryAssetID, AssetName, AssetImportance, AssetEventTypeName, LocationName
|
|
FROM
|
|
(
|
|
SELECT ts.SceneID,
|
|
CONVERT(int, NULL) AS CharacterID,
|
|
CONVERT(nvarchar(200), NULL) AS CharacterName,
|
|
CONVERT(bit, 0) AS IsPov,
|
|
sa.StoryAssetID,
|
|
sa.AssetName,
|
|
sa.Importance AS AssetImportance,
|
|
aet.TypeName AS AssetEventTypeName,
|
|
CONVERT(nvarchar(max), NULL) AS LocationName,
|
|
ROW_NUMBER() OVER (PARTITION BY ts.SceneID, sa.StoryAssetID ORDER BY ae.UpdatedDate DESC, ae.AssetEventID DESC) AS rn
|
|
FROM #TimelineScenes ts
|
|
INNER JOIN dbo.AssetEvents ae ON ae.SceneID = ts.SceneID
|
|
INNER JOIN dbo.StoryAssets sa ON sa.StoryAssetID = ae.StoryAssetID AND sa.ProjectID = @ProjectID AND sa.IsArchived = 0
|
|
INNER JOIN dbo.AssetEventTypes aet ON aet.AssetEventTypeID = ae.AssetEventTypeID
|
|
) assetRows
|
|
WHERE rn = 1
|
|
ORDER BY SceneID;
|
|
END;
|
|
GO
|