Example #1
0
        /// <summary>
        /// The function may return permissions for more claims than required.
        /// </summary>
        public IEnumerable <PrincipalPermissionInfo> GetPrincipalPermissions(IPrincipal principal, IEnumerable <Guid> claimIds = null)
        {
            CsUtility.Materialize(ref claimIds);
            if (claimIds != null && !claimIds.Any())
            {
                return(Enumerable.Empty <PrincipalPermissionInfo>());
            }

            var query = _principalPermissionRepository.Query()
                        .Where(principalPermission => principalPermission.IsAuthorized != null &&
                               principalPermission.PrincipalID == principal.ID);

            if (claimIds != null && claimIds.Count() < _sqlFilterItemsLimit)
            {
                query = query.Where(principalPermission => claimIds.Contains(principalPermission.ClaimID.Value));
            }

            return(query.Select(principalPermission => new PrincipalPermissionInfo
            {
                ID = principalPermission.ID,
                PrincipalID = principalPermission.PrincipalID.Value,
                ClaimID = principalPermission.ClaimID.Value,
                IsAuthorized = principalPermission.IsAuthorized.Value,
            })
                   .ToList());
        }
        private static IEnumerable <IConceptInfo> InitializeNonparsablePropertiesRecursive(IAlternativeInitializationConcept alternativeInitializationConcept, HashSet <string> alreadyCreated, int depth, ILogger traceLogger)
        {
            if (depth > 10)
            {
                throw new DslSyntaxException(alternativeInitializationConcept, "Macro concept references cannot be resolved.");
            }

            List <IConceptInfo> result = new List <IConceptInfo>();

            IEnumerable <IConceptInfo> createdConcepts;

            alternativeInitializationConcept.InitializeNonparsableProperties(out createdConcepts);
            CsUtility.Materialize(ref createdConcepts);

            if (createdConcepts != null && createdConcepts.Count() > 0)
            {
                traceLogger.Trace(() => alternativeInitializationConcept.GetShortDescription() + " generated on alternative initialization: "
                                  + string.Join(", ", createdConcepts.Select(c => c.GetShortDescription())) + ".");

                result.AddRange(createdConcepts);
                foreach (var concept in createdConcepts.OfType <IAlternativeInitializationConcept>())
                {
                    if (!alreadyCreated.Contains(concept.GetFullDescription()))
                    {
                        alreadyCreated.Add(concept.GetFullDescription());
                        result.AddRange(InitializeNonparsablePropertiesRecursive(concept, alreadyCreated, depth + 1, traceLogger));
                    }
                }
            }

            return(result);
        }
Example #3
0
        /// <summary>
        /// The function may return permissions for more claims than required.
        /// </summary>
        public IEnumerable <RolePermissionInfo> GetRolePermissions(IEnumerable <Guid> roleIds, IEnumerable <Guid> claimIds = null)
        {
            CsUtility.Materialize(ref roleIds);
            CsUtility.Materialize(ref claimIds);
            if (!roleIds.Any() || (claimIds != null && !claimIds.Any()))
            {
                return(Enumerable.Empty <RolePermissionInfo>());
            }

            var query = _rolePermissionRepository.Query()
                        .Where(rolePermission => rolePermission.IsAuthorized != null &&
                               roleIds.Contains(rolePermission.RoleID.Value));

            if (claimIds != null && claimIds.Count() < _sqlFilterItemsLimit)
            {
                query = query.Where(rolePermission => claimIds.Contains(rolePermission.ClaimID.Value));
            }

            return(query.Select(rolePermission => new RolePermissionInfo
            {
                ID = rolePermission.ID,
                RoleID = rolePermission.RoleID.Value,
                ClaimID = rolePermission.ClaimID.Value,
                IsAuthorized = rolePermission.IsAuthorized.Value,
            })
                   .ToList());
        }
Example #4
0
        /// <summary>
        /// Clears the roles' authorization data from the cache: RoleRoles, RolePermissions and Role (full list).
        /// </summary>
        public void ClearCacheRoles(IEnumerable <Guid> roleIds)
        {
            CsUtility.Materialize(ref roleIds);
            _logger.Trace(() => "ClearCacheRoles: " + string.Join(", ", roleIds) + ".");

            var deleteKeys =
                roleIds.Distinct()
                .Select(roleId => "AuthorizationDataCache.RoleRoles." + roleId.ToString())
                .Concat(roleIds.Select(roleId => "AuthorizationDataCache.RolePermissions." + roleId.ToString()))
                .Concat(new[] { "AuthorizationDataCache.Roles" });

            var cache = MemoryCache.Default;

            foreach (string key in deleteKeys)
            {
                cache.Remove(key);
            }

            var systemRoles = (IDictionary <SystemRole, Guid>)cache.Get("AuthorizationDataCache.SystemRoles");

            if (systemRoles != null && systemRoles.Values.Intersect(roleIds).Any())
            {
                _logger.Trace(() => "ClearCacheRoles: SystemRoles.");
                cache.Remove("AuthorizationDataCache.SystemRoles");
            }
        }
