Skip to content

Commit

Permalink
[#2733] parse and validate sort
Browse files Browse the repository at this point in the history
  • Loading branch information
kindly committed Aug 7, 2012
1 parent 697ed53 commit f411b79
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
47 changes: 42 additions & 5 deletions ckanext/datastore/db.py
Expand Up @@ -2,6 +2,7 @@
import ckan.plugins as p
import json
import datetime
import shlex

_pg_types = {}
_type_names = set()
Expand Down Expand Up @@ -304,14 +305,53 @@ def _where(field_ids, data_dict):

q = data_dict.get('q')
if q:
where_clauses.append('_full_text @@ to_tsquery(%s)'.format(q))
where_clauses.append('_full_text @@ to_tsquery(%s)')
values.append(q)

where_clause = ' and '.join(where_clauses)
if where_clause:
where_clause = 'where ' + where_clause
return where_clause, values

def _sort(context, sort, field_ids):

if not sort:
return ''

if isinstance(sort, basestring):
clauses = sort.split(',')
elif isinstance(sort, list):
clauses = sort
else:
raise p.toolkit.ValidationError({
'sort': 'sort is not a list or a string'
})

clause_parsed = []

for clause in clauses:
clause_parts = shlex.split(clause)
if len(clause_parts) == 1:
field, sort = clause_parts[0], 'asc'
elif len(clause_parts) == 2:
field, sort = clause_parts
else:
raise p.toolkit.ValidationError({
'sort': 'not valid syntax for sort clause'
})
if field not in field_ids:
raise p.toolkit.ValidationError({
'sort': 'field {} not it table'.format(field)
})
if sort.lower() not in ('asc', 'desc'):
raise p.toolkit.ValidationError({
'sort': 'sorting can only be asc or desc'
})
clause_parsed.append('"{}" {}'.format(field, sort))

if clause_parsed:
return "order by " + ", ".join(clause_parsed)


def delete_data(context, data_dict):
fields = _get_fields(context, data_dict)
Expand Down Expand Up @@ -354,10 +394,7 @@ def search_data(context, data_dict):
_validate_int(limit, 'limit')
_validate_int(offset, 'offset')

if data_dict.get('sort'):
sort = 'order by {}'.format(data_dict['sort'])
else:
sort = ''
sort = _sort(context, data_dict.get('sort'), field_ids)

sql_string = '''select {}, count(*) over() as full_count
from "{}" {} {} limit {} offset {}'''\
Expand Down
4 changes: 2 additions & 2 deletions ckanext/datastore/tests/test_datastore.py
Expand Up @@ -532,7 +532,7 @@ def test_search_filters(self):

def test_search_sort(self):
data = {'resource_id': self.data['resource_id'],
'sort': 'book asc'}
'sort': 'book asc, author desc'}
postparams = '%s=1' % json.dumps(data)
auth = {'Authorization': str(self.sysadmin_user.apikey)}
res = self.app.post('/api/action/datastore_search', params=postparams,
Expand All @@ -549,7 +549,7 @@ def test_search_sort(self):
assert result['records'] == expected_records

data = {'resource_id': self.data['resource_id'],
'sort': 'book desc'}
'sort': ['book desc', '"author" asc']}
postparams = '%s=1' % json.dumps(data)
res = self.app.post('/api/action/datastore_search', params=postparams,
extra_environ=auth)
Expand Down

0 comments on commit f411b79

Please sign in to comment.