633 lines
25 KiB
Transact-SQL
633 lines
25 KiB
Transact-SQL
SET ANSI_NULLS ON;
|
|
GO
|
|
SET QUOTED_IDENTIFIER ON;
|
|
GO
|
|
|
|
IF OBJECT_ID(N'dbo.NameLocales', N'U') IS NULL
|
|
BEGIN
|
|
CREATE TABLE dbo.NameLocales
|
|
(
|
|
NameLocaleID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_NameLocales PRIMARY KEY,
|
|
LocaleCode nvarchar(16) NOT NULL,
|
|
DisplayName nvarchar(100) NOT NULL,
|
|
IsoCountryCode nvarchar(3) NOT NULL,
|
|
EvidenceBasis nvarchar(300) NOT NULL,
|
|
DefaultConfidence decimal(9,4) NOT NULL,
|
|
SortOrder int NOT NULL,
|
|
IsActive bit NOT NULL CONSTRAINT DF_NameLocales_IsActive DEFAULT 1,
|
|
CreatedUtc datetime2(0) NOT NULL CONSTRAINT DF_NameLocales_CreatedUtc DEFAULT SYSUTCDATETIME(),
|
|
UpdatedUtc datetime2(0) NOT NULL CONSTRAINT DF_NameLocales_UpdatedUtc DEFAULT SYSUTCDATETIME(),
|
|
CONSTRAINT UQ_NameLocales_LocaleCode UNIQUE (LocaleCode),
|
|
CONSTRAINT CK_NameLocales_DefaultConfidence CHECK (DefaultConfidence >= 0 AND DefaultConfidence <= 1)
|
|
);
|
|
END;
|
|
GO
|
|
|
|
IF OBJECT_ID(N'dbo.GivenNames', N'U') IS NULL
|
|
BEGIN
|
|
CREATE TABLE dbo.GivenNames
|
|
(
|
|
GivenNameID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_GivenNames PRIMARY KEY,
|
|
GivenNameKey nvarchar(80) NOT NULL,
|
|
DisplayName nvarchar(120) NOT NULL,
|
|
NormalisedName nvarchar(120) COLLATE Latin1_General_100_CI_AI_SC NOT NULL,
|
|
NameType nvarchar(40) NOT NULL,
|
|
IsWordAmbiguous bit NOT NULL,
|
|
IsActive bit NOT NULL CONSTRAINT DF_GivenNames_IsActive DEFAULT 1,
|
|
Notes nvarchar(500) NULL,
|
|
CreatedUtc datetime2(0) NOT NULL CONSTRAINT DF_GivenNames_CreatedUtc DEFAULT SYSUTCDATETIME(),
|
|
UpdatedUtc datetime2(0) NOT NULL CONSTRAINT DF_GivenNames_UpdatedUtc DEFAULT SYSUTCDATETIME(),
|
|
CONSTRAINT UQ_GivenNames_GivenNameKey UNIQUE (GivenNameKey),
|
|
CONSTRAINT UQ_GivenNames_NormalisedName UNIQUE (NormalisedName),
|
|
CONSTRAINT CK_GivenNames_NameType CHECK (NameType IN (N'Canonical', N'Independent', N'Diminutive', N'Nickname', N'Variant'))
|
|
);
|
|
END;
|
|
GO
|
|
|
|
IF OBJECT_ID(N'dbo.NameRelationships', N'U') IS NULL
|
|
BEGIN
|
|
CREATE TABLE dbo.NameRelationships
|
|
(
|
|
NameRelationshipID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_NameRelationships PRIMARY KEY,
|
|
RelationshipKey nvarchar(80) NOT NULL,
|
|
FromGivenNameID int NOT NULL,
|
|
ToGivenNameID int NOT NULL,
|
|
RelationshipType nvarchar(40) NOT NULL,
|
|
Strength decimal(9,4) NOT NULL,
|
|
IsBidirectional bit NOT NULL,
|
|
IsActive bit NOT NULL CONSTRAINT DF_NameRelationships_IsActive DEFAULT 1,
|
|
CurationSource nvarchar(120) NULL,
|
|
Notes nvarchar(500) NULL,
|
|
CreatedUtc datetime2(0) NOT NULL CONSTRAINT DF_NameRelationships_CreatedUtc DEFAULT SYSUTCDATETIME(),
|
|
UpdatedUtc datetime2(0) NOT NULL CONSTRAINT DF_NameRelationships_UpdatedUtc DEFAULT SYSUTCDATETIME(),
|
|
CONSTRAINT UQ_NameRelationships_RelationshipKey UNIQUE (RelationshipKey),
|
|
CONSTRAINT FK_NameRelationships_FromGivenName FOREIGN KEY (FromGivenNameID) REFERENCES dbo.GivenNames(GivenNameID),
|
|
CONSTRAINT FK_NameRelationships_ToGivenName FOREIGN KEY (ToGivenNameID) REFERENCES dbo.GivenNames(GivenNameID),
|
|
CONSTRAINT CK_NameRelationships_NotSelf CHECK (FromGivenNameID <> ToGivenNameID),
|
|
CONSTRAINT CK_NameRelationships_Strength CHECK (Strength >= 0 AND Strength <= 1),
|
|
CONSTRAINT CK_NameRelationships_Type CHECK (RelationshipType IN (N'ShortForm', N'Diminutive', N'Nickname', N'SpellingVariant', N'AlternativeForm', N'AnglicisedForm'))
|
|
);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'UX_NameRelationships_ActivePairType' AND object_id = OBJECT_ID(N'dbo.NameRelationships'))
|
|
CREATE UNIQUE INDEX UX_NameRelationships_ActivePairType ON dbo.NameRelationships(FromGivenNameID, ToGivenNameID, RelationshipType) WHERE IsActive = 1;
|
|
GO
|
|
|
|
IF OBJECT_ID(N'dbo.NameUsages', N'U') IS NULL
|
|
BEGIN
|
|
CREATE TABLE dbo.NameUsages
|
|
(
|
|
NameUsageID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_NameUsages PRIMARY KEY,
|
|
UsageKey nvarchar(80) NOT NULL,
|
|
GivenNameID int NOT NULL,
|
|
NameLocaleID int NOT NULL,
|
|
BirthYearFrom int NOT NULL,
|
|
BirthYearTo int NOT NULL,
|
|
MaleWeight decimal(9,4) NOT NULL,
|
|
FemaleWeight decimal(9,4) NOT NULL,
|
|
UsageWeight decimal(9,4) NOT NULL,
|
|
Confidence decimal(9,4) NOT NULL,
|
|
SourceType nvarchar(60) NOT NULL,
|
|
SourceReference nvarchar(300) NULL,
|
|
IsActive bit NOT NULL CONSTRAINT DF_NameUsages_IsActive DEFAULT 1,
|
|
Notes nvarchar(500) NULL,
|
|
CreatedUtc datetime2(0) NOT NULL CONSTRAINT DF_NameUsages_CreatedUtc DEFAULT SYSUTCDATETIME(),
|
|
UpdatedUtc datetime2(0) NOT NULL CONSTRAINT DF_NameUsages_UpdatedUtc DEFAULT SYSUTCDATETIME(),
|
|
CONSTRAINT UQ_NameUsages_UsageKey UNIQUE (UsageKey),
|
|
CONSTRAINT UQ_NameUsages_NameLocaleYears UNIQUE (GivenNameID, NameLocaleID, BirthYearFrom, BirthYearTo),
|
|
CONSTRAINT FK_NameUsages_GivenName FOREIGN KEY (GivenNameID) REFERENCES dbo.GivenNames(GivenNameID),
|
|
CONSTRAINT FK_NameUsages_NameLocale FOREIGN KEY (NameLocaleID) REFERENCES dbo.NameLocales(NameLocaleID),
|
|
CONSTRAINT CK_NameUsages_YearOrder CHECK (BirthYearFrom <= BirthYearTo),
|
|
CONSTRAINT CK_NameUsages_Weights CHECK (MaleWeight >= 0 AND MaleWeight <= 1 AND FemaleWeight >= 0 AND FemaleWeight <= 1 AND UsageWeight >= 0 AND UsageWeight <= 1 AND Confidence >= 0 AND Confidence <= 1),
|
|
CONSTRAINT CK_NameUsages_GenderTotal CHECK (ABS((MaleWeight + FemaleWeight) - 1.0000) <= 0.0002),
|
|
CONSTRAINT CK_NameUsages_SourceType CHECK (SourceType IN (N'OfficialStatisticalDerived', N'OfficialSourceBlendedEstimate'))
|
|
);
|
|
END;
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_NameUsages_QueryPath' AND object_id = OBJECT_ID(N'dbo.NameUsages'))
|
|
CREATE INDEX IX_NameUsages_QueryPath ON dbo.NameUsages(GivenNameID, NameLocaleID, IsActive, BirthYearFrom, BirthYearTo) INCLUDE (MaleWeight, FemaleWeight, UsageWeight, Confidence, SourceType);
|
|
GO
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_GivenNames_Search' AND object_id = OBJECT_ID(N'dbo.GivenNames'))
|
|
CREATE INDEX IX_GivenNames_Search ON dbo.GivenNames(IsActive, NormalisedName, DisplayName) INCLUDE (NameType, IsWordAmbiguous);
|
|
GO
|
|
|
|
IF OBJECT_ID(N'dbo.NameReferenceImports', N'U') IS NULL
|
|
BEGIN
|
|
CREATE TABLE dbo.NameReferenceImports
|
|
(
|
|
NameReferenceImportID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_NameReferenceImports PRIMARY KEY,
|
|
PackageID nvarchar(120) NOT NULL,
|
|
SemanticVersion nvarchar(40) NOT NULL,
|
|
PackageChecksum nvarchar(128) NULL,
|
|
StartedUtc datetime2(0) NOT NULL CONSTRAINT DF_NameReferenceImports_StartedUtc DEFAULT SYSUTCDATETIME(),
|
|
CompletedUtc datetime2(0) NULL,
|
|
Succeeded bit NOT NULL CONSTRAINT DF_NameReferenceImports_Succeeded DEFAULT 0,
|
|
LocaleRows int NOT NULL CONSTRAINT DF_NameReferenceImports_LocaleRows DEFAULT 0,
|
|
GivenNameRows int NOT NULL CONSTRAINT DF_NameReferenceImports_GivenNameRows DEFAULT 0,
|
|
RelationshipRows int NOT NULL CONSTRAINT DF_NameReferenceImports_RelationshipRows DEFAULT 0,
|
|
UsageRows int NOT NULL CONSTRAINT DF_NameReferenceImports_UsageRows DEFAULT 0,
|
|
ErrorSummary nvarchar(max) NULL
|
|
);
|
|
END;
|
|
GO
|
|
|
|
IF TYPE_ID(N'dbo.NameLocaleImportTable') IS NULL
|
|
CREATE TYPE dbo.NameLocaleImportTable AS TABLE
|
|
(
|
|
LocaleCode nvarchar(16) NOT NULL,
|
|
DisplayName nvarchar(100) NOT NULL,
|
|
IsoCountryCode nvarchar(3) NOT NULL,
|
|
EvidenceBasis nvarchar(300) NOT NULL,
|
|
DefaultConfidence decimal(9,4) NOT NULL,
|
|
SortOrder int NOT NULL,
|
|
IsActive bit NOT NULL
|
|
);
|
|
GO
|
|
|
|
IF TYPE_ID(N'dbo.GivenNameImportTable') IS NULL
|
|
CREATE TYPE dbo.GivenNameImportTable AS TABLE
|
|
(
|
|
GivenNameKey nvarchar(80) NOT NULL,
|
|
DisplayName nvarchar(120) NOT NULL,
|
|
NormalisedName nvarchar(120) NOT NULL,
|
|
NameType nvarchar(40) NOT NULL,
|
|
IsWordAmbiguous bit NOT NULL,
|
|
IsActive bit NOT NULL,
|
|
Notes nvarchar(500) NULL
|
|
);
|
|
GO
|
|
|
|
IF TYPE_ID(N'dbo.NameRelationshipImportTable') IS NULL
|
|
CREATE TYPE dbo.NameRelationshipImportTable AS TABLE
|
|
(
|
|
RelationshipKey nvarchar(80) NOT NULL,
|
|
FromGivenNameKey nvarchar(80) NOT NULL,
|
|
ToGivenNameKey nvarchar(80) NOT NULL,
|
|
RelationshipType nvarchar(40) NOT NULL,
|
|
Strength decimal(9,4) NOT NULL,
|
|
IsBidirectional bit NOT NULL,
|
|
IsActive bit NOT NULL,
|
|
CurationSource nvarchar(120) NULL,
|
|
Notes nvarchar(500) NULL
|
|
);
|
|
GO
|
|
|
|
IF TYPE_ID(N'dbo.NameUsageImportTable') IS NULL
|
|
CREATE TYPE dbo.NameUsageImportTable AS TABLE
|
|
(
|
|
UsageKey nvarchar(80) NOT NULL,
|
|
GivenNameKey nvarchar(80) NOT NULL,
|
|
LocaleCode nvarchar(16) NOT NULL,
|
|
BirthYearFrom int NOT NULL,
|
|
BirthYearTo int NOT NULL,
|
|
MaleWeight decimal(9,4) NOT NULL,
|
|
FemaleWeight decimal(9,4) NOT NULL,
|
|
UsageWeight decimal(9,4) NOT NULL,
|
|
Confidence decimal(9,4) NOT NULL,
|
|
SourceType nvarchar(60) NOT NULL,
|
|
SourceReference nvarchar(300) NULL,
|
|
IsActive bit NOT NULL,
|
|
Notes nvarchar(500) NULL
|
|
);
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.NameReferenceImport_GetLatest
|
|
@PackageID nvarchar(120),
|
|
@SemanticVersion nvarchar(40)
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
SELECT TOP (1) *
|
|
FROM dbo.NameReferenceImports
|
|
WHERE PackageID = @PackageID
|
|
AND SemanticVersion = @SemanticVersion
|
|
AND Succeeded = 1
|
|
ORDER BY CompletedUtc DESC, NameReferenceImportID DESC;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.NameReferenceImport_Start
|
|
@PackageID nvarchar(120),
|
|
@SemanticVersion nvarchar(40),
|
|
@PackageChecksum nvarchar(128)
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
INSERT dbo.NameReferenceImports (PackageID, SemanticVersion, PackageChecksum)
|
|
VALUES (@PackageID, @SemanticVersion, @PackageChecksum);
|
|
|
|
SELECT CAST(SCOPE_IDENTITY() AS int) AS NameReferenceImportID;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.NameReferenceImport_Complete
|
|
@NameReferenceImportID int,
|
|
@Succeeded bit,
|
|
@LocaleRows int,
|
|
@GivenNameRows int,
|
|
@RelationshipRows int,
|
|
@UsageRows int,
|
|
@ErrorSummary nvarchar(max) = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
UPDATE dbo.NameReferenceImports
|
|
SET CompletedUtc = SYSUTCDATETIME(),
|
|
Succeeded = @Succeeded,
|
|
LocaleRows = @LocaleRows,
|
|
GivenNameRows = @GivenNameRows,
|
|
RelationshipRows = @RelationshipRows,
|
|
UsageRows = @UsageRows,
|
|
ErrorSummary = @ErrorSummary
|
|
WHERE NameReferenceImportID = @NameReferenceImportID;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.NameLocale_BulkUpsert
|
|
@Rows dbo.NameLocaleImportTable READONLY
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
MERGE dbo.NameLocales WITH (HOLDLOCK) AS target
|
|
USING @Rows AS source
|
|
ON target.LocaleCode = source.LocaleCode
|
|
WHEN MATCHED THEN
|
|
UPDATE SET DisplayName = source.DisplayName,
|
|
IsoCountryCode = source.IsoCountryCode,
|
|
EvidenceBasis = source.EvidenceBasis,
|
|
DefaultConfidence = source.DefaultConfidence,
|
|
SortOrder = source.SortOrder,
|
|
IsActive = source.IsActive,
|
|
UpdatedUtc = SYSUTCDATETIME()
|
|
WHEN NOT MATCHED THEN
|
|
INSERT (LocaleCode, DisplayName, IsoCountryCode, EvidenceBasis, DefaultConfidence, SortOrder, IsActive)
|
|
VALUES (source.LocaleCode, source.DisplayName, source.IsoCountryCode, source.EvidenceBasis, source.DefaultConfidence, source.SortOrder, source.IsActive);
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.GivenName_BulkUpsert
|
|
@Rows dbo.GivenNameImportTable READONLY
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
MERGE dbo.GivenNames WITH (HOLDLOCK) AS target
|
|
USING @Rows AS source
|
|
ON target.GivenNameKey = source.GivenNameKey
|
|
WHEN MATCHED THEN
|
|
UPDATE SET DisplayName = source.DisplayName,
|
|
NormalisedName = source.NormalisedName,
|
|
NameType = source.NameType,
|
|
IsWordAmbiguous = source.IsWordAmbiguous,
|
|
IsActive = source.IsActive,
|
|
Notes = source.Notes,
|
|
UpdatedUtc = SYSUTCDATETIME()
|
|
WHEN NOT MATCHED THEN
|
|
INSERT (GivenNameKey, DisplayName, NormalisedName, NameType, IsWordAmbiguous, IsActive, Notes)
|
|
VALUES (source.GivenNameKey, source.DisplayName, source.NormalisedName, source.NameType, source.IsWordAmbiguous, source.IsActive, source.Notes);
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.NameRelationship_BulkUpsert
|
|
@Rows dbo.NameRelationshipImportTable READONLY
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
MERGE dbo.NameRelationships WITH (HOLDLOCK) AS target
|
|
USING
|
|
(
|
|
SELECT r.*, f.GivenNameID AS FromGivenNameID, t.GivenNameID AS ToGivenNameID
|
|
FROM @Rows r
|
|
INNER JOIN dbo.GivenNames f ON f.GivenNameKey = r.FromGivenNameKey
|
|
INNER JOIN dbo.GivenNames t ON t.GivenNameKey = r.ToGivenNameKey
|
|
) AS source
|
|
ON target.RelationshipKey = source.RelationshipKey
|
|
WHEN MATCHED THEN
|
|
UPDATE SET FromGivenNameID = source.FromGivenNameID,
|
|
ToGivenNameID = source.ToGivenNameID,
|
|
RelationshipType = source.RelationshipType,
|
|
Strength = source.Strength,
|
|
IsBidirectional = source.IsBidirectional,
|
|
IsActive = source.IsActive,
|
|
CurationSource = source.CurationSource,
|
|
Notes = source.Notes,
|
|
UpdatedUtc = SYSUTCDATETIME()
|
|
WHEN NOT MATCHED THEN
|
|
INSERT (RelationshipKey, FromGivenNameID, ToGivenNameID, RelationshipType, Strength, IsBidirectional, IsActive, CurationSource, Notes)
|
|
VALUES (source.RelationshipKey, source.FromGivenNameID, source.ToGivenNameID, source.RelationshipType, source.Strength, source.IsBidirectional, source.IsActive, source.CurationSource, source.Notes);
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.NameUsage_BulkUpsert
|
|
@Rows dbo.NameUsageImportTable READONLY
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
MERGE dbo.NameUsages WITH (HOLDLOCK) AS target
|
|
USING
|
|
(
|
|
SELECT r.*, g.GivenNameID, l.NameLocaleID
|
|
FROM @Rows r
|
|
INNER JOIN dbo.GivenNames g ON g.GivenNameKey = r.GivenNameKey
|
|
INNER JOIN dbo.NameLocales l ON l.LocaleCode = r.LocaleCode
|
|
) AS source
|
|
ON target.UsageKey = source.UsageKey
|
|
WHEN MATCHED THEN
|
|
UPDATE SET GivenNameID = source.GivenNameID,
|
|
NameLocaleID = source.NameLocaleID,
|
|
BirthYearFrom = source.BirthYearFrom,
|
|
BirthYearTo = source.BirthYearTo,
|
|
MaleWeight = source.MaleWeight,
|
|
FemaleWeight = source.FemaleWeight,
|
|
UsageWeight = source.UsageWeight,
|
|
Confidence = source.Confidence,
|
|
SourceType = source.SourceType,
|
|
SourceReference = source.SourceReference,
|
|
IsActive = source.IsActive,
|
|
Notes = source.Notes,
|
|
UpdatedUtc = SYSUTCDATETIME()
|
|
WHEN NOT MATCHED THEN
|
|
INSERT (UsageKey, GivenNameID, NameLocaleID, BirthYearFrom, BirthYearTo, MaleWeight, FemaleWeight, UsageWeight, Confidence, SourceType, SourceReference, IsActive, Notes)
|
|
VALUES (source.UsageKey, source.GivenNameID, source.NameLocaleID, source.BirthYearFrom, source.BirthYearTo, source.MaleWeight, source.FemaleWeight, source.UsageWeight, source.Confidence, source.SourceType, source.SourceReference, source.IsActive, source.Notes);
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.NameLocale_List
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
SELECT *
|
|
FROM dbo.NameLocales
|
|
WHERE IsActive = 1
|
|
ORDER BY SortOrder, DisplayName;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.GivenName_Recognise
|
|
@NormalisedName nvarchar(120),
|
|
@LocaleCode nvarchar(16) = NULL,
|
|
@BirthYear int = NULL
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
DECLARE @GivenNameID int;
|
|
DECLARE @NameLocaleID int;
|
|
|
|
SELECT TOP (1) @GivenNameID = GivenNameID
|
|
FROM dbo.GivenNames
|
|
WHERE NormalisedName = @NormalisedName COLLATE Latin1_General_100_CI_AI_SC
|
|
AND IsActive = 1;
|
|
|
|
SELECT TOP (1) @NameLocaleID = NameLocaleID
|
|
FROM dbo.NameLocales
|
|
WHERE IsActive = 1
|
|
AND LocaleCode = COALESCE(@LocaleCode, N'en-US');
|
|
|
|
IF @NameLocaleID IS NULL
|
|
SELECT TOP (1) @NameLocaleID = NameLocaleID FROM dbo.NameLocales WHERE LocaleCode = N'en-US' AND IsActive = 1;
|
|
|
|
SELECT *
|
|
FROM dbo.GivenNames
|
|
WHERE GivenNameID = @GivenNameID;
|
|
|
|
IF @GivenNameID IS NOT NULL
|
|
BEGIN
|
|
SELECT TOP (1)
|
|
u.*,
|
|
l.LocaleCode,
|
|
l.DisplayName AS LocaleDisplayName,
|
|
CASE
|
|
WHEN @BirthYear IS NULL THEN N'General'
|
|
WHEN @BirthYear BETWEEN u.BirthYearFrom AND u.BirthYearTo THEN N'ExactEra'
|
|
ELSE N'NearestEra'
|
|
END AS YearMatchKind
|
|
FROM dbo.NameUsages u
|
|
INNER JOIN dbo.NameLocales l ON l.NameLocaleID = u.NameLocaleID
|
|
WHERE u.GivenNameID = @GivenNameID
|
|
AND u.NameLocaleID = @NameLocaleID
|
|
AND u.IsActive = 1
|
|
ORDER BY
|
|
CASE WHEN @BirthYear IS NOT NULL AND @BirthYear BETWEEN u.BirthYearFrom AND u.BirthYearTo THEN 0 ELSE 1 END,
|
|
CASE WHEN @BirthYear IS NULL THEN ABS(1960 - ((u.BirthYearFrom + u.BirthYearTo) / 2)) ELSE ABS(@BirthYear - ((u.BirthYearFrom + u.BirthYearTo) / 2)) END,
|
|
u.UsageWeight DESC;
|
|
|
|
EXEC dbo.GivenName_Relationships @GivenNameID = @GivenNameID;
|
|
END;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.GivenName_Relationships
|
|
@GivenNameID int
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
SELECT
|
|
r.NameRelationshipID,
|
|
r.RelationshipKey,
|
|
r.FromGivenNameID,
|
|
r.ToGivenNameID,
|
|
f.DisplayName AS FromDisplayName,
|
|
t.DisplayName AS ToDisplayName,
|
|
r.RelationshipType,
|
|
r.Strength,
|
|
r.IsBidirectional,
|
|
r.IsActive,
|
|
r.CurationSource,
|
|
r.Notes
|
|
FROM dbo.NameRelationships r
|
|
INNER JOIN dbo.GivenNames f ON f.GivenNameID = r.FromGivenNameID
|
|
INNER JOIN dbo.GivenNames t ON t.GivenNameID = r.ToGivenNameID
|
|
WHERE r.IsActive = 1
|
|
AND (r.FromGivenNameID = @GivenNameID OR (r.IsBidirectional = 1 AND r.ToGivenNameID = @GivenNameID))
|
|
ORDER BY r.Strength DESC, t.DisplayName;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.GivenName_Search
|
|
@UserID int,
|
|
@ProjectID int,
|
|
@BookID int = NULL,
|
|
@Search nvarchar(120) = NULL,
|
|
@LocaleCode nvarchar(16) = NULL,
|
|
@BirthYear int = NULL,
|
|
@GenderPreference nvarchar(12) = NULL,
|
|
@GenderThreshold decimal(9,4) = NULL,
|
|
@NameType nvarchar(40) = NULL,
|
|
@MinimumUsage decimal(9,4) = NULL,
|
|
@UsedScope nvarchar(20) = N'Project',
|
|
@UsedOnly bit = NULL,
|
|
@Page int = 1,
|
|
@PageSize int = 25
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.ProjectUserAccess WHERE ProjectID = @ProjectID AND UserID = @UserID AND IsActive = 1)
|
|
BEGIN
|
|
SELECT TOP (0) CAST(NULL AS int) AS GivenNameID;
|
|
RETURN;
|
|
END;
|
|
|
|
IF @Page < 1 SET @Page = 1;
|
|
IF @PageSize < 1 SET @PageSize = 25;
|
|
IF @PageSize > 100 SET @PageSize = 100;
|
|
|
|
DECLARE @NameLocaleID int = NULL;
|
|
IF @LocaleCode IS NOT NULL
|
|
BEGIN
|
|
SELECT TOP (1) @NameLocaleID = NameLocaleID FROM dbo.NameLocales WHERE LocaleCode = @LocaleCode AND IsActive = 1;
|
|
END;
|
|
|
|
;WITH UsageChoice AS
|
|
(
|
|
SELECT
|
|
u.*,
|
|
l.LocaleCode,
|
|
l.DisplayName AS LocaleDisplayName,
|
|
ROW_NUMBER() OVER (PARTITION BY u.GivenNameID ORDER BY
|
|
CASE WHEN @BirthYear IS NOT NULL AND @BirthYear BETWEEN u.BirthYearFrom AND u.BirthYearTo THEN 0 ELSE 1 END,
|
|
CASE WHEN @BirthYear IS NULL THEN ABS(1960 - ((u.BirthYearFrom + u.BirthYearTo) / 2)) ELSE ABS(@BirthYear - ((u.BirthYearFrom + u.BirthYearTo) / 2)) END,
|
|
u.UsageWeight DESC) AS rn
|
|
FROM dbo.NameUsages u
|
|
INNER JOIN dbo.NameLocales l ON l.NameLocaleID = u.NameLocaleID
|
|
WHERE u.IsActive = 1
|
|
AND (@NameLocaleID IS NULL OR u.NameLocaleID = @NameLocaleID)
|
|
),
|
|
Used AS
|
|
(
|
|
SELECT g.GivenNameID, COUNT(DISTINCT c.CharacterID) AS UsedCount,
|
|
STRING_AGG(CONVERT(nvarchar(max), c.CharacterName + N' (' + p.ProjectName + COALESCE(N' / ' + b.BookTitle, N'') + N')'), N'; ') AS UsedSummary
|
|
FROM dbo.GivenNames g
|
|
INNER JOIN
|
|
(
|
|
SELECT c.CharacterID, c.ProjectID, c.CharacterName, c.CharacterName AS MatchedName
|
|
FROM dbo.Characters c
|
|
WHERE c.IsArchived = 0
|
|
UNION ALL
|
|
SELECT c.CharacterID, c.ProjectID, c.CharacterName, ca.Alias AS MatchedName
|
|
FROM dbo.CharacterAliases ca
|
|
INNER JOIN dbo.Characters c ON c.CharacterID = ca.CharacterID
|
|
WHERE c.IsArchived = 0
|
|
) c ON UPPER(LTRIM(RTRIM(c.MatchedName))) = g.NormalisedName COLLATE Latin1_General_100_CI_AI_SC
|
|
INNER JOIN dbo.Projects p ON p.ProjectID = c.ProjectID
|
|
INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = c.ProjectID AND pua.UserID = @UserID AND pua.IsActive = 1
|
|
LEFT JOIN dbo.Books b ON b.ProjectID = c.ProjectID AND b.IsArchived = 0
|
|
WHERE (@UsedScope = N'Library' OR c.ProjectID = @ProjectID)
|
|
AND (@BookID IS NULL OR @UsedScope <> N'Book' OR b.BookID = @BookID)
|
|
GROUP BY g.GivenNameID
|
|
),
|
|
Related AS
|
|
(
|
|
SELECT x.GivenNameID,
|
|
STRING_AGG(CONVERT(nvarchar(max), x.DisplayName), N', ') AS RelatedForms
|
|
FROM
|
|
(
|
|
SELECT r.FromGivenNameID AS GivenNameID, t.DisplayName
|
|
FROM dbo.NameRelationships r
|
|
INNER JOIN dbo.GivenNames t ON t.GivenNameID = r.ToGivenNameID
|
|
WHERE r.IsActive = 1
|
|
UNION
|
|
SELECT r.ToGivenNameID AS GivenNameID, f.DisplayName
|
|
FROM dbo.NameRelationships r
|
|
INNER JOIN dbo.GivenNames f ON f.GivenNameID = r.FromGivenNameID
|
|
WHERE r.IsActive = 1 AND r.IsBidirectional = 1
|
|
) x
|
|
GROUP BY x.GivenNameID
|
|
),
|
|
Filtered AS
|
|
(
|
|
SELECT
|
|
g.GivenNameID, g.GivenNameKey, g.DisplayName, g.NormalisedName, g.NameType, g.IsWordAmbiguous,
|
|
u.MaleWeight, u.FemaleWeight, u.UsageWeight, u.Confidence, u.BirthYearFrom, u.BirthYearTo, u.LocaleCode, u.LocaleDisplayName, u.SourceType,
|
|
rel.RelatedForms,
|
|
COALESCE(used.UsedSummary, N'') AS UsedSummary,
|
|
COALESCE(used.UsedCount, 0) AS UsedCount,
|
|
COUNT(1) OVER() AS TotalRows
|
|
FROM dbo.GivenNames g
|
|
LEFT JOIN UsageChoice u ON u.GivenNameID = g.GivenNameID AND u.rn = 1
|
|
LEFT JOIN Used used ON used.GivenNameID = g.GivenNameID
|
|
LEFT JOIN Related rel ON rel.GivenNameID = g.GivenNameID
|
|
WHERE g.IsActive = 1
|
|
AND (@Search IS NULL OR g.NormalisedName LIKE UPPER(LTRIM(RTRIM(@Search))) + N'%' COLLATE Latin1_General_100_CI_AI_SC OR g.DisplayName LIKE @Search + N'%')
|
|
AND (@NameType IS NULL OR g.NameType = @NameType)
|
|
AND (@MinimumUsage IS NULL OR u.UsageWeight >= @MinimumUsage)
|
|
AND (@UsedOnly IS NULL OR (@UsedOnly = 1 AND COALESCE(used.UsedCount, 0) > 0) OR (@UsedOnly = 0 AND COALESCE(used.UsedCount, 0) = 0))
|
|
AND (
|
|
@GenderPreference IS NULL
|
|
OR @GenderThreshold IS NULL
|
|
OR (@GenderPreference = N'Female' AND u.FemaleWeight >= @GenderThreshold)
|
|
OR (@GenderPreference = N'Male' AND u.MaleWeight >= @GenderThreshold)
|
|
OR (@GenderPreference = N'Mixed' AND u.MaleWeight >= (1 - @GenderThreshold) AND u.FemaleWeight >= (1 - @GenderThreshold))
|
|
)
|
|
)
|
|
SELECT *
|
|
FROM Filtered
|
|
ORDER BY
|
|
CASE WHEN @Search IS NOT NULL AND NormalisedName = UPPER(LTRIM(RTRIM(@Search))) COLLATE Latin1_General_100_CI_AI_SC THEN 0 ELSE 1 END,
|
|
UsageWeight DESC,
|
|
DisplayName
|
|
OFFSET (@Page - 1) * @PageSize ROWS FETCH NEXT @PageSize ROWS ONLY;
|
|
END;
|
|
GO
|
|
|
|
CREATE OR ALTER PROCEDURE dbo.GivenName_UsedDecorations
|
|
@UserID int,
|
|
@ProjectID int,
|
|
@BookID int = NULL,
|
|
@NormalisedName nvarchar(120),
|
|
@UsedScope nvarchar(20) = N'Project'
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM dbo.ProjectUserAccess WHERE ProjectID = @ProjectID AND UserID = @UserID AND IsActive = 1)
|
|
RETURN;
|
|
|
|
SELECT
|
|
rows.MatchedName,
|
|
rows.MatchType,
|
|
c.CharacterID,
|
|
c.CharacterName,
|
|
p.ProjectID,
|
|
p.ProjectName,
|
|
b.BookID,
|
|
b.BookTitle,
|
|
b.Subtitle AS BookSubtitle,
|
|
CASE WHEN b.BookID IS NOT NULL THEN N'Book' ELSE N'Project' END AS Scope
|
|
FROM
|
|
(
|
|
SELECT c.CharacterID, c.ProjectID, c.CharacterName AS MatchedName, N'Character' AS MatchType
|
|
FROM dbo.Characters c
|
|
WHERE c.IsArchived = 0
|
|
UNION ALL
|
|
SELECT ca.CharacterID, c.ProjectID, ca.Alias AS MatchedName, N'Alias' AS MatchType
|
|
FROM dbo.CharacterAliases ca
|
|
INNER JOIN dbo.Characters c ON c.CharacterID = ca.CharacterID
|
|
WHERE c.IsArchived = 0
|
|
) rows
|
|
INNER JOIN dbo.Characters c ON c.CharacterID = rows.CharacterID
|
|
INNER JOIN dbo.Projects p ON p.ProjectID = c.ProjectID
|
|
INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = c.ProjectID AND pua.UserID = @UserID AND pua.IsActive = 1
|
|
LEFT JOIN dbo.SceneCharacters sc ON sc.CharacterID = c.CharacterID
|
|
LEFT JOIN dbo.Scenes s ON s.SceneID = sc.SceneID AND s.IsArchived = 0
|
|
LEFT JOIN dbo.Chapters ch ON ch.ChapterID = s.ChapterID AND ch.IsArchived = 0
|
|
LEFT JOIN dbo.Books b ON b.BookID = ch.BookID AND b.IsArchived = 0
|
|
WHERE UPPER(LTRIM(RTRIM(rows.MatchedName))) = @NormalisedName COLLATE Latin1_General_100_CI_AI_SC
|
|
AND (@UsedScope = N'Library' OR c.ProjectID = @ProjectID)
|
|
AND (@BookID IS NULL OR @UsedScope <> N'Book' OR b.BookID = @BookID)
|
|
ORDER BY p.ProjectName, b.SortOrder, c.CharacterName;
|
|
END;
|
|
GO
|