Example #1
0
        public async Task<ActionResult> Query(DateTimeOffset? from, DateTimeOffset? to, string name, string tagger, string[] ob, int? ps, int? pn)
        {
            // Convert the simple filtering criteria:
            TagQuery tq = new TagQuery(from, to, name, tagger);

            // Is ordering desired? Possibly paging?
            if (ob != null)
            {
                // Convert the ordering instructions "column:asc,column:desc,...":
                var orderBy = new ReadOnlyCollection<OrderByApplication<TagOrderBy>>(
                    (
                        from o in ob
                        let spl = o.Split(':')
                        let tgob = convertTagOrderBy(spl[0])
                        let dir = spl.Length > 1 ? convertDirection(spl[1]) : defaultOrderBy(tgob)
                        select new OrderByApplication<TagOrderBy>(tgob, dir)
                    ).ToArray(ob.Length)
                );

                // Determine if paging is requested and is valid:
                if (ps.HasValue && pn.HasValue && ps.Value > 0 && pn > 0)
                {
                    // Paging looks valid:
                    var results = await cms.tgrepo.SearchTags(tq, orderBy, new PagingRequest(pn.Value, ps.Value));

                    return Json(new
                    {
                        results = new
                        {
                            count = results.TotalCount,
                            pageCount = results.PageCount,
                            pageNumber = results.Paging.PageNumber,
                            pageSize = results.Paging.PageSize,
                            isFirstPage = results.IsFirstPage,
                            isLastPage = results.IsLastPage,
                            orderedBy = results.OrderedBy.SelectAsArray(x => new { dir = convertDirection(x.Direction), by = convertTagOrderBy(x.OrderBy) }),
                            page = results.Collection.SelectAsArray(tg => tg.ToJSON())
                        }
                    }, JsonRequestBehavior.AllowGet);
                }
                else
                {
                    // No paging or invalid paging parameters:
                    var results = await cms.tgrepo.SearchTags(tq, orderBy);

                    return Json(new
                    {
                        results = new
                        {
                            count = results.Collection.Count,
                            orderedBy = results.OrderedBy.SelectAsArray(x => new { dir = convertDirection(x.Direction), by = convertTagOrderBy(x.OrderBy) }),
                            items = results.Collection.SelectAsArray(tg => tg.ToJSON())
                        }
                    }, JsonRequestBehavior.AllowGet);
                }
            }
            else
            {
                // No ordering or paging:
                var results = await cms.tgrepo.SearchTags(tq);

                return Json(new
                {
                    results = new
                    {
                        count = results.Collection.Count,
                        items = results.Collection.SelectAsArray(tg => tg.ToJSON())
                    }
                }, JsonRequestBehavior.AllowGet);
            }
        }
        public async Task<PagedQueryResponse<TagQuery, Tag, TagOrderBy>> SearchTags(TagQuery query, ReadOnlyCollection<OrderByApplication<TagOrderBy>> orderBy, PagingRequest paging)
        {
            // Filter the results:
            List<Tag> tags = await searchTags(query);
            // Order the results:
            IEnumerable<Tag> ordered = orderResults(tags, orderBy);
            tags = ordered.ToList(tags.Count);
            // Page the results:
            List<Tag> page = tags.Skip(paging.PageIndex * paging.PageSize).Take(paging.PageSize).ToList(paging.PageSize);

            return new PagedQueryResponse<TagQuery, Tag, TagOrderBy>(query, new ReadOnlyCollection<Tag>(page), orderBy, paging, tags.Count);
        }
        public async Task<FullQueryResponse<TagQuery, Tag>> SearchTags(TagQuery query)
        {
            List<Tag> tags = await searchTags(query);

            // Return our read-only collection:
            return new FullQueryResponse<TagQuery, Tag>(query, new ReadOnlyCollection<Tag>(tags));
        }
        public async Task<OrderedFullQueryResponse<TagQuery, Tag, TagOrderBy>> SearchTags(TagQuery query, ReadOnlyCollection<OrderByApplication<TagOrderBy>> orderBy)
        {
            // Filter the results:
            List<Tag> tags = await searchTags(query);
            // Order the results:
            IEnumerable<Tag> ordered = orderResults(tags, orderBy);
            tags = ordered.ToList(tags.Count);

            return new OrderedFullQueryResponse<TagQuery, Tag, TagOrderBy>(query, new ReadOnlyCollection<Tag>(tags), orderBy);
        }
        private async Task<List<Tag>> searchTags(TagQuery query)
        {
            // First, filter tags by name so that we don't have read them all:
            IEnumerable<TagName> filteredTagNames = getAllTagNames();
            if (query.Name != null)
                filteredTagNames = filteredTagNames.Where(tn => tn.ToString().StartsWith(query.Name));

            DateTimeOffset rightNow = DateTimeOffset.Now;

            List<Tag> tags = new List<Tag>();
            foreach (TagName tagName in filteredTagNames)
            {
                var eid = await getTagIDByName(tagName).ConfigureAwait(continueOnCapturedContext: false);
                if (eid.HasErrors) continue;

                var etg = await getTag(eid.Value).ConfigureAwait(continueOnCapturedContext: false);
                if (etg.HasErrors) continue;

                Tag tg = etg.Value;

                // Filter by tagger name:
                if ((query.Tagger != null) &&
                    (!tg.Tagger.StartsWith(query.Tagger)))
                    continue;

                // Filter by date range:
                if (!((!query.DateFrom.HasValue || (tg.DateTagged >= query.DateFrom.Value)) &&
                       (!query.DateTo.HasValue || (tg.DateTagged <= query.DateTo.Value))))
                    continue;

                tags.Add(tg);
            }

            return tags;
        }