Public Access
123 lines
4.7 KiB
C#
123 lines
4.7 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace MeetingAssistant.Speakers;
|
|
|
|
internal static class SpeakerIdentitySchema
|
|
{
|
|
public static async Task EnsureCreatedOrUpdatedAsync(
|
|
SpeakerIdentityDbContext context,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
await context.Database.EnsureCreatedAsync(cancellationToken);
|
|
await EnsureSpeakerIdentityTimestampColumnsAsync(context, cancellationToken);
|
|
await context.Database.ExecuteSqlRawAsync(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS "SpeakerAliases" (
|
|
"Id" INTEGER NOT NULL CONSTRAINT "PK_SpeakerAliases" PRIMARY KEY AUTOINCREMENT,
|
|
"SpeakerIdentityId" INTEGER NOT NULL,
|
|
"Name" TEXT NOT NULL,
|
|
CONSTRAINT "FK_SpeakerAliases_SpeakerIdentities_SpeakerIdentityId"
|
|
FOREIGN KEY ("SpeakerIdentityId") REFERENCES "SpeakerIdentities" ("Id") ON DELETE CASCADE
|
|
);
|
|
""",
|
|
cancellationToken);
|
|
await context.Database.ExecuteSqlRawAsync(
|
|
"""
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "IX_SpeakerAliases_SpeakerIdentityId_Name"
|
|
ON "SpeakerAliases" ("SpeakerIdentityId", "Name");
|
|
""",
|
|
cancellationToken);
|
|
await context.Database.ExecuteSqlRawAsync(
|
|
"""
|
|
CREATE TABLE IF NOT EXISTS "SpeakerIdentityReferences" (
|
|
"Id" INTEGER NOT NULL CONSTRAINT "PK_SpeakerIdentityReferences" PRIMARY KEY AUTOINCREMENT,
|
|
"SpeakerIdentityId" INTEGER NOT NULL,
|
|
"MeetingNotePath" TEXT NOT NULL,
|
|
"TranscriptPath" TEXT NOT NULL,
|
|
"CreatedAt" TEXT NOT NULL,
|
|
CONSTRAINT "FK_SpeakerIdentityReferences_SpeakerIdentities_SpeakerIdentityId"
|
|
FOREIGN KEY ("SpeakerIdentityId") REFERENCES "SpeakerIdentities" ("Id") ON DELETE CASCADE
|
|
);
|
|
""",
|
|
cancellationToken);
|
|
await context.Database.ExecuteSqlRawAsync(
|
|
"""
|
|
CREATE UNIQUE INDEX IF NOT EXISTS "IX_SpeakerIdentityReferences_SpeakerIdentityId_MeetingNotePath_TranscriptPath"
|
|
ON "SpeakerIdentityReferences" ("SpeakerIdentityId", "MeetingNotePath", "TranscriptPath");
|
|
""",
|
|
cancellationToken);
|
|
}
|
|
|
|
private static async Task EnsureSpeakerIdentityTimestampColumnsAsync(
|
|
SpeakerIdentityDbContext context,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
const string defaultTimestamp = "1970-01-01T00:00:00.0000000+00:00";
|
|
var hasCreatedAt = await HasColumnAsync(context, "SpeakerIdentities", "CreatedAt", cancellationToken);
|
|
if (!hasCreatedAt)
|
|
{
|
|
await context.Database.ExecuteSqlRawAsync(
|
|
$"""
|
|
ALTER TABLE "SpeakerIdentities"
|
|
ADD COLUMN "CreatedAt" TEXT NOT NULL DEFAULT '{defaultTimestamp}';
|
|
""",
|
|
cancellationToken);
|
|
}
|
|
|
|
var hasUpdatedAt = await HasColumnAsync(context, "SpeakerIdentities", "UpdatedAt", cancellationToken);
|
|
if (!hasUpdatedAt)
|
|
{
|
|
await context.Database.ExecuteSqlRawAsync(
|
|
$"""
|
|
ALTER TABLE "SpeakerIdentities"
|
|
ADD COLUMN "UpdatedAt" TEXT NOT NULL DEFAULT '{defaultTimestamp}';
|
|
""",
|
|
cancellationToken);
|
|
await context.Database.ExecuteSqlRawAsync(
|
|
$"""
|
|
UPDATE "SpeakerIdentities"
|
|
SET "UpdatedAt" = "CreatedAt"
|
|
WHERE "UpdatedAt" = '{defaultTimestamp}';
|
|
""",
|
|
cancellationToken);
|
|
}
|
|
}
|
|
|
|
private static async Task<bool> HasColumnAsync(
|
|
SpeakerIdentityDbContext context,
|
|
string tableName,
|
|
string columnName,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var connection = context.Database.GetDbConnection();
|
|
var shouldClose = connection.State == System.Data.ConnectionState.Closed;
|
|
if (shouldClose)
|
|
{
|
|
await connection.OpenAsync(cancellationToken);
|
|
}
|
|
|
|
try
|
|
{
|
|
await using var command = connection.CreateCommand();
|
|
command.CommandText = $"""PRAGMA table_info("{tableName}")""";
|
|
await using var reader = await command.ExecuteReaderAsync(cancellationToken);
|
|
while (await reader.ReadAsync(cancellationToken))
|
|
{
|
|
if (string.Equals(reader.GetString(1), columnName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
if (shouldClose)
|
|
{
|
|
await connection.CloseAsync();
|
|
}
|
|
}
|
|
}
|
|
}
|