Пример #1
0

        
Пример #2
0
        private async Task <object> ResolveConnection(ResolveConnectionContext <object> context, IQueryBuilder <Person> personQueryBuilder)
        {
            _personRepository.Context = context;

            var first             = context.First;
            var afterCursor       = Cursor.FromCursor <DateTime?>(context.After);
            var last              = context.Last;
            var beforeCursor      = Cursor.FromCursor <DateTime?>(context.Before);
            var cancellationToken = context.CancellationToken;

            var getPersonTask          = GetPeople(first, afterCursor, last, beforeCursor, cancellationToken);
            var getHasNextPageTask     = GetHasNextPage(first, afterCursor, cancellationToken);
            var getHasPreviousPageTask = GetHasPreviousPage(last, beforeCursor, cancellationToken);
            var totalCountTask         = _personRepository.GetTotalCount(cancellationToken);

            await Task.WhenAll(getPersonTask, getHasNextPageTask, getHasPreviousPageTask, totalCountTask);

            var people          = getPersonTask.Result;
            var hasNextPage     = getHasNextPageTask.Result;
            var hasPreviousPage = getHasPreviousPageTask.Result;
            var totalCount      = totalCountTask.Result;

            var(firstCursor, lastCursor) = Cursor.GetFirstAndLastCursor(people, x => x.CreateDate);

            return(new Connection <Person>()
            {
                Edges = people
                        .Select(x =>
                                new Edge <Person>()
                {
                    Cursor = Cursor.ToCursor(x.CreateDate),
                    Node = x
                })
                        .ToList(),
                PageInfo = new PageInfo()
                {
                    HasNextPage = hasNextPage,
                    HasPreviousPage = hasPreviousPage,
                    StartCursor = firstCursor,
                    EndCursor = lastCursor,
                },
                TotalCount = totalCount,
            });
        }
Пример #3
0
        private async static Task <object> ResolveCountriesConnection(
            ICountryRepository countryRepository,
            ResolveConnectionContext <object> context)
        {
            var first             = context.First;
            var afterCode         = Cursor.FromCursor <string>(context.After);
            var last              = context.Last;
            var beforeCode        = Cursor.FromCursor <string>(context.Before);
            var cancellationToken = context.CancellationToken;

            var getCountriesTask       = GetCountries(countryRepository, first, afterCode, last, afterCode, cancellationToken);
            var getHasNextPageTask     = GetHasNextPage(countryRepository, first, afterCode, cancellationToken);
            var getHasPreviousPageTask = GetHasPreviousPage(countryRepository, last, beforeCode, cancellationToken);
            var totalCountTask         = countryRepository.GetTotalCount(cancellationToken);

            await Task.WhenAll(getCountriesTask, getHasNextPageTask, getHasPreviousPageTask, totalCountTask);

            var countries       = getCountriesTask.Result;
            var hasNextPage     = getHasNextPageTask.Result;
            var hasPreviousPage = getHasPreviousPageTask.Result;
            var totalCount      = totalCountTask.Result;

            var(firstCursor, lastCursor) = Cursor.GetFirstAndLastCursor(countries, x => x.Code);

            return(new Connection <Country>
            {
                Edges = countries
                        .Select(x =>
                                new Edge <Country>
                {
                    Cursor = Cursor.ToCursor(x.Code),
                    Node = x
                })
                        .ToList(),
                PageInfo = new PageInfo
                {
                    HasNextPage = hasNextPage,
                    HasPreviousPage = hasPreviousPage,
                    StartCursor = firstCursor,
                    EndCursor = lastCursor
                },
                TotalCount = totalCount
            });
        }
