352 lines
13 KiB
Transact-SQL
352 lines
13 KiB
Transact-SQL
SET ANSI_NULLS ON;
|
|
GO
|
|
SET QUOTED_IDENTIFIER ON;
|
|
GO
|
|
|
|
IF COL_LENGTH(N'dbo.CharacterEnrichmentRuns', N'CharacterID') IS NULL
|
|
BEGIN
|
|
ALTER TABLE dbo.CharacterEnrichmentRuns ADD CharacterID int NULL;
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.foreign_keys WHERE name = N'FK_CharacterEnrichmentRuns_Characters')
|
|
BEGIN
|
|
ALTER TABLE dbo.CharacterEnrichmentRuns
|
|
ADD CONSTRAINT FK_CharacterEnrichmentRuns_Characters FOREIGN KEY (CharacterID) REFERENCES dbo.Characters(CharacterID);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_CharacterEnrichmentRuns_ActiveCharacter' AND object_id = OBJECT_ID(N'dbo.CharacterEnrichmentRuns'))
|
|
BEGIN
|
|
CREATE UNIQUE INDEX UX_CharacterEnrichmentRuns_ActiveCharacter
|
|
ON dbo.CharacterEnrichmentRuns(BookID, CharacterID)
|
|
WHERE CharacterID IS NOT NULL AND IsCurrent = 1 AND Status IN (N'Queued', N'Running');
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_CharacterEnrichmentRuns_Character_Current' AND object_id = OBJECT_ID(N'dbo.CharacterEnrichmentRuns'))
|
|
BEGIN
|
|
CREATE INDEX IX_CharacterEnrichmentRuns_Character_Current
|
|
ON dbo.CharacterEnrichmentRuns(CharacterID, IsCurrent, UpdatedUtc DESC)
|
|
INCLUDE (BookID, UserID, Status, CompletedUtc);
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterEnrichmentRun_QueueCharacter
|
|
@CharacterID int,
|
|
@UserID int,
|
|
@BookID int = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
SET XACT_ABORT ON;
|
|
|
|
DECLARE @ProjectID int, @ResolvedBookID int, @PipelineID int, @ExistingID int, @Version nvarchar(120), @WasCoalesced bit = 1;
|
|
|
|
SELECT TOP (1)
|
|
@ProjectID = c.ProjectID,
|
|
@ResolvedBookID = ch.BookID
|
|
FROM dbo.Characters c
|
|
INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = c.ProjectID
|
|
INNER JOIN dbo.SceneCharacters sc ON sc.CharacterID = c.CharacterID
|
|
INNER JOIN dbo.Scenes s ON s.SceneID = sc.SceneID AND s.IsArchived = 0
|
|
INNER JOIN dbo.Chapters ch ON ch.ChapterID = s.ChapterID AND ch.IsArchived = 0
|
|
INNER JOIN dbo.SceneManuscriptSources sms ON sms.SceneID = s.SceneID
|
|
WHERE c.CharacterID = @CharacterID
|
|
AND c.IsArchived = 0
|
|
AND pua.UserID = @UserID
|
|
AND pua.AccessRole = N'Owner'
|
|
AND pua.IsActive = 1
|
|
AND (@BookID IS NULL OR ch.BookID = @BookID)
|
|
ORDER BY ch.SortOrder, ch.ChapterNumber, s.SortOrder, s.SceneNumber, s.SceneID;
|
|
|
|
IF @ProjectID IS NULL OR @ResolvedBookID IS NULL
|
|
THROW 52221, 'Character could not be queued for enrichment for this user and book.', 1;
|
|
|
|
SELECT TOP (1) @PipelineID = StoryIntelligenceBookPipelineID
|
|
FROM dbo.StoryIntelligenceBookPipelines
|
|
WHERE ProjectID = @ProjectID AND BookID = @ResolvedBookID
|
|
ORDER BY StoryIntelligenceBookPipelineID DESC;
|
|
|
|
SET @Version = CONCAT(N'ManualCharacter:', @CharacterID, N':Book:', @ResolvedBookID);
|
|
|
|
BEGIN TRANSACTION;
|
|
|
|
SELECT TOP (1) @ExistingID = CharacterEnrichmentRunID
|
|
FROM dbo.CharacterEnrichmentRuns WITH (UPDLOCK, HOLDLOCK)
|
|
WHERE BookID = @ResolvedBookID
|
|
AND CharacterID = @CharacterID
|
|
AND IsCurrent = 1
|
|
AND Status IN (N'Queued', N'Running')
|
|
ORDER BY CharacterEnrichmentRunID DESC;
|
|
|
|
IF @ExistingID IS NULL
|
|
BEGIN
|
|
UPDATE dbo.CharacterEnrichmentRuns
|
|
SET IsCurrent = 0,
|
|
Status = N'Superseded',
|
|
UpdatedUtc = SYSUTCDATETIME()
|
|
WHERE BookID = @ResolvedBookID
|
|
AND CharacterID = @CharacterID
|
|
AND IsCurrent = 1;
|
|
|
|
INSERT dbo.CharacterEnrichmentRuns
|
|
(ProjectID, BookID, UserID, CharacterID, StoryIntelligenceBookPipelineID, CharacterResolutionVersion, Status, TotalCharacters, CurrentStage, CurrentMessage)
|
|
VALUES
|
|
(@ProjectID, @ResolvedBookID, @UserID, @CharacterID, @PipelineID, @Version, N'Queued', 1, N'Queued', N'Character reanalysis is queued.');
|
|
|
|
SET @ExistingID = CAST(SCOPE_IDENTITY() AS int);
|
|
SET @WasCoalesced = 0;
|
|
END;
|
|
|
|
COMMIT TRANSACTION;
|
|
|
|
SELECT runRows.*, WasCoalesced = @WasCoalesced
|
|
FROM dbo.CharacterEnrichmentRuns runRows
|
|
WHERE runRows.CharacterEnrichmentRunID = @ExistingID;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterEnrichmentRun_Retry
|
|
@BookID int,
|
|
@UserID int
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
SET XACT_ABORT ON;
|
|
|
|
DECLARE @PreviousID int, @ProjectID int, @PipelineID int, @Version nvarchar(120);
|
|
SELECT TOP (1)
|
|
@PreviousID = CharacterEnrichmentRunID,
|
|
@ProjectID = ProjectID,
|
|
@PipelineID = StoryIntelligenceBookPipelineID,
|
|
@Version = CharacterResolutionVersion
|
|
FROM dbo.CharacterEnrichmentRuns
|
|
WHERE BookID = @BookID AND UserID = @UserID AND CharacterID IS NULL AND IsCurrent = 1 AND Status = N'Failed'
|
|
ORDER BY CharacterEnrichmentRunID DESC;
|
|
|
|
IF @PreviousID IS NULL
|
|
BEGIN
|
|
SELECT TOP (0) * FROM dbo.CharacterEnrichmentRuns;
|
|
RETURN;
|
|
END;
|
|
|
|
UPDATE dbo.CharacterEnrichmentRuns
|
|
SET IsCurrent = 0,
|
|
Status = N'Superseded',
|
|
UpdatedUtc = SYSUTCDATETIME()
|
|
WHERE CharacterEnrichmentRunID = @PreviousID;
|
|
|
|
EXEC dbo.CharacterEnrichmentRun_Queue
|
|
@ProjectID = @ProjectID,
|
|
@BookID = @BookID,
|
|
@UserID = @UserID,
|
|
@StoryIntelligenceBookPipelineID = @PipelineID,
|
|
@CharacterResolutionVersion = @Version;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterEnrichmentRun_GetCurrentByBook
|
|
@BookID int
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
SELECT TOP (1) *
|
|
FROM dbo.CharacterEnrichmentRuns
|
|
WHERE BookID = @BookID AND CharacterID IS NULL AND IsCurrent = 1
|
|
ORDER BY CharacterEnrichmentRunID DESC;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterEnrichmentRun_GetCurrentByCharacter
|
|
@CharacterID int,
|
|
@UserID int
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
SELECT TOP (1) runRows.*
|
|
FROM dbo.CharacterEnrichmentRuns runRows
|
|
INNER JOIN dbo.Characters c ON c.CharacterID = @CharacterID AND c.ProjectID = runRows.ProjectID
|
|
INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = c.ProjectID
|
|
WHERE runRows.CharacterID = @CharacterID
|
|
AND runRows.UserID = @UserID
|
|
AND runRows.IsCurrent = 1
|
|
AND pua.UserID = @UserID
|
|
AND pua.AccessRole = N'Owner'
|
|
AND pua.IsActive = 1
|
|
ORDER BY runRows.CharacterEnrichmentRunID DESC;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterEnrichment_ContextGet
|
|
@ProjectID int,
|
|
@BookID int,
|
|
@CharacterID int = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
SELECT
|
|
BookTitle = CASE WHEN NULLIF(LTRIM(RTRIM(b.Subtitle)), N'') IS NULL THEN b.BookTitle ELSE CONCAT(b.BookTitle, N': ', b.Subtitle) END,
|
|
b.StoryEra,
|
|
SeriesStartDate = CAST(NULL AS date)
|
|
FROM dbo.Books b
|
|
WHERE b.BookID = @BookID AND b.ProjectID = @ProjectID AND b.IsArchived = 0;
|
|
|
|
SELECT DISTINCT
|
|
c.CharacterID,
|
|
c.CharacterName,
|
|
c.BirthDate,
|
|
c.AgeAtSeriesStart,
|
|
c.Height,
|
|
c.EyeColour,
|
|
c.DefaultDescription
|
|
FROM dbo.Characters c
|
|
INNER JOIN dbo.SceneCharacters sc ON sc.CharacterID = c.CharacterID
|
|
INNER JOIN dbo.Scenes s ON s.SceneID = sc.SceneID AND s.IsArchived = 0
|
|
INNER JOIN dbo.Chapters ch ON ch.ChapterID = s.ChapterID AND ch.IsArchived = 0
|
|
INNER JOIN dbo.SceneManuscriptSources sms ON sms.SceneID = s.SceneID
|
|
WHERE c.ProjectID = @ProjectID
|
|
AND c.IsArchived = 0
|
|
AND ch.BookID = @BookID
|
|
AND (@CharacterID IS NULL OR c.CharacterID = @CharacterID)
|
|
ORDER BY c.CharacterName;
|
|
|
|
SELECT alias.CharacterID, alias.Alias
|
|
FROM dbo.CharacterAliases alias
|
|
INNER JOIN dbo.Characters c ON c.CharacterID = alias.CharacterID
|
|
WHERE c.ProjectID = @ProjectID
|
|
AND c.IsArchived = 0
|
|
AND (@CharacterID IS NULL OR c.CharacterID = @CharacterID)
|
|
ORDER BY alias.CharacterID, alias.SortOrder, alias.Alias;
|
|
|
|
SELECT
|
|
sc.CharacterID,
|
|
s.SceneID,
|
|
ch.ChapterID,
|
|
ch.ChapterNumber,
|
|
ch.ChapterTitle,
|
|
s.SceneNumber,
|
|
s.SceneTitle,
|
|
sms.SourceText
|
|
FROM dbo.SceneCharacters sc
|
|
INNER JOIN dbo.Characters c ON c.CharacterID = sc.CharacterID AND c.ProjectID = @ProjectID AND c.IsArchived = 0
|
|
INNER JOIN dbo.Scenes s ON s.SceneID = sc.SceneID AND s.IsArchived = 0
|
|
INNER JOIN dbo.Chapters ch ON ch.ChapterID = s.ChapterID AND ch.BookID = @BookID AND ch.IsArchived = 0
|
|
INNER JOIN dbo.SceneManuscriptSources sms ON sms.SceneID = s.SceneID
|
|
WHERE @CharacterID IS NULL OR sc.CharacterID = @CharacterID
|
|
ORDER BY sc.CharacterID, ch.SortOrder, ch.ChapterNumber, s.SortOrder, s.SceneNumber, s.SceneID;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.CharacterEnrichmentCharacterStatus_Get
|
|
@CharacterID int,
|
|
@UserID int
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
DECLARE @ProjectID int;
|
|
SELECT @ProjectID = c.ProjectID
|
|
FROM dbo.Characters c
|
|
INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = c.ProjectID
|
|
WHERE c.CharacterID = @CharacterID
|
|
AND c.IsArchived = 0
|
|
AND pua.UserID = @UserID
|
|
AND pua.AccessRole = N'Owner'
|
|
AND pua.IsActive = 1;
|
|
|
|
IF @ProjectID IS NULL
|
|
BEGIN
|
|
SELECT TOP (0)
|
|
CharacterID = CAST(NULL AS int),
|
|
BookID = CAST(NULL AS int),
|
|
CharacterEnrichmentRunID = CAST(NULL AS int),
|
|
Status = CAST(NULL AS nvarchar(30)),
|
|
CurrentStage = CAST(NULL AS nvarchar(120)),
|
|
CurrentMessage = CAST(NULL AS nvarchar(300)),
|
|
LastAnalysedUtc = CAST(NULL AS datetime2),
|
|
ErrorMessage = CAST(NULL AS nvarchar(max)),
|
|
Summary = CAST(NULL AS nvarchar(max)),
|
|
DateOfBirth = CAST(NULL AS nvarchar(500)),
|
|
AgeAtStartOfSeries = CAST(NULL AS nvarchar(500)),
|
|
Height = CAST(NULL AS nvarchar(500)),
|
|
EyeColour = CAST(NULL AS nvarchar(500)),
|
|
UpdatedUtc = CAST(NULL AS datetime2);
|
|
RETURN;
|
|
END;
|
|
|
|
DECLARE @Attempt TABLE
|
|
(
|
|
CharacterEnrichmentRunID int NULL,
|
|
BookID int NULL,
|
|
Status nvarchar(30) NULL,
|
|
CurrentStage nvarchar(120) NULL,
|
|
CurrentMessage nvarchar(300) NULL,
|
|
ErrorMessage nvarchar(max) NULL,
|
|
UpdatedUtc datetime2 NULL
|
|
);
|
|
|
|
INSERT @Attempt
|
|
SELECT TOP (1)
|
|
runRows.CharacterEnrichmentRunID,
|
|
runRows.BookID,
|
|
runRows.Status,
|
|
runRows.CurrentStage,
|
|
runRows.CurrentMessage,
|
|
runRows.ErrorMessage,
|
|
runRows.UpdatedUtc
|
|
FROM dbo.CharacterEnrichmentRuns runRows
|
|
WHERE runRows.UserID = @UserID
|
|
AND runRows.ProjectID = @ProjectID
|
|
AND runRows.CharacterID = @CharacterID
|
|
AND runRows.IsCurrent = 1
|
|
ORDER BY CASE runRows.Status WHEN N'Queued' THEN 0 WHEN N'Running' THEN 0 WHEN N'Failed' THEN 1 WHEN N'Completed' THEN 2 ELSE 9 END,
|
|
runRows.UpdatedUtc DESC,
|
|
runRows.CharacterEnrichmentRunID DESC;
|
|
|
|
DECLARE @SuccessRunID int, @SuccessBookID int, @LastAnalysedUtc datetime2;
|
|
SELECT TOP (1)
|
|
@SuccessRunID = runRows.CharacterEnrichmentRunID,
|
|
@SuccessBookID = runRows.BookID,
|
|
@LastAnalysedUtc = runRows.CompletedUtc
|
|
FROM dbo.CharacterEnrichmentRuns runRows
|
|
WHERE runRows.UserID = @UserID
|
|
AND runRows.ProjectID = @ProjectID
|
|
AND runRows.Status = N'Completed'
|
|
AND runRows.CompletedUtc IS NOT NULL
|
|
AND (
|
|
runRows.CharacterID = @CharacterID
|
|
OR EXISTS
|
|
(
|
|
SELECT 1
|
|
FROM dbo.CharacterEnrichmentEvidence evidence
|
|
WHERE evidence.CharacterEnrichmentRunID = runRows.CharacterEnrichmentRunID
|
|
AND evidence.CharacterID = @CharacterID
|
|
)
|
|
)
|
|
ORDER BY runRows.CompletedUtc DESC, runRows.CharacterEnrichmentRunID DESC;
|
|
|
|
SELECT
|
|
CharacterID = @CharacterID,
|
|
BookID = COALESCE((SELECT TOP (1) BookID FROM @Attempt), @SuccessBookID),
|
|
CharacterEnrichmentRunID = COALESCE((SELECT TOP (1) CharacterEnrichmentRunID FROM @Attempt), @SuccessRunID),
|
|
Status = COALESCE((SELECT TOP (1) Status FROM @Attempt), CASE WHEN @SuccessRunID IS NULL THEN N'Not analysed' ELSE N'Completed' END),
|
|
CurrentStage = (SELECT TOP (1) CurrentStage FROM @Attempt),
|
|
CurrentMessage = (SELECT TOP (1) CurrentMessage FROM @Attempt),
|
|
LastAnalysedUtc = @LastAnalysedUtc,
|
|
ErrorMessage = (SELECT TOP (1) ErrorMessage FROM @Attempt),
|
|
Summary = MAX(CASE WHEN evidence.FieldName = N'Summary' THEN evidence.Value END),
|
|
DateOfBirth = MAX(CASE WHEN evidence.FieldName = N'DateOfBirth' THEN evidence.Value END),
|
|
AgeAtStartOfSeries = MAX(CASE WHEN evidence.FieldName = N'AgeAtStartOfSeries' THEN evidence.Value END),
|
|
Height = MAX(CASE WHEN evidence.FieldName = N'Height' THEN evidence.Value END),
|
|
EyeColour = MAX(CASE WHEN evidence.FieldName = N'EyeColour' THEN evidence.Value END),
|
|
UpdatedUtc = COALESCE((SELECT TOP (1) UpdatedUtc FROM @Attempt), @LastAnalysedUtc, SYSUTCDATETIME())
|
|
FROM (SELECT 1 AS Anchor) anchor
|
|
LEFT JOIN dbo.CharacterEnrichmentEvidence evidence
|
|
ON evidence.CharacterEnrichmentRunID = @SuccessRunID
|
|
AND evidence.CharacterID = @CharacterID;
|
|
END;
|
|
GO
|