Example #5
0
        public static void Save(IEnumerable <InstalledPackage> packages)
        {
            CsUtility.Materialize(ref packages);
            string serialized = JsonConvert.SerializeObject(packages, _serializerSettings);

            File.WriteAllText(GetPackagesFilePath(), serialized, Encoding.UTF8);
        }
Example #6
0
        /// <summary>
        /// Case-insensitive comparison.
        /// </summary>
        public static void AssertContains(string text, IEnumerable <string> patterns, string message = null, string errorContext = null)
        {
            CsUtility.Materialize(ref patterns);
            if (patterns.Any(string.IsNullOrEmpty))
            {
                throw new ArgumentException("Given list of patterns contains an empty string.");
            }

            Console.WriteLine("[AssertContains] Text: '" + text + "'.");

            foreach (var pattern in patterns)
            {
                Console.Write("[AssertContains] Looking for pattern '" + pattern + "'.");

                if (text.ToLower().Contains(pattern.ToLower()))
                {
                    Console.WriteLine(" Found.");
                }
                else
                {
                    Console.WriteLine(" Not found.");
                    Console.WriteLine(errorContext);
                    Assert.Fail("Text should contain pattern '" + pattern + "'."
                                + (string.IsNullOrEmpty(message) ? " " + message : "")
                                + " " + "The text is '" + text.Limit(200, true) + "'.");
                }
            }
        }
Example #7
0
 private void LogConcepts(StringBuilder report, string reportName, IEnumerable <IConceptInfo> concepts, bool first = false)
 {
     CsUtility.Materialize(ref concepts);
     if (concepts != null && concepts.Any())
     {
         report.Append(first ? "" : "\r\n").Append(reportName).Append(": ").Append(string.Join(", ", concepts.Select(c => c.GetShortDescription())) + ".");
     }
 }
Example #8
0
 private void LogConcepts(StringBuilder report, string reportName, IEnumerable <IConceptInfo> concepts)
 {
     CsUtility.Materialize(ref concepts);
     if (concepts != null && concepts.Count() > 0)
     {
         report.Append("\r\n  " + reportName + ": " + string.Join(", ", concepts.Select(c => c.GetShortDescription())) + ".");
     }
 }
Example #9
0
        /// <returns>Result is a List&lt;&gt; of the data structure type.
        /// The list is returned as IEnumerable&lt;&gt; of the interface type,
        /// to allow strongly-typed use of the list through TEntityInterface interface.
        /// Neither List&lt;&gt; or IList&lt;&gt; are covariant, so IEnumerable&lt;&gt; is used.</returns>
        public IEnumerable <TEntityInterface> CreateList <TSource>(IEnumerable <TSource> source, Action <TSource, TEntityInterface> initializer)
        {
            CsUtility.Materialize(ref source);
            var newItems = CreateList(source.Count());

            foreach (var pair in source.Zip(newItems, (sourceItem, newItem) => new { sourceItem, newItem }))
            {
                initializer(pair.sourceItem, pair.newItem);
            }
            return(newItems);
        }
        /// <summary>
        /// The function may return more claims than required.
        /// Note that the result will not include claims that are inactive or do not exist, and that the order of returned items might not match the parameter.
        /// </summary>
        public IDictionary <Claim, ClaimInfo> GetClaims(IEnumerable <Claim> requiredClaims = null)
        {
            CsUtility.Materialize(ref requiredClaims);
            if (requiredClaims != null && requiredClaims.Count() == 0)
            {
                return(new Dictionary <Claim, ClaimInfo>());
            }

            var queryClaims = _claimRepository.Query().Where(claim => claim.Active != null && claim.Active.Value);

            if (requiredClaims != null)
            {
                var claimsResources = requiredClaims.Select(claim => claim.Resource).Distinct().ToList();
                var claimsRights    = requiredClaims.Select(claim => claim.Right).Distinct().ToList();

                if (claimsResources.Count < _sqlFilterItemsLimit && claimsRights.Count < _sqlFilterItemsLimit)
                {
                    queryClaims = queryClaims.Where(claim => claimsResources.Contains(claim.ClaimResource) && claimsRights.Contains(claim.ClaimRight));
                }
            }

            var loadedClaims = queryClaims
                               .Select(claim => new ClaimInfo
            {
                ID       = claim.ID,
                Resource = claim.ClaimResource,
                Right    = claim.ClaimRight
            })
                               .ToList();

            Dictionary <Claim, ClaimInfo> claimsIndex;

            try
            {
                claimsIndex = loadedClaims.ToDictionary(item => new Claim(item.Resource, item.Right));
            }
            catch
            {
                var duplicates = loadedClaims.GroupBy(item => new Claim(item.Resource, item.Right))
                                 .Where(g => g.Count() > 1)
                                 .FirstOrDefault();
                if (duplicates != null)
                {
                    throw new FrameworkException(string.Format("Loaded duplicate claims: '{0} {1}' and '{2} {3}'.",
                                                               duplicates.First().Resource, duplicates.First().Right,
                                                               duplicates.Last().Resource, duplicates.Last().Right));
                }
                throw;
            }

            return(claimsIndex);
        }