Пример #4
0
        /// <summary>
        /// Gets Connection.
        /// </summary>
        /// <typeparam name="T">T item.</typeparam>
        /// <param name="context">Connection context.</param>
        /// <param name="enumerable">An IEnumerable of T items.</param>
        /// <param name="defaultPageLimit">Default page limit.</param>
        /// <returns></returns>
        public static async Task <Connection <T> > GetConnectionAsync <T>(this ResolveConnectionContext <object> context, IEnumerable <T> enumerable, int defaultPageLimit = 10)
        {
            // Ref: https://graphql.org/learn/pagination/

            var list = enumerable.ToList();

            var total = list.Count;
            int skip  = 0;
            int take  = defaultPageLimit;

            var edges = list.Select(TransformToEdge).ToList();

            if (!string.IsNullOrEmpty(context.After))
            {
                skip = GetIndex(context.After) + 1;
            }

            if (context.First.HasValue)
            {
                take = context.First.Value;
            }

            var hasNextPage = total > skip + take;

            var filtered = edges.Skip(skip).Take(take).ToList();

            var first = filtered.FirstOrDefault().GetCursor();

            var connection = new Connection <T>
            {
                TotalCount = total,
                Edges      = filtered,
                PageInfo   = new PageInfo
                {
                    StartCursor     = first,
                    EndCursor       = filtered.LastOrDefault().GetCursor(),
                    HasNextPage     = hasNextPage,
                    HasPreviousPage = GetIndex(first) > 0
                }
            };

            return(await Task.FromResult(connection));
        }
Пример #5
0
        public static Connection <TSource> ToConnection <TSource, TParent>(
            IEnumerable <TSource> slice,
            ResolveConnectionContext <TParent> context,
            int sliceStartIndex,
            int totalCount,
            bool strictCheck = true
            )
        {
            var sliceList = slice as IList <TSource> ?? slice.ToList();

            var metrics = ArraySliceMetrics.Create(
                sliceList,
                context,
                sliceStartIndex,
                totalCount,
                strictCheck
                );

            var edges = metrics.Slice.Select((item, i) => new Edge <TSource>
            {
                Node   = item,
                Cursor = OffsetToCursor(metrics.StartOffset + i)
            })
                        .ToList();

            var firstEdge = edges.FirstOrDefault();
            var lastEdge  = edges.LastOrDefault();

            return(new Connection <TSource>
            {
                Edges = edges,
                TotalCount = totalCount,
                PageInfo = new PageInfo
                {
                    StartCursor = firstEdge?.Cursor,
                    EndCursor = lastEdge?.Cursor,
                    HasPreviousPage = metrics.HasPrevious,
                    HasNextPage = metrics.HasNext,
                }
            });
        }
        public static Connection <TSource> ToConnection <TSource, TParent>(this IEnumerable <TSource> source,
                                                                           ResolveConnectionContext <TParent> context, int totalCount)
        {
            // TODO: Implement paging logic
            var items = source.Select(x => new Edge <TSource>
            {
                Node = x
            }).ToList();

            var after  = context.After;
            var before = context.Before;
            var first  = context.First;
            var last   = context.Last;

            return(new Connection <TSource>
            {
                Edges = items,
                PageInfo = new PageInfo
                {
                }
            });
        }
