Ejemplo n.º 1
0
 public DeleteBuilder <T> And(Expression <Func <T, bool> > parameter)
 {
     this.AddStatement(QueryHelper.And(parameter));
     return(new DeleteBuilder <T>(Build()));
 }
Ejemplo n.º 2
0
        protected List <QueryResult> Query(List <QueryModel> queries, string cacheKey = null, int cacheMinutes = 0)
        {
            var result = new List <QueryResult>();

            if (queries == null)
            {
                return(result);
            }

            if (!string.IsNullOrEmpty(cacheKey))
            {
                object o = null;
                if (PuckCache.Cache.TryGetValue(cacheKey, out o))
                {
                    var _res = o as List <QueryResult>;
                    if (_res != null)
                    {
                        return(_res);
                    }
                }
            }

            var models = ApiHelper.GetModelTypes();

            void DoIncludes(List <ExpandoObject> results, List <string> includes, int includesIndex = 0)
            {
                if (includesIndex > includes.Count - 1)
                {
                    return;
                }
                var include    = includes[includesIndex];
                var properties = include.Split(".", StringSplitOptions.RemoveEmptyEntries);

                void GetProperty(object currentProp, object _setProp, string _setPropName, string[] properties, int i)
                {
                    var prop = properties[i];

                    if (ApiHelper.ExpandoHasProperty(currentProp as ExpandoObject, prop))
                    {
                        var obj = ApiHelper.GetExpandoProperty(currentProp as ExpandoObject, prop);

                        if (obj == null)
                        {
                            return;
                        }

                        var objType = obj.GetType();
                        if (objType.Equals(typeof(ExpandoObject)))
                        {
                            _setProp     = currentProp;
                            _setPropName = prop;
                            currentProp  = obj;
                            i++;
                            GetProperty(currentProp, _setProp, _setPropName, properties, i);
                        }
                        else if (i == properties.Length - 1 && objType.Equals(typeof(List <Object>)))
                        {
                            //we have the List<PuckReference> property
                            _setProp     = currentProp;
                            _setPropName = prop;
                            currentProp  = obj;
                            i++;
                            DoGetFromReferences(currentProp, _setProp, _setPropName);
                        }
                        else if (objType.Equals(typeof(List <Object>)))
                        {
                            _setProp     = currentProp;
                            _setPropName = prop;
                            currentProp  = obj;
                            i++;
                            var lprop = currentProp as List <object>;
                            foreach (var o in lprop)
                            {
                                GetProperty(o, _setProp, _setPropName, properties, i);
                            }
                        }
                    }
                }

                void DoGetFromReferences(object currentProp, object _setProp, string _setPropName)
                {
                    if (currentProp != null && currentProp.GetType().Equals(typeof(List <object>)))
                    {
                        var lprop = currentProp as List <object>;
                        if (lprop.Any() && lprop[0].GetType().Equals(typeof(ExpandoObject)))
                        {
                            var refQuery  = new QueryHelper <BaseModel>();
                            var qhinner1  = refQuery.New();
                            var hasQuery  = false;
                            var j         = 0;
                            var sortOrder = new Dictionary <Guid, int>();
                            foreach (var reference in lprop)
                            {
                                var  eref = reference as ExpandoObject;
                                Guid id;
                                if (ApiHelper.ExpandoHasProperty(eref, "Id") && ApiHelper.ExpandoHasProperty(eref, "Variant") && Guid.TryParse(ApiHelper.GetExpandoProperty(eref, "Id").ToString(), out id))
                                {
                                    hasQuery = true;
                                    var qhinner2 = qhinner1.New().Id(ApiHelper.GetExpandoProperty(eref, "Id").ToString());
                                    qhinner2.Variant(ApiHelper.GetExpandoProperty(eref, "Variant").ToString().ToLower());
                                    qhinner1.Group(
                                        qhinner2
                                        );
                                    sortOrder[id] = j;
                                }
                                j++;
                            }
                            refQuery.And().Group(qhinner1);
                            List <ExpandoObject> unsortedRefResult = refQuery.GetAllExpando(limit: int.MaxValue);
                            var refResult = unsortedRefResult.OrderBy(x => sortOrder[Guid.Parse(ApiHelper.GetExpandoProperty(x, "Id").ToString())]).ToList();
                            ApiHelper.SetExpandoProperty(_setProp as ExpandoObject, _setPropName, refResult);
                            DoIncludes(refResult, includes, includesIndex: includesIndex + 1);
                        }
                    }
                }

                foreach (var item in results)
                {
                    GetProperty(item, null, "", properties, 0);
                }
            }

            foreach (var query in queries)
            {
                if (string.IsNullOrEmpty(query.Type))
                {
                    result.Add(new QueryResult {
                        Total = 0, Results = new List <ExpandoObject>()
                    });
                    continue;
                }
                Type type = null;
                if (!PuckCache.ModelNameToType.TryGetValue(query.Type, out type))
                {
                    result.Add(new QueryResult {
                        Total = 0, Results = new List <ExpandoObject>()
                    });
                    continue;
                }

                var qht      = typeof(QueryHelper <>);
                var typeArgs = new Type[] { type };
                var gtype    = qht.MakeGenericType(typeArgs);

                var qho = Activator.CreateInstance(gtype, new object[] { true, true });

                var interfaceTypes      = new List <Type>();
                var interfaceProperties = new Dictionary <string, FlattenedObject>();

                var fieldTypeMappings     = new Dictionary <string, Type>();
                var fieldAnalyzerMappings = new Dictionary <string, Analyzer>();

                if (!string.IsNullOrEmpty(query.Implements))
                {
                    var interfaceNames = query.Implements.Split(',', StringSplitOptions.RemoveEmptyEntries);
                    foreach (var interfaceName in interfaceNames)
                    {
                        Tuple <Type, List <FlattenedObject> > vals = null;
                        if (PuckCache.InterfaceNameToType.TryGetValue(interfaceName, out vals))
                        {
                            interfaceTypes.Add(vals.Item1);

                            foreach (var flattenedObject in vals.Item2)
                            {
                                interfaceProperties[flattenedObject.Key] = flattenedObject;
                                fieldTypeMappings[flattenedObject.Key]   = flattenedObject.Type;
                                if (flattenedObject.Analyzer != null)
                                {
                                    fieldAnalyzerMappings[flattenedObject.Key] = flattenedObject.Analyzer;
                                }
                            }
                        }
                    }
                }

                if (interfaceTypes.Any())
                {
                    var miImplements = gtype.GetMethod("Implements", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(Type[]) }, null);
                    miImplements.Invoke(qho, new object[] { interfaceTypes.ToArray() });
                }

                if (!string.IsNullOrEmpty(query.Sorts))
                {
                    var miSort = gtype.GetMethod("SortByField", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(string), typeof(bool), typeof(Type) }, null);
                    foreach (var sort in query.Sorts.Split(',', StringSplitOptions.RemoveEmptyEntries))
                    {
                        var sortParams = sort.Split(":", StringSplitOptions.RemoveEmptyEntries);
                        if (sortParams.Length == 0)
                        {
                            continue;
                        }
                        var             desc     = sortParams[1] == "desc";
                        FlattenedObject flatObj  = null;
                        Type            propType = null;
                        if (interfaceProperties.TryGetValue(sortParams[0], out flatObj))
                        {
                            propType = flatObj.Type;
                        }
                        miSort.Invoke(qho, new object[] { sortParams[0], desc, propType });
                    }
                }
                if (!string.IsNullOrEmpty(query.Query))
                {
                    var miAppendQuery = gtype.GetMethod("AppendQuery");
                    miAppendQuery.Invoke(qho, new object[] { query.Query });
                }
                var miQueryNoCast = gtype.GetMethod("GetAllExpando");
                var qresult       = miQueryNoCast.Invoke(qho, new object[] { query.Take, query.Skip, fieldTypeMappings, fieldAnalyzerMappings }) as List <ExpandoObject>;

                if (query.Include != null)
                {
                    foreach (var includes in query.Include)
                    {
                        DoIncludes(qresult, includes, includesIndex: 0);
                    }
                }

                if (query.Fields != null && query.Fields.Any())
                {
                    for (var i = 0; i < qresult.Count; i++)
                    {
                        var r = new ExpandoObject();
                        foreach (var field in query.Fields)
                        {
                            if (((IDictionary <string, object>)qresult[i]).ContainsKey(field))
                            {
                                ((IDictionary <string, object>)r)[field] = ((IDictionary <string, object>)qresult[i])[field];
                            }
                        }
                        qresult[i] = r;
                    }
                }

                var totalHitsPi = qho.GetType().GetProperty("TotalHits");

                result.Add(new QueryResult {
                    Total = (int)totalHitsPi.GetValue(qho), Results = qresult
                });
            }

            if (!string.IsNullOrEmpty(cacheKey))
            {
                PuckCache.Cache.Set(cacheKey, result, TimeSpan.FromMinutes(cacheMinutes));
            }

            return(result);
        }