Example #11
0
        public IList <FilterObject> ToFilterObjects(IEnumerable <FilterCriteria> genericFilter)
        {
            CsUtility.Materialize(ref genericFilter);

            foreach (var filter in genericFilter)
            {
                ValidateAndPrepare(filter);
            }

            var filterObjects = new List <FilterObject>(genericFilter.Count());

            bool handledPropertyFilter = false;

            foreach (var filter in genericFilter)
            {
                if (IsPropertyFilter(filter))
                {
                    if (!handledPropertyFilter)
                    {
                        handledPropertyFilter = true;
                        filterObjects.Add(CombinePropertyFilters(genericFilter));
                    }
                }
                else
                {
                    var filterObject = new FilterObject
                    {
                        FilterType = GetSpecificFilterType(filter.Filter),
                        Parameter  = filter.Value
                    };

                    if (string.Equals(filter.Operation, FilterOperationNotMatches, StringComparison.OrdinalIgnoreCase))
                    {
                        if (ReflectionHelper <IEntity> .GetPredicateExpressionParameter(filterObject.FilterType) != null)
                        {
                            filterObject.Parameter = Not((LambdaExpression)filterObject.Parameter);
                        }
                        else
                        {
                            throw new FrameworkException(FilterOperationNotMatches + " operation is only allowed on a filter expression: Expression<Func<T, bool>>.");
                        }
                    }

                    filterObjects.Add(filterObject);
                }
            }

            return(filterObjects);
        }
Example #12
0
        /// <summary>
        /// Clears the roles' authorization data from the cache: RoleRoles, RolePermissions and Role (full list).
        /// </summary>
        public void ClearCacheRoles(IEnumerable <Guid> roleIds)
        {
            CsUtility.Materialize(ref roleIds);
            _logger.Trace(() => "ClearCacheRoles: " + string.Join(", ", roleIds) + ".");

            var deleteKeys =
                roleIds.Distinct()
                .Select(roleId => "AuthorizationDataCache.RoleRoles." + roleId.ToString())
                .Concat(roleIds.Select(roleId => "AuthorizationDataCache.RolePermissions." + roleId.ToString()))
                .Concat(new[] { "AuthorizationDataCache.Roles" });

            var cache = MemoryCache.Default;

            foreach (string key in deleteKeys)
            {
                cache.Remove(key);
            }
        }
        public void SaveConcepts(IEnumerable <IConceptInfo> concepts)
        {
            var sw = Stopwatch.StartNew();

            CsUtility.Materialize(ref concepts);
            _performanceLogger.Write(sw, "SaveConcepts: Materialize.");

            var serializerSettings = new JsonSerializerSettings
            {
                PreserveReferencesHandling = PreserveReferencesHandling.All,
                ReferenceLoopHandling      = ReferenceLoopHandling.Serialize,
                TypeNameHandling           = TypeNameHandling.All,
                Formatting = Formatting.Indented,
            };

            JsonUtility.SerializeToFile(concepts, DslModelFilePath, serializerSettings);
            _performanceLogger.Write(sw, "SaveConcepts: Serialize and write.");
        }
