< Summary

Information
Class: Elsa.Common.Services.MemoryStore<T>
Assembly: Elsa.Common
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Common/Services/MemoryStore.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 49
Coverable lines: 49
Total lines: 198
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 14
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Entities()100%210%
get_Queryable()100%210%
Add(...)100%210%
AddMany(...)0%620%
Save(...)100%210%
SaveMany(...)0%620%
Update(...)100%210%
Find(...)100%210%
FindMany(...)100%210%
FindMany(...)0%2040%
List()100%210%
Delete(...)100%210%
DeleteWhere(...)0%620%
DeleteMany(...)0%620%
DeleteMany(...)0%620%
Query(...)100%210%
Any(...)100%210%
Count(...)100%210%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Common/Services/MemoryStore.cs

#LineLine coverage
 1using System.Collections.Concurrent;
 2using Elsa.Common.Entities;
 3
 4namespace Elsa.Common.Services;
 5
 6/// <summary>
 7/// A simple in-memory store for entities.
 8/// </summary>
 9/// <typeparam name="TEntity">The type of entity to store.</typeparam>
 10public class MemoryStore<TEntity>
 11{
 012    private IDictionary<string, TEntity> Entities { get; set; } = new ConcurrentDictionary<string, TEntity>();
 13
 14    /// <summary>
 15    /// Gets a queryable of all entities.
 16    /// </summary>
 017    public IQueryable<TEntity> Queryable => Entities.Values.AsQueryable();
 18
 19    /// <summary>
 20    /// Adds an entity.
 21    /// </summary>
 22    /// <param name="entity">The entity to add.</param>
 23    /// <param name="idAccessor">A function that returns the ID of the entity.</param>
 024    public void Add(TEntity entity, Func<TEntity, string> idAccessor) => Entities.Add(idAccessor(entity), entity);
 25
 26    /// <summary>
 27    /// Adds many entities.
 28    /// </summary>
 29    /// <param name="entities">The entities to add.</param>
 30    /// <param name="idAccessor">A function that returns the ID of the entity.</param>
 31    public void AddMany(IEnumerable<TEntity> entities, Func<TEntity, string> idAccessor)
 32    {
 033        foreach (var entity in entities)
 034            Add(entity, idAccessor);
 035    }
 36
 37    /// <summary>
 38    /// Adds or updates an entity.
 39    /// </summary>
 40    /// <param name="entity">The entity to add or update.</param>
 41    /// <param name="idAccessor">A function that returns the ID of the entity.</param>
 042    public void Save(TEntity entity, Func<TEntity, string> idAccessor) => Entities[idAccessor(entity)] = entity;
 43
 44    /// <summary>
 45    /// Adds or updates many entities.
 46    /// </summary>
 47    /// <param name="entities">The entities to add or update.</param>
 48    /// <param name="idAccessor">A function that returns the ID of the entity.</param>
 49    public void SaveMany(IEnumerable<TEntity> entities, Func<TEntity, string> idAccessor)
 50    {
 051        foreach (var entity in entities)
 052            Save(entity, idAccessor);
 053    }
 54
 55    /// <summary>
 56    /// Updates an entity.
 57    /// </summary>
 58    /// <param name="entity">The entity to update.</param>
 59    /// <param name="idAccessor">A function that returns the ID of the entity.</param>
 060    public void Update(TEntity entity, Func<TEntity, string> idAccessor) => Entities[idAccessor(entity)] = entity;
 61
 62    /// <summary>
 63    /// Finds an entity matching the specified predicate.
 64    /// </summary>
 65    /// <param name="predicate">A predicate to match.</param>
 66    /// <returns>The matching entity or null if no match was found.</returns>
 067    public TEntity? Find(Func<TEntity, bool> predicate) => Entities.Values.Where(predicate).FirstOrDefault();
 68
 69    /// <summary>
 70    /// Finds all entities matching the specified predicate.
 71    /// </summary>
 72    /// <param name="predicate">A predicate to match.</param>
 73    /// <returns>The matching entities.</returns>
 074    public IEnumerable<TEntity> FindMany(Func<TEntity, bool> predicate) => Entities.Values.Where(predicate);
 75
 76    /// <summary>
 77    /// Finds all entities matching the specified predicate and orders them by the specified key.
 78    /// </summary>
 79    /// <param name="predicate">The predicate to match.</param>
 80    /// <param name="orderBy">The key to order by.</param>
 81    /// <param name="orderDirection">The order direction.</param>
 82    /// <typeparam name="TKey">The type of the key.</typeparam>
 83    /// <returns>The matching entities.</returns>
 84    public IEnumerable<TEntity> FindMany<TKey>(Func<TEntity, bool> predicate, Func<TEntity, TKey> orderBy, OrderDirectio
 85    {
 086        var query = Entities.Values.Where(predicate);
 87
 088        query = orderDirection switch
 089        {
 090            OrderDirection.Ascending => query.OrderBy(orderBy),
 091            OrderDirection.Descending => query.OrderByDescending(orderBy),
 092            _ => query.OrderBy(orderBy)
 093        };
 94
 095        return query;
 96    }
 97
 98    /// <summary>
 99    /// Lists all entities.
 100    /// </summary>
 101    /// <returns>All entities.</returns>
 0102    public IEnumerable<TEntity> List() => Entities.Values;
 103
 104    /// <summary>
 105    /// Deletes an entity by ID.
 106    /// </summary>
 107    /// <param name="id">The ID of the entity to delete.</param>
 108    /// <returns>True if the entity was deleted, otherwise false.</returns>
 0109    public bool Delete(string id) => Entities.Remove(id);
 110
 111    /// <summary>
 112    /// Deletes all entities matching the specified predicate.
 113    /// </summary>
 114    /// <param name="predicate">The predicate to match.</param>
 115    /// <returns>The number of entities deleted.</returns>
 116    public long DeleteWhere(Func<TEntity, bool> predicate)
 117    {
 0118        var query =
 0119            from entry in Entities
 0120            where predicate(entry.Value)
 0121            select entry;
 122
 0123        var entries = query.ToList();
 0124        foreach (var entry in entries)
 0125            Entities.Remove(entry);
 126
 0127        return entries.Count;
 128    }
 129
 130    /// <summary>
 131    /// Deletes all entities matching the specified IDs.
 132    /// </summary>
 133    /// <param name="ids">The IDs of the entities to delete.</param>
 134    /// <returns>The number of entities deleted.</returns>
 135    public long DeleteMany(IEnumerable<string> ids)
 136    {
 0137        var count = 0;
 0138        foreach (var id in ids)
 139        {
 0140            count++;
 0141            Entities.Remove(id);
 142        }
 143
 0144        return count;
 145    }
 146
 147    /// <summary>
 148    /// Deletes the specified entities.
 149    /// </summary>
 150    /// <param name="entities">The entities to delete.</param>
 151    /// <param name="idAccessor">A function that returns the ID of the entity.</param>
 152    /// <returns></returns>
 153    public long DeleteMany(IEnumerable<TEntity> entities, Func<TEntity, string> idAccessor)
 154    {
 0155        var count = 0;
 0156        var list = entities.ToList();
 157
 0158        foreach (var entity in list)
 159        {
 0160            count++;
 0161            var id = idAccessor(entity);
 0162            Entities.Remove(id);
 163        }
 164
 0165        return count;
 166    }
 167
 168    /// <summary>
 169    /// Returns a queryable of all entities.
 170    /// </summary>
 171    /// <param name="query">A function that returns a queryable.</param>
 172    /// <returns>A queryable of all entities.</returns>
 173    public IEnumerable<TEntity> Query(Func<IQueryable<TEntity>, IQueryable<TEntity>> query)
 174    {
 0175        var queryable = Entities.Values.AsQueryable();
 0176        return query(queryable);
 177    }
 178
 179    /// <summary>
 180    /// Returns true if any entity matches the specified predicate.
 181    /// </summary>
 182    /// <param name="predicate">The predicate to match.</param>
 183    /// <returns>True if any entity matches the specified predicate, otherwise false.</returns>
 0184    public bool Any(Func<TEntity, bool> predicate) => Entities.Values.Any(predicate);
 185
 186    /// <summary>
 187    /// Returns the number of entities matching the specified predicate.
 188    /// </summary>
 189    /// <param name="predicate">The predicate to match.</param>
 190    /// <param name="propertySelector">The property to distinct by.</param>
 191    /// <returns>True if any entity matches the specified predicate, otherwise false.</returns>
 192    public long Count<TProperty>(Func<TEntity, bool> predicate, Func<TEntity, TProperty> propertySelector)
 193    {
 0194        return Entities.Values
 0195            .DistinctBy(propertySelector)
 0196            .Count(predicate);
 197    }
 198}