// generate a list of url (ids) based on search terms private async Task <BuildNodesInfo> BuildNodesAsync(SearchDataProvider searchDP, string search, string languageId, bool haveUser, List <DataProviderFilterInfo> extraFilters) { if (string.IsNullOrEmpty(search)) { return(new BuildNodesInfo()); } BuildNodesInfo list = null; for ( ; ;) { search = search.Trim(); if (search.Length <= 0) { break; } char c = search[0]; if (c == '(') { parenLevel++; search = search.Remove(0, 1); list = await BuildNodesAsync(searchDP, search, languageId, haveUser, extraFilters); search = list.Search; } else if (c == ')') { if (parenLevel <= 0) { throw new Error(this.__ResStr("invQueryCloseParen", "Invalid query - too many ')'")); } parenLevel--; list.Search = search.Remove(0, 1); return(list); } else { string token; int irp = search.IndexOf(')'); int i = search.IndexOf(' '); if (irp >= 0 && (irp < i || i < 0)) { i = irp; } int ilp = search.IndexOf('('); if (ilp >= 0 && (ilp < i || i < 0)) { i = ilp; } if (i < 0) { token = search; search = ""; } else { token = search.Substring(0, i); search = search.Remove(0, i); } if (list != null) { if (string.Compare(token, GetKeyWordOr(), true) == 0) { BuildNodesInfo rhsList = await BuildNodesAsync(searchDP, search, languageId, haveUser, extraFilters); search = rhsList.Search; list.Data = list.Data.Union(rhsList.Data, new SearchDataComparer()).ToList(); } else if (string.Compare(token, GetKeyWordAnd(), true) == 0) { BuildNodesInfo rhsList = await BuildNodesAsync(searchDP, search, languageId, haveUser, extraFilters); search = rhsList.Search; list.Data = list.Data.Intersect(rhsList.Data, new SearchDataComparer()).ToList(); } else { List <DataProviderFilterInfo> filters = DataProviderFilterInfo.Copy(extraFilters); if (token.EndsWith("*")) { token = token.TrimEnd(new char[] { '*' }); filters = DataProviderFilterInfo.Join(filters, new DataProviderFilterInfo { Field = nameof(SearchData.SearchTerm), Operator = "StartsWith", Value = token }); } else { filters = DataProviderFilterInfo.Join(filters, new DataProviderFilterInfo { Field = nameof(SearchData.SearchTerm), Operator = "==", Value = token }); } DataProviderGetRecords <SearchData> rhsList = await searchDP.GetItemsWithUrlAsync(0, 0, null, filters); list.Data = list.Data.Intersect(rhsList.Data, new SearchDataComparer()).ToList(); } } else { List <DataProviderFilterInfo> filters = DataProviderFilterInfo.Copy(extraFilters); if (token.EndsWith("*")) { token = token.TrimEnd(new char[] { '*' }); filters = DataProviderFilterInfo.Join(filters, new DataProviderFilterInfo { Field = nameof(SearchData.SearchTerm), Operator = "StartsWith", Value = token }); } else { filters = DataProviderFilterInfo.Join(filters, new DataProviderFilterInfo { Field = nameof(SearchData.SearchTerm), Operator = "==", Value = token }); } list = new BuildNodesInfo { Search = search }; list.Data = (await searchDP.GetItemsWithUrlAsync(0, 0, null, filters)).Data; search = list.Search; } } } if (parenLevel > 0) { throw new Error(this.__ResStr("invQueryOpenParen", "Invalid query - unmatched '('")); } list.Search = search; return(list); }