public async Task ValidateAsync(object?value, ValidationContext context, AddError addError) { var count = context.Path.Count(); if (value != null && (count == 0 || (count == 2 && context.Path.Last() == InvariantPartitioning.Key))) { FilterNode <ClrValue>?filter = null; if (value is string s) { filter = ClrFilter.Eq(Path(context), s); } else if (value is double d) { filter = ClrFilter.Eq(Path(context), d); } if (filter != null) { var found = await checkUniqueness(filter); if (found.Any(x => x.Id != context.ContentId)) { addError(context.Path, T.Get("contents.validation.unique")); } } } }
public async ValueTask ValidateAsync(object value, ValidationContext context, AddError addError) { if (value is ContentData data) { var validateableFields = context.Schema.Fields.Where(IsValidateableField); var filters = new List <FilterNode <ClrValue> >(); foreach (var field in validateableFields) { var fieldValue = TryGetValue(field, data); if (fieldValue != null) { filters.Add(ClrFilter.Eq($"data.{field.Name}.iv", fieldValue)); } } if (filters.Count > 0) { var filter = ClrFilter.And(filters); var found = await contentRepository.QueryIdsAsync(context.AppId.Id, context.SchemaId.Id, filter); if (found.Any(x => x.Id != context.ContentId)) { addError(Enumerable.Empty <string>(), "A content with the same values already exist."); } } } }
public async Task ValidateAsync(object?value, ValidationContext context, AddError addError) { if (context.Mode == ValidationMode.Optimized) { return; } var count = context.Path.Count(); if (value != null && (count == 0 || (count == 2 && context.Path.Last() == InvariantPartitioning.Key))) { FilterNode <ClrValue>?filter = null; if (value is string s) { filter = ClrFilter.Eq(Path(context), s); } else if (value is double d) { filter = ClrFilter.Eq(Path(context), d); } if (filter != null) { var found = await checkUniqueness(filter); if (found.Any(x => x.Id != context.ContentId)) { addError(context.Path, "Another content with the same value exists."); } } } }
public async Task ValidateAsync(object value, ValidationContext context, AddError addError) { var count = context.Path.Count(); if (value != null && (count == 0 || (count == 2 && context.Path.Last() == InvariantPartitioning.Key))) { FilterNode <ClrValue> filter = null; if (value is string s) { filter = ClrFilter.Eq(Path(context), s); } else if (value is double d) { filter = ClrFilter.Eq(Path(context), d); } if (filter != null) { var found = await context.GetContentIdsAsync(context.SchemaId, filter); if (found.Any(x => x != context.ContentId)) { addError(context.Path, "Another content with the same value exists."); } } } }
public void Should_not_normalize_other_field() { var source = ClrFilter.Eq("other", "value"); var result = FilterTagTransformer.Transform(source, appId, tagService); Assert.Equal("other == 'value'", result.ToString()); A.CallTo(() => tagService.GetTagIdsAsync(appId, A <string> .Ignored, A <HashSet <string> > .Ignored)) .MustNotHaveHappened(); }
public void Should_not_fail_when_tags_not_found() { A.CallTo(() => tagService.GetTagIdsAsync(appId, TagGroups.Assets, A <HashSet <string> > .That.Contains("name1"))) .Returns(new Dictionary <string, string>()); var source = ClrFilter.Eq("tags", "name1"); var result = FilterTagTransformer.Transform(source, appId, tagService); Assert.Equal("tags == 'name1'", result.ToString()); }
public void Should_not_normalize_non_data_field() { var source = ClrFilter.Eq("no.data", "value"); var result = FilterTagTransformer.Transform(source, appId.Id, schema, tagService); Assert.Equal("no.data == 'value'", result !.ToString()); A.CallTo(() => tagService.GetTagIdsAsync(appId.Id, A <string> ._, A <HashSet <string> > ._)) .MustNotHaveHappened(); }
public void Should_normalize_tags() { A.CallTo(() => tagService.GetTagIdsAsync(appId.Id, TagGroups.Schemas(schemaId.Id), A <HashSet <string> > .That.Contains("name1"))) .Returns(new Dictionary <string, string> { ["name1"] = "id1" }); var source = ClrFilter.Eq("data.tags2.iv", "name1"); var result = FilterTagTransformer.Transform(source, appId.Id, schema, tagService); Assert.Equal("data.tags2.iv == 'id1'", result.ToString()); }
public async Task Should_normalize_tags() { A.CallTo(() => tagService.GetTagIdsAsync(appId, TagGroups.Assets, A <HashSet <string> > .That.Contains("name1"))) .Returns(new Dictionary <string, string> { ["name1"] = "id1" }); var source = ClrFilter.Eq("tags", "name1"); var result = await FilterTagTransformer.TransformAsync(source, appId, tagService); Assert.Equal("tags == 'id1'", result !.ToString()); }
public override async ValueTask <FilterNode <ClrValue>?> Visit(CompareFilter <ClrValue> nodeIn, Args args) { if (nodeIn.Value.Value is FilterSphere sphere) { var field = string.Join(".", nodeIn.Path.Skip(1)); var searchQuery = new GeoQuery(args.Schema.Id, field, sphere.Latitude, sphere.Longitude, sphere.Radius, 1000); var searchScope = args.Context.Scope(); var ids = await args.TextIndex.SearchAsync(args.Context.App, searchQuery, searchScope); if (ids == null || ids.Count == 0) { return(ClrFilter.Eq("id", "__notfound__")); } return(ClrFilter.In("id", ids.Select(x => x.ToString()).ToList())); } return(nodeIn); }
private async Task TransformFilterAsync(ClrQuery query, Context context, ISchemaEntity?schema) { if (query.Filter != null && schema != null) { query.Filter = await GeoQueryTransformer.TransformAsync(query.Filter, context, schema, textIndex); } if (!string.IsNullOrWhiteSpace(query.FullText)) { if (schema == null) { throw new InvalidOperationException(); } var textQuery = new TextQuery(query.FullText, 1000) { PreferredSchemaId = schema.Id }; var fullTextIds = await textIndex.SearchAsync(context.App, textQuery, context.Scope()); var fullTextFilter = ClrFilter.Eq("id", "__notfound__"); if (fullTextIds?.Any() == true) { fullTextFilter = ClrFilter.In("id", fullTextIds.Select(x => x.ToString()).ToList()); } if (query.Filter != null) { query.Filter = ClrFilter.And(query.Filter, fullTextFilter); } else { query.Filter = fullTextFilter; } query.FullText = null; } }
public override FilterNode <ClrValue> Visit(BinaryOperatorNode nodeIn) { if (nodeIn.OperatorKind == BinaryOperatorKind.And) { return(ClrFilter.And(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this))); } if (nodeIn.OperatorKind == BinaryOperatorKind.Or) { return(ClrFilter.Or(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this))); } if (nodeIn.Left is SingleValueFunctionCallNode functionNode) { if (string.Equals(functionNode.Name, "geo.distance", StringComparison.OrdinalIgnoreCase) && nodeIn.OperatorKind == BinaryOperatorKind.LessThan) { var valueDistance = (double)ConstantWithTypeVisitor.Visit(nodeIn.Right).Value !; if (functionNode.Parameters.ElementAt(1) is not ConstantNode constantNode) { throw new NotSupportedException(); } if (constantNode.Value is not GeographyPoint geographyPoint) { throw new NotSupportedException(); } var property = PropertyPathVisitor.Visit(functionNode.Parameters.ElementAt(0)); return(ClrFilter.Lt(property, new FilterSphere(geographyPoint.Longitude, geographyPoint.Latitude, valueDistance))); } else { var regexFilter = Visit(functionNode); var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); if (value.ValueType == ClrValueType.Boolean && value.Value is bool booleanRight) { if ((nodeIn.OperatorKind == BinaryOperatorKind.Equal && !booleanRight) || (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual && booleanRight)) { regexFilter = ClrFilter.Not(regexFilter); } return(regexFilter); } } } else { if (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Ne(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.Equal) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Eq(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.LessThan) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Lt(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.LessThanOrEqual) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Le(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThan) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Gt(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThanOrEqual) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Ge(PropertyPathVisitor.Visit(nodeIn.Left), value)); } } throw new NotSupportedException(); }
public override FilterNode <ClrValue> Visit(BinaryOperatorNode nodeIn) { if (nodeIn.OperatorKind == BinaryOperatorKind.And) { return(ClrFilter.And(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this))); } if (nodeIn.OperatorKind == BinaryOperatorKind.Or) { return(ClrFilter.Or(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this))); } if (nodeIn.Left is SingleValueFunctionCallNode functionNode) { var regexFilter = Visit(functionNode); var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); if (value.ValueType == ClrValueType.Boolean && value.Value is bool booleanRight) { if ((nodeIn.OperatorKind == BinaryOperatorKind.Equal && !booleanRight) || (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual && booleanRight)) { regexFilter = ClrFilter.Not(regexFilter); } return(regexFilter); } } else { if (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Ne(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.Equal) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Eq(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.LessThan) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Lt(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.LessThanOrEqual) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Le(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThan) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Gt(PropertyPathVisitor.Visit(nodeIn.Left), value)); } if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThanOrEqual) { var value = ConstantWithTypeVisitor.Visit(nodeIn.Right); return(ClrFilter.Ge(PropertyPathVisitor.Visit(nodeIn.Left), value)); } } throw new NotSupportedException(); }