Fix pagination of repositories

Fixes #1725
This commit is contained in:
Joseph Schorr 2016-08-15 16:11:45 -04:00
parent 1c4d3326c2
commit 7f5b536ddb
5 changed files with 70 additions and 39 deletions

View file

@ -149,7 +149,8 @@ class RepositoryList(ApiResource):
user = get_authenticated_user()
username = user.username if user else None
repo_query = None
next_page_token = None
repos = None
# Lookup the requested repositories (either starred or non-starred.)
if parsed_args['starred']:
@ -157,24 +158,29 @@ class RepositoryList(ApiResource):
# No repositories should be returned, as there is no user.
abort(400)
repo_query = model.repository.get_user_starred_repositories(user)
# Return the full list of repos starred by the current user.
repos = list(model.repository.get_user_starred_repositories(user))
elif parsed_args['namespace']:
# Repositories filtered by namespace do not need pagination (their results are fairly small),
# so we just do the lookup directly.
repos = list(model.repository.get_visible_repositories(username=username,
include_public=parsed_args['public'],
namespace=parsed_args['namespace']))
else:
# Determine the starting offset for pagination. Note that we don't use the normal
# model.modelutil.paginate method here, as that does not operate over UNION queries, which
# get_visible_repositories will return if there is a logged-in user (for performance reasons).
#
# Also note the +1 on the limit, as paginate_query uses the extra result to determine whether
# there is a next page.
start_id = model.modelutil.pagination_start(page_token)
repo_query = model.repository.get_visible_repositories(username=username,
include_public=parsed_args['public'],
namespace=parsed_args['namespace'])
start_id=start_id,
limit=REPOS_PER_PAGE+1)
# Note: We only limit repositories when there isn't a namespace or starred filter, as they
# result in far smaller queries.
if not parsed_args['namespace'] and not parsed_args['starred']:
# TODO: Fix pagination to support union queries and then remove this hack.
repo_query = model.repository.get_visible_repositories(None,
include_public=parsed_args['public'])
repos, next_page_token = model.modelutil.paginate(repo_query, RepositoryTable,
page_token=page_token, limit=REPOS_PER_PAGE,
id_alias='rid')
else:
repos = list(repo_query)
next_page_token = None
repos, next_page_token = model.modelutil.paginate_query(repo_query, limit=REPOS_PER_PAGE,
id_alias='rid')
# Collect the IDs of the repositories found for subequent lookup of popularity
# and/or last modified.