Exemple #1
0
        private async Task <TreeNodeInfo> getNodeByPathSegment(TreePtr tree, GDID gParent, string pathSegment, DateTime asOfUtc, ICacheParams caching)
        {
            if (gParent.IsZero)
            {
                gParent = Constraints.G_VERY_ROOT_NODE;
            }

            var tblCache = s_CacheTableName[tree];
            var keyCache = nameof(getNodeByPathSegment) + gParent.ToHexString() + (pathSegment ?? string.Empty) + asOfUtc.Ticks;

            var node = await m_Data.Cache.FetchThroughAsync(
                keyCache, tblCache, caching,
                async key =>
            {
                var qry = new Query <TreeNodeInfo>("Tree.GetNodeInfo")
                {
                    new Query.Param("tree", tree),
                    new Query.Param("gparent", gParent),
                    new Query.Param("psegment", pathSegment),
                    new Query.Param("asof", asOfUtc)
                };
                return(await m_Data.TreeLoadDocAsync(tree, qry));
            }
                ).ConfigureAwait(false);

            return(node);
        }
Exemple #2
0
        /// <inheritdoc/>
        public async Task PurgeAsync(Atom idForest, Atom idTree)
        {
            idForest.HasRequiredValue(nameof(idForest));
            idTree.HasRequiredValue(nameof(idForest));
            App.Authorize(TreePurgePermission.Instance);
            var tree = new TreePtr(idForest, idTree);

            var qry = new Query <Doc>("Tree.Purge");
            await m_Data.TreeExecuteAsync(tree, qry);
        }
Exemple #3
0
        private void purgeCacheTables(TreePtr tree)
        {
            var tname = s_CacheTableName[tree];
            var tbl   = m_Data.Cache.Tables[tname];

            if (tbl == null)
            {
                return;
            }
            tbl.Purge();
        }
Exemple #4
0
        public static async Task <TDoc> treeExecuteAsync <TDoc>(this IForestDataSource forestData,
                                                                TreePtr tree,
                                                                Query <TDoc> qry) where TDoc : Doc
        {
            var doc = await forestData.GetCrudData(tree).ExecuteAsync(qry).ConfigureAwait(false);

            if (doc == null)
            {
                return(null);
            }
            var result = doc.CastTo <TDoc>($"Query returned value of type `{doc.GetType().DisplayNameWithExpandedGenericArgs()}`");

            return(result);
        }
Exemple #5
0
        /// <summary>
        /// Gets ICrudDataStore context for Corporate Area
        /// </summary>
        public static ICrudDataStore GetCrudData(this IForestDataSource forestData, TreePtr tree)
        {
            var tds = forestData.NonNull(nameof(forestData)).TryGetTreeDataStore(tree.IdForest, tree.IdTree);

            if (tds == null)
            {
                var tnmsg = "Forest tree `{0}` is not found".Args(tree);
                throw new ValidationException(tnmsg)
                      {
                          HttpStatusCode = 404, HttpStatusDescription = tnmsg
                      };
            }

            return((tds as ICrudDataStore).NonNull(DATA_STORE_CLAUSE));
        }
Exemple #6
0
        private async Task <TreeNodeInfo> getNodeByTreePath(TreePtr tree, TreePath path, DateTime asOfUtc, ICacheParams caching)
        {
            var tblCache = s_CacheTableName[tree];
            var keyCache = nameof(getNodeByTreePath) + path + asOfUtc.Ticks;

            var result = await m_Data.Cache.FetchThroughAsync(
                keyCache, tblCache, caching,
                async key => {
                TreeNodeInfo nodeParent = null;
                TreeNodeInfo node       = null;
                for (var i = -1; i < path.Count; i++) //going from LEFT to RIGHT
                {
                    var segment = i < 0 ? Constraints.VERY_ROOT_PATH_SEGMENT : path[i];
                    node        = await getNodeByPathSegment(tree, nodeParent == null ? GDID.ZERO : nodeParent.Gdid, segment, asOfUtc, caching).ConfigureAwait(false);
                    if (node == null)
                    {
                        return(null);     // deleted
                    }
                    //Config chain inheritance pattern
                    if (nodeParent == null)
                    {
                        node.EffectiveConfig = new ConfigVector(node.LevelConfig.Content);//Copy
                        node.FullPath        = Constraints.VERY_ROOT_PATH_SEGMENT;
                    }
                    else
                    {
                        var confHere   = node.LevelConfig.Node.NonEmpty(nameof(node.LevelConfig));
                        var confParent = nodeParent.EffectiveConfig.Node.NonEmpty(nameof(nodeParent.EffectiveConfig));
                        var confResult = new MemoryConfiguration()
                        {
                            Application = this.App
                        };
                        confResult.CreateFromNode(confParent); //inherit
                        confResult.Root.OverrideBy(confHere);  //override
                        node.EffectiveConfig = new ConfigVector(confResult.Root);
                        node.FullPath        = TreePath.Join(nodeParent.FullPath, node.PathSegment);
                    }
                    nodeParent = node;
                    App.Authorize(new TreePermission(TreeAccessLevel.Read, node.FullPathId));
                }
                return(node);
            }).ConfigureAwait(false);

            return(result);
        }
Exemple #7
0
        private async Task <IEnumerable <TreeNodeHeader> > getChildNodeListByGdid(TreePtr tree, GDID gdidAddress, DateTime asOfUtc, ICacheParams caching)
        {
            var tblCache = s_CacheTableName[tree];
            var keyCache = nameof(getChildNodeListByGdid) + gdidAddress.ToHexString() + asOfUtc.Ticks;

            var nodes = await m_Data.Cache.FetchThroughAsync(
                keyCache, tblCache, caching,
                async key =>
            {
                var qry = new Query <TreeNodeHeader>("Tree.GetChildNodeList")
                {
                    new Query.Param("tree", tree),
                    new Query.Param("gparent", gdidAddress),
                    new Query.Param("asof", asOfUtc)
                };
                return(await m_Data.TreeLoadEnumerableAsync(tree, qry));
            }
                ).ConfigureAwait(false);

            return(nodes);
        }
