protected virtual AcsSearch BuildSearch(SearchRequest request) { var search = new AcsSearch(request.CombinationOperator); foreach (var searchGroup in request.Groups) { var group = new AcsSearch(searchGroup.CombinationOperator); foreach (var requestFilter in searchGroup.Filter) { var definition = _fieldDefinitions.Single(fd => fd.Name.Equals(requestFilter.Field, StringComparison.InvariantCultureIgnoreCase)); if (definition.IsSearchable || definition.IsFilterable) { group.AppendFilter(definition, requestFilter.Operator, requestFilter.Value); } else { throw new Exception($"{requestFilter.Field} is neither searchable nor filterable"); } } search.AddGroup(group); } if (string.IsNullOrEmpty(search.Query)) { search.Query = "*"; } return(search); }
public void AddGroup(AcsSearch group) { if (!string.IsNullOrEmpty(group.Query) && group.Query != "*") { AppendQuery($"({group.Query})"); } if (!string.IsNullOrEmpty(group.Filter)) { AppendFilter($"({group.Filter})"); } }
public void AppendFilter(SearchFieldDefinition field, string filterOperator, string value) { if (field.IsSearchable) { AppendFilter($"search.ismatch('\"{value}\"', '{field.Name}')"); return; } if (filterOperator == Operators.Between) { string[] dateParts = value.Split( new string[] { " to " }, StringSplitOptions.RemoveEmptyEntries); if (dateParts.Length != 2) { // Then get upset 💢 throw new FormatException( $"Between values need to contain 2 valid " + $"{nameof(DateTime)}s, seperated by the keyword " + $"\"to\". For example, \"2018-06-29T00:00:00Z\" to " + $"\"2018-07-01T00:00:00Z\"."); } // Else... // Try and build up a group query of our own. AcsSearch between = new AcsSearch("and"); between.AppendFilter(field, Operators.LessThan, dateParts.Last()); between.AppendFilter(field, Operators.GreaterThan, dateParts.First()); AddGroup(between); } else { if (filterOperator == Operators.In) { var values = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()); var conditionValue = values.Aggregate((x, y) => $"{x},{y}"); AppendFilter($"search.in({field.Name}, '{conditionValue}', ',')"); } else { string conditionValue; if (filterOperator == Operators.IsNull || filterOperator == Operators.IsNotNull) { conditionValue = "null"; } else { if (IsNumericType(field.DataType)) { conditionValue = value; } else if (IsDateType(field.DataType)) { DateTime dtm; if (!DateTime.TryParse(value, out dtm)) { throw new Exception($"{value} is not a valid date/time value for {field.Name}"); } conditionValue = dtm.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"); } else { conditionValue = $"'{value}'"; } } var acsOperator = OperatorMappings[filterOperator.ToLower()]; AppendFilter($"{field.Name} {acsOperator} {conditionValue}"); } } }