Пример #7
0
        public static async Task <Connection <T> > ToConnection <T, TSource>(
            this Query query,
            ResolveConnectionContext <TSource> context,
            Func <T, string> cursorSelector)
            where T : class
            where TSource : class
        {
            var xQuery = query as XQuery;

            if (xQuery == null)
            {
                throw new ArgumentException("Make sure the query object is instantiated from a queryFactory", nameof(query));
            }

            if (!xQuery.Clauses.Any(q => q.Component == "select"))
            {
                xQuery.Select("*");
            }

            var statement = xQuery.Compiler.Compile(
                xQuery.Slice(
                    context.After?.FromCursor().ToString(),
                    context.First.GetValueOrDefault(0),
                    context.Before?.FromCursor().ToString(),
                    context.Last.GetValueOrDefault(0)));

            // Some custom mapping logic. Until the `RowNumber` field is found, all fields are considered
            // to be part of `T`. This methodology works because the last field selected is in fact the
            // `RowNumber` field (through the Slice function).
            var totalCount = 0;

            var dictionary = xQuery.Connection.Query(
                sql: statement.Sql,
                param: statement.NamedBindings,
                map: (T t, (long rowNumber, long rowCount)meta) => {
                totalCount = (int)meta.rowCount;
                return(new KeyValuePair <long, T>(meta.rowNumber, t));
            },
Пример #8
0
        public ScopedContextBase()
        {
            _scopedServiceProviderMock = new Mock <IServiceProvider>(MockBehavior.Strict);
            _scopedServiceProvider     = _scopedServiceProviderMock.Object;
            _scopedServiceScopeMock    = new Mock <IServiceScope>(MockBehavior.Strict);
            _scopedServiceScopeMock.Setup(x => x.ServiceProvider).Returns(_scopedServiceProvider).Verifiable();
            _scopedServiceScopeMock.Setup(x => x.Dispose()).Verifiable();
            var scopedServiceScope = _scopedServiceScopeMock.Object;

            _serviceScopeFactoryMock = new Mock <IServiceScopeFactory>(MockBehavior.Strict);
            _serviceScopeFactoryMock.Setup(x => x.CreateScope()).Returns(scopedServiceScope).Verifiable();
            var serviceScopeFactory = _serviceScopeFactoryMock.Object;

            _requestServicesMock = new Mock <IServiceProvider>(MockBehavior.Strict);
            _requestServicesMock.Setup(x => x.GetService(It.Is <Type>(t => t == typeof(IServiceScopeFactory)))).Returns(serviceScopeFactory).Verifiable();
            var requestServices = _requestServicesMock.Object;

            _scopedContext = new ResolveFieldContext
            {
                RequestServices = requestServices
            };
            _scopedConnectionContext = new ResolveConnectionContext <object>(_scopedContext, false, default);
        }
        public Connection <IContent> CreateIContentConnection(
            ResolveConnectionContext <IContent> context,
            LoaderOptions loaderOptions,
            int defaultPageSize)
        {
            int first = context.PageSize ?? defaultPageSize;

            int.TryParse(context.After, out int after);

            var items = GetChildren(
                context.Source.ContentLink,
                loaderOptions,
                after,
                first,
                out bool hasNextPage
                );

            var pageInfo  = CreatePageInfo(first, after, hasNextPage);
            int endCursor = int.Parse(pageInfo.EndCursor);

            var edges = new List <Edge <IContent> >();

            for (int i = 0; i < items.Count(); i++)
            {
                edges.Add(new Edge <IContent> {
                    Node = items.ElementAt(i), Cursor = ((endCursor - first) + i + 1).ToString()
                });
            }

            return(new Connection <IContent>
            {
                TotalCount = items.Count(),
                Edges = edges,
                PageInfo = pageInfo
            });
        }
Пример #10
0
 public static Connection <TSource> ToConnection <TSource, TParent>(
     IEnumerable <TSource> items,
     ResolveConnectionContext <TParent> context)
 {
     return(ToConnection(items, context, 0, items.Count()));
 }
        /*
         * This is just a mock extension. Modify to suit your own needs.
         */
        public static async Task <Connection <TResult> > ToConnection <TResult, TSource>(
            this IEnumerable <TResult> enumerable,
            ResolveConnectionContext <TSource> context)
            where TResult : IId
            where TSource : class
        {
            await Task.Delay(8);    // Again, we have some network activity going on here :)

            IList <TResult> resultset;

            // In this if else tree we select the pages we want
            if (!string.IsNullOrWhiteSpace(context.After))
            {
                resultset = enumerable
                            .SkipWhile(q => q.Id != context.After.FromCursor())
                            .Skip(1) // We skip an additional one because other the 'after' cursor would be included in the results.
                            .Take(context.First.GetValueOrDefault(context.PageSize ?? 10))
                            .ToList();
            }
            else if (!string.IsNullOrWhiteSpace(context.Before))
            {
                throw new NotImplementedException();
            }
            else if (context.First != null)
            {
                resultset = enumerable
                            .Take(context.First.Value)
                            .ToList();
            }
            else if (context.Last != null)
            {
                throw new NotImplementedException();
            }
            else
            {
                // We're out of options. Return a default selection
                resultset = enumerable
                            .Take(context.PageSize ?? 10)
                            .ToList();
            }


            // The rest of this method is used to construct the connection we're returning
            var edges = resultset.Select((item, i) => new Edge <TResult>
            {
                Node   = item,
                Cursor = item?.Id.ToCursor()
            })
                        .ToList();

            var connection = new Connection <TResult>
            {
                Edges      = edges,
                TotalCount = enumerable.Count(),
                PageInfo   = new PageInfo
                {
                    StartCursor     = edges.FirstOrDefault()?.Cursor,
                    EndCursor       = edges.LastOrDefault()?.Cursor,
                    HasPreviousPage = true,
                    HasNextPage     = true,
                }
            };

            return(connection);
        }
Пример #12
0

        
Пример #13
0

        
Пример #14
0
 public ArraySliceMetrics(
     IList <TSource> slice,
     ResolveConnectionContext <TParent> context)
     : this(slice, context, 0, slice.Count)
 {
 }