Skip to content

Commit

Permalink
Merge pull request #2522 from ckan/revision-list-limit
Browse files Browse the repository at this point in the history
#1431 Add paging to revision_list
  • Loading branch information
wardi committed Sep 3, 2015
2 parents 29d8a51 + bf64b56 commit c357989
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 4 deletions.
49 changes: 45 additions & 4 deletions ckan/logic/action/get.py
Expand Up @@ -187,17 +187,58 @@ def current_package_list_with_resources(context, data_dict):


def revision_list(context, data_dict):
'''Return a list of the IDs of the site's revisions.
'''Return a list of the IDs of the site's revisions. They are sorted with
the newest first.
:rtype: list of strings
Since the results are limited to 50 IDs, you can page through them using
parameter ``since_id``.
:param since_id: the revision ID after which you want the revisions
:type id: string
:param since_time: the timestamp after which you want the revisions
:type id: string
:param sort: the order to sort the related items in, possible values are
'time_asc', 'time_desc' (default). (optional)
:type sort: string
:rtype: list of revision IDs, limited to 50
'''
model = context['model']
since_id = data_dict.get('since_id')
since_time_str = data_dict.get('since_time')
sort_str = data_dict.get('sort')
PAGE_LIMIT = 50

_check_access('revision_list', context, data_dict)

revs = model.Session.query(model.Revision).all()
return [rev.id for rev in revs]
since_time = None
if since_id:
rev = model.Session.query(model.Revision).get(since_id)
if rev is None:
raise NotFound
since_time = rev.timestamp
elif since_time_str:
try:
from ckan.lib import helpers as h
since_time = h.date_str_to_datetime(since_time_str)
except ValueError:
raise logic.ValidationError('Timestamp did not parse')
revs = model.Session.query(model.Revision)
if since_time:
revs = revs.filter(model.Revision.timestamp > since_time)

sortables = {
'time_asc': model.Revision.timestamp.asc,
'time_desc': model.Revision.timestamp.desc,
}
if sort_str and sort_str not in sortables:
raise logic.ValidationError(
'Invalid sort value. Allowable values: %r' % sortables.keys())
sort_func = sortables.get(sort_str or 'time_desc')
revs = revs.order_by(sort_func())

revs = revs.limit(PAGE_LIMIT)
return [rev_.id for rev_ in revs]


def package_revision_list(context, data_dict):
Expand Down
85 changes: 85 additions & 0 deletions ckan/tests/logic/action/test_get.py
Expand Up @@ -1692,3 +1692,88 @@ def test_tag_list_vocab_not_found(self):
nose.tools.assert_raises(
logic.NotFound,
helpers.call_action, 'tag_list', vocabulary_id='does-not-exist')


class TestRevisionList(helpers.FunctionalTestBase):

@classmethod
def setup_class(cls):
super(TestRevisionList, cls).setup_class()
helpers.reset_db()

# Error cases

def test_date_instead_of_revision(self):
nose.tools.assert_raises(
logic.NotFound,
helpers.call_action,
'revision_list',
since_id='2010-01-01T00:00:00')

def test_date_invalid(self):
nose.tools.assert_raises(
logic.ValidationError,
helpers.call_action,
'revision_list',
since_time='2010-02-31T00:00:00')

def test_revision_doesnt_exist(self):
nose.tools.assert_raises(
logic.NotFound,
helpers.call_action,
'revision_list',
since_id='1234')

def test_sort_param_not_valid(self):
nose.tools.assert_raises(
logic.ValidationError,
helpers.call_action,
'revision_list',
sort='invalid')

# Normal usage

@classmethod
def _create_revisions(cls, num_revisions):
from ckan import model
rev_ids = []
for i in xrange(num_revisions):
rev = model.repo.new_revision()
rev.id = unicode(i)
model.Session.commit()
rev_ids.append(rev.id)
return rev_ids

def test_all_revisions(self):
rev_ids = self._create_revisions(2)
revs = helpers.call_action('revision_list')
# only test the 2 newest revisions, since the system creates one at
# start-up.
eq(revs[:2], rev_ids[::-1])

def test_revisions_since_id(self):
self._create_revisions(4)
revs = helpers.call_action('revision_list', since_id='1')
eq(revs, ['3', '2'])

def test_revisions_since_time(self):
from ckan import model
self._create_revisions(4)

rev1 = model.Session.query(model.Revision).get('1')
revs = helpers.call_action('revision_list',
since_time=rev1.timestamp.isoformat())
eq(revs, ['3', '2'])

def test_revisions_returned_are_limited(self):
self._create_revisions(55)
revs = helpers.call_action('revision_list', since_id='1')
eq(len(revs), 50) # i.e. limited to 50
eq(revs[0], '54')
eq(revs[-1], '5')

def test_sort_asc(self):
self._create_revisions(4)
revs = helpers.call_action('revision_list', since_id='1',
sort='time_asc')
eq(revs, ['2', '3'])

0 comments on commit c357989

Please sign in to comment.