/// <summary>
 /// Find the items specified by the <paramref name="where"/> clause.
 /// </summary>
 /// <param name="param">The fields for the <paramref name="where"/> condition.</param>
 /// <param name="where">The search condition for the SELECT statement.</param>
 /// <param name="orderBy">An expression for how to order the result.</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>
 /// <returns>The found items.</returns>
 protected async Task <IEnumerable <TDatabaseItem> > InternalSearchWhereAsync(object param, string where, string orderBy,
                                                                              int offset, int limit)
 {
     InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
     InternalContract.RequireGreaterThanOrEqualTo(0, limit, nameof(limit));
     where = where ?? "1=1";
     return(await InternalSearchAsync(param, $"SELECT * FROM [{TableMetadata.TableName}] WHERE ({where})", orderBy, offset, limit));
 }
 /// <inheritdoc />
 public async Task <PageEnvelope <TDatabaseItem> > SearchAllAsync(string orderBy, int offset, int?limit = null,
                                                                  CancellationToken token = default)
 {
     InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
     if (limit != null)
     {
         InternalContract.RequireGreaterThanOrEqualTo(0, limit.Value, nameof(limit));
     }
     return(await SearchWhereAsync(null, orderBy, null, offset, limit, token));
 }
示例#3
0
 /// <summary>
 /// Get the registered type for a specific <paramref name="schemaName"/> and <paramref name="schemaVersion"/>.
 /// </summary>
 private Type Get(string schemaName, int schemaVersion)
 {
     InternalContract.RequireNotNull(schemaName, nameof(schemaName));
     InternalContract.RequireGreaterThanOrEqualTo(0, schemaVersion, nameof(schemaVersion));
     if (!_typeDictionary.TryGetValue(schemaName, out var versionDictionary))
     {
         return(null);
     }
     return(versionDictionary.TryGetValue(schemaVersion, out var type) ? type : null);
 }
        /// <inheritdoc />
        public async Task PublishAsync(string entityName, string eventName, int majorVersion, int minorVersion, JObject eventBody)
        {
            InternalContract.RequireNotNullOrWhitespace(entityName, nameof(entityName));
            InternalContract.RequireNotNullOrWhitespace(eventName, nameof(eventName));
            InternalContract.RequireGreaterThanOrEqualTo(1, majorVersion, nameof(majorVersion));
            InternalContract.RequireGreaterThanOrEqualTo(0, minorVersion, nameof(minorVersion));

            FulcrumAssert.IsTrue(FulcrumApplication.IsInDevelopment, $"This method can only be called in run time level Development. The run time level was {FulcrumApplication.Setup.RunTimeLevel}");
            var relativeUrl = $"api/BusinessEvents/{entityName}/{eventName}/{majorVersion}/{minorVersion}";
            await RestClient.PostNoResponseContentAsync(relativeUrl, eventBody);
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="maximumCount">The maximum number of parallel executions for this semaphore.</param>
 /// <param name="timeSpanBetweenRetries">The time to wait between new tries to raise the semaphore.
 /// The minimum wait time is (1 ms).
 /// Null means that we will use the minimum wait time.</param>
 public NexusAsyncSemaphore(int maximumCount, TimeSpan?timeSpanBetweenRetries = null)
 {
     _maximumCount = maximumCount;
     InternalContract.RequireGreaterThanOrEqualTo(1, maximumCount, nameof(maximumCount));
     if (timeSpanBetweenRetries == null)
     {
         timeSpanBetweenRetries = TimeSpan.FromMilliseconds(1);
     }
     InternalContract.RequireGreaterThanOrEqualTo(TimeSpan.FromMilliseconds(1), timeSpanBetweenRetries.Value, nameof(timeSpanBetweenRetries));
     _timeSpanBetweenRetries = timeSpanBetweenRetries.Value;
     _count = 0;
     _insideLockLevel.Value = 0;
 }
示例#6
0
        public void GreaterThanOrEqualOk()
        {
            const string parameterName = "parameterName";

            try
            {
                InternalContract.RequireGreaterThanOrEqualTo(1, 1, parameterName);
            }
            catch (Exception e)
            {
                UT.Assert.Fail($"Expected no exception but got {e.Message}.");
            }
        }
        public void GreaterThanOrEqualOk()
        {
            const string parameterName = "parameterName";

            try
            {
                InternalContract.RequireGreaterThanOrEqualTo(1, 1, parameterName);
            }
            catch (Exception e)
            {
                Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail($"Expected no exception but got {e.Message}.");
            }
        }
        /// <summary>
        /// Find the items specified by the <paramref name="selectStatement"/>.
        /// </summary>
        /// <param name="param">The fields for the <paramref name="selectStatement"/> condition.</param>
        /// <param name="selectStatement">The SELECT statement, including WHERE, but not ORDER BY.</param>
        /// <param name="orderBy">An expression for how to order the result.</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>
        /// <returns>The found items.</returns>
        ///
        protected async Task <IEnumerable <TDatabaseItem> > InternalSearchAsync(object param, string selectStatement, string orderBy,
                                                                                int offset, int limit)
        {
            InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
            InternalContract.RequireGreaterThanOrEqualTo(0, limit, nameof(limit));
            InternalContract.RequireNotNullOrWhitespace(selectStatement, nameof(selectStatement));
            orderBy = orderBy ?? TableMetadata.GetOrderBy() ?? "1";
            var sqlQuery = $"{selectStatement} " +
                           $" ORDER BY {orderBy}" +
                           $" OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY";

            return(await QueryAsync(sqlQuery, param));
        }
        public static Task RandomDelayAsync(TimeSpan minTime, TimeSpan maxTime, CancellationToken cancellationToken = default)
        {
            InternalContract.RequireGreaterThanOrEqualTo(TimeSpan.Zero, minTime, nameof(minTime));
            InternalContract.RequireGreaterThanOrEqualTo(minTime, maxTime, nameof(maxTime));

            var minTimeInSeconds = minTime.TotalSeconds;
            var maxTimeInSeconds = maxTime.TotalSeconds;
            var interval         = maxTimeInSeconds - minTimeInSeconds;

            var waitTimeInSeconds = minTimeInSeconds + Random.NextDouble() * interval;
            var waitTime          = TimeSpan.FromSeconds(waitTimeInSeconds);

            return(Task.Delay(waitTime, cancellationToken));
        }
        public void GreaterThanOrEqualFail()
        {
            const string parameterName = "parameterName";

            try
            {
                InternalContract.RequireGreaterThanOrEqualTo(1, 2, 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}.");
            }
        }
示例#11
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);
        }
