Skip to content

Commit

Permalink
Merge pull request ckan#7357 from ckan/7356-nulls-last
Browse files Browse the repository at this point in the history
extend datastore_search sort clause to include optional nulls first/last
  • Loading branch information
amercader authored Mar 9, 2023
2 parents fe879f9 + 5975fee commit 4bfc77a
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
1 change: 1 addition & 0 deletions changes/7356.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
datastore_search sort parameters now support "nulls first" and "nulls last"
6 changes: 5 additions & 1 deletion ckanext/datastore/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ def get_all_resources_ids_in_datastore() -> list[str]:

def _parse_sort_clause( # type: ignore
clause: str, fields_types: Container[str]):
clause_match = re.match(u'^(.+?)( +(asc|desc) *)?$', clause, re.I)
clause_match = re.match(
u'^(.+?)( +(asc|desc))?( nulls +(first|last) *)?$', clause, re.I
)

if not clause_match:
return False
Expand All @@ -38,6 +40,8 @@ def _parse_sort_clause( # type: ignore
if field[0] == field[-1] == u'"':
field = field[1:-1]
sort = (clause_match.group(3) or u'asc').lower()
if clause_match.group(4):
sort += (clause_match.group(4)).lower()

if field not in fields_types:
return False
Expand Down
2 changes: 1 addition & 1 deletion ckanext/datastore/logic/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ def datastore_search(context: Context, data_dict: dict[str, Any]):
(optional, default: all fields in original order)
:type fields: list or comma separated string
:param sort: comma separated field names with ordering
e.g.: "fieldname1, fieldname2 desc"
e.g.: "fieldname1, fieldname2 desc nulls last"
:type sort: string
:param include_total: True to return total matching record count
(optional, default: true)
Expand Down
25 changes: 25 additions & 0 deletions ckanext/datastore/tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,31 @@ def test_search_filter_with_percent_in_column_name(self):
result = helpers.call_action("datastore_search", **search_data)
assert result["total"] == 1

@pytest.mark.ckan_config("ckan.plugins", "datastore")
@pytest.mark.usefixtures("clean_datastore", "with_plugins")
def test_search_sort_nulls_first_last(self):
resource = factories.Resource()
data = {
"resource_id": resource["id"],
"force": True,
"records": [{"a": 1, "b": "Y"}, {"b": "Z"}],
}
helpers.call_action("datastore_create", **data)

search_data = {
"resource_id": data["resource_id"],
"sort": [u"a desc nulls last"],
}
result = helpers.call_action("datastore_search", **search_data)
assert result["records"][0]['b'] == 'Y'

search_data = {
"resource_id": data["resource_id"],
"sort": [u"a desc nulls first"],
}
result = helpers.call_action("datastore_search", **search_data)
assert result["records"][0]['b'] == 'Z'


@pytest.mark.usefixtures("with_request_context")
class TestDatastoreSearchLegacyTests(object):
Expand Down

0 comments on commit 4bfc77a

Please sign in to comment.