lib/graphql/pagination/relation_connection.rb in graphql-1.13.2 vs lib/graphql/pagination/relation_connection.rb in graphql-1.13.3
- old
+ new
@@ -33,11 +33,11 @@
true
elsif first
if @nodes && @nodes.count < first
false
else
- relation_larger_than(sliced_nodes, first)
+ relation_larger_than(sliced_nodes, @sliced_nodes_offset, first)
end
else
false
end
end
@@ -52,13 +52,14 @@
end
private
# @param relation [Object] A database query object
+ # @param _initial_offset [Integer] The number of items already excluded from the relation
# @param size [Integer] The value against which we check the relation size
# @return [Boolean] True if the number of items in this relation is larger than `size`
- def relation_larger_than(relation, size)
+ def relation_larger_than(relation, _initial_offset, size)
relation_count(set_limit(relation, size + 1)) == size + 1
end
# @param relation [Object] A database query object
# @return [Integer, nil] The offset value, or nil if there isn't one
@@ -109,36 +110,57 @@
else
relation
end
end
- # Apply `before` and `after` to the underlying `items`,
- # returning a new relation.
- def sliced_nodes
- @sliced_nodes ||= begin
- paginated_nodes = items
-
+ def calculate_sliced_nodes_parameters
+ if defined?(@sliced_nodes_limit)
+ return
+ else
if after_offset
previous_offset = relation_offset(items) || 0
- paginated_nodes = set_offset(paginated_nodes, previous_offset + after_offset)
+ relation_offset = previous_offset + after_offset
end
if before_offset && after_offset
if after_offset < before_offset
# Get the number of items between the two cursors
space_between = before_offset - after_offset - 1
- paginated_nodes = set_limit(paginated_nodes, space_between)
+ relation_limit = space_between
else
- # TODO I think this is untested
# The cursors overextend one another to an empty set
- paginated_nodes = null_relation(paginated_nodes)
+ @sliced_nodes_null_relation = true
end
elsif before_offset
# Use limit to cut off the tail of the relation
- paginated_nodes = set_limit(paginated_nodes, before_offset - 1)
+ relation_limit = before_offset - 1
end
+ @sliced_nodes_limit = relation_limit
+ @sliced_nodes_offset = relation_offset || 0
+ end
+ end
+
+ # Apply `before` and `after` to the underlying `items`,
+ # returning a new relation.
+ def sliced_nodes
+ @sliced_nodes ||= begin
+ calculate_sliced_nodes_parameters
+ paginated_nodes = items
+
+ if @sliced_nodes_null_relation
+ paginated_nodes = null_relation(paginated_nodes)
+ else
+ if @sliced_nodes_limit
+ paginated_nodes = set_limit(paginated_nodes, @sliced_nodes_limit)
+ end
+
+ if @sliced_nodes_offset
+ paginated_nodes = set_offset(paginated_nodes, @sliced_nodes_offset)
+ end
+ end
+
paginated_nodes
end
end
# @return [Integer, nil]
@@ -153,36 +175,41 @@
# Apply `first` and `last` to `sliced_nodes`,
# returning a new relation
def limited_nodes
@limited_nodes ||= begin
- paginated_nodes = sliced_nodes
- previous_limit = relation_limit(paginated_nodes)
+ calculate_sliced_nodes_parameters
+ if @sliced_nodes_null_relation
+ # it's an empty set
+ return sliced_nodes
+ end
+ relation_limit = @sliced_nodes_limit
+ relation_offset = @sliced_nodes_offset
- if first && (previous_limit.nil? || previous_limit > first)
+ if first && (relation_limit.nil? || relation_limit > first)
# `first` would create a stricter limit that the one already applied, so add it
- paginated_nodes = set_limit(paginated_nodes, first)
+ relation_limit = first
end
if last
- if (lv = relation_limit(paginated_nodes))
- if last <= lv
+ if relation_limit
+ if last <= relation_limit
# `last` is a smaller slice than the current limit, so apply it
- offset = (relation_offset(paginated_nodes) || 0) + (lv - last)
- paginated_nodes = set_offset(paginated_nodes, offset)
- paginated_nodes = set_limit(paginated_nodes, last)
+ relation_offset += (relation_limit - last)
+ relation_limit = last
end
else
# No limit, so get the last items
- sliced_nodes_count = relation_count(@sliced_nodes)
- offset = (relation_offset(paginated_nodes) || 0) + sliced_nodes_count - [last, sliced_nodes_count].min
- paginated_nodes = set_offset(paginated_nodes, offset)
- paginated_nodes = set_limit(paginated_nodes, last)
+ sliced_nodes_count = relation_count(sliced_nodes)
+ relation_offset += (sliced_nodes_count - [last, sliced_nodes_count].min)
+ relation_limit = last
end
end
- @paged_nodes_offset = relation_offset(paginated_nodes)
- paginated_nodes
+ @paged_nodes_offset = relation_offset
+ paginated_nodes = items
+ paginated_nodes = set_offset(paginated_nodes, relation_offset)
+ set_limit(paginated_nodes, relation_limit)
end
end
# Load nodes after applying first/last/before/after,
# returns an array of nodes