示例#1
0
        /// <summary>
        /// A special intermediate function for converting string chaining into real chaining.
        /// </summary>
        /// <param name="chainDataString"></param>
        /// <param name="search"></param>
        /// <param name="previousChains"></param>
        /// <typeparam name="S"></typeparam>
        /// <typeparam name="V"></typeparam>
        /// <returns></returns>
        protected Task ChainStringAsync <S, V>(ChainRequestString chainDataString, Func <S, Task <List <V> > > search, List <List <IIdView> > previousChains)
            where S : IConstrainedSearcher where V : IIdView
        {
            var t = timer.StartTimer($"{chainDataString.endpoint} {string.Join(".", chainDataString.chains)}");

            try
            {
                var chainData = new ChainRequest <S, V>(chainDataString)
                {
                    retriever = search
                };

                try
                {
                    chainData.baseSearch = JsonSerializer.Deserialize <S>(chainDataString.search, config.JsonOptions);
                }
                catch (Exception ex)
                {
                    //I don't care too much about json deseralize errors, just the message. I don't even log it.
                    throw new BadRequestException(ex.Message + " (CHAIN REMINDER: json search comes last AFTER all . chaining in a request)");
                }

                return(ChainAsync(chainData, previousChains));
            }
            finally
            {
                timer.EndTimer(t);
            }
        }
示例#2
0
        /// <summary>
        /// THE REAL PROPER CHAINING ENDPOINT! Will perform ONE chain request (after linking with previous chains)
        /// </summary>
        /// <param name="data"></param>
        /// <param name="baggage"></param>
        /// <typeparam name="S"></typeparam>
        /// <typeparam name="V"></typeparam>
        /// <returns></returns>
        public async Task ChainAsync <S, V>(ChainRequest <S, V> data, List <List <IIdView> > previousChains)
            where V : IIdView where S : IConstrainedSearcher
        {
            Dictionary <string, PropertyInfo> properties = null;

            Type type = typeof(V);

            //My poor design has led to this...
            if (type == typeof(UserViewFull))
            {
                type = typeof(UserViewBasic);
            }

            var baseProperties = GetProperties(type);

            //Before doing ANYTHING, IMMEDIATELY convert fields to actual properties. It's easy if they pass us null: they want everything.
            if (data.fields == null)
            {
                properties = baseProperties.ToDictionary(x => x.Name, x => x);
            }
            else
            {
                var lowerFields = data.fields.Select(x => x.ToLower());
                properties = baseProperties.Where(x => lowerFields.Contains(x.Name.ToLower())).ToDictionary(x => x.Name, x => x);

                if (properties.Count != data.fields.Count)
                {
                    throw new BadRequestException($"Unknown fields in list: {string.Join(",", data.fields)}");
                }
            }

            //Parse the chains, get the ids. WARN: THIS IS DESTRUCTIVE TO DATA.BASESEARCH!!!
            foreach (var c in data.chains)
            {
                LinkToSearch(c, previousChains, data.baseSearch);
            }

            var myResults = await data.retriever(data.baseSearch);

            previousChains.Add(myResults.Cast <IIdView>().ToList());

            //Only add ones that aren't in the list
            foreach (var v in myResults)
            {
                if (!data.mergeList.Any(x => x.id == v.id))
                {
                    var result = new TaggedChainResult()
                    {
                        id = v.id, result = new ExpandoObject()
                    };

                    foreach (var p in properties)
                    {
                        result.result.TryAdd(p.Key, p.Value.GetValue(v));
                    }

                    lock (data.mergeLock)
                    {
                        data.mergeList.Add(result);
                    }
                }
            }
        }