Example #14
0
        /// <summary>
        /// Clears the principals' authorization data from the cache: Principal, PrincipalRoles and PrincipalPermissions.
        /// </summary>
        public void ClearCachePrincipals(IEnumerable <IPrincipal> principals)
        {
            CsUtility.Materialize(ref principals);
            _logger.Trace(() => "ClearCachePrincipals: " + string.Join(", ", principals.Select(p => p.Name + " " + p.ID.ToString())) + ".");

            var deleteKeys =
                principals.Select(principal => "AuthorizationDataCache.Principal." + principal.Name.ToLower())
                .Concat(principals.Select(principal => "AuthorizationDataCache.PrincipalRoles." + principal.Name.ToLower() + "." + principal.ID.ToString()))
                .Concat(principals.Select(principal => "AuthorizationDataCache.PrincipalPermissions." + principal.Name.ToLower() + "." + principal.ID.ToString()))
                .Distinct();

            var cache = MemoryCache.Default;

            foreach (string key in deleteKeys)
            {
                cache.Remove(key);
            }
        }
Example #15
0
        public void SaveConcepts(IEnumerable <IConceptInfo> concepts)
        {
            var sw = Stopwatch.StartNew();

            var serializerSettings = new JsonSerializerSettings
            {
                PreserveReferencesHandling = PreserveReferencesHandling.All,
                ReferenceLoopHandling      = ReferenceLoopHandling.Serialize,
                TypeNameHandling           = TypeNameHandling.All,
            };

            CsUtility.Materialize(ref concepts);
            string serializedConcepts = JsonConvert.SerializeObject(concepts, serializerSettings);
            string path = Path.Combine(Paths.GeneratedFolder, DslModelFileName);

            File.WriteAllText(path, serializedConcepts, Encoding.UTF8);

            _performanceLogger.Write(sw, "DslModelFile.Save.");
        }
Example #16
0
        public void ExecuteSql(IEnumerable <string> commands, bool useTransaction, Action <int> beforeExecute, Action <int> afterExecute)
        {
            CsUtility.Materialize(ref commands);

            _logger.Trace(() => "Executing " + commands.Count() + " commands" + (useTransaction ? "" : " without transaction") + ".");

            SafeExecuteCommand(
                com =>
            {
                int count = 0;
                foreach (var sql in commands)
                {
                    count++;
                    if (sql == null)
                    {
                        throw new FrameworkException("SQL script is null.");
                    }

                    _logger.Trace(() => "Executing command: " + sql);

                    if (string.IsNullOrWhiteSpace(sql))
                    {
                        continue;
                    }

                    var sw = Stopwatch.StartNew();
                    try
                    {
                        com.CommandText = sql;

                        beforeExecute?.Invoke(count - 1);
                        com.ExecuteNonQuery();
                    }
                    finally
                    {
                        afterExecute?.Invoke(count - 1);
                        LogPerformanceIssue(sw, sql);
                    }
                }
                CheckTransactionState(useTransaction, com, commands);
            },
                useTransaction);
        }
Example #17
0
        /// <summary>
        /// Note that the result will not include roles that do not exist, and that the order of returned items might not match the parameter.
        /// </summary>
        public IDictionary <Guid, string> GetRoles(IEnumerable <Guid> roleIds = null)
        {
            CsUtility.Materialize(ref roleIds);
            if (roleIds != null && !roleIds.Any())
            {
                return(new Dictionary <Guid, string>());
            }

            var query = _roleRepository.Query();

            if (roleIds != null)
            {
                query = query.Where(role => roleIds.Contains(role.ID));
            }

            return(query
                   .Select(role => new { role.ID, role.Name }) // This select avoids loading extra columns from database.
                   .ToDictionary(role => role.ID, role => role.Name));
        }
Example #18
0
        public static void Save(IEnumerable <InstalledPackage> packages)
        {
            CsUtility.Materialize(ref packages);

            // Package folder is saved as relative path, to allow moving the deployed folder.
            foreach (var package in packages)
            {
                package.SetRelativeFolderPath();
            }

            string serialized = JsonConvert.SerializeObject(packages, _serializerSettings);

            foreach (var package in packages)
            {
                package.SetAbsoluteFolderPath();
            }

            File.WriteAllText(PackagesFilePath, serialized, Encoding.UTF8);
        }
        /// <summary>
        /// Note that the result will not include roles that do not exist, and that the order of returned items might not match the parameter.
        /// </summary>
        public IDictionary <Guid, string> GetRoles(IEnumerable <Guid> roleIds = null)
        {
            CsUtility.Materialize(ref roleIds);
            if (roleIds != null && roleIds.Count() == 0)
            {
                return(new Dictionary <Guid, string>());
            }

            var query = _roleRepository.Query();

            if (roleIds != null)
            {
                query = query.Where(role => roleIds.Contains(role.ID));
            }

            return(query
                   .Select(role => new { ID = role.ID, Name = role.Name })
                   .ToList()
                   .ToDictionary(role => role.ID, role => role.Name));
        }
