Add ID-based pagination to logs using new decorators and an encrypted token

Fixes #599
This commit is contained in:
Joseph Schorr 2015-12-22 09:05:17 -05:00
parent af77b92bcf
commit bd0a098282
8 changed files with 110 additions and 36 deletions

View file

@ -95,4 +95,4 @@ config = Config()
# moving the minimal number of things to _basequery
# TODO document the methods and modules for each one of the submodules below.
from data.model import (blob, build, image, log, notification, oauth, organization, permission,
repository, storage, tag, team, token, user, release)
repository, storage, tag, team, token, user, release, modelutil)

View file

@ -41,9 +41,7 @@ def get_aggregated_logs(start_time, end_time, performer=None, repository=None, n
return query.group_by(date, LogEntry.kind)
def list_logs(start_time, end_time, performer=None, repository=None, namespace=None, page=None,
count=None):
def get_logs_query(start_time, end_time, performer=None, repository=None, namespace=None):
Performer = User.alias()
selections = [LogEntry, Performer]
@ -52,10 +50,7 @@ def list_logs(start_time, end_time, performer=None, repository=None, namespace=N
.join(Performer, JOIN_LEFT_OUTER,
on=(LogEntry.performer == Performer.id).alias('performer')))
if page and count:
query = query.paginate(page, count)
return list(query.order_by(LogEntry.datetime.desc()))
return query
def log_action(kind_name, user_or_organization_name, performer=None, repository=None,

29
data/model/modelutil.py Normal file
View file

@ -0,0 +1,29 @@
def paginate(query, model, descending=False, page_token=None, limit=50):
""" Paginates the given query using an ID range, starting at the optional page_token.
Returns a *list* of matching results along with an unencrypted page_token for the
next page, if any. If descending is set to True, orders by the ID descending rather
than ascending.
"""
query = query.limit(limit + 1)
if descending:
query = query.order_by(model.id.desc())
else:
query = query.order_by(model.id)
if page_token is not None:
start_id = page_token.get('start_id')
if start_id is not None:
if descending:
query = query.where(model.id <= start_id)
else:
query = query.where(model.id >= start_id)
results = list(query)
page_token = None
if len(results) > limit:
page_token = {
'start_id': results[limit].id
}
return results[0:limit], page_token