< Summary - ZhEaIsNsAaBn.Libraries coverage (affected: 23 packages)

Information
Class: ZhEaIsNsAaBn.DbSeeder.Design.SeedDiff
Assembly: ZhEaIsNsAaBn.DbSeeder.Design
File(s): /home/runner/work/ZhEaIsNsAaBn.Libraries.V1/ZhEaIsNsAaBn.Libraries.V1/src/DataBasePackages/ZhEaIsNsAaBn.DbSeeder.Design/Diff/SeedDiff.cs
Line coverage
100%
Covered lines: 29
Uncovered lines: 0
Coverable lines: 29
Total lines: 70
Line coverage: 100%
Branch coverage
95%
Covered branches: 23
Total branches: 24
Branch coverage: 95.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Compute(...)95.83%2424100%
Changed(...)100%11100%
Repurposed(...)100%11100%

File(s)

/home/runner/work/ZhEaIsNsAaBn.Libraries.V1/ZhEaIsNsAaBn.Libraries.V1/src/DataBasePackages/ZhEaIsNsAaBn.DbSeeder.Design/Diff/SeedDiff.cs

#LineLine coverage
 1namespace ZhEaIsNsAaBn.DbSeeder.Design;
 2
 3/// <summary>
 4/// Compares a table's snapshot with its rows now and builds the migration's table file:
 5/// new row → <c>Upsert</c>; changed row → <c>Upsert</c>; row gone → <c>Delete</c>; flag set since → <c>SoftDelete</c>; 
 6/// <c>Restore</c>. <b>Every key that existed in the snapshot and is touched gets its <c>Before</c> row</b> (data column
 7/// </summary>
 8internal static class SeedDiff
 9{
 10    public static (DesignTable File, IReadOnlyList<string> Warnings) Compute( ExportedTable snapshot, ExportedTable curr
 11    {
 21012        var file     = new DesignTable { Entity = current.Shape.EntityType.Name, MatchBy = current.Shape.IsBusinessKey ?
 21013        var then     = snapshot.Rows.ToDictionary( r => r.Key, StringComparer.Ordinal );
 21014        var now      = current.Rows.Select( r => r.Key ).ToHashSet( StringComparer.Ordinal );
 21015        var columns  = current.Shape.DataColumns.Select( c => c.PropertyName ).ToList();
 21016        var before   = new HashSet<string>( StringComparer.Ordinal );
 21017        var warnings = new List<string>();
 18
 19
 156020        foreach ( var row in current.Rows )
 21        {
 57022            var existed = then.TryGetValue( row.Key, out var old );
 23
 62124            if ( !existed ) { file.Upsert.Add( row ); }
 51925            else if ( Changed( old!, row, columns ) is { Count: > 0 } changed )
 26            {
 327                file.Upsert.Add( row );
 328                before.Add( row.Key );
 329                warnings.AddRange( Repurposed( current, row, old!, changed ) );
 30            }
 31
 32
 57033            var deletedNow  = current.SoftDeleted.Contains( row.Key );
 57034            var deletedThen = existed && snapshot.SoftDeleted.Contains( row.Key );
 35
 57036            if ( deletedNow && !deletedThen )
 37            {
 338                file.SoftDelete.Add( row.Only( current.MatchNames ) );
 39
 640                if ( existed ) { before.Add( row.Key ); }
 41            }
 56742            else if ( !deletedNow && deletedThen )
 43            {
 344                file.Restore.Add( row.Only( current.MatchNames ) );
 345                before.Add( row.Key );
 46            }
 47        }
 48
 42649        foreach ( var old in snapshot.Rows.Where( r => !now.Contains( r.Key ) ) )
 50        {
 351            file.Delete.Add( old.Only( current.MatchNames ) );
 352            before.Add( old.Key );
 53        }
 54
 55
 56        // Only properties the model still has, so the runtime accepts the Before rows.
 21057        file.Before.AddRange( before.Select( k => then[ k ].Only( columns ) ) );
 58
 21059        return ( file, warnings );
 60    }
 61
 62
 63    private static List<string> Changed( DesignRow old, DesignRow now, IReadOnlyList<string> columns )
 51964        => columns.Where( c => ( old[ c ] ?? "null" ) != ( now[ c ] ?? "null" ) ).ToList();
 65
 66    /// §8.4: same key, but a name-like column changed — the row may have been reused for something else.
 67    private static IEnumerable<string> Repurposed( ExportedTable table, DesignRow now, DesignRow old, IReadOnlyList<stri
 368        => changed.Where( c => c.StartsWith( "Name", StringComparison.Ordinal ) || c.StartsWith( "Title", StringComparis
 369                  .Select( c => $"{table.Shape.EntityType.ClrType.Name} {now.Key.Replace( SeedKeyComparer.Separator, ','
 70}