コード例 #1
0
        public static IEnumerable <QueryPlanNode> BuildDeferred(QueryPlanContext context)
        {
            var processed = new HashSet <int>();

            while (context.Deferred.TryPop(out IFragment? fragment) &&
                   processed.Add(fragment.Id))
            {
                yield return(Build(context, fragment.SelectionSet));
            }
        }
コード例 #2
0
        public static QueryPlanNode Build(QueryPlanContext context, ISelectionSet selectionSet)
        {
            foreach (ISelection selection in selectionSet.Selections)
            {
                Visit(selection, context);
            }

            CollectFragments(selectionSet, context);

            return(Optimize(context.Root !));
        }
コード例 #3
0
        private static void Visit(ISelection selection, QueryPlanContext context)
        {
            if (selection.IsStreamable && selection.SelectionSet is not null)
            {
                QueryPlanContext streamContext = context.Branch();

                VisitChildren(selection, streamContext);

                if (streamContext.Root is not null &&
                    !context.Streams.ContainsKey(selection.Id))
                {
                    context.Streams.Add(selection.Id, new(selection.Id, streamContext.Root));
                }

                if (streamContext.Streams.Count > 0)
                {
                    foreach (StreamPlanNode streamPlan in streamContext.Streams.Values)
                    {
                        if (!context.Streams.ContainsKey(selection.Id))
                        {
                            context.Streams.Add(selection.Id, streamPlan);
                        }
                    }
                }
            }

            if (context.NodePath.Count == 0)
            {
                context.Root = new ResolverNode(selection);
                context.NodePath.Push(context.Root);
            }
            else
            {
                QueryPlanNode parent = context.NodePath.Peek();

                if (selection.Strategy == SelectionExecutionStrategy.Serial)
                {
                    if (parent is ResolverNode {
                        Strategy : ExecutionStrategy.Serial
                    } p)
                    {
                        p.Selections.Add(selection);
                    }
                    else if (context.SelectionPath.Count > 0 &&
                             context.NodePath.TryPeek(2, out QueryPlanNode? grandParent) &&
                             grandParent is ResolverNode {
                        Strategy: ExecutionStrategy.Serial
                    } gp&&
                             gp.Selections.Contains(context.SelectionPath.PeekOrDefault() !))
                    {
                        gp.Selections.Add(selection);
                    }
コード例 #4
0
        public static QueryPlan Build(IPreparedOperation operation)
        {
            if (operation is null)
            {
                throw new ArgumentNullException(nameof(operation));
            }

            var context = new QueryPlanContext(operation);

            OperationNode operationNode = Prepare(context);

            QueryPlan[] deferredPlans =
                operationNode.Deferred.Count > 0
                    ? new QueryPlan[operationNode.Deferred.Count]
                    : Array.Empty <QueryPlan>();

            Dictionary <int, QueryPlan>?streamPlans =
                context.Streams.Count > 0
                    ? new Dictionary <int, QueryPlan>()
                    : null;

            if (operationNode.Deferred.Count > 0)
            {
                for (var i = 0; i < operationNode.Deferred.Count; i++)
                {
                    deferredPlans[i] = new QueryPlan(
                        operationNode.Deferred[i].CreateStep(),
                        deferredPlans,
                        streamPlans);
                }
            }

            if (context.Streams.Count > 0)
            {
                foreach (StreamPlanNode streamPlanNode in context.Streams.Values)
                {
                    var streamPlan = new QueryPlan(
                        streamPlanNode.Root.CreateStep(),
                        deferredPlans,
                        streamPlans);

                    streamPlans !.Add(streamPlanNode.Id, streamPlan);
                }
            }

            return(new QueryPlan(operationNode.CreateStep(), deferredPlans, streamPlans));
        }
コード例 #5
0
        public static OperationNode Build(QueryPlanContext context)
        {
            var root = new SequenceNode {
                CancelOnError = true
            };

            context.Root = root;
            context.NodePath.Push(root);

            foreach (ISelection mutation in context.Operation.GetRootSelectionSet().Selections)
            {
                context.SelectionPath.Push(mutation);

                var mutationStep = new ResolverNode(
                    mutation,
                    context.SelectionPath.PeekOrDefault(),
                    GetStrategyFromSelection(mutation));

                root.AddNode(mutationStep);

                QueryStrategy.VisitChildren(mutation, context);
            }

            context.NodePath.Pop();

            QueryPlanNode optimized     = QueryStrategy.Optimize(context.Root);
            var           operationNode = new OperationNode(optimized);

            if (context.Deferred.Count > 0)
            {
                foreach (QueryPlanNode?deferred in QueryStrategy.BuildDeferred(context))
                {
                    operationNode.Deferred.Add(deferred);
                }
            }

            if (context.Streams.Count > 0)
            {
                operationNode.Streams.AddRange(context.Streams.Values);
            }

            return(operationNode);
        }
コード例 #6
0
        public static OperationNode Build(QueryPlanContext context)
        {
            QueryPlanNode root          = Build(context, context.Operation.GetRootSelectionSet());
            var           operationNode = new OperationNode(root);

            if (context.Deferred.Count > 0)
            {
                foreach (QueryPlanNode?deferred in BuildDeferred(context))
                {
                    operationNode.Deferred.Add(deferred);
                }
            }

            if (context.Streams.Count > 0)
            {
                operationNode.Streams.AddRange(context.Streams.Values);
            }

            return(operationNode);
        }
コード例 #7
0
 private static OperationNode Prepare(QueryPlanContext context)
 {
     return(context.Operation.Definition.Operation is OperationType.Mutation
         ? MutationStrategy.Build(context)
         : QueryStrategy.Build(context));
 }