kopia lustrzana https://github.com/simonw/datasette
Error handling for ?_sort and ?_sort_desc
Verifies that they match an existing column, and only one or the other option is provided - refs #189 Eses a new DatasetteError exception that closes #193pull/200/head
rodzic
bfb19e3a17
commit
a87df963a0
|
@ -45,6 +45,10 @@ HASH_LENGTH = 7
|
||||||
connections = threading.local()
|
connections = threading.local()
|
||||||
|
|
||||||
|
|
||||||
|
class DatasetteError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class RenderMixin(HTTPMethodView):
|
class RenderMixin(HTTPMethodView):
|
||||||
def render(self, templates, **context):
|
def render(self, templates, **context):
|
||||||
template = self.jinja_env.select_template(templates)
|
template = self.jinja_env.select_template(templates)
|
||||||
|
@ -205,7 +209,7 @@ class BaseView(RenderMixin):
|
||||||
return response_or_template_contexts
|
return response_or_template_contexts
|
||||||
else:
|
else:
|
||||||
data, extra_template_data, templates = response_or_template_contexts
|
data, extra_template_data, templates = response_or_template_contexts
|
||||||
except (sqlite3.OperationalError, InvalidSql) as e:
|
except (sqlite3.OperationalError, InvalidSql, DatasetteError) as e:
|
||||||
data = {
|
data = {
|
||||||
'ok': False,
|
'ok': False,
|
||||||
'error': str(e),
|
'error': str(e),
|
||||||
|
@ -613,12 +617,26 @@ class TableView(RowTableShared):
|
||||||
search_description = 'search matches "{}"'.format(search)
|
search_description = 'search matches "{}"'.format(search)
|
||||||
params['search'] = search
|
params['search'] = search
|
||||||
|
|
||||||
|
info = self.ds.inspect()
|
||||||
|
table_rows = None
|
||||||
|
sortable_columns = set()
|
||||||
|
if not is_view:
|
||||||
|
table_info = info[name]['tables'][table]
|
||||||
|
table_rows = table_info['count']
|
||||||
|
sortable_columns = set(table_info['columns'])
|
||||||
|
|
||||||
# Allow for custom sort order
|
# Allow for custom sort order
|
||||||
sort = special_args.get('_sort')
|
sort = special_args.get('_sort')
|
||||||
if sort:
|
if sort:
|
||||||
|
if sort not in sortable_columns:
|
||||||
|
raise DatasetteError('Cannot sort table by {}'.format(sort))
|
||||||
order_by = escape_sqlite(sort)
|
order_by = escape_sqlite(sort)
|
||||||
sort_desc = special_args.get('_sort_desc')
|
sort_desc = special_args.get('_sort_desc')
|
||||||
if sort_desc:
|
if sort_desc:
|
||||||
|
if sort_desc not in sortable_columns:
|
||||||
|
raise DatasetteError('Cannot sort table by {}'.format(sort_desc))
|
||||||
|
if sort:
|
||||||
|
raise DatasetteError('Cannot use _sort and _sort_desc at the same time')
|
||||||
order_by = '{} desc'.format(escape_sqlite(sort_desc))
|
order_by = '{} desc'.format(escape_sqlite(sort_desc))
|
||||||
|
|
||||||
count_sql = 'select count(*) from {table_name} {where}'.format(
|
count_sql = 'select count(*) from {table_name} {where}'.format(
|
||||||
|
@ -728,11 +746,6 @@ class TableView(RowTableShared):
|
||||||
if use_rowid and filter_columns[0] == 'rowid':
|
if use_rowid and filter_columns[0] == 'rowid':
|
||||||
filter_columns = filter_columns[1:]
|
filter_columns = filter_columns[1:]
|
||||||
|
|
||||||
info = self.ds.inspect()
|
|
||||||
table_rows = None
|
|
||||||
if not is_view:
|
|
||||||
table_rows = info[name]['tables'][table]['count']
|
|
||||||
|
|
||||||
# Pagination next link
|
# Pagination next link
|
||||||
next_value = None
|
next_value = None
|
||||||
next_url = None
|
next_url = None
|
||||||
|
|
|
@ -400,6 +400,24 @@ def test_sortable_and_filtered(app_client):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_sortable_argument_errors(app_client):
|
||||||
|
response = app_client.get(
|
||||||
|
'/test_tables/sortable.json?_sort=badcolumn',
|
||||||
|
gather_request=False
|
||||||
|
)
|
||||||
|
assert 'Cannot sort table by badcolumn' == response.json['error']
|
||||||
|
response = app_client.get(
|
||||||
|
'/test_tables/sortable.json?_sort_desc=badcolumn2',
|
||||||
|
gather_request=False
|
||||||
|
)
|
||||||
|
assert 'Cannot sort table by badcolumn2' == response.json['error']
|
||||||
|
response = app_client.get(
|
||||||
|
'/test_tables/sortable.json?_sort=content&_sort_desc=pk2',
|
||||||
|
gather_request=False
|
||||||
|
)
|
||||||
|
assert 'Cannot use _sort and _sort_desc at the same time' == response.json['error']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('path,expected_rows', [
|
@pytest.mark.parametrize('path,expected_rows', [
|
||||||
('/test_tables/simple_primary_key.json?content=hello', [
|
('/test_tables/simple_primary_key.json?content=hello', [
|
||||||
['1', 'hello'],
|
['1', 'hello'],
|
||||||
|
|
Ładowanie…
Reference in New Issue