/// <summary> /// Inspects the operation and determines a final complexity score. /// </summary> /// <param name="operation">The complexity score for the given operations.</param> /// <returns>System.Single.</returns> public float Calculate(IGraphFieldExecutableOperation operation) { float totalWeight = 0; foreach (var field in operation.FieldContexts) { totalWeight += this.CalculateFieldWeight(field); } switch (operation.OperationType) { case GraphCollection.Query: totalWeight *= QUERY_WEIGHT; break; case GraphCollection.Mutation: totalWeight *= MUTATION_WEIGHT; break; case GraphCollection.Subscription: totalWeight *= SUBSCIRPTION_WEIGHT; break; } return(totalWeight); }
/// <summary> /// Adds a parsed executable operation to the plan's operation collection. /// </summary> /// <param name="operation">The completed and validated operation to add.</param> public void AddOperation(IGraphFieldExecutableOperation operation) { Validation.ThrowIfNull(operation, nameof(operation)); var name = operation.OperationName?.Trim() ?? string.Empty; this.Messages.AddRange(operation.Messages); _operations.Add(name, operation); }
/// <summary> /// Initializes a new instance of the <see cref="ResolvedVariableGenerator" /> class. /// </summary> /// <param name="schema">The schema.</param> /// <param name="operation">The operation.</param> public ResolvedVariableGenerator(ISchema schema, IGraphFieldExecutableOperation operation) { _schema = Validation.ThrowIfNullOrReturn(schema, nameof(schema)); _operation = Validation.ThrowIfNullOrReturn(operation, nameof(operation)); }
/// <summary> /// Initializes a new instance of the <see cref="ClientSubscription{TSchema}" /> class. /// </summary> /// <param name="clientProxy">The client proxy that will own this subscription.</param> /// <param name="originalQuerydata">The original querydata that generated this subscription.</param> /// <param name="queryPlan">The query plan.</param> /// <param name="selectedOperation">The selected operation from the query plan /// from which to generate the subscription.</param> /// <param name="subscriptionid">A unique id to assign to this subscription. A guid id /// will be generated if this value is not supplied.</param> public ClientSubscription( ISubscriptionClientProxy clientProxy, GraphQueryData originalQuerydata, IGraphQueryPlan queryPlan, IGraphFieldExecutableOperation selectedOperation, string subscriptionid = null) { this.Client = Validation.ThrowIfNullOrReturn(clientProxy, nameof(clientProxy)); this.QueryData = Validation.ThrowIfNullOrReturn(originalQuerydata, nameof(originalQuerydata)); this.QueryOperation = Validation.ThrowIfNullOrReturn(selectedOperation, nameof(selectedOperation)); this.QueryPlan = Validation.ThrowIfNullOrReturn(queryPlan, nameof(queryPlan)); this.Messages = this.QueryPlan?.Messages ?? new GraphMessageCollection(); this.Id = string.IsNullOrWhiteSpace(subscriptionid) ? Guid.NewGuid().ToString("N") : subscriptionid.Trim(); this.IsValid = false; // parsing the query plan will garuntee that if the document contains // a subscription that it contains only one operation and // that a top level field will be a subscription-ready field. // // However, ensure that the operation that will be executed // does in fact represent a subscription being harnesssed if (this.QueryOperation.OperationType != GraphCollection.Subscription) { this.Messages.Critical( $"The chosen operation is not a subscription operation.", Constants.ErrorCodes.BAD_REQUEST); return; } var currentContext = this.QueryOperation.FieldContexts[0]; // find the first non-virtual field referenced, it should be a controller // its garunteed to exist via the document generation rule engine // but it could be deep, walk down the subscirption tree to find it while (currentContext?.Field != null) { // when pointing at a subscription field we're done if (!currentContext.Field.IsVirtual) { this.Field = currentContext.Field as ISubscriptionGraphField; break; } currentContext = currentContext?.ChildContexts.Count == 1 ? currentContext.ChildContexts?[0] : null; } // just in case it wasn't found... // this is theoretically not possible but just in case // the user swaps out some DI components incorrectly or by mistake... if (this.Field == null) { this.Messages.Add( GraphMessageSeverity.Critical, "An eventable field could not found in the subscription operation. Ensure you include a field declared " + "as a subscription field.", Constants.ErrorCodes.BAD_REQUEST); } this.IsValid = this.Messages.IsSucessful && this.QueryOperation != null && this.Field != null; }