/// <summary> /// As traversers propagate through the traversal, it is possible to only allow a certain number of them /// to pass through with range()-step (filter). When the low-end of the range is not met, objects are continued /// to be iterated. When within the low (inclusive) and high (exclusive) range, traversers are emitted. /// When above the high range, the traversal breaks out of iteration. /// Finally, the use of -1 on the high range will emit remaining traversers after the low range begins /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="GremlinQueryBuilderException"></exception> public static GremlinQueryBuilder Range(this GremlinQueryBuilder builder, GremlinScope scope, IGremlinParameter start, IGremlinParameter end) { if (start == null) { throw new ArgumentNullException(nameof(start)); } if (end == null) { throw new ArgumentNullException(nameof(end)); } if (!start.IsNumber(true)) { throw new GremlinQueryBuilderException( $"{nameof(Range)} only supports numeric parameters and scope and '{start.TrueValue}' does not appear to conform to this"); } if (!end.IsNumber(true)) { throw new GremlinQueryBuilderException( $"{nameof(Range)} only supports numeric parameters and scope and '{end.TrueValue}' does not appear to conform to this"); } builder.AddArgument(start as GremlinArgument); builder.AddArgument(end as GremlinArgument); return(builder.Add($"range({scope.QueryStringValue},{start.QueryStringValue},{end.QueryStringValue})")); }
/// <summary> /// The limit()-step is analogous to <seealso cref="RangeFunction.Range(CosmosDB.Gremlin.Fluent.GremlinQueryBuilder,CosmosDB.Gremlin.Fluent.IGremlinParameter,CosmosDB.Gremlin.Fluent.IGremlinParameter)"/> save that the lower end range is set to 0. /// It can also be applied with local scope, in which case it operates on the incoming collection /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="parameter"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="GremlinQueryBuilderException"></exception> public static GremlinQueryBuilder Limit(this GremlinQueryBuilder builder, GremlinScope scope, IGremlinParameter parameter) { if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } if (!parameter.IsNumber(true)) { throw new GremlinQueryBuilderException( $"{nameof(Limit)} only supports numeric parameters and scope and " + $"'{parameter.TrueValue}' does not appear to conform to this"); } builder.AddArgument(parameter as GremlinArgument); return(builder.Add($"limit({scope.QueryStringValue},{parameter.QueryStringValue})")); }
/// <summary> /// The sample()-step is useful for sampling some number of traversers previous in the traversal /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="parameter"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="GremlinQueryBuilderException"></exception> public static GremlinQueryBuilder Sample(this GremlinQueryBuilder builder, GremlinScope scope, IGremlinParameter parameter) { // this function can only take true or false if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } if (!(parameter.TrueValue is int || parameter.TrueValue is uint)) { throw new GremlinQueryBuilderException( $"{nameof(Sample)} only supports integer parameters and scope and '{parameter.TrueValue}' does not appear to conform to this"); } builder.AddArgument(parameter as GremlinArgument); return(builder.Add($"sample({scope.QueryStringValue},{parameter.QueryStringValue})")); }
/// <summary> /// With dedup()-step (filter), repeatedly seen objects are removed from the traversal stream. N /// ote that if a traverser’s bulk is greater than 1, then it is set to 1 before being emitted. /// If dedup() is provided an array of strings, then it will ensure that the de-duplication is not /// with respect to the current traverser object, but to the path history of the traverser /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="parameters"></param> /// <returns></returns> public static GremlinQueryBuilder Dedup(this GremlinQueryBuilder builder, GremlinScope scope, params IGremlinParameter[] parameters) { if (parameters == null || !parameters.Any()) { return(builder.Add("dedup()")); } else { if (!parameters.All(p => p.TrueValue is string)) { throw new GremlinQueryBuilderException( $"{nameof(Dedup)} requires all parameters supplied to {nameof(parameters)} to be strings"); } builder.AddArguments(parameters.OfType <GremlinArgument>().ToArray()); return(builder.Add($"dedup({scope.QueryStringValue},{parameters.Expand()})")); } }
/// <summary> /// The tail()-step is analogous to limit()-step, except that it emits the last n-objects /// instead of the first n-objects /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="parameter"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="GremlinQueryBuilderException"></exception> public static GremlinQueryBuilder Tail(this GremlinQueryBuilder builder, GremlinScope scope, long parameter) { // shortcut overload for common scenario return(builder.Tail(scope, (GremlinParameter)parameter)); }
/// <summary> /// The aggregate()-step (sideEffect) is used to aggregate all the objects at a particular point of traversal into a Collection. /// The step is uses Scope to help determine the aggregating behavior. /// For global scope this means that the step will use eager evaluation in that no objects continue on until all /// previous objects have been fully aggregated. The eager evaluation model is crucial in situations where /// everything at a particular point is required for future computation. /// By default, when the overload of aggregate() is called without a Scope, the default is global /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="parameter"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="GremlinQueryBuilderException"></exception> public static GremlinQueryBuilder Aggregate(this GremlinQueryBuilder builder, GremlinScope scope, IGremlinParameter parameter) { if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } if (!(parameter.TrueValue is string)) { throw new GremlinQueryBuilderException( $"{nameof(Aggregate)} only accepts string parameters and {parameter.TrueValue} is not"); } builder.AddArgument(parameter as GremlinArgument); return(builder.Add($"aggregate({scope.QueryStringValue},{parameter.QueryStringValue})")); }
/// <summary> /// As traversers propagate through the traversal, it is possible to only allow a certain number of them /// to pass through with range()-step (filter). When the low-end of the range is not met, objects are continued /// to be iterated. When within the low (inclusive) and high (exclusive) range, traversers are emitted. /// When above the high range, the traversal breaks out of iteration. /// Finally, the use of -1 on the high range will emit remaining traversers after the low range begins /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="GremlinQueryBuilderException"></exception> public static GremlinQueryBuilder Range(this GremlinQueryBuilder builder, GremlinScope scope, long start, long end) { // For implicit operators return(builder.Range(scope, (GremlinParameter)start, (GremlinParameter)end)); }
/// <summary> /// The limit()-step is analogous to <seealso cref="RangeFunction.Range(CosmosDB.Gremlin.Fluent.GremlinQueryBuilder,CosmosDB.Gremlin.Fluent.IGremlinParameter,CosmosDB.Gremlin.Fluent.IGremlinParameter)"/> save that the lower end range is set to 0. /// It can also be applied with local scope, in which case it operates on the incoming collection /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="parameter"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="GremlinQueryBuilderException"></exception> public static GremlinQueryBuilder Limit(this GremlinQueryBuilder builder, GremlinScope scope, long parameter) { // For implicit operators return(builder.Limit(scope, (GremlinParameter)parameter)); }
/// <summary> /// The sample()-step is useful for sampling some number of traversers previous in the traversal /// </summary> /// <param name="builder"></param> /// <param name="scope"></param> /// <param name="parameter"></param> /// <returns></returns> public static GremlinQueryBuilder Sample(this GremlinQueryBuilder builder, GremlinScope scope, int parameter) { // For implicit operators return(builder.Sample(scope, (GremlinParameter)parameter)); }