Example #20
0
        /// <param name="sameRecord">Compare key properties, determining the records that should be inserted or deleted.
        /// Typical implementation:
        /// <code>
        ///     class CompareName : IComparer&lt;ISomeEntity&gt;
        ///     {
        ///         public int Compare(ISomeEntity x, ISomeEntity y) { return string.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase); }
        ///     }
        /// </code></param>
        /// <param name="sameValue">Compare other properties, determining the records that should be updated.
        /// Comparison may also include key properties with stricter constraints (such as case sensitivity).
        /// Typical implementation:
        /// <code>(x, y) =&gt; x.Name == y.Name &amp;&amp; x.SomeValue == y.SomeValue;</code></param>
        /// <param name="filterLoad">For supported filters types see <see cref="Load{TParameter}(TParameter)"/> function.</param>
        /// <param name="assign">Typical implementation:
        /// <code>(destination, source) =&gt; {
        ///     destination.Property1 = source.Property1;
        ///     destination.Property2 = source.Property2; }</code></param>
        /// <param name="beforeSave"><code>(toInsert, toUpdate, toDelete) => { some code; } </code></param>
        public void InsertOrUpdateOrDelete(
            IEnumerable <TEntityInterface> newItems,
            IComparer <TEntityInterface> sameRecord,
            Func <TEntityInterface, TEntityInterface, bool> sameValue,
            object filterLoad,
            Action <TEntityInterface, TEntityInterface> assign,
            BeforeSave beforeSave = null)
        {
            var stopwatch = Stopwatch.StartNew();

            // Initialize new items:

            CsUtility.Materialize(ref newItems);
            _performanceLogger.Write(stopwatch, () => string.Format("{0}.InsertOrUpdateOrDelete: Initialize new items ({1})",
                                                                    _repositoryName, newItems.Count()));

            // Load old items:

            IEnumerable <TEntityInterface> oldItems = this.Load(filterLoad);

            _performanceLogger.Write(stopwatch, () => string.Format("{0}.InsertOrUpdateOrDelete: Load old items ({1})",
                                                                    _repositoryName, oldItems.Count()));

            // Compare new and old items:

            IEnumerable <TEntityInterface> toInsert, toUpdate, toDelete;

            Diff(oldItems, newItems, sameRecord, sameValue, assign, out toInsert, out toUpdate, out toDelete);
            _performanceLogger.Write(stopwatch, () => string.Format("{0}.InsertOrUpdateOrDelete: Diff ({1} new items, {2} old items, {3} to insert, {4} to update, {5} to delete)",
                                                                    _repositoryName, newItems.Count(), oldItems.Count(), toInsert.Count(), toUpdate.Count(), toDelete.Count()));

            // Modify old items to match new items:

            if (beforeSave != null)
            {
                beforeSave(ref toInsert, ref toUpdate, ref toDelete);
            }
            Save(toInsert, toUpdate, toDelete);
            _performanceLogger.Write(stopwatch, () => string.Format("{0}.InsertOrUpdateOrDelete: Save ({1} new items, {2} old items, {3} to insert, {4} to update, {5} to delete)",
                                                                    _repositoryName, newItems.Count(), oldItems.Count(), toInsert.Count(), toUpdate.Count(), toDelete.Count()));
        }
