private static JsonObject CreatePaginationConnection()

in src/Core/Resolvers/SqlPaginationUtil.cs [84:168]


        private static JsonObject CreatePaginationConnection(JsonElement root, PaginationMetadata paginationMetadata, GroupByMetadata? groupByMetadata = null)
        {
            // Maintains the connection JSON object *Connection
            JsonObject connection = new();

            // in dw we wrap array with "" and hence jsonValueKind is string instead of array.
            if (root.ValueKind is JsonValueKind.String)
            {
                using JsonDocument document = JsonDocument.Parse(root.GetString()!);
                root = document.RootElement.Clone();
            }

            // If the request includes either hasNextPage or endCursor then to correctly return those
            // values we need to determine the correct pagination logic
            bool isPaginationRequested = paginationMetadata.RequestedHasNextPage || paginationMetadata.RequestedEndCursor;

            IEnumerable<JsonElement> rootEnumerated = root.EnumerateArray();
            int returnedElementCount = rootEnumerated.Count();
            bool hasExtraElement = false;

            if (isPaginationRequested)
            {
                // structure.Limit() is first + 1 for paginated queries where hasNextPage or endCursor is requested
                hasExtraElement = returnedElementCount == paginationMetadata.Structure!.Limit();
                if (hasExtraElement)
                {
                    // In a pagination scenario where we have an extra element, this element
                    // must be removed since it was only used to determine if there are additional
                    // records after those requested.
                    rootEnumerated = rootEnumerated.Take(rootEnumerated.Count() - 1);
                    --returnedElementCount;
                }
            }

            if (paginationMetadata.RequestedHasNextPage)
            {
                // add hasNextPage to connection elements
                connection.Add(QueryBuilder.HAS_NEXT_PAGE_FIELD_NAME, hasExtraElement);
            }

            if (paginationMetadata.RequestedItems)
            {
                if (hasExtraElement)
                {
                    // use rootEnumerated to make the *Connection.items since the last element of rootEnumerated
                    // is removed if the result has an extra element
                    connection.Add(QueryBuilder.PAGINATION_FIELD_NAME, JsonSerializer.Serialize(rootEnumerated.ToArray()));
                }
                else
                {
                    // if the result doesn't have an extra element, just return the dbResult for *Connection.items
                    connection.Add(QueryBuilder.PAGINATION_FIELD_NAME, root.ToString()!);
                }
            }

            if (groupByMetadata is not null && paginationMetadata.RequestedGroupBy == true)
            {

                connection.Add(QueryBuilder.GROUP_BY_FIELD_NAME, GenerateGroupByObjectFromResult(groupByMetadata, rootEnumerated));
            }

            if (paginationMetadata.RequestedEndCursor)
            {
                // Note: if we do not add endCursor to the connection but it was in the request, its value will
                // automatically be populated as null.
                // Need to validate we have an extra element, because otherwise there is no next page
                // and endCursor should be left as null.
                if (returnedElementCount > 0 && hasExtraElement)
                {
                    JsonElement lastElemInRoot = rootEnumerated.ElementAtOrDefault(returnedElementCount - 1);
                    connection.Add(QueryBuilder.PAGINATION_TOKEN_FIELD_NAME,
                        MakeCursorFromJsonElement(
                            lastElemInRoot,
                            paginationMetadata.Structure!.PrimaryKey(),
                            paginationMetadata.Structure!.OrderByColumns,
                            paginationMetadata.Structure!.EntityName,
                            paginationMetadata.Structure!.DatabaseObject.SchemaName,
                            paginationMetadata.Structure!.DatabaseObject.Name,
                            paginationMetadata.Structure!.MetadataProvider,
                            paginationMetadata.RequestedGroupBy));
                }
            }

            return connection;
        }