Exemple #8
0
        /// <inheritdoc/>
        public async Task <ChangeResult> SaveNodeAsync(TreeNode node)
        {
            node.NonNull(nameof(node));
            var tree = new TreePtr(node.Forest, node.Tree);

            tree.IsAssigned.IsTrue("Assigned Tree");
            App.Authorize(new TreePermission(TreeAccessLevel.Setup, node.Id));

            var qry = new Query <EntityChangeInfo>("Tree.SaveNode")
            {
                new Query.Param("n", node)
            };

            //1. Update database
            var change = await m_Data.TreeExecuteAsync(tree, qry);

            //purge cache for that tree
            purgeCacheTables(new TreePtr(node.Forest, node.Tree));
#warning Add shim for EVENT NOTIFICATION system

            return(new ChangeResult(ChangeResult.ChangeType.Processed, 1, "Saved", change));
        }
Exemple #9
0
        private async Task <IEnumerable <TreeNodeHeader> > getChildNodeListByTreePath(TreePtr tree, TreePath pathAddress, DateTime asOfUtc, ICacheParams caching)
        {
            var nodeParent = await getNodeByTreePath(tree, pathAddress, asOfUtc, caching).ConfigureAwait(false);

            if (nodeParent == null)
            {
                return(null);
            }

            var result = await getChildNodeListByGdid(tree, nodeParent.Gdid, asOfUtc, caching);

            return(result);
        }
Exemple #10
0
        private async Task <TreeNodeInfo> getNodeByGdid(HashSet <GDID> graph, TreePtr tree, GDID gNode, DateTime asOfUtc, ICacheParams caching)
        {
            var tblCache = s_CacheTableName[tree];
            var keyCache = nameof(getNodeByGdid) + gNode.ToHexString() + asOfUtc.Ticks;
            var result   = await m_Data.Cache.FetchThroughAsync(
                keyCache, tblCache, caching,
                async key =>
            {
                if (!graph.Add(gNode))
                {
                    //circular reference
                    var err = new ConfigException("Circular reference in config tree = `{0}`, gnode = `{1}`, asof = `{2}`".Args(tree, gNode, asOfUtc));
                    WriteLogFromHere(Log.MessageType.CatastrophicError,
                                     err.Message,
                                     err,
                                     pars: new { tree = tree.ToString(), gnode = gNode, asof = asOfUtc }.ToJson());
                    throw err;
                }

                //1 - fetch THIS level - rightmost part of the tree
                var qry = new Query <TreeNodeInfo>("Tree.GetNodeInfoByGdid")
                {
                    new Query.Param("tree", tree),
                    new Query.Param("gdid", gNode),
                    new Query.Param("asof", asOfUtc)
                };

                var node = await m_Data.TreeLoadDocAsync(tree, qry);
                if (node == null)
                {
                    return(null);
                }

                //2 - if IAM ROOT, there is no parent for root
                node.EffectiveConfig = new ConfigVector(node.LevelConfig.Content);//Copy
                node.FullPath        = Constraints.VERY_ROOT_PATH_SEGMENT;

                if (node.Gdid == Constraints.G_VERY_ROOT_NODE)
                {
                    return(node);
                }

                //3 - Fetch parent of THIS
                TreeNodeInfo nodeParent = await getNodeByGdid(graph, tree, node.G_Parent, asOfUtc, caching).ConfigureAwait(false);
                if (nodeParent == null)
                {
                    return(null);
                }

                //4 - calculate effective config
                var cfgNode   = node.LevelConfig.Node.NonEmpty(nameof(node.LevelConfig));
                var cfgParent = nodeParent.EffectiveConfig.Node.NonEmpty(nameof(nodeParent.EffectiveConfig));

                var confResult = new MemoryConfiguration()
                {
                    Application = this.App
                };
                confResult.CreateFromNode(cfgParent); //inherit
                confResult.Root.OverrideBy(cfgNode);  //override
                node.EffectiveConfig.Node = confResult.Root;

                node.FullPath = TreePath.Join(nodeParent.FullPath, node.PathSegment);

                //the security check is done post factum AFTER tree node full path is known
                return(node);
            }
                ).ConfigureAwait(false);

            if (result == null)
            {
                return(null);
            }
            App.Authorize(new TreePermission(TreeAccessLevel.Read, result.FullPathId));
            return(result);
        }
Exemple #11
0
 /// <summary>
 /// Extension which executes a query in tree data context and does not fetch any result
 /// </summary>
 public static ConfiguredTaskAwaitable <TDoc> TreeExecuteAsync <TDoc>(this IForestDataSource forestData,
                                                                      TreePtr tree,
                                                                      Query <TDoc> qry) where TDoc : Doc
 => forestData.treeExecuteAsync(tree, qry).ConfigureAwait(false);
Exemple #12
0
 /// <summary>
 /// Extension which loads a document returned by query executed in tree data context
 /// </summary>
 public static ConfiguredTaskAwaitable <TDoc> TreeLoadDocAsync <TDoc>(this IForestDataSource forestData,
                                                                      TreePtr tree,
                                                                      Query <TDoc> qry) where TDoc : Doc
 => forestData.GetCrudData(tree).LoadDocAsync(qry).ConfigureAwait(false);