< Summary

Information
Class: Elsa.Labels.Services.InMemoryWorkflowDefinitionLabelStore
Assembly: Elsa.Labels
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Labels/Services/InMemoryWorkflowDefinitionLabelStore.cs
Line coverage
100%
Covered lines: 51
Uncovered lines: 0
Coverable lines: 51
Total lines: 134
Line coverage: 100%
Branch coverage
92%
Covered branches: 24
Total branches: 26
Branch coverage: 92.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Labels/Services/InMemoryWorkflowDefinitionLabelStore.cs

#LineLine coverage
 1using Elsa.Common.Entities;
 2using Elsa.Common.Multitenancy;
 3using Elsa.Common.Services;
 4using Elsa.Labels.Contracts;
 5using Elsa.Labels.Entities;
 6
 7namespace Elsa.Labels.Services;
 8
 9/// <summary>
 10/// An in-memory store of workflow-label associations.
 11/// </summary>
 12/// <remarks>
 13/// Ambient tenant is applied here rather than in callers.
 14/// EF owns that via <c>SetTenantIdFilter</c> / <c>ApplyTenantId</c>; Memory must compensate.
 15/// Labels contracts have no TenantAgnostic flag, so isolation always applies (EF query filter).
 16/// </remarks>
 17public class InMemoryWorkflowDefinitionLabelStore : IWorkflowDefinitionLabelStore, IWorkflowDefinitionLabelQuery
 18{
 19    private readonly MemoryStore<WorkflowDefinitionLabel> _store;
 20    private readonly ITenantAccessor? _tenantAccessor;
 21
 22    /// <summary>
 23    /// Constructor.
 24    /// </summary>
 1925    public InMemoryWorkflowDefinitionLabelStore(MemoryStore<WorkflowDefinitionLabel> store, ITenantAccessor? tenantAcces
 26    {
 1927        _store = store;
 1928        _tenantAccessor = tenantAccessor;
 1929    }
 30
 31    /// <inheritdoc />
 32    public Task SaveAsync(WorkflowDefinitionLabel record, CancellationToken cancellationToken = default)
 33    {
 3634        ApplyCurrentTenant(record);
 3635        lock (_store.Sync)
 7236            _store.Save(record, x => x.Id);
 3637        return Task.CompletedTask;
 38    }
 39
 40    /// <inheritdoc />
 41    public Task SaveManyAsync(IEnumerable<WorkflowDefinitionLabel> records, CancellationToken cancellationToken = defaul
 42    {
 343        var list = records.ToList();
 44
 1645        foreach (var record in list)
 546            ApplyCurrentTenant(record);
 47
 348        lock (_store.Sync)
 849            _store.SaveMany(list, x => x.Id);
 350        return Task.CompletedTask;
 51    }
 52
 53    /// <inheritdoc />
 54    public Task<bool> DeleteAsync(string id, CancellationToken cancellationToken = default)
 55    {
 356        lock (_store.Sync)
 1057            return Task.FromResult(_store.DeleteWhere(x => x.Id == id && IsVisible(x)) > 0);
 358    }
 59
 60    /// <inheritdoc />
 61    public Task<IEnumerable<WorkflowDefinitionLabel>> FindByWorkflowDefinitionVersionIdAsync(string workflowDefinitionVe
 62    {
 3663        var result = _store.Query(query => query.WhereVisibleToTenant(CurrentTenantId).Where(x => x.WorkflowDefinitionVe
 1864        return Task.FromResult(result);
 65    }
 66
 67    /// <inheritdoc />
 68    public Task<IEnumerable<WorkflowDefinitionLabel>> FindByLabelIdsAsync(IEnumerable<string> labelIds, CancellationToke
 69    {
 2470        var ids = labelIds.ToHashSet();
 4871        var result = _store.Query(query => query.WhereVisibleToTenant(CurrentTenantId).Where(x => ids.Contains(x.LabelId
 2472        return Task.FromResult(result);
 73    }
 74
 75    /// <inheritdoc />
 76    public Task ReplaceAsync(IEnumerable<WorkflowDefinitionLabel> removed, IEnumerable<WorkflowDefinitionLabel> added, C
 77    {
 878        var removedIds = removed.Select(x => x.Id).ToHashSet();
 379        var addedList = added.ToList();
 80
 1281        foreach (var record in addedList)
 382            ApplyCurrentTenant(record);
 83
 384        lock (_store.Sync)
 85        {
 1186            _store.DeleteWhere(x => removedIds.Contains(x.Id) && IsVisible(x));
 687            _store.SaveMany(addedList, x => x.Id);
 388        }
 89
 390        return Task.CompletedTask;
 91    }
 92
 93    /// <inheritdoc />
 94    public Task<long> DeleteByWorkflowDefinitionIdAsync(string workflowDefinitionId, CancellationToken cancellationToken
 95    {
 396        lock (_store.Sync)
 1297            return Task.FromResult(_store.DeleteWhere(x => x.WorkflowDefinitionId == workflowDefinitionId && IsVisible(x
 398    }
 99
 100    /// <inheritdoc />
 101    public Task<long> DeleteByWorkflowDefinitionVersionIdAsync(string workflowDefinitionVersionId, CancellationToken can
 102    {
 1103        lock (_store.Sync)
 5104            return Task.FromResult(_store.DeleteWhere(x => x.WorkflowDefinitionVersionId == workflowDefinitionVersionId 
 1105    }
 106
 107    /// <inheritdoc />
 108    public Task<long> DeleteByWorkflowDefinitionIdsAsync(IEnumerable<string> workflowDefinitionIds, CancellationToken ca
 109    {
 1110        var ids = workflowDefinitionIds.ToList();
 1111        lock (_store.Sync)
 4112            return Task.FromResult(_store.DeleteWhere(x => ids.Contains(x.WorkflowDefinitionId) && IsVisible(x)));
 1113    }
 114
 115    /// <inheritdoc />
 116    public Task<long> DeleteByWorkflowDefinitionVersionIdsAsync(IEnumerable<string> workflowDefinitionVersionIds, Cancel
 117    {
 1118        var ids = workflowDefinitionVersionIds.ToList();
 1119        lock (_store.Sync)
 6120            return Task.FromResult(_store.DeleteWhere(x => ids.Contains(x.WorkflowDefinitionVersionId) && IsVisible(x)))
 1121    }
 122
 19123    private bool IsVisible(Entity entity) => TenantVisibility.IsVisible(entity.TenantId, CurrentTenantId);
 124
 61125    private string CurrentTenantId => _tenantAccessor?.TenantId ?? Tenant.DefaultTenantId;
 126
 127    private void ApplyCurrentTenant(Entity entity)
 128    {
 44129        if (entity.TenantId == Tenant.AgnosticTenantId || _tenantAccessor is null)
 5130            return;
 131
 39132        entity.TenantId ??= _tenantAccessor.TenantId;
 39133    }
 134}