/// <summary> /// Parse a specially-formatted request into a temporary chain container. The container is not complete /// </summary> /// <param name="request"></param> /// <returns></returns> public ChainRequestString ParseInitialChainString(string request) { var match = Regex.Match(request, config.RequestRegex, RegexOptions.IgnoreCase); var result = new ChainRequestString() { viewableIdentifier = request, search = match.Groups["search"].Value, endpoint = match.Groups["endpoint"].Value, name = match.Groups["name"].Value }; //Convert chaining strings into proper chaining objects. result.chains = match.Groups["chain"].Captures.Select(x => { var c = x.Value; var match = Regex.Match(c, config.ChainRegex, RegexOptions.IgnoreCase); var chaining = new Chaining() { viewableIdentifier = c, getFieldPath = match.Groups["field"].Value.Split("_".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList(), searchFieldPath = match.Groups["searchfield"].Value.Split("_".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList() }; int tempIndex = 0; if (!int.TryParse(match.Groups["index"].Value, out tempIndex)) { throw new BadRequestException($"Can't parse chain index: {match.Groups["index"]}"); } chaining.index = tempIndex; return(chaining); }); if (string.IsNullOrWhiteSpace(result.search)) { result.search = "{}"; } return(result); }
/// <summary> /// Using the given chaining, link the appropriate field(s) from old chains into the current search. /// </summary> /// <param name="chain"></param> /// <param name="existingChains"></param> /// <param name="search"></param> /// <typeparam name="S"></typeparam> /// <returns></returns> public List <long> LinkToSearch <S>(Chaining chain, List <List <IIdView> > existingChains, S search) where S : IIdSearcher { if (chain.searchFieldPath.Count == 0) { chain.searchFieldPath.Add("Ids"); } // Before going out and getting stuff, make sure ALL our fields are good. Reflection is expensive! if (chain.index < 0 || chain.getFieldPath.Count == 0 || existingChains.Count <= chain.index) { throw new BadRequestException($"Bad chain index or missing field: {chain}"); } //Uh-oh, assume it is list of long... even if it's not ogh. WHY DO WE DO THIS? This is bad code, but we're getting a REFERENCE //to the search ids so we can append to them later. This is NECESSARY, DO NOT REMOVE! Without appending to searchids, this does //not work, this is DESIGNED to have side effects and directly modify the given search (which is this part) var searchIds = (List <long>)GetIdsFromFieldPath(search, chain.searchFieldPath); try { var ids = existingChains[chain.index].SelectMany(x => GetIdsFromFieldPath(x, chain.getFieldPath)).ToList(); //Ensure a true "empty search" if there were no results. There is a CHANCE that later linkings //will actually add values to this search field. This is OK; the max value will not break the search. if (ids.Count() == 0) { ids.Add(long.MaxValue); } searchIds.AddRange(ids); return(ids); } catch (Exception ex) { throw new BadRequestException($"Bad/missing chain field: {chain} ({ex.Message})"); } }
/// <summary> /// Using the given chaining, link the appropriate field(s) from old chains into the current search. /// </summary> /// <param name="chain"></param> /// <param name="existingChains"></param> /// <param name="search"></param> /// <typeparam name="S"></typeparam> /// <returns></returns> public List <long> LinkToSearch <S>(Chaining chain, List <List <IIdView> > existingChains, S search) where S : IIdSearcher { if (chain.searchFieldPath.Count == 0) //string.IsNullOrEmpty(chain.searchField)) { chain.searchFieldPath.Add("Ids"); } // Before going out and getting stuff, make sure ALL our fields are good. Reflection is expensive! if (chain.index < 0 || chain.getFieldPath.Count == 0 || existingChains.Count <= chain.index) { throw new BadRequestException($"Bad chain index or missing field: {chain}"); } //Uh-oh, assume it is list of long... even if it's not ogh var searchIds = (List <long>)GetIdsFromFieldPath(search, chain.searchFieldPath); try { var ids = existingChains[chain.index].SelectMany(x => GetIdsFromFieldPath(x, chain.getFieldPath)).ToList(); //GetIdsFromFieldPath(existingChains[chain.index], chain.getFieldPath).ToList(); //Ensure a true "empty search" if there were no results. There is a CHANCE that later linkings //will actually add values to this search field. This is OK; the max value will not break the search. if (ids.Count() == 0) { ids.Add(long.MaxValue); } searchIds.AddRange(ids); return(ids); } catch (Exception ex) { throw new BadRequestException($"Bad/missing chain field: {chain} ({ex.Message})"); } }