Example #21
0
        /// <param name="sameRecord">Compare key properties, determining the records that should be inserted or deleted.
        /// If set to null, the items will be compared by the ID property.
        /// Typical implementation:
        /// <code>
        ///     class CompareName : IComparer&lt;ISomeEntity&gt;
        ///     {
        ///         public int Compare(ISomeEntity x, ISomeEntity y) { return string.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase); }
        ///     }
        /// </code></param>
        /// <param name="sameValue">Compare other properties, determining the records that should be updated.
        /// Comparison may also include key properties with stricter constraints (such as case sensitivity).
        /// Typical implementation:
        /// <code>(x, y) =&gt; x.Name == y.Name &amp;&amp; x.SomeValue == y.SomeValue;</code></param>
        /// <param name="filterLoad">For supported filters types see <see cref="Load"/> function.</param>
        /// <param name="assign">Typical implementation:
        /// <code>(destination, source) =&gt; {
        ///     destination.Property1 == source.Property1;
        ///     destination.Property2 == source.Property2; }</code></param>
        /// <param name="filterDeactivateDeleted">A filter that selects items that should be deactivated instead of deleted.
        /// Typical implementation:
        /// <code>(Func&lt;IEntity, bool&gt;)(item =&gt; ItemsInUseHashSet.Contains(item.ID))</code>
        /// <br/>For supported filters types see <see cref="Filter"/> function.
        /// </param>
        /// <param name="beforeSave"><code>(toInsert, toUpdate, toDelete) => { some code; } </code></param>
        public void InsertOrUpdateOrDeleteOrDeactivate(
            IEnumerable <TEntityInterface> newItems,
            IComparer <TEntityInterface> sameRecord,
            Func <TEntityInterface, TEntityInterface, bool> sameValue,
            object filterLoad,
            Action <TEntityInterface, TEntityInterface> assign,
            object filterDeactivateDeleted,
            BeforeSave beforeSave = null)
        {
            var stopwatch = Stopwatch.StartNew();

            // Initialize new items:

            CsUtility.Materialize(ref newItems);
            foreach (var newItem in newItems.Cast <IDeactivatable>())
            {
                if (newItem.Active == null)
                {
                    newItem.Active = true;
                }
            }
            _performanceLogger.Write(stopwatch, () => $"InsertOrUpdateOrDeleteOrDeactivate: Initialize new items ({newItems.Count()})");

            // Load old items:

            IEnumerable <TEntityInterface> oldItems = this.Load(filterLoad);

            _performanceLogger.Write(stopwatch, () => $"InsertOrUpdateOrDeleteOrDeactivate: Load old items ({oldItems.Count()})");

            // Compare new and old items:

            IEnumerable <TEntityInterface> toInsert, toUpdate, toDelete;

            Diff(oldItems, newItems, sameRecord, sameValue, assign, out toInsert, out toUpdate, out toDelete);
            _performanceLogger.Write(stopwatch, () => $"InsertOrUpdateOrDeleteOrDeactivate: Diff ({newItems.Count()} new items, {oldItems.Count()} old items, {toInsert.Count()} to insert, {toUpdate.Count()} to update, {toDelete.Count()} to delete)");

            // Deactivate some items instead of deleting:

            IEnumerable <TEntityInterface> toDeactivate = Filter(toDelete, filterDeactivateDeleted);
            int activeToDeactivateCount = 0;

            if (toDeactivate.Any())
            {
                int oldDeleteCount = toDelete.Count();

                // Don't delete items that should be deactivated:
                if (toDeactivate.Count() == oldDeleteCount)
                {
                    toDelete = CreateList(0);
                }
                else
                {
                    var toDeactivateIndex = new HashSet <TEntityInterface>(toDeactivate, new InstanceComparer());
                    toDelete = Reflection.ToListOfEntity(toDelete.Where(item => !toDeactivateIndex.Contains(item)));
                }
                if (toDelete.Count() + toDeactivate.Count() != oldDeleteCount)
                {
                    throw new FrameworkException($"Invalid number of items to deactivate for '{_genericRepositoryName}'." +
                                                 $" Verify if the deactivation filter ({filterDeactivateDeleted.GetType().FullName}) on that data structure returns a valid subset of the given items." +
                                                 $" {oldDeleteCount} items to remove: {toDeactivate.Count()} items to deactivate and {toDelete.Count()} items remaining to delete (should be {oldDeleteCount - toDeactivate.Count()}).");
                }

                // Update the items to deactivate (unless already deactivated):
                var activeToDeactivate = toDeactivate.Cast <IDeactivatable>().Where(item => item.Active == null || item.Active == true).ToList();
                foreach (var item in activeToDeactivate)
                {
                    item.Active = false;
                }
                Reflection.AddRange(toUpdate, Reflection.CastAsEntity(activeToDeactivate));
                activeToDeactivateCount = activeToDeactivate.Count;
            }
            _performanceLogger.Write(stopwatch, () => $"InsertOrUpdateOrDeleteOrDeactivate: Deactivate ({activeToDeactivateCount} to deactivate, {toDeactivate.Count() - activeToDeactivateCount} already deactivated)");

            // Modify old items to match new items:

            if (beforeSave != null)
            {
                beforeSave(ref toInsert, ref toUpdate, ref toDelete);
                CsUtility.Materialize(ref toInsert);
                CsUtility.Materialize(ref toUpdate);
                CsUtility.Materialize(ref toDelete);
            }
            Save(toInsert, toUpdate, toDelete);
            _performanceLogger.Write(stopwatch, () => $"InsertOrUpdateOrDeleteOrDeactivate: Save ({newItems.Count()} new items, {oldItems.Count()} old items, {toInsert.Count()} to insert, {toUpdate.Count()} to update, {toDelete.Count()} to delete)");
        }