示例#12
0
        /// <summary>
        /// Register a <paramref name="type"/> for a specific <paramref name="schemaName"/> and <paramref name="schemaVersion"/>.
        /// </summary>
        public SchemaParser Add(string schemaName, int schemaVersion, Type type)
        {
            InternalContract.RequireNotNull(schemaName, nameof(schemaName));
            InternalContract.RequireGreaterThanOrEqualTo(0, schemaVersion, nameof(schemaVersion));
            InternalContract.RequireNotNull(type, nameof(type));
            if (!_typeDictionary.TryGetValue(schemaName, out var versionDictionary))
            {
                versionDictionary = new ConcurrentDictionary <int, Type>();
                if (!_typeDictionary.TryAdd(schemaName, versionDictionary))
                {
                    versionDictionary = _typeDictionary[schemaName];
                }
            }

            var success = versionDictionary.TryAdd(schemaVersion, type);

            InternalContract.Require(success, $"Schema {schemaName} version {schemaVersion} had already been added.");

            return(this);
        }
 /// <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));
     }
 }
        /// <inheritdoc />
        public async Task <PageEnvelope <TDatabaseItem> > SearchWhereAsync(string where = null, string orderBy = null, object param = null, int offset = 0, int?limit = null, CancellationToken token = default)
        {
            limit = limit ?? PageInfo.DefaultLimit;
            InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
            InternalContract.RequireGreaterThanOrEqualTo(0, limit.Value, nameof(limit));
            var total = await CountItemsWhereAsync(where, param, token);

            var data = await InternalSearchWhereAsync(param, where, orderBy, offset, limit.Value, token);

            var dataAsArray = data as TDatabaseItem[] ?? data.ToArray();

            return(new PageEnvelope <TDatabaseItem>
            {
                Data = dataAsArray,
                PageInfo = new PageInfo
                {
                    Offset = offset,
                    Limit = limit.Value,
                    Returned = dataAsArray.Length,
                    Total = total
                }
            });
        }
示例#15
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));
        }
        /// <inheritdoc />
        public async Task <PageEnvelope <TDatabaseItem> > SearchAdvancedAsync(string countFirst, string selectFirst, string selectRest, string orderBy = null, object param = null, int offset = 0, int?limit = null, CancellationToken token = default(CancellationToken))
        {
            limit = limit ?? PageInfo.DefaultLimit;
            InternalContract.RequireGreaterThanOrEqualTo(0, offset, nameof(offset));
            InternalContract.RequireGreaterThanOrEqualTo(0, limit.Value, nameof(limit));
            var total = await CountItemsAdvancedAsync(countFirst, selectRest, param, token);

            var selectStatement = selectRest == null ? null : $"{selectFirst} {selectRest}";
            var data            = await InternalSearchAsync(param, selectStatement, orderBy, offset, limit.Value);

            var dataAsArray = data as TDatabaseItem[] ?? data.ToArray();

            return(new PageEnvelope <TDatabaseItem>
            {
                Data = dataAsArray,
                PageInfo = new PageInfo
                {
                    Offset = offset,
                    Limit = limit.Value,
                    Returned = dataAsArray.Length,
                    Total = total
                }
            });
        }
示例#17
0
 /// <summary>
 /// Register a <paramref name="type"/> for an anonymous schema name and a specific <paramref name="schemaVersion"/>.
 /// </summary>
 /// <remarks>Same as registering the schema name "".</remarks>
 public SchemaParser Add(int schemaVersion, Type type)
 {
     InternalContract.RequireGreaterThanOrEqualTo(0, schemaVersion, nameof(schemaVersion));
     InternalContract.RequireNotNull(type, nameof(type));
     return(Add("", schemaVersion, type));
 }