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

Information
Line coverage
100%
Covered lines: 49
Uncovered lines: 0
Coverable lines: 49
Total lines: 119
Line coverage: 100%
Branch coverage
88%
Covered branches: 38
Total branches: 43
Branch coverage: 88.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Upserts(...)100%11100%
Upserts(...)83.33%66100%
SoftDeleteValues(...)100%11100%
RestoreValues(...)50%22100%
Id(...)100%66100%
Values(...)89.65%2929100%

File(s)

/home/runner/work/ZhEaIsNsAaBn.Libraries.V1/ZhEaIsNsAaBn.Libraries.V1/src/DataBasePackages/ZhEaIsNsAaBn.DbSeeder/Running/SeedRowWriter.cs

#LineLine coverage
 1namespace ZhEaIsNsAaBn.DbSeeder;
 2
 3/// <summary>
 4/// The write rules of §6.2, provider-neutral. Insert: created date / by / user (date <b>always</b> from the clock, also
 5/// has a database default) and the soft-delete flag <see langword="false"/>. Update (only when a data column changed): 
 6/// date / by / user. The user is <c>SystemUser( id, name )</c>; the time is the configured clock's local time, one valu
 7/// </summary>
 8internal sealed class SeedRowWriter
 9{
 10    private readonly SeedOptions _options;
 11    private readonly DateTime    _now;
 12
 13
 46414    public SeedRowWriter( SeedOptions options, DateTime now )
 15    {
 46416        _options = options;
 46417        _now     = now;
 46418    }
 19
 20
 21    /// The upserts of one table: one write, or one per dependency level for a self-referencing table.
 22    /// <returns>The writes; otherwise <c>SystemUserRequired</c> or <c>CycleDetected</c>.</returns>
 94523    public LayerResponse<IReadOnlyList<SeedTableWrite>> Upserts( SeedBoundTable table, string migrationId ) => Upserts( 
 24
 25    /// The upserts of arbitrary rows of the table (e.g. the <c>Before</c> rows of a rollback), same rules.
 26    public LayerResponse<IReadOnlyList<SeedTableWrite>> Upserts( SeedBoundTable table, IReadOnlyList<SeedColumn> columns
 27    {
 28        // A new row starts not deleted (the flag is managed, never in data, and often NOT NULL without a database defau
 102329        var insert = Values( table, (SeedRole.CreatedDate, _ => _now), (SeedRole.CreatedById, Id), (SeedRole.CreatedByUs
 102330                             (SeedRole.SoftDeleteFlag, _ => false) );
 31
 102332        if ( insert.IsFailure ) { return LayerResponse<IReadOnlyList<SeedTableWrite>>.Failure( insert ); }
 33
 34
 101735        var update = Values( table, (SeedRole.UpdatedDate, _ => _now), (SeedRole.UpdatedById, Id), (SeedRole.UpdatedByUs
 36
 101737        if ( update.IsFailure ) { return LayerResponse<IReadOnlyList<SeedTableWrite>>.Failure( update ); }
 38
 39
 101740        var written         = columns.Select( c => c.PropertyName ).ToHashSet( StringComparer.Ordinal );
 101741        var selfReferences  = table.SelfReferences.Where( k => k.Properties.Concat( k.PrincipalKey.Properties ).All( p =
 101742        var (levels, cycle) = SeedRowLevels.Split( columns, rows, selfReferences );
 43
 101744        if ( levels is null )
 45        {
 346            return SeedErrors.CycleDetected( migrationId, cycle.Select( r => $"{table.EntityType.Name}[{r}]" ).ToList() 
 47        }
 48
 49
 101450        return levels.Select( rows => new SeedTableWrite
 101451                                          {
 101452                                              Table        = table.Table,
 101453                                              Columns      = columns,
 101454                                              Rows         = rows,
 101455                                              InsertValues = insert.Result!,
 101456                                              UpdateValues = update.Result!
 101457                                          } )
 101458                     .ToList();
 59    }
 60
 61    /// The flag and the deleted fields of a soft delete.
 62    /// <returns>The values; otherwise <c>SystemUserRequired</c>.</returns>
 63    public LayerResponse<IReadOnlyList<SeedColumnValue>> SoftDeleteValues( SeedBoundTable table )
 18964        => Values( table, (SeedRole.SoftDeleteFlag, _ => true), (SeedRole.DeletedDate, _ => _now), (SeedRole.DeletedById
 65
 66
 67    /// Bringing a soft-deleted row back: the flag <see langword="false"/>, the deleted fields cleared (where nullable),
 68    /// <returns>The values; otherwise <c>SystemUserRequired</c>.</returns>
 69    public LayerResponse<IReadOnlyList<SeedColumnValue>> RestoreValues( SeedBoundTable table )
 70    {
 6271        var cleared = table.Managed
 6272                           .Where( m => m.Key is SeedRole.DeletedDate or SeedRole.DeletedById or SeedRole.DeletedByUser 
 6273                           .Select( m => new SeedColumnValue { Column = m.Value, Value = null } );
 74
 6275        var stamped = Values( table, (SeedRole.SoftDeleteFlag, _ => false), (SeedRole.UpdatedDate, _ => _now), (SeedRole
 6276                              (SeedRole.UpdatedByUser, _ => _options.SystemUserName) );
 77
 6278        return stamped.IsFailure ? stamped : stamped.Result!.Concat( cleared ).ToList();
 79    }
 80
 81    private object? Id( SeedColumn column )
 82    {
 84783        var expected = Nullable.GetUnderlyingType( column.Property.ClrType ) ?? column.Property.ClrType;
 84
 84785        return _options.SystemUserId is null || _options.SystemUserId.GetType() == expected
 84786                   ? _options.SystemUserId
 84787                   : throw new InvalidOperationException( $"SystemUser's key is {_options.SystemUserId.GetType().Name} b
 88    }
 89
 90    private LayerResponse<IReadOnlyList<SeedColumnValue>> Values( SeedBoundTable table, params (SeedRole Role, Func<Seed
 91    {
 229192        var values = new List<SeedColumnValue>();
 93
 94
 2083795        foreach ( var (role, value) in roles )
 96        {
 813297            if ( table[ role ] is not { } column ) { continue; }
 98
 362999            if ( role is SeedRole.CreatedById or SeedRole.CreatedByUser or SeedRole.UpdatedById or SeedRole.UpdatedByUse
 3629100              && _options.SystemUserId is null )
 101            {
 6102                return SeedErrors.SystemUserRequired( table.EntityType.Name );
 103            }
 104
 105
 3623106            var raw = value( column );
 107
 3620108            values.Add( new SeedColumnValue
 3620109                            {
 3620110                                Column  = column,
 3620111                                Value   = raw is null ? null : column.Property.GetTypeMapping().Converter?.ConvertToProv
 3620112                                IsClock = role is SeedRole.CreatedDate or SeedRole.UpdatedDate or SeedRole.DeletedDate
 3620113                            } );
 114        }
 115
 116
 2282117        return values;
 118    }
 119}