Example #22
0
        public static void UpdateCodes <T>(ISqlExecuter sqlExecuter, string entityName, string propertyName, IEnumerable <AutoCodeItem <T> > autoCodeItems, Action <T, string> setCode)
            where T : IEntity
        {
            CsUtility.Materialize(ref autoCodeItems);

            var parsedAutoCode = autoCodeItems
                                 .Where(acItem => !string.IsNullOrEmpty(acItem.Code))
                                 .Select(acItem =>
            {
                int numberOfPluses = GetNumberOfPluses(acItem.Code, acItem.Item.ID, entityName, propertyName);
                if (numberOfPluses > 0)
                {
                    return new
                    {
                        acItem.Item,
                        acItem.Grouping,
                        Prefix            = acItem.Code.Substring(0, acItem.Code.Length - numberOfPluses),
                        MinDigits         = numberOfPluses,
                        ProvidedCodeValue = (int?)null
                    }
                }
                ;

                int suffixDigitsCount = GetSuffixDigitsCount(acItem.Code);
                if (suffixDigitsCount > 0)
                {
                    return new
                    {
                        acItem.Item,
                        acItem.Grouping,
                        Prefix            = acItem.Code.Substring(0, acItem.Code.Length - suffixDigitsCount),
                        MinDigits         = suffixDigitsCount,
                        ProvidedCodeValue = (int?)int.Parse(acItem.Code.Substring(acItem.Code.Length - suffixDigitsCount))
                    }
                }
                ;

                return(null);
            })
                                 .Where(acItem => acItem != null)
                                 .ToList();

            var autoCodeGroups = parsedAutoCode
                                 .GroupBy(acItem => new { acItem.Grouping, acItem.Prefix })
                                 .Select(g => new
            {
                g.Key.Grouping,
                g.Key.Prefix,
                MinDigits           = g.Max(acItem => acItem.MinDigits),
                ItemsToGenerateCode = g.Where(acItem => acItem.ProvidedCodeValue == null).Select(acItem => acItem.Item).ToList(),
                MaxProvidedCode     = g.Max(acItem => acItem.ProvidedCodeValue)
            })
                                 .OrderBy(acGroup => acGroup.Grouping)
                                 .ThenBy(acGroup => acGroup.Prefix)
                                 .ToList();

            foreach (var autoCodeGroup in autoCodeGroups)
            {
                if (autoCodeGroup.MaxProvidedCode != null)
                {
                    string sql = string.Format("EXEC Common.UpdateAutoCodeCache {0}, {1}, {2}, {3}, {4}, {5}",
                                               Rhetos.Utilities.SqlUtility.QuoteText(entityName),
                                               Rhetos.Utilities.SqlUtility.QuoteText(propertyName),
                                               Rhetos.Utilities.SqlUtility.QuoteText(autoCodeGroup.Grouping),
                                               Rhetos.Utilities.SqlUtility.QuoteText(autoCodeGroup.Prefix),
                                               autoCodeGroup.MinDigits,
                                               autoCodeGroup.MaxProvidedCode);

                    sqlExecuter.ExecuteSql(sql);
                }

                if (autoCodeGroup.ItemsToGenerateCode.Count > 0)
                {
                    string sql = string.Format("EXEC Common.GetNextAutoCodeCached {0}, {1}, {2}, {3}, {4}, {5}",
                                               Rhetos.Utilities.SqlUtility.QuoteText(entityName),
                                               Rhetos.Utilities.SqlUtility.QuoteText(propertyName),
                                               Rhetos.Utilities.SqlUtility.QuoteText(autoCodeGroup.Grouping),
                                               Rhetos.Utilities.SqlUtility.QuoteText(autoCodeGroup.Prefix),
                                               autoCodeGroup.MinDigits,
                                               autoCodeGroup.ItemsToGenerateCode.Count);

                    int?minDigits = null;
                    int?lastCode  = null;
                    sqlExecuter.ExecuteReader(sql, reader =>
                    {
                        minDigits = reader.GetInt32(0);
                        lastCode  = reader.GetInt32(1);
                    });

                    for (int i = 0; i < autoCodeGroup.ItemsToGenerateCode.Count; i++)
                    {
                        string codeSuffix = (lastCode.Value - autoCodeGroup.ItemsToGenerateCode.Count + i + 1).ToString();
                        if (codeSuffix.Length < minDigits.Value)
                        {
                            codeSuffix = new string('0', minDigits.Value - codeSuffix.Length) + codeSuffix;
                        }

                        setCode(autoCodeGroup.ItemsToGenerateCode[i], autoCodeGroup.Prefix + codeSuffix);
                    }
                }
            }
        }
