Skip to content

Commit

Permalink
feat: suspicious cases list queries
Browse files Browse the repository at this point in the history
  • Loading branch information
emalfroy authored Dec 19, 2023
1 parent e9e7217 commit 4928a08
Show file tree
Hide file tree
Showing 36 changed files with 866 additions and 637 deletions.
22 changes: 10 additions & 12 deletions src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,19 @@ public class IntegrationContext : DbContext
public DbSet<PostInfo> PostInfo { get; set; }
public DbSet<RoadSegment> RoadSegments { get; set; }

public DbSet<SuspiciousCaseListItem> SuspiciousCaseListItems { get; set; }

public DbSet<BuildingUnitAddressRelations> BuildingUnitAddressRelations { get; set; }
public DbSet<ParcelAddressRelations> ParcelAddressRelations { get; set; }

public DbSet<CurrentAddressWithoutLinkedParcelOrBuildingUnits> CurrentAddressWithoutLinkedParcelOrBuildingUnits { get; set; }
public DbSet<ProposedAddressWithoutLinkedParcelOrBuildingUnits> ProposedAddressWithoutLinkedParcelOrBuildingUnits { get; set; }
public DbSet<CurrentAddressWithoutLinkedParcelOrBuildingUnit> CurrentAddressWithoutLinkedParcelOrBuildingUnits { get; set; }
public DbSet<ProposedAddressWithoutLinkedParcelOrBuildingUnit> ProposedAddressWithoutLinkedParcelOrBuildingUnits { get; set; }
public DbSet<AddressesLinkedToMultipleBuildingUnits> AddressesLinkedToMultipleBuildingUnits { get; set; }
public DbSet<AddressesWithMultipleLinks> AddressesWithMultipleLinks { get; set; }
public DbSet<AddressesWithoutPostalCode> AddressesWithoutPostalCode { get; set; }
public DbSet<CurrentAddressesOutsideMunicipalityBounds> CurrentAddressesOutsideMunicipalityBounds { get; set; }

public DbSet<CurrentAddressWithoutLinkedParcels> CurrentAddressWithoutLinkedParcels { get; set; }
public DbSet<CurrentStreetNameWithoutLinkedRoadSegments> CurrentStreetNameWithoutLinkedRoadSegments { get; set; }
public DbSet<ParcelsLinkedToMultipleAddresses> ParcelsLinkedToMultipleAddresses { get; set; }

public IntegrationContext() { }
public IntegrationContext()

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'Municipalities' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'MunicipalityGeometries' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'StreetNames' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'Buildings' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'BuildingUnits' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'Addresses' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'Parcels' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'PostInfo' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'RoadSegments' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 40 in src/Basisregisters.IntegrationDb.Schema/IntegrationContext.cs

View workflow job for this annotation

GitHub Actions / Build

Non-nullable property 'SuspiciousCaseListItems' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
{ }

public IntegrationContext(DbContextOptions<IntegrationContext> options)
: base(options) { }
Expand All @@ -61,6 +59,8 @@ public class ConfigBasedIntegrationContextFactory : IDesignTimeDbContextFactory<
{
public IntegrationContext CreateDbContext(string[] args)
{
var migrationConnectionStringName = "IntegrationDbAdmin";

var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
Expand All @@ -71,11 +71,9 @@ public IntegrationContext CreateDbContext(string[] args)

var builder = new DbContextOptionsBuilder<IntegrationContext>();

var connectionStringName = "IntegrationDbAdmin";

var connectionString = configuration
.GetConnectionString(connectionStringName)
?? throw new InvalidOperationException($"Could not find a connection string with name '{connectionStringName}'");
.GetConnectionString(migrationConnectionStringName)
?? throw new InvalidOperationException($"Could not find a connection string with name '{migrationConnectionStringName}'");

builder
.UseNpgsql(connectionString, npgSqlOptions =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.EntityFrameworkCore.Migrations;

using Basisregisters.IntegrationDb.Schema.Models.Views;
using Basisregisters.IntegrationDb.Schema.Models.Views.SuspiciousCases;
#nullable disable

namespace Basisregisters.IntegrationDb.Schema.Migrations
Expand All @@ -10,19 +12,17 @@ public partial class Add_Views : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql(Views.BuildingUnitAddressRelations.Create);
migrationBuilder.Sql(Views.ParcelAddressRelations.Create);
migrationBuilder.Sql(BuildingUnitAddressRelationConfiguration.Create);
migrationBuilder.Sql(ParcelAddressRelationConfiguration.Create);

// 1. Adressen ‘ingebruik’ zonder koppeling aan perceel of gebouweenheid
migrationBuilder.Sql(Views.CurrentAddressWithoutLinkedParcelOrBuildingUnit.Create);
migrationBuilder.Sql(CurrentAddressWithoutLinkedParcelOrBuildingUnitsConfiguration.Create);
// 2. Adressen ‘voorgesteld’ zonder koppeling aan perceel of gebouweenheid
migrationBuilder.Sql(Views.ProposedAddressWithoutLinkedParcelOrBuildingUnit.Create);
// 3. Huisnummers zonder postcode
//migrationBuilder.Sql(Views.AddressesWithoutPostalCode.Create);
migrationBuilder.Sql(ProposedAddressWithoutLinkedParcelOrBuildingUnitsConfiguration.Create);
// 4. Adressen die buiten de grenzen van de gemeente vallen
migrationBuilder.Sql(Views.CurrentAddressesOutsideMunicipalityBounds.Create);
migrationBuilder.Sql(CurrentAddressesOutsideMunicipalityBoundsConfiguration.Create);
// 5. Straatnamen "in gebruik" zonder koppeling met wegverbinding TODO
migrationBuilder.Sql(Views.CurrentStreetNameWithoutLinkedRoadSegments.Create);
migrationBuilder.Sql(CurrentStreetNameWithoutLinkedRoadSegmentsConfiguration.Create);

// 6. Straatnamen langer dan 2 jaar “voorgesteld”
// 7. Adressen bestaat langer dan 2 jaar en heeft nog de status “voorgesteld”
Expand All @@ -36,13 +36,10 @@ protected override void Up(MigrationBuilder migrationBuilder)
// 15. Actueel Gebouweenheid gekoppeld aan meerdere actieve adressen

// 16. Actieve adres gekoppeld aan meerdere actuele gebouweenheden
migrationBuilder.Sql(Views.AddressesLinkedToMultipleBuildingUnits.Create);
migrationBuilder.Sql(AddressesLinkedToMultipleBuildingUnitsConfiguration.Create);

// TODO: review
// migrationBuilder.Sql(Views.AddressesLinkedToMultipleParcels.Create);
// migrationBuilder.Sql(Views.AddressesWithMultipleLinks.Create);
// migrationBuilder.Sql(Views.ParcelsLinkedToMultipleAddresses.Create);
// migrationBuilder.Sql(Views.CurrentAddressWithoutLinkedParcels.Create);
// Suspicious cases List items
migrationBuilder.Sql(SuspiciousCaseListItemConfiguration.Create);
}

protected override void Down(MigrationBuilder migrationBuilder)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Basisregisters.IntegrationDb.Schema.Models
{
public enum SuspiciousCasesType
{
CurrentAddressWithoutLinkedParcelsOrBuildingUnits = 1,
ProposedAddressWithoutLinkedParcelsOrBuildingUnits = 2,
AddressesOutsideOfMunicipalityBoundaries = 3,
CurrentStreetNamesWithoutRoadSegment = 4,
StreetNamesLongerThanTwoYearsProposed = 5,
AddressesLongerThanTwoYearsProposed = 6,
RoadSegmentsLongerThanTwoYearsProposed = 7,
BuildingLongerThanTwoYearsPlanned = 8,
BuildingUnitLongerThanTwoYearsPlanned = 9,
StreetNameWithOnlyOneRoadSegmentToOnlyOneSide = 10,
AddressesAppointedByAdministratorOutsideLinkedBuilding = 11,
AddressesWithBuildingUnitSpecificationOutsideLinkedActiveBuildingUnit = 12,
BuildingUnitsWithoutAddress = 13,
BuildingUnitsLinkedToMultipleAddresses = 14,
AddressesLinkedToMultipleBuildingUnits = 15
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,26 @@ public void Configure(EntityTypeBuilder<BuildingUnitAddressRelations> builder)
""BuildingUnitPersistentLocalId"",
""AddressPersistentLocalId"",
""Timestamp""
FROM {Views.BuildingUnitAddressRelations.Table} ");

builder.HasIndex(x => x.BuildingUnitPersistentLocalId);
builder.HasIndex(x => x.AddressPersistentLocalId);
FROM {ViewName} ");
}

public const string ViewName = @$"""{IntegrationContext.Schema}"".""VIEW_{nameof(BuildingUnitAddressRelations)}""";
public const string Create = $@"
CREATE MATERIALIZED VIEW IF NOT EXISTS {ViewName} AS
SELECT
bu.""PersistentLocalId"" AS ""BuildingUnitPersistentLocalId"",
unnested_address_id AS ""AddressPersistentLocalId"",
CURRENT_TIMESTAMP AS ""Timestamp""
FROM
""Integration"".""BuildingUnits"" bu
WHERE
bu.""IsRemoved"" = false
CROSS JOIN
unnest(string_to_array(bu.""Addresses"", ', ')::int[]) AS unnested_address_id;

CREATE INDEX ""IX_Address_PersistentLocalId"" ON ""Integration"".""{ViewName}""(""{nameof(BuildingUnitAddressRelations.AddressPersistentLocalId)}"")
CREATE INDEX ""IX_BuildingUnit_PersistentLocalId"" ON ""Integration"".""{ViewName}""(""{nameof(BuildingUnitAddressRelations.BuildingUnitPersistentLocalId)}"")
";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public class ParcelAddressRelations
public int? AddressPersistentLocalId { get; set; }
public DateTimeOffset Timestamp { get; set; }

public ParcelAddressRelations() { }
public ParcelAddressRelations()
{ }
}

public sealed class ParcelAddressRelationConfiguration : IEntityTypeConfiguration<ParcelAddressRelations>
Expand All @@ -25,10 +26,30 @@ public void Configure(EntityTypeBuilder<ParcelAddressRelations> builder)
""CaPaKey"",
""AddressPersistentLocalId"",
""Timestamp""
FROM {Views.ParcelAddressRelations.Table} ");
FROM {ViewName} ");

builder.HasIndex(x => x.CaPaKey);
builder.HasIndex(x => x.AddressPersistentLocalId);
}


public const string ViewName = @$"""{IntegrationContext.Schema}"".""VIEW_{nameof(ParcelAddressRelations)}""";
public const string Create = $@"
CREATE MATERIALIZED VIEW IF NOT EXISTS {ViewName} AS
SELECT
p.""CaPaKey"",
unnested_address_id AS ""AddressPersistentLocalId"",
CURRENT_TIMESTAMP AS ""Timestamp""
FROM
""Integration"".""Parcels"" p
WHERE
p.""IsRemoved"" = false
CROSS JOIN
unnest(string_to_array(p.""Addresses"", ', ')::int[]) AS unnested_address_id;

CREATE CLUSTERED INDEX ""IX_AddressPersistentLocalId"" ON ""Integration"".""{ViewName}""(""{nameof(ParcelAddressRelations.AddressPersistentLocalId)}"")
CREATE INDEX ""IX_CaPaKey"" ON ""Integration"".""{ViewName}""(""{nameof(ParcelAddressRelations.CaPaKey)}"")
";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
namespace Basisregisters.IntegrationDb.Schema.Models.Views.SuspiciousCases
{
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public class ActiveBuildingUnitWithoutAddress
{
public int BuildingUnitPersistentLocalId { get; set; }
public int NisCode { get; set; }
public DateTimeOffset Timestamp { get; set; }

public ActiveBuildingUnitWithoutAddress()
{ }
}

public sealed class ActiveBuildingUnitWithoutAddressConfiguration : IEntityTypeConfiguration<ActiveBuildingUnitWithoutAddress>
{
public void Configure(EntityTypeBuilder<ActiveBuildingUnitWithoutAddress> builder)
{
builder
.ToView(nameof(ActiveBuildingUnitWithoutAddress), IntegrationContext.Schema)
.HasNoKey()
.ToSqlQuery(@$"SELECT
""BuildingUnitPersistentLocalId"",
""NisCode"",
""Timestamp""
FROM {ViewName}");
}

public const string ViewName = @$"""{IntegrationContext.Schema}"".""VIEW_{nameof(ActiveBuildingUnitWithoutAddress)}""";
public const string Create = $@"
CREATE MATERIALIZED VIEW IF NOT EXISTS {ViewName} AS
SELECT
bu.""PersistentLocalId"" AS ""BuildingUnitPersistentLocalId"",
muni.""NisCode"" AS ""NisCode"",
CURRENT_TIMESTAMP AS ""Timestamp""
FROM ""Integration"".""BuildingUnits"" AS bu
LEFT OUTER JOIN ""Integration"".""VIEW_BuildingUnitAddressRelations"" AS rel
ON bu.""PersistentLocalId"" = rel.""BuildingUnitPersistentLocalId""
INNER JOIN ""Integration"".""MunicipalityGeometries"" AS muni
ON ST_Within(bu.""Geometry"", muni.""Geometry"") IS TRUE
WHERE
bu.""IsRemoved"" IS FALSE
AND bu.""Status"" IN ('gepland','gerealiseerd')
AND rel.""AddressPersistentLocalId"" IS NULL
ORDER BY bu.""PersistentLocalId"";

CREATE INDEX ""IX_BuildingUnitPersistentLocalId"" ON {ViewName} USING btree (""{nameof(ActiveBuildingUnitWithoutAddress.BuildingUnitPersistentLocalId)}"");
CREATE INDEX ""IX_NisCode"" ON {ViewName} USING btree (""{nameof(ActiveBuildingUnitWithoutAddress.NisCode)}"");
";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public class AddressesLinkedToMultipleBuildingUnits
public int NisCode { get; set; }
public DateTimeOffset Timestamp { get; set; }

public AddressesLinkedToMultipleBuildingUnits() { }
public AddressesLinkedToMultipleBuildingUnits()
{ }
}

public sealed class AddressesLinkedToMultipleBuildingUnitsConfiguration : IEntityTypeConfiguration<AddressesLinkedToMultipleBuildingUnits>
Expand All @@ -27,9 +28,30 @@ public void Configure(EntityTypeBuilder<AddressesLinkedToMultipleBuildingUnits>
""LinkedBuildingUnitCount"",
""NisCode"",
""Timestamp""
FROM {Views.AddressesLinkedToMultipleBuildingUnits.Table} ");

builder.HasIndex(x => x.AddressPersistentLocalId);
FROM {ViewName} ");
}


public const string ViewName = @$"""{IntegrationContext.Schema}"".""VIEW_{nameof(AddressesLinkedToMultipleBuildingUnits)}""";
public const string Create = $@"
CREATE MATERIALIZED VIEW IF NOT EXISTS {ViewName} AS
SELECT
a.""PersistentLocalId"" AS ""AddressPersistentLocalId"",
COUNT(*) AS ""LinkedBuildingUnitCount"",
a.""NisCode"",
CURRENT_TIMESTAMP AS ""Timestamp""

FROM {BuildingUnitAddressRelationConfiguration.ViewName} relation
JOIN ""Integration"".""Addresses"" a ON a.""PersistentLocalId"" = relation.""AddressPersistentLocalId""
WHERE
a.""IsRemoved"" = false
GROUP BY
a.""PersistentLocalId""
HAVING
COUNT(*) > 1;

CREATE INDEX ""IX_{nameof(AddressesLinkedToMultipleBuildingUnits)}_AddressPersistentLocalId"" ON {ViewName} USING btree (""{nameof(AddressesLinkedToMultipleBuildingUnits.AddressPersistentLocalId)}"");
";
}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit 4928a08

Please sign in to comment.