public Task <IStorableProduct> ReadAsync(int id)
        {
            InternalContract.RequireGreaterThan(0, id, nameof(id));
            var product = GetProductOrThrowNotFound(id);

            return(Task.FromResult(product));
        }
        /// <summary>
        /// <paramref name="constant"/> + <paramref name="coefficient"/> * Math.Pow(<paramref name="exponentiationBase"/>, <paramref name="consecutiveFails"/> - 1)
        /// If the calculated value is greater than <paramref name="max"/>, then max is returned.
        /// </summary>
        public static TimeSpan Exponential(int consecutiveFails, TimeSpan max, TimeSpan constant, TimeSpan coefficient, double exponentiationBase = 2.0)
        {
            InternalContract.RequireGreaterThan(0, consecutiveFails, nameof(consecutiveFails));
            var calculatedTimeSpan = TimeSpan.FromSeconds(constant.TotalSeconds + Math.Pow(exponentiationBase, consecutiveFails - 1) * coefficient.TotalSeconds);

            return(calculatedTimeSpan < max ? calculatedTimeSpan : max);
        }
        /// <summary>
        /// <paramref name="constant"/> + <paramref name="coefficient"/> * (<paramref name="consecutiveFails"/> - 1)
        /// If the calculated value is greater than <paramref name="max"/>, then max is returned.
        /// </summary>
        public static TimeSpan Linear(int consecutiveFails, TimeSpan max, TimeSpan constant, TimeSpan coefficient)
        {
            InternalContract.RequireGreaterThan(0, consecutiveFails, nameof(consecutiveFails));
            var calculatedTimeSpan = TimeSpan.FromSeconds(constant.TotalSeconds + (consecutiveFails - 1) * coefficient.TotalSeconds);

            return(calculatedTimeSpan < max ? calculatedTimeSpan : max);
        }
예제 #4
0
        public async Task DeleteAsync(string stringId)
        {
            var isInt = int.TryParse(stringId, out int id);

            InternalContract.Require(isInt, $"Could not parse '{stringId}' as an integer");
            InternalContract.RequireGreaterThan(0, id, nameof(id));
            var dalProduct = await _productPersistance.DeleteAsync(id).ConfigureAwait(false);

            return(FromDal(dalProduct));
        }
        public void GreaterThanOk()
        {
            const string parameterName = "parameterName";

            try
            {
                InternalContract.RequireGreaterThan(1, 2, parameterName);
            }
            catch (Exception e)
            {
                Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail($"Expected no exception but got {e.Message}.");
            }
        }
예제 #6
0
        public void GreaterThanOk()
        {
            const string parameterName = "parameterName";

            try
            {
                InternalContract.RequireGreaterThan(1, 2, parameterName);
            }
            catch (Exception e)
            {
                UT.Assert.Fail($"Expected no exception but got {e.Message}.");
            }
        }
        private async Task CacheItemCollectionOperationAsync(TModel[] itemsArray, int limit, string key, bool isSetOperation, CancellationToken token)
        {
            InternalContract.RequireNotNull(itemsArray, nameof(itemsArray));
            InternalContract.RequireGreaterThan(0, limit, nameof(limit));
            if (!isSetOperation)
            {
                InternalContract.Require(limit == int.MaxValue, $"When {nameof(isSetOperation)} is false, then {nameof(limit)} must be set to int.MaxValue ({int.MaxValue}), but it was set to {limit}.");
            }
            try
            {
                if (Options.SaveCollections)
                {
                    var cacheArrayTask = isSetOperation
                        ? CacheSetAsync(itemsArray, limit, key, token)
                        : Cache.RemoveAsync(key, token);
                    var cachePageTasks = new List <Task>();

                    // Cache individual pages
                    var offset = 0;
                    while (offset < itemsArray.Length)
                    {
                        var data         = itemsArray.Skip(offset).Take(PageInfo.DefaultLimit);
                        var pageEnvelope = new PageEnvelope <TModel>(offset, PageInfo.DefaultLimit, itemsArray.Length, data);
                        var task         = CacheItemPageOperationAsync(pageEnvelope, limit, key, isSetOperation, token);
                        cachePageTasks.Add(task);
                        offset += PageInfo.DefaultLimit;
                    }
                    await Task.WhenAll(cachePageTasks);

                    await cacheArrayTask;
                }
                else
                {
                    // Cache individual items
                    var cacheIndividualItemTasks = isSetOperation
                    ? itemsArray.Select(item => CacheSetAsync(item, token))
                        : itemsArray.Select(item => CacheRemoveByIdAsync(GetIdDelegate(item), token));
                    await Task.WhenAll(cacheIndividualItemTasks);
                }
            }
            finally
            {
                _collectionOperations.TryRemove(key, out _);
            }
        }
        public void GreaterThanFail()
        {
            const string parameterName = "parameterName";

            try
            {
                InternalContract.RequireGreaterThan(1, 1, parameterName);
                Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail("An exception should have been thrown");
            }
            catch (FulcrumContractException fulcrumException)
            {
                Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(fulcrumException.TechnicalMessage.Contains(parameterName));
            }
            catch (Exception e)
            {
                Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail($"Expected a specific FulcrumException but got {e.GetType().FullName}.");
            }
        }
예제 #9
0
        /// <summary>
        /// This method will get all items and then do the filter and sorting in memory.
        /// </summary>
        /// <param name="parentId">The specific parent to search the child items for.</param>
        /// <param name="details">The search details</param>
        /// <param name="offset">The number of items that will be skipped in result.</param>
        /// <param name="limit">The maximum number of items to return.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled</param>
        /// <returns>A page of the found items.</returns>
        /// <remarks>If your persistence layer supports search, then avoid using this, at it always reads all the items.</remarks>
        public async Task <PageEnvelope <TModel> > SearchChildrenAsync(TId parentId, SearchDetails <TModel> details, int offset, int?limit = null,
                                                                       CancellationToken cancellationToken = default)
        {
            limit = limit ?? PageInfo.DefaultLimit;
            InternalContract.RequireNotNull(details, nameof(details));
            InternalContract.RequireValidated(details, nameof(details));
            InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
            InternalContract.RequireGreaterThan(0, limit.Value, nameof(limit));

            var allItems = (await _service.ReadChildrenAsync(parentId, int.MaxValue, cancellationToken))
                           .ToList();

            var list = SearchHelper.FilterAndSort(allItems, details)
                       .Skip(offset)
                       .Take(limit.Value);
            var page = new PageEnvelope <TModel>(offset, limit.Value, allItems.Count(), list);

            return(page);
        }
 /// <inheritdoc />
 public Task <IPageEnvelope <TStorableItem, TId> > ReadAllAsync(int offset = 0, int limit = 100)
 {
     InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
     InternalContract.RequireGreaterThan(0, limit, nameof(limit));
     lock (_memoryItems)
     {
         var keys = _memoryItems.Keys.Skip(offset).Take(limit);
         var list = keys.Select(GetMemoryItem).ToList();
         IPageEnvelope <TStorableItem, TId> page = new PageEnvelope <TStorableItem, TId>
         {
             PageInfo = new PageInfo
             {
                 Offset   = offset,
                 Limit    = limit,
                 Returned = list.Count,
                 Total    = _memoryItems.Count
             },
             Data = list
         };
         return(Task.FromResult(page));
     }
 }
예제 #11
0
        /// <inheritdoc />
        public Task <PageEnvelope <TManyModel> > SearchChildrenAsync(Guid parentId, SearchDetails <TManyModel> details, int offset, int?limit = null,
                                                                     CancellationToken cancellationToken = default)
        {
            InternalContract.RequireNotNull(details, nameof(details));
            InternalContract.RequireValidated(details, nameof(details));
            InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
            if (limit != null)
            {
                InternalContract.RequireGreaterThan(0, limit.Value, nameof(limit));
            }

            var whereAsModel = details.GetWhereAsModel("%", "_");
            var param        = whereAsModel == null ? new TManyModel() : whereAsModel;
            var property     = typeof(TManyModel).GetProperty(ParentColumnName);

            FulcrumAssert.IsNotNull(property, CodeLocation.AsString());
            property?.SetValue(param, parentId);

            var where = CrudSearchHelper.GetWhereStatement(details, ParentColumnName);
            var orderBy = CrudSearchHelper.GetOrderByStatement(details);

            return(SearchWhereAsync(where, orderBy, param, offset, limit, cancellationToken));
        }
        /// <summary>
        /// Get a value from the cache if all constraints are fulfilled.
        /// </summary>
        protected internal async Task <TModel[]> CacheGetAsync(int limit, string key, CancellationToken token)
        {
            InternalContract.RequireGreaterThan(0, limit, nameof(limit));
            if (limit > _limitOfItemsInReadAllCache)
            {
                return(null);
            }
            if (UseCacheAtAllMethodAsync != null &&
                !await UseCacheAtAllMethodAsync(typeof(TModel[])))
            {
                return(null);
            }

            return(await GetAndMaybeReturnAsync(key, cacheEnvelope =>
            {
                var array = SerializingSupport.Deserialize <TModel[]>(cacheEnvelope.Data);
                if (limit > array.Length)
                {
                    return array;
                }
                var subset = array.Take(limit);
                return subset as TModel[] ?? subset.ToArray();
            }, token : token));
        }
예제 #13
0
 /// <inheritdoc />
 public Task <IEnumerable <TModel> > ReadAllAsync(int limit = Int32.MaxValue, CancellationToken cancellationToken = default)
 {
     InternalContract.RequireGreaterThan(0, limit, nameof(limit));
     return(StorageHelper.ReadPagesAsync <TModel>((offset, ct) => _service.ReadAllWithPagingAsync(offset, null, ct), limit, cancellationToken));
 }