Example #23
0
        private void ExpandMacroConcepts(DslContainer dslContainer)
        {
            var swTotal = Stopwatch.StartNew();
            var sw      = Stopwatch.StartNew();

            int iteration = 0;
            var iterationCreatedConcepts      = new List <IConceptInfo>();
            int lastNewConceptTime            = 0;
            var lastNewConceptTimeByIteration = new List <int>();
            var lastNewConceptTimeByMacro     = new Dictionary <string, int>();
            var recommendedMacroOrder         = _macroOrderRepository.Load().ToDictionary(m => m.EvaluatorName, m => m.EvaluatorOrder);
            var macroEvaluators         = ListMacroEvaluators(recommendedMacroOrder);
            var macroStopwatches        = macroEvaluators.ToDictionary(macro => macro.Name, macro => new Stopwatch());
            var createdTypesInIteration = new List <CreatedTypesInIteration>(dslContainer.Concepts.Count() * 5);

            _performanceLogger.Write(sw, "ExpandMacroConcepts initialization ("
                                     + macroEvaluators.Count + " evaluators, "
                                     + dslContainer.Concepts.Count() + " parsed concepts resolved, "
                                     + dslContainer.UnresolvedConceptsCount() + " unresolved).");

            do
            {
                iteration++;
                if (iteration > MacroIterationLimit)
                {
                    throw new DslSyntaxException(string.Format(
                                                     "Possible infinite loop detected with recursive macro concept {1}. Iteration limit ({0}) exceeded while expanding macro.",
                                                     MacroIterationLimit,
                                                     iterationCreatedConcepts.First().GetShortDescription()));
                }

                iterationCreatedConcepts.Clear();
                _logger.Trace("Expanding macro concepts, iteration {0}.", iteration);

                foreach (var macroEvaluator in macroEvaluators)
                {
                    macroStopwatches[macroEvaluator.Name].Start();
                    foreach (var conceptInfo in dslContainer.FindByType(macroEvaluator.Implements, macroEvaluator.ImplementsDerivations).ToList())
                    {
                        var macroCreatedConcepts = macroEvaluator.Evaluate(conceptInfo, dslContainer);
                        CsUtility.Materialize(ref macroCreatedConcepts);

                        if (macroCreatedConcepts != null && macroCreatedConcepts.Any())
                        {
                            _logger.Trace(() => "Evaluating macro " + macroEvaluator.Name + " on " + conceptInfo.GetShortDescription() + ".");

                            var aiCreatedConcepts = AlternativeInitialization.InitializeNonparsableProperties(macroCreatedConcepts, _logger);

                            var newUniqueConcepts = dslContainer.AddNewConceptsAndReplaceReferences(aiCreatedConcepts);
                            newUniqueConcepts.AddRange(dslContainer.AddNewConceptsAndReplaceReferences(macroCreatedConcepts));

                            _logger.Trace(() => LogCreatedConcepts(dslContainer, macroCreatedConcepts, newUniqueConcepts));

                            iterationCreatedConcepts.AddRange(newUniqueConcepts);

                            // Optimization analysis:
                            if (newUniqueConcepts.Count > 0)
                            {
                                lastNewConceptTimeByMacro[macroEvaluator.Name] = ++lastNewConceptTime;
                            }
                            createdTypesInIteration.AddRange(newUniqueConcepts.Select(nuc =>
                                                                                      new CreatedTypesInIteration {
                                Macro = macroEvaluator.Name, Created = nuc.BaseConceptInfoType().Name, Iteration = iteration
                            }));
                        }
                    }
                    macroStopwatches[macroEvaluator.Name].Stop();
                }

                lastNewConceptTimeByIteration.Add(lastNewConceptTime);

                _performanceLogger.Write(sw, "ExpandMacroConcepts iteration " + iteration + " ("
                                         + iterationCreatedConcepts.Count + " new concepts, "
                                         + dslContainer.UnresolvedConceptsCount() + " left unresolved).");
            } while (iterationCreatedConcepts.Count > 0);

            _evaluatorsOrderLogger.Trace(() => swTotal.Elapsed + "\r\n"
                                         + ReportLastEvaluationOrder(lastNewConceptTimeByMacro, lastNewConceptTimeByIteration));

            foreach (var macroStopwatch in macroStopwatches.OrderByDescending(msw => msw.Value.Elapsed.TotalSeconds).Take(5))
            {
                _performanceLogger.Write(macroStopwatch.Value, () => "ExpandMacroConcepts total time for " + macroStopwatch.Key + ".");
            }

            _logger.Trace(() => LogCreatedTypesInIteration(createdTypesInIteration));

            dslContainer.ReportErrorForUnresolvedConcepts();

            SaveMacroEvaluationOrder(lastNewConceptTimeByMacro);

            _performanceLogger.Write(swTotal, "ExpandMacroConcepts.");
        }