/// <summary> /// Transforms the defined filters into the expected Postgrest format. /// /// See: http://postgrest.org/en/v7.0.0/api.html#operators /// </summary> /// <param name="filter"></param> /// <returns></returns> internal KeyValuePair <string, string> PrepareFilter(QueryFilter filter) { var attr = filter.Op.GetAttribute <MapToAttribute>(); if (attr is MapToAttribute asAttribute) { var strBuilder = new StringBuilder(); switch (filter.Op) { case Operator.Or: case Operator.And: if (filter.Criteria is List <QueryFilter> subFilters) { var list = new List <KeyValuePair <string, string> >(); foreach (var subFilter in subFilters) { list.Add(PrepareFilter(subFilter)); } foreach (var preppedFilter in list) { strBuilder.Append($"{preppedFilter.Key}.{preppedFilter.Value},"); } return(new KeyValuePair <string, string>(asAttribute.Mapping, $"({strBuilder.ToString().Trim(',')})")); } break; case Operator.Not: if (filter.Criteria is QueryFilter notFilter) { var prepped = PrepareFilter(notFilter); return(new KeyValuePair <string, string>(prepped.Key, $"not.{prepped.Value}")); } break; case Operator.Like: case Operator.ILike: if (filter.Criteria is string likeCriteria) { return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.{likeCriteria.Replace("%", "*")}")); } break; case Operator.In: if (filter.Criteria is List <object> inCriteria) { foreach (var item in inCriteria) { strBuilder.Append($"\"{item}\","); } return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.({strBuilder.ToString().Trim(',')})")); } else if (filter.Criteria is Dictionary <string, object> dictCriteria) { return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.{JsonConvert.SerializeObject(dictCriteria)}")); } break; case Operator.Contains: case Operator.ContainedIn: case Operator.Overlap: if (filter.Criteria is List <object> listCriteria) { foreach (var item in listCriteria) { strBuilder.Append($"{item},"); } return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.{{{strBuilder.ToString().Trim(',')}}}")); } else if (filter.Criteria is Dictionary <string, object> dictCriteria) { return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.{JsonConvert.SerializeObject(dictCriteria)}")); } else if (filter.Criteria is IntRange rangeCriteria) { return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.{rangeCriteria.ToPostgresString()}")); } break; case Operator.StrictlyLeft: case Operator.StrictlyRight: case Operator.NotRightOf: case Operator.NotLeftOf: case Operator.Adjacent: if (filter.Criteria is IntRange rangeCritera) { return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.{rangeCritera.ToPostgresString()}")); } break; case Operator.FTS: case Operator.PHFTS: case Operator.PLFTS: case Operator.WFTS: if (filter.Criteria is FullTextSearchConfig searchConfig) { return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}({searchConfig.Config}).{searchConfig.QueryText}")); } break; default: return(new KeyValuePair <string, string>(filter.Property, $"{asAttribute.Mapping}.{filter.Criteria}")); } } return(new KeyValuePair <string, string>()); }
/// <summary> /// Adds a NOT filter to the current query args. /// </summary> /// <param name="filter"></param> /// <returns></returns> public Table <T> Not(QueryFilter filter) { filters.Add(new QueryFilter(Operator.Not, filter)); return(this); }