74 lines
3.5 KiB
C#
74 lines
3.5 KiB
C#
using Dapper;
|
|
using PlotLine.Models;
|
|
|
|
namespace PlotLine.Data;
|
|
|
|
public interface ICharacterIntelligenceRepository
|
|
{
|
|
Task<IReadOnlyList<CharacterIntelligenceProfile>> ListProfilesAsync(int importSessionId);
|
|
Task<CharacterIntelligenceProfile> UpsertProfileAsync(CharacterIntelligenceProfileSave request);
|
|
Task AddEvidenceAsync(CharacterIntelligenceEvidenceSave request);
|
|
}
|
|
|
|
public sealed class CharacterIntelligenceRepository(ISqlConnectionFactory connectionFactory) : ICharacterIntelligenceRepository
|
|
{
|
|
public async Task<IReadOnlyList<CharacterIntelligenceProfile>> ListProfilesAsync(int importSessionId)
|
|
{
|
|
using var connection = connectionFactory.CreateConnection();
|
|
var rows = await connection.QueryAsync<CharacterIntelligenceProfile>(
|
|
"""
|
|
SELECT *
|
|
FROM dbo.CharacterIntelligenceProfiles
|
|
WHERE ImportSessionID = @ImportSessionID
|
|
ORDER BY IsRecurring DESC, Confidence DESC, CanonicalName;
|
|
""",
|
|
new { ImportSessionID = importSessionId });
|
|
return rows.ToList();
|
|
}
|
|
|
|
public async Task<CharacterIntelligenceProfile> UpsertProfileAsync(CharacterIntelligenceProfileSave request)
|
|
{
|
|
using var connection = connectionFactory.CreateConnection();
|
|
return await connection.QuerySingleAsync<CharacterIntelligenceProfile>(
|
|
"""
|
|
MERGE dbo.CharacterIntelligenceProfiles WITH (HOLDLOCK) AS target
|
|
USING (SELECT @ImportSessionID AS ImportSessionID, @CanonicalIdentityKey AS CanonicalIdentityKey) AS source
|
|
ON target.ImportSessionID = source.ImportSessionID
|
|
AND target.CanonicalIdentityKey = source.CanonicalIdentityKey
|
|
WHEN MATCHED THEN
|
|
UPDATE SET
|
|
CanonicalName = @CanonicalName,
|
|
ProfileJson = @ProfileJson,
|
|
Confidence = @Confidence,
|
|
NarrativeImportance = @NarrativeImportance,
|
|
IsRecurring = CASE WHEN @IsRecurring = 1 THEN 1 ELSE target.IsRecurring END,
|
|
EvidenceVersion = @EvidenceVersion,
|
|
LastUpdatedSceneResultID = @SceneResultID,
|
|
UpdatedUtc = SYSUTCDATETIME()
|
|
WHEN NOT MATCHED THEN
|
|
INSERT (ImportSessionID, ProjectID, BookID, CanonicalIdentityKey, CanonicalName, ProfileJson, Confidence, NarrativeImportance, IsRecurring, EvidenceVersion, LastUpdatedSceneResultID)
|
|
VALUES (@ImportSessionID, @ProjectID, @BookID, @CanonicalIdentityKey, @CanonicalName, @ProfileJson, @Confidence, @NarrativeImportance, @IsRecurring, @EvidenceVersion, @SceneResultID);
|
|
|
|
SELECT *
|
|
FROM dbo.CharacterIntelligenceProfiles
|
|
WHERE ImportSessionID = @ImportSessionID
|
|
AND CanonicalIdentityKey = @CanonicalIdentityKey;
|
|
""",
|
|
request);
|
|
}
|
|
|
|
public async Task AddEvidenceAsync(CharacterIntelligenceEvidenceSave request)
|
|
{
|
|
using var connection = connectionFactory.CreateConnection();
|
|
await connection.ExecuteAsync(
|
|
"""
|
|
INSERT dbo.CharacterIntelligenceEvidenceEvents
|
|
(CharacterIntelligenceProfileID, SceneResultID, FieldName, PreviousValue, NewValue, Evidence, Confidence, IsContradiction, Source)
|
|
VALUES
|
|
(@CharacterIntelligenceProfileID, @SceneResultID, @FieldName, @PreviousValue, @NewValue, @Evidence, @Confidence, @IsContradiction, @Source);
|
|
""",
|
|
request);
|
|
}
|
|
}
|
|
|