diff --git a/pycsw/core/repository.py b/pycsw/core/repository.py index 59093fb53..687a3d546 100644 --- a/pycsw/core/repository.py +++ b/pycsw/core/repository.py @@ -87,11 +87,12 @@ def connect(dbapi_connection, connection_rec): return clazz._engines[url] ''' Class to interact with underlying repository ''' - def __init__(self, database, context, app_root=None, table='records', repo_filter=None): + def __init__(self, database, context, app_root=None, table='records', repo_filter=None, stable_sort = False): ''' Initialize repository ''' self.context = context self.filter = repo_filter + self.stable_sort = stable_sort self.fts = False self.database = database self.table = table @@ -450,7 +451,11 @@ def query(self, constraint, sortby=None, typenames=None, query = query.order_by(func.get_geometry_area(sortby_column)) else: # aspatial sort query = query.order_by(sortby_column) - + + if self.stable_sort: + identifier = self.context.md_core_model['mappings']['pycsw:Identifier'] + query = query.order_by(identifier) + # always apply limit and offset return [str(total), self._get_repo_filter(query).limit( maxrecords).offset(startposition).all()] diff --git a/pycsw/server.py b/pycsw/server.py index 67b705252..49fba5e99 100644 --- a/pycsw/server.py +++ b/pycsw/server.py @@ -417,7 +417,8 @@ def dispatch(self, writer=sys.stdout, write_headers=True): self.context, self.environ.get('local.app_root', None), self.config['repository'].get('table'), - repo_filter + repo_filter, + self.config['repository'].get('stable_sort', False) ) LOGGER.debug( 'Repository loaded (local): %s.' % self.repository.dbtype) diff --git a/tests/functionaltests/suites/stablesort/default.yml b/tests/functionaltests/suites/stablesort/default.yml new file mode 100644 index 000000000..8ac161a6e --- /dev/null +++ b/tests/functionaltests/suites/stablesort/default.yml @@ -0,0 +1,98 @@ +# ================================================================= +# +# Authors: Tom Kralidis +# +# Copyright (c) 2024 Tom Kralidis +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# ================================================================= + +server: + url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml + mimetype: application/xml; charset=UTF-8 + encoding: UTF-8 + language: en-US + maxrecords: 10 + pretty_print: true + +logging: + level: DEBUG + +federatedcatalogues: + - http://geo.data.gov/geoportal/csw/discovery + +manager: + transactions: false + allowed_ips: + - 127.0.0.1 + +metadata: + identification: + title: pycsw Geospatial Catalogue + description: pycsw is an OARec and OGC CSW server implementation written in Python + keywords: + - catalogue + - discovery + keywords_type: theme + fees: None + accessconstraints: None + provider: + name: pycsw + url: https://pycsw.org/ + contact: + name: Kralidis, Tom + position: Senior Systems Scientist + address: TBA + city: Toronto + stateorprovince: Ontario + postalcode: M9C 3Z9 + country: Canada + phone: +01-416-xxx-xxxx + fax: +01-416-xxx-xxxx + email: tomkralidis@gmail.com + url: http://kralidis.ca/ + hours: 0800h - 1600h EST + instructions: During hours of service. Off on weekends. + role: pointOfContact + + inspire: + enabled: false + languages_supported: + - eng + - gre + default_language: eng + date: 2011-03-29 + gemet_keywords: + - Utility and governmental services + conformity_service: notEvaluated + contact_name: National Technical University of Athens + contact_email: tzotsos@gmail.com + temp_extent: + begin: 2011-02-01 + end: 2011-03-30 + +repository: + # sqlite + database: sqlite:///tests/functionaltests/suites/cite/data/cite.db + table: records + stable_sort: true diff --git a/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page1.xml b/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page1.xml new file mode 100644 index 000000000..4a4a9ed1b --- /dev/null +++ b/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page1.xml @@ -0,0 +1,42 @@ + + + + + + + urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493 + Maecenas enim + http://purl.org/dc/dcmitype/Text + application/xhtml+xml + Marine sediments + Pellentesque tempus magna non sapien fringilla blandit. + + + urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec + Aliquam fermentum purus quis arcu + http://purl.org/dc/dcmitype/Text + Hydrography--Dictionaries + application/pdf + 2006-05-12 + Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi. + + + urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db + http://purl.org/dc/dcmitype/Text + Fuscé vitae ligulä + 2003-05-09 + Land titles + text/rtf + Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla. + + + urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd + http://purl.org/dc/dcmitype/Service + Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus. + + 60.042 13.754 + 68.410 17.920 + + + + diff --git a/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page2.xml b/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page2.xml new file mode 100644 index 000000000..72b17c116 --- /dev/null +++ b/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page2.xml @@ -0,0 +1,37 @@ + + + + + + + urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4 + http://purl.org/dc/dcmitype/Service + Ut facilisis justo ut lacus + Vegetation + urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 + + + urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a + http://purl.org/dc/dcmitype/Service + Physiography + Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam. + urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 + + + urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f + http://purl.org/dc/dcmitype/Image + image/svg+xml + Lorem ipsum + GR-22 + Tourism--Greece + Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu. + + + urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e + http://purl.org/dc/dcmitype/Image + image/jp2 + Vestibulum massa purus + urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc + + + diff --git a/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page3.xml b/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page3.xml new file mode 100644 index 000000000..6fcdfd14d --- /dev/null +++ b/tests/functionaltests/suites/stablesort/expected/get_GetRecords-page3.xml @@ -0,0 +1,44 @@ + + + + + + + urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2 + http://purl.org/dc/dcmitype/Image + Lorem ipsum dolor sit amet + image/jpeg + IT-FI + + + urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357 + http://purl.org/dc/dcmitype/Dataset + Physiography-Landforms + FI-ES + Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque. + + + urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 + http://purl.org/dc/dcmitype/Dataset + Mauris sed neque + Vegetation-Cropland + Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit. + 2006-03-26 + + 47.595 -4.097 + 51.217 0.889 + + + + urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc + http://purl.org/dc/dcmitype/Dataset + Ñunç elementum + Hydrography-Oceanographic + 2005-10-24 + + 44.792 -6.171 + 51.126 -2.228 + + + + diff --git a/tests/functionaltests/suites/stablesort/get/requests.txt b/tests/functionaltests/suites/stablesort/get/requests.txt new file mode 100644 index 000000000..ec9803965 --- /dev/null +++ b/tests/functionaltests/suites/stablesort/get/requests.txt @@ -0,0 +1,3 @@ +GetRecords-page1,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:type:D&maxRecords=4&startPosition=1 +GetRecords-page2,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:type:D&maxRecords=4&startPosition=5 +GetRecords-page3,service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:type:D&maxRecords=4&startPosition=9