refactor(dir): ♻ make ViewUrl owned by FilterList

This commit is contained in:
Collin M. Barrett 2021-12-05 09:52:35 -06:00
parent 8d5040400c
commit ccb7ca3c03
10 changed files with 51055 additions and 51071 deletions

View file

@ -14,7 +14,7 @@
namespace FilterLists.Directory.Infrastructure.Migrations.Migrations
{
[DbContext(typeof(QueryDbContext))]
[Migration("20211205104001_Initial")]
[Migration("20211205154614_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -297,46 +297,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
b.ToTable("filter_list_tags", (string)null);
});
modelBuilder.Entity("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.FilterListViewUrl", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
b.Property<long>("FilterListId")
.HasColumnType("bigint")
.HasColumnName("filter_list_id");
b.Property<short>("Primariness")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)1)
.HasColumnName("primariness");
b.Property<short>("SegmentNumber")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)1)
.HasColumnName("segment_number");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text")
.HasColumnName("url");
b.HasKey("Id")
.HasName("pk_filter_list_view_urls");
b.HasIndex("FilterListId", "SegmentNumber", "Primariness")
.IsUnique()
.HasDatabaseName("ix_filter_list_view_urls_filter_list_id_segment_number_primari");
b.ToTable("filter_list_view_urls", (string)null);
});
modelBuilder.Entity("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.Fork", b =>
{
b.Property<long>("UpstreamFilterListId")
@ -705,7 +665,55 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.IsRequired()
.HasConstraintName("fk_filter_lists_licenses_license_id");
b.OwnsMany("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.FilterListViewUrl", "ViewUrls", b1 =>
{
b1.Property<long>("FilterListId")
.HasColumnType("bigint")
.HasColumnName("filter_list_id");
b1.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b1.Property<long>("Id"));
b1.Property<short>("Primariness")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)1)
.HasColumnName("primariness");
b1.Property<short>("SegmentNumber")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)1)
.HasColumnName("segment_number");
b1.Property<string>("Url")
.IsRequired()
.HasColumnType("text")
.HasColumnName("url");
b1.HasKey("FilterListId", "Id")
.HasName("pk_filter_list_view_urls");
b1.HasIndex("FilterListId", "SegmentNumber", "Primariness")
.IsUnique()
.HasDatabaseName("ix_filter_list_view_urls_filter_list_id_segment_number_primari");
b1.ToTable("filter_list_view_urls", (string)null);
b1.WithOwner("FilterList")
.HasForeignKey("FilterListId")
.HasConstraintName("fk_filter_list_view_urls_filter_lists_filter_list_id");
b1.Navigation("FilterList");
});
b.Navigation("License");
b.Navigation("ViewUrls");
});
modelBuilder.Entity("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.FilterListLanguage", b =>
@ -792,18 +800,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
b.Navigation("Tag");
});
modelBuilder.Entity("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.FilterListViewUrl", b =>
{
b.HasOne("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.FilterList", "FilterList")
.WithMany("ViewUrls")
.HasForeignKey("FilterListId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_filter_list_view_urls_filter_lists_filter_list_id");
b.Navigation("FilterList");
});
modelBuilder.Entity("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.Fork", b =>
{
b.HasOne("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.FilterList", "ForkFilterList")
@ -890,8 +886,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
b.Navigation("IncludesFilterLists");
b.Navigation("UpstreamFilterLists");
b.Navigation("ViewUrls");
});
modelBuilder.Entity("FilterLists.Directory.Infrastructure.Persistence.Queries.Entities.Language", b =>

View file

@ -364,7 +364,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
},
constraints: table =>
{
table.PrimaryKey("pk_filter_list_view_urls", x => x.id);
table.PrimaryKey("pk_filter_list_view_urls", x => new { x.filter_list_id, x.id });
table.ForeignKey(
name: "fk_filter_list_view_urls_filter_lists_filter_list_id",
column: x => x.filter_list_id,

View file

@ -47,6 +47,23 @@ public virtual void Configure(EntityTypeBuilder<FilterList> builder)
e.Property<long>(nameof(FilterListTag.TagId));
e.HasKey(nameof(FilterListTag.FilterListId), nameof(FilterListTag.TagId));
});
builder.OwnsMany(
f => f.ViewUrls,
b =>
{
b.ToTable($"{nr.RewriteName(nameof(FilterListViewUrl))}s");
b.Property(u => u.SegmentNumber)
.HasDefaultValue(1);
b.Property(u => u.Primariness)
.HasDefaultValue(1);
b.HasIndex(
nameof(FilterListViewUrl.FilterListId),
nameof(FilterListViewUrl.SegmentNumber),
nameof(FilterListViewUrl.Primariness))
.IsUnique();
});
builder.Navigation(f => f.ViewUrls)
.AutoInclude();
builder.HasMany(f => f.Maintainers)
.WithMany(m => m.FilterLists)
.UsingEntity(
@ -102,7 +119,5 @@ public virtual void Configure(EntityTypeBuilder<FilterList> builder)
.HasForeignKey(nameof(Change.FilterListId));
builder.Navigation(f => f.Changes)
.AutoInclude();
builder.Navigation(f => f.ViewUrls)
.AutoInclude();
}
}

View file

@ -1,18 +0,0 @@
using System.Globalization;
using EFCore.NamingConventions.Internal;
using FilterLists.Directory.Domain.Aggregates.FilterLists;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace FilterLists.Directory.Infrastructure.Persistence.Commands.EntityTypeConfigurations;
internal class FilterListViewUrlTypeConfiguration : IEntityTypeConfiguration<FilterListViewUrl>
{
public virtual void Configure(EntityTypeBuilder<FilterListViewUrl> builder)
{
// TODO: register and resolve INameRewriter
var nr = new SnakeCaseNameRewriter(CultureInfo.InvariantCulture);
builder.ToTable($"{nr.RewriteName(nameof(Queries.Entities.FilterListViewUrl))}s");
}
}

View file

@ -1,4 +1,6 @@
using Microsoft.EntityFrameworkCore;
using System.Globalization;
using EFCore.NamingConventions.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace FilterLists.Directory.Infrastructure.Persistence.Queries.Entities;
@ -36,6 +38,9 @@ internal class FilterListTypeConfiguration : EntityRequiringApprovalTypeConfigur
{
public override void Configure(EntityTypeBuilder<FilterList> builder)
{
// TODO: register and resolve INameRewriter
var nr = new SnakeCaseNameRewriter(CultureInfo.InvariantCulture);
builder.HasIndex(f => f.Name)
.IsUnique();
builder.Property(f => f.LicenseId)
@ -43,6 +48,19 @@ public override void Configure(EntityTypeBuilder<FilterList> builder)
builder.HasOne(f => f.License)
.WithMany(l => l.FilterLists)
.OnDelete(DeleteBehavior.Restrict);
builder.OwnsMany(
f => f.ViewUrls,
b =>
{
b.ToTable($"{nr.RewriteName(nameof(FilterListViewUrl))}s");
b.Property(u => u.SegmentNumber)
.HasDefaultValue(1);
b.Property(u => u.Primariness)
.HasDefaultValue(1);
b.HasIndex(u => new { u.FilterListId, u.SegmentNumber, u.Primariness })
.IsUnique();
b.HasDataJsonFile<FilterListViewUrl>();
});
builder.HasDataJsonFileEntityRequiringApproval<FilterList>();
base.Configure(builder);
}

View file

@ -1,9 +1,4 @@
using System.Globalization;
using EFCore.NamingConventions.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace FilterLists.Directory.Infrastructure.Persistence.Queries.Entities;
namespace FilterLists.Directory.Infrastructure.Persistence.Queries.Entities;
public record FilterListViewUrl
{
@ -14,22 +9,3 @@ public record FilterListViewUrl
public short Primariness { get; init; }
public Uri Url { get; init; } = default!;
}
internal class FilterListViewUrlConfiguration : IEntityTypeConfiguration<FilterListViewUrl>
{
public virtual void Configure(EntityTypeBuilder<FilterListViewUrl> builder)
{
// TODO: register and resolve INameRewriter
var nr = new SnakeCaseNameRewriter(CultureInfo.InvariantCulture);
builder.ToTable($"{nr.RewriteName(nameof(FilterListViewUrl))}s");
builder.Property(u => u.SegmentNumber)
.HasDefaultValue(1);
builder.Property(u => u.Primariness)
.HasDefaultValue(1);
builder.HasIndex(u => new { u.FilterListId, u.SegmentNumber, u.Primariness })
.IsUnique();
builder.HasQueryFilter(u => u.FilterList.IsApproved);
builder.HasDataJsonFile<FilterListViewUrl>();
}
}

View file

@ -53,6 +53,17 @@ public static void HasDataJsonFile<TEntity>(this EntityTypeBuilder entityTypeBui
entityTypeBuilder.HasData(entities);
}
public static void HasDataJsonFile<TEntity>(this OwnedNavigationBuilder ownedNavigationBuilder) where TEntity : class
{
var entities = Deserialize<TEntity>();
if (entities.Count == 0)
{
return;
}
ownedNavigationBuilder.HasData(entities);
}
private static List<TEntity> Deserialize<TEntity>()
{
// uncomment to short-circuit HasData() when adding a migration