Esempio n. 1
0
        /// <summary>
        /// Get an IQueryable in the extended type given the base type, sourcing data without fetching
        /// non-summarised fields
        /// </summary>
        /// <param name="tBase">The base type</param>
        /// <returns>IQueryable in extended type which doesn't fetch non-summarised fields</returns>
        public IQueryable SummarisedSet(Type tBase)
        {
            var extender = LyniconSystem.Instance.Extender;

            if (!extender.BaseTypes.Contains(tBase))
            {
                throw new Exception("No composite of base type " + tBase.FullName);
            }

            // Below hack required because constructing the 'project' query (which is .Select(..) under the covers)
            // causes a database connection to be made, so this must be avoided.  The result of the IQueryable returned
            // is not relevant as it will be ignored, however the item type IS used in TotalCache.
            if (Repository.Instance.AvoidConnection)
            {
                Type itemType = extender[tBase] ?? tBase;
                Type listType = typeof(List <>).MakeGenericType(itemType);
                return(((IEnumerable)(Activator.CreateInstance(listType))).AsQueryable());
            }

            Type       sumsType = extender.Summarised(tBase);
            IQueryable q        = (IQueryable)ReflectionX.InvokeGenericMethod(this, "SummarisedSet", sumsType);

            var project  = projectors[tBase];
            var selectMi = selectors[tBase];

            var qryOut = (IQueryable)selectMi.Invoke(null, new object[] { q, project });

            return(qryOut);
        }
Esempio n. 2
0
        public override Func <IQueryable <T>, IQueryable <T> > Apply <T>()
        {
            if (keySet == null)
            {
                Type summType = ContentTypeHierarchy.SummaryTypes[this.refType];
                ReflectionX.InvokeGenericMethod(this, "SetKeySet", false, mi => true, new List <Type> {
                    this.refType, summType
                });
            }

            // encodes x => x.Prop
            var xParam     = Expression.Parameter(typeof(T), "x");
            var accessProp = Expression.MakeMemberAccess(xParam, this.PropInfo);
            var selector   = Expression.Lambda(accessProp, xParam);

            Type propType = this.PropInfo.PropertyType;

            Dictionary <Type, TypeConverter> converters =
                this.keySet.Select(k => k.GetType()).Distinct().ToDictionary(t => t, t => TypeDescriptor.GetConverter(t));

            this.keySet = this.keySet.Select(k => k.GetType() == propType
                ? k
                : converters[k.GetType()].ConvertTo(k, propType)).ToList();
            // if foreign key field was nullable
            return(iq => iq.WhereIn(selector, this.keySet, propType));
        }
Esempio n. 3
0
        /// <summary>
        /// Get containers by query
        /// </summary>
        /// <typeparam name="T">The type of the resulting containers</typeparam>
        /// <param name="targetType">The content type or summary type of the intended output</param>
        /// <param name="types">The allowed types of contained content items returned</param>
        /// <param name="queryBody">An operator on an IQueryable of the container type to filter the ones to return</param>
        /// <returns>Resulting list of containers</returns>
        public virtual IEnumerable <T> Get <T>(Type targetType, IEnumerable <Type> types, Func <IQueryable <T>, IQueryable <T> > queryBody) where T : class
        {
            if (types == null || !types.Any())
            {
                yield break;
            }

            if (types.Count() == 1)
            {
                var contentType = types.Single();

                var itemEnum = (IEnumerable)ReflectionX.InvokeGenericMethod(this, "BasicGet", new Type[] { contentType, typeof(T) }, targetType, queryBody);
                foreach (object res in itemEnum)
                {
                    yield return(res as T);
                }
            }
            else
            {
                foreach (Type t in types)
                {
                    foreach (var res in this.Get <T>(targetType, new Type[] { t }, queryBody))
                    {
                        yield return(res);
                    }
                }
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Get containers by addresses
 /// </summary>
 /// <param name="targetType">type of contained items these will produce - either 'object' or a summary type</param>
 /// <param name="addresses">list of addresses to fetch</param>
 /// <returns>container(s) at addresses</returns>
 public IEnumerable <object> Get(Type targetType, IEnumerable <Address> addresses)
 {
     foreach (var addressG in addresses.GroupBy(ad => ad.Type))
     {
         Type contT      = System.Collator.ContainerType(addressG.Key);
         var  pathPiInfo = contT.GetProperties()
                           .Select(pi => new { pi, a = pi.GetCustomAttribute <AddressComponentAttribute>() })
                           .FirstOrDefault(pii => pii.a != null && pii.a.UsePath);
         if (pathPiInfo != null) // container has a single property in which the path is stored - we can get all using same repository in one query
         {
             foreach (object res in (IEnumerable)ReflectionX.InvokeGenericMethod(this, "Get",
                                                                                 mi => { var parms = mi.GetParameters(); return(parms.Length == 2 && parms[1].Name == "addresses"); },
                                                                                 new Type[] { contT }, targetType, addressG))
             {
                 yield return(res);
             }
         }
         else // we have to use a query for each item as the path is spread across multiple fields
         {
             foreach (Address a in addressG)
             {
                 var results = (IEnumerable)ReflectionX.InvokeGenericMethod(this, "Get", m => m.GetParameters()[1].ParameterType == typeof(Address), new Type[] { contT }, a.Type, a);
                 foreach (var res in results)
                 {
                     yield return(res);
                 }
             }
         }
     }
 }
Esempio n. 5
0
 /// <inheritdoc/>
 public override IEnumerable <T> Get <T>(IEnumerable <Address> addresses)
 {
     foreach (var ag in addresses.GroupBy(a => a.Type))
     {
         var typeResults = (IEnumerable <T>)ReflectionX.InvokeGenericMethod(this, "GetAddressesOfType", false, mi => true, new Type[] { typeof(T), ag.Key }, ag);
         foreach (var res in typeResults)
         {
             yield return(res);
         }
     }
 }
Esempio n. 6
0
 /// <inheritdoc/>
 public override IEnumerable <T> Get <T>(IEnumerable <ItemId> ids)
 {
     foreach (var idg in ids.GroupBy(id => id.Type))
     {
         var typeResults = (IEnumerable <T>)ReflectionX.InvokeGenericMethod(this, "GetIdsOfType", false, mi => true, new Type[] { typeof(T), idg.Key }, idg);
         foreach (var res in typeResults)
         {
             yield return(res);
         }
     }
 }
Esempio n. 7
0
        public IActionResult ScanReferences()
        {
            List <string> errors = new List <string>();

            foreach (Type t in ContentTypeHierarchy.AllContentTypes)
            {
                List <string> refErrors = (List <string>)ReflectionX.InvokeGenericMethod(this, "GetReferenceErrors", t);
                errors.AddRange(refErrors);
            }

            return(PartialView(errors));
        }
Esempio n. 8
0
        /// <summary>
        /// Get markup to show all the items of a type in a paged box on the List page
        /// </summary>
        /// <param name="datatype">The data type</param>
        /// <returns>Markup of the paged box listing the items</returns>
        public ActionResult GetPage(string datatype)
        {
            ViewData.Add("UrlPermission", LyniconSecurityManager.Current.CurrentUserInRole(Lynicon.Membership.User.EditorRole));
            ViewData.Add("DelPermission", LyniconSecurityManager.Current.CurrentUserInRole(Lynicon.Membership.User.AdminRole));
            Type type          = ContentTypeHierarchy.GetContentType(datatype);
            Type containerType = Collator.Instance.ContainerType(type);
            // invoke Collator.Instance.GetList<Summary, type>(new Type[] { type }, RouteData).ToArray();
            var summs = (IEnumerable <Summary>)ReflectionX.InvokeGenericMethod(Collator.Instance, "GetList", new Type[] { typeof(Summary), containerType }, new Type[] { type }, RouteData);
            var data  = summs.ToArray();

            return(PartialView("ItemPage", data));
        }
Esempio n. 9
0
        /// <summary>
        /// Get a DbQuery (in the extended type) for a given base type
        /// </summary>
        /// <param name="tBase">The base type</param>
        /// <param name="useIncludes">Whether to use includes specified by AlwaysIncludesAttribute</param>
        /// <returns>A DbQuery against the underlying database</returns>
        public IQueryable CompositeSet(Type tBase, bool useIncludes)
        {
            var extender = LyniconSystem.Instance.Extender;
            var ext      = extender[tBase];

            if (ext == null)
            {
                throw new Exception("No composite of base type " + tBase.FullName);
            }

            IQueryable q = (IQueryable)ReflectionX.InvokeGenericMethod(this, "InnerCompositeSet", ext, true, useIncludes);

            return(q);
        }
Esempio n. 10
0
        /// <summary>
        /// Get containers by ids
        /// </summary>
        /// <typeparam name="T">The type of the resulting containers</typeparam>
        /// <param name="targetType">The content type or summary type of the intended output</param>
        /// <param name="ids">The ItemIds of the containers to fetch</param>
        /// <returns></returns>
        public virtual IEnumerable <T> Get <T>(Type targetType, IEnumerable <ItemId> ids) where T : class
        {
            bool isSummary = typeof(Summary).IsAssignableFrom(targetType);

            TContext db = GetDb();

            try
            {
                foreach (var idg in ids.GroupBy(ii => ii.Type))
                {
                    if (idg.Count() > MaximumIdBatchSize)
                    {
                        throw new ArgumentException("Request for too many ids at once, request in batches of maximum size " + MaximumIdBatchSize);
                    }

                    var qed = new QueryEventData <IQueryable>
                    {
                        QueryBody = (Func <IQueryable, IQueryable>)ReflectionX.InvokeGenericMethod(this, "GetIdsQuery", idg.Key, idg.Select(ii => ii.Id))
                    };

                    qed.Source = ApplyIncludes(idg.Key, ((TContext)db).Set(idg.Key));

                    qed.Ids = ids;

                    qed = EventHub.Instance.ProcessEvent(isSummary ? "Repository.Get.Summaries.Ids" : "Repository.Get.Items.Ids", this, qed).Data as QueryEventData <IQueryable>;

                    if (qed.EnumSource != null)
                    {
                        foreach (var res in qed.EnumSource)
                        {
                            yield return(res as T);
                        }
                    }
                    else
                    {
                        foreach (var res in qed.QueryBody(qed.Source).AsFacade <T>())
                        {
                            yield return(res);
                        }
                    }
                }
            }
            finally
            {
                if (!isSummary)
                {
                    EndCallDb((TContext)db);
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Get a data item, or list of items, via the route which maps to them
        /// </summary>
        /// <typeparam name="T">type of the item(s), a generic list if a list of items, could be a summary type</typeparam>
        /// <param name="contentType">the content type of the item(s)</param>
        /// <param name="rd">route data</param>
        /// <returns>the mapped items(s)</returns>
        public T Get <T>(Type contentType, RouteData rd) where T : class
        {
            //CodeTimer.MarkTime("Get via route START");

            try
            {
                if (typeof(T).IsGenericType() && typeof(T).GetGenericTypeDefinition() == typeof(List <>))
                {
                    Type        elType = typeof(T).GetGenericArguments()[0];
                    ICollator   coll;
                    List <Type> contentTypes;
                    bool        isSummary = typeof(Summary).IsAssignableFrom(elType);
                    if (isSummary)
                    {
                        contentTypes = ContentTypeHierarchy.GetSummaryContainers(elType);
                        if (contentTypes.Select(ct => Registered(ct)).Distinct().Count() != 1)
                        {
                            throw new Exception("Content types containing summary type " + elType.FullName + " dont have 1 unique registered collator, requirement for a dataroute with list type");
                        }

                        coll = Registered(contentTypes.First());
                    }
                    else
                    {
                        coll         = Registered(elType);
                        contentTypes = new List <Type> {
                            elType
                        };
                    }

                    T itemList = (T)ReflectionX.InvokeGenericMethod(coll, "GetList",
                                                                    new Type[] { elType, isSummary ? elType : ContainerType(elType) },
                                                                    contentTypes,
                                                                    rd);
                    return(itemList);
                }
                else
                {
                    ICollator coll = Registered(contentType);
                    return(coll.Get <T>(new List <Address> {
                        coll.GetAddress(contentType, rd)
                    }).FirstOrDefault());
                }
            }
            finally
            {
                //CodeTimer.MarkTime("Get via route END");
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Get total count of items of a given type in api
        /// </summary>
        /// <param name="targetType">type type of item to count</param>
        /// <returns>count</returns>
        public int GetCount(Type targetType)
        {
            Type type = targetType;

            if (Registered(targetType) is ContentRepository)
            {
                type = typeof(ContentItem);
            }

            Type iqType = typeof(IQueryable <>).MakeGenericType(type);

            ParameterExpression iqParam  = Expression.Parameter(iqType, "iq");
            LambdaExpression    queryExp = Expression.Lambda(iqParam, iqParam);

            return((int)ReflectionX.InvokeGenericMethod(this, "GetCount", type, new Type[] { targetType }, queryExp.Compile()));
        }
Esempio n. 13
0
        public override Func <IQueryable <T>, IQueryable <T> > Apply <T>()
        {
            if (keySet == null)
            {
                Type summType = ContentTypeHierarchy.SummaryTypes[this.refType];
                ReflectionX.InvokeGenericMethod(this, "SetKeySet", false, mi => true, new List <Type> {
                    this.refType, summType
                });
            }

            // encodes x => x.Prop
            var xParam     = Expression.Parameter(typeof(T), "x");
            var accessProp = Expression.MakeMemberAccess(xParam, this.PropInfo);
            var selector   = Expression.Lambda(accessProp, xParam);

            Type propType = this.PropInfo.PropertyType;

            // if foreign key field was nullable
            return(iq => iq.WhereIn(selector, this.keySet, propType));
        }
Esempio n. 14
0
        /// <summary>
        /// Get containers by ids
        /// </summary>
        /// <typeparam name="T">The type of the resulting containers</typeparam>
        /// <param name="targetType">The content type or summary type of the intended output</param>
        /// <param name="ids">The ItemIds of the containers to fetch</param>
        /// <returns></returns>
        public IEnumerable <T> Get <T>(Type targetType, IEnumerable <ItemId> ids) where T : class
        {
            bool isSummary = typeof(Summary).IsAssignableFrom(targetType);

            using (var dataSource = DataSourceFactory.Create(isSummary))
            {
                foreach (var idg in ids.GroupBy(ii => ii.Type))
                {
                    if (idg.Count() > MaximumIdBatchSize)
                    {
                        throw new ArgumentException("Request for too many ids at once, request in batches of maximum size " + MaximumIdBatchSize);
                    }

                    var qed = new QueryEventData <IQueryable>
                    {
                        QueryBody = (Func <IQueryable, IQueryable>)ReflectionX.InvokeGenericMethod(this, "GetIdsQuery", idg.Key, idg.Select(ii => ii.Id)),
                        Source    = dataSource.GetSource(idg.Key),
                        Ids       = ids
                    };

                    qed = EventHub.Instance.ProcessEvent(isSummary ? "Repository.Get.Summaries.Ids" : "Repository.Get.Items.Ids", this, qed).Data as QueryEventData <IQueryable>;

                    if (qed.EnumSource != null)
                    {
                        foreach (var res in qed.EnumSource)
                        {
                            yield return(res as T);
                        }
                    }
                    else
                    {
                        foreach (var res in qed.QueryBody(qed.Source).AsFacade <T>())
                        {
                            yield return(res);
                        }
                    }
                }
            }
        }
Esempio n. 15
0
 /// <summary>
 /// Apply a sort to a result row list based on the settings in this FieldFilter
 /// </summary>
 /// <param name="source">The result row list</param>
 /// <returns>The sorted result row list</returns>
 public override IEnumerable <Tuple <object, Summary> > ApplySort(IEnumerable <Tuple <object, Summary> > source)
 {
     return((IEnumerable <Tuple <object, Summary> >)ReflectionX.InvokeGenericMethod(this, "ApplySort", false, mi => true, new Type[] { PropInfo.PropertyType }, source));
 }
Esempio n. 16
0
        /// <summary>
        /// Get a list of container x summary tuples where the content is one of the a list of content types, filtered by container and
        /// summary filters
        /// </summary>
        /// <param name="contentTypes">The allowed content types</param>
        /// <param name="containerFilters">The filters operating on containers</param>
        /// <param name="summaryFilters">The filters operating on summaries</param>
        /// <returns></returns>
        public List <Tuple <object, Summary> > GetFilterSummaries(List <Type> contentTypes, List <ListFilter> containerFilters, List <ListFilter> summaryFilters)
        {
            // Containers

            var  showContFields = new List <PropertyInfo>();
            Type containerType  = typeof(object);

            // find most general common type of all ApplicableTypes of filters.  If none exists, return empty list.
            foreach (var filt in containerFilters.Where(f => f.Active))
            {
                if (containerType.IsAssignableFrom(filt.ApplicableType))
                {
                    containerType = filt.ApplicableType;
                }
                else
                {
                    return(new List <Tuple <object, Summary> >());
                }
            }

            if (contentTypes == null || contentTypes.Count == 0)
            {
                contentTypes = ContentTypeHierarchy.AllContentTypes.ToList();
            }
            else
            {
                contentTypes = contentTypes
                               .SelectMany(t => ContentTypeHierarchy.ContentSubtypes.ContainsKey(t)
                                     ? ContentTypeHierarchy.ContentSubtypes[t].Concat(t)
                                     : new List <Type> {
                    t
                })
                               .Distinct()
                               .ToList();
            }

            // content types must be contained within container type
            contentTypes = contentTypes.Where(ct => containerType.IsAssignableFrom(Collator.Instance.ContainerType(ct))).ToList();
            if (contentTypes.Count == 0)
            {
                return(new List <Tuple <object, Summary> >());
            }

            var containers = ((IEnumerable <object>)ReflectionX.InvokeGenericMethod(this, "GetFilteredContainers",
                                                                                    containerType, contentTypes, containerFilters.Where(f => f.Active).ToList()));

            // Summaries
            var showFields = new List <PropertyInfo>();

            Type summaryType = typeof(Summary);

            foreach (var filt in summaryFilters)
            {
                if (summaryType.IsAssignableFrom(filt.ApplicableType))
                {
                    summaryType = filt.ApplicableType;
                }
                else
                {
                    return(new List <Tuple <object, Summary> >());
                }
            }

            var results = (List <Tuple <object, Summary> >)ReflectionX.InvokeGenericMethod(this, "FilterContainers",
                                                                                           summaryType, containers, summaryFilters.Where(f => f.Active).ToList());

            var orderFilter = containerFilters.FirstOrDefault(cf => cf.Sort != 0);

            if (orderFilter == null)
            {
                orderFilter = summaryFilters.FirstOrDefault(sf => sf.Sort != 0);
            }
            if (orderFilter != null)
            {
                results = orderFilter.ApplySort(results).ToList();
            }

            return(results);
        }
Esempio n. 17
0
 /// <summary>
 /// Get new item whose data address is given by a specified route
 /// </summary>
 /// <param name="type">type of new item</param>
 /// <param name="rd">the specified route</param>
 /// <returns>the new item</returns>
 public object GetNew(Type type, RouteData rd)
 {
     return(ReflectionX.InvokeGenericMethod(this, "GetNew",
                                            mi => mi.GetParameters().First().ParameterType == typeof(RouteData),
                                            new Type[] { type }, rd));
 }
Esempio n. 18
0
 /// <summary>
 /// Get some summaries by their ids
 /// </summary>
 /// <param name="returnType">type of items returned by repository</param>
 /// <param name="summaryType">type of summary these will produce</param>
 /// <param name="targetType">the type of which these are summaries</param>
 /// <param name="ids">ids of items</param>
 /// <returns>summary details of items in containers</returns>
 public IEnumerable <object> Get(Type returnType, Type summaryType, Type targetType, IEnumerable <object> ids)
 {
     return((IEnumerable <object>)ReflectionX.InvokeGenericMethod(this, "Get", mi => mi.GetParameters()[2].ParameterType == typeof(IEnumerable <object>), new Type[] { returnType }, summaryType, targetType, ids));
 }
Esempio n. 19
0
 /// <summary>
 /// Get new item whose address is given
 /// </summary>
 /// <param name="a">the address to create it at</param>
 /// <returns>the new item</returns>
 public object GetNew(Address a)
 {
     return(ReflectionX.InvokeGenericMethod(this, "GetNew",
                                            mi => mi.GetParameters().First().ParameterType == typeof(Address) && mi.GetGenericArguments().Length == 1,
                                            new Type[] { a.Type }, a));
 }
Esempio n. 20
0
 /// <summary>
 /// Get an item's summary by id
 /// </summary>
 /// <param name="returnType">type returned by repository</param>
 /// <param name="summaryType">type of summary this will produce</param>
 /// <param name="targetType">the type of which this is a summary</param>
 /// <param name="id">id of item</param>
 /// <returns>summary details of item in a container</returns>
 public object Get(Type returnType, Type summaryType, Type targetType, object id)
 {
     return(ReflectionX.InvokeGenericMethod(this, "Get", returnType, summaryType, targetType, id));
 }