diff --git a/services/Directory/FilterLists.Directory.Domain/Aggregates/AggregateType.cs b/services/Directory/FilterLists.Directory.Domain/Aggregates/AggregateType.cs new file mode 100644 index 000000000..e018ca840 --- /dev/null +++ b/services/Directory/FilterLists.Directory.Domain/Aggregates/AggregateType.cs @@ -0,0 +1,12 @@ +namespace FilterLists.Directory.Domain.Aggregates; + +public enum AggregateType +{ + FilterList, + Language, + License, + Maintainer, + Software, + Syntax, + Tag +} diff --git a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/Context/CommandDbContext.cs b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/Context/CommandDbContext.cs index 391213a6f..55720239d 100644 --- a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/Context/CommandDbContext.cs +++ b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/Context/CommandDbContext.cs @@ -1,12 +1,19 @@ -using FilterLists.Directory.Domain.Aggregates.FilterLists; +using FilterLists.Directory.Domain.Aggregates; +using FilterLists.Directory.Domain.Aggregates.FilterLists; using FilterLists.Directory.Domain.Aggregates.Licenses; using FilterLists.Directory.Infrastructure.Persistence.Commands.EntityTypeConfigurations; using Microsoft.EntityFrameworkCore; +using Npgsql; namespace FilterLists.Directory.Infrastructure.Persistence.Commands.Context; internal class CommandDbContext : DbContext, ICommandContext { + static CommandDbContext() + { + NpgsqlConnection.GlobalTypeMapper.MapEnum(); + } + public CommandDbContext(DbContextOptions options) : base(options) { } @@ -18,5 +25,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly, type => type.Namespace == typeof(FilterListTypeConfiguration).Namespace); + modelBuilder.HasPostgresEnum(); } } diff --git a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/EntityTypeConfigurations/ChangeTypeConfiguration.cs b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/EntityTypeConfigurations/ChangeTypeConfiguration.cs index b8b62c854..ef1121858 100644 --- a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/EntityTypeConfigurations/ChangeTypeConfiguration.cs +++ b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Commands/EntityTypeConfigurations/ChangeTypeConfiguration.cs @@ -1,4 +1,7 @@ -using FilterLists.Directory.Domain.Aggregates.Changes; +using System.Globalization; +using EFCore.NamingConventions.Internal; +using FilterLists.Directory.Domain.Aggregates; +using FilterLists.Directory.Domain.Aggregates.Changes; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -8,6 +11,12 @@ internal class ChangeTypeConfiguration : IEntityTypeConfiguration { public virtual void Configure(EntityTypeBuilder builder) { + // TODO: register and resolve INameRewriter + var nr = new SnakeCaseNameRewriter(CultureInfo.InvariantCulture); builder.Property(nameof(Queries.Entities.Change.Id)); + + // TODO: TDiscriminator should really be AggregateType rather than string but needs name rewriting + builder.HasDiscriminator(nr.RewriteName(nameof(Queries.Entities.Change.AggregateType))) + .HasValue(nr.RewriteName(nameof(AggregateType.FilterList))); } } diff --git a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Context/QueryDbContext.cs b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Context/QueryDbContext.cs index 34de1085f..1714787e5 100644 --- a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Context/QueryDbContext.cs +++ b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Context/QueryDbContext.cs @@ -1,10 +1,17 @@ -using FilterLists.Directory.Infrastructure.Persistence.Queries.Entities; +using FilterLists.Directory.Domain.Aggregates; +using FilterLists.Directory.Infrastructure.Persistence.Queries.Entities; using Microsoft.EntityFrameworkCore; +using Npgsql; namespace FilterLists.Directory.Infrastructure.Persistence.Queries.Context; public class QueryDbContext : DbContext { + static QueryDbContext() + { + NpgsqlConnection.GlobalTypeMapper.MapEnum(); + } + public QueryDbContext(DbContextOptions options) : base(options) { } @@ -34,5 +41,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly, type => type.Namespace == typeof(FilterListTypeConfiguration).Namespace); + modelBuilder.HasPostgresEnum(); } } diff --git a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Entities/Change.cs b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Entities/Change.cs index 79a4be35c..a7baa5a26 100644 --- a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Entities/Change.cs +++ b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/Queries/Entities/Change.cs @@ -1,6 +1,7 @@ using System.Globalization; using System.Text.Json; using EFCore.NamingConventions.Internal; +using FilterLists.Directory.Domain.Aggregates; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; @@ -16,7 +17,7 @@ public record Change public string? RejectedReason { get; private init; } public JsonDocument? AggregateBefore { get; private init; } public JsonDocument? AggregateAfter { get; private init; } - public string? AggregateType { get; private init; } + public AggregateType? AggregateType { get; private init; } public int? FilterListId { get; private init; } public FilterList? FilterList { get; } public string? LanguageIso6391 { get; private init; } @@ -33,17 +34,6 @@ public record Change public Tag? Tag { get; } } -internal enum AggregateType -{ - FilterList, - Language, - License, - Maintainer, - Software, - Syntax, - Tag -} - internal class UpdateConfiguration : IEntityTypeConfiguration { public virtual void Configure(EntityTypeBuilder builder) @@ -54,16 +44,17 @@ public virtual void Configure(EntityTypeBuilder builder) static string BuildComputedAggregateTypeSql() { - var nameRewriter = new SnakeCaseNameRewriter(CultureInfo.InvariantCulture); + // TODO: register and resolve INameRewriter + var nr = new SnakeCaseNameRewriter(CultureInfo.InvariantCulture); return $@" CASE - WHEN {nameRewriter.RewriteName(nameof(Change.FilterListId))} IS NOT NULL THEN '{AggregateType.FilterList}' - WHEN {nameRewriter.RewriteName(nameof(Change.LanguageIso6391))} IS NOT NULL THEN '{AggregateType.Language}' - WHEN {nameRewriter.RewriteName(nameof(Change.LicenseId))} IS NOT NULL THEN '{AggregateType.License}' - WHEN {nameRewriter.RewriteName(nameof(Change.MaintainerId))} IS NOT NULL THEN '{AggregateType.Maintainer}' - WHEN {nameRewriter.RewriteName(nameof(Change.SoftwareId))} IS NOT NULL THEN '{AggregateType.Software}' - WHEN {nameRewriter.RewriteName(nameof(Change.SyntaxId))} IS NOT NULL THEN '{AggregateType.Syntax}' - WHEN {nameRewriter.RewriteName(nameof(Change.TagId))} IS NOT NULL THEN '{AggregateType.Tag}' + WHEN {nr.RewriteName(nameof(Change.FilterListId))} IS NOT NULL THEN '{nr.RewriteName(nameof(AggregateType.FilterList))}'::{nr.RewriteName(nameof(AggregateType))} + WHEN {nr.RewriteName(nameof(Change.LanguageIso6391))} IS NOT NULL THEN '{nr.RewriteName(nameof(AggregateType.Language))}'::{nr.RewriteName(nameof(AggregateType))} + WHEN {nr.RewriteName(nameof(Change.LicenseId))} IS NOT NULL THEN '{nr.RewriteName(nameof(AggregateType.License))}'::{nr.RewriteName(nameof(AggregateType))} + WHEN {nr.RewriteName(nameof(Change.MaintainerId))} IS NOT NULL THEN '{nr.RewriteName(nameof(AggregateType.Maintainer))}'::{nr.RewriteName(nameof(AggregateType))} + WHEN {nr.RewriteName(nameof(Change.SoftwareId))} IS NOT NULL THEN '{nr.RewriteName(nameof(AggregateType.Software))}'::{nr.RewriteName(nameof(AggregateType))} + WHEN {nr.RewriteName(nameof(Change.SyntaxId))} IS NOT NULL THEN '{nr.RewriteName(nameof(AggregateType.Syntax))}'::{nr.RewriteName(nameof(AggregateType))} + WHEN {nr.RewriteName(nameof(Change.TagId))} IS NOT NULL THEN '{nr.RewriteName(nameof(AggregateType.Tag))}'::{nr.RewriteName(nameof(AggregateType))} ELSE NULL END"; } diff --git a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/SeedExtensions.cs b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/SeedExtensions.cs index 472dba893..0f5c5eb0c 100644 --- a/services/Directory/FilterLists.Directory.Infrastructure/Persistence/SeedExtensions.cs +++ b/services/Directory/FilterLists.Directory.Infrastructure/Persistence/SeedExtensions.cs @@ -5,6 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Npgsql; namespace FilterLists.Directory.Infrastructure.Persistence; @@ -15,6 +16,9 @@ public static async Task MigrateAsync(this IHost host) using var scope = host.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); await db.Database.MigrateAsync(); + await using var conn = (NpgsqlConnection)db.Database.GetDbConnection(); + await conn.OpenAsync(); + conn.ReloadTypes(); } }