Skip to content

Commit 00225c2

Browse files
authored
Add stable sort (#1157)
1 parent 3aaf5f1 commit 00225c2

File tree

7 files changed

+233
-3
lines changed

7 files changed

+233
-3
lines changed

pycsw/core/repository.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,12 @@ def connect(dbapi_connection, connection_rec):
8787
return clazz._engines[url]
8888

8989
''' Class to interact with underlying repository '''
90-
def __init__(self, database, context, app_root=None, table='records', repo_filter=None):
90+
def __init__(self, database, context, app_root=None, table='records', repo_filter=None, stable_sort = False):
9191
''' Initialize repository '''
9292

9393
self.context = context
9494
self.filter = repo_filter
95+
self.stable_sort = stable_sort
9596
self.fts = False
9697
self.database = database
9798
self.table = table
@@ -456,7 +457,11 @@ def query(self, constraint, sortby=None, typenames=None,
456457
query = query.order_by(func.get_geometry_area(sortby_column))
457458
else: # aspatial sort
458459
query = query.order_by(sortby_column)
459-
460+
461+
if self.stable_sort:
462+
identifier = self.context.md_core_model['mappings']['pycsw:Identifier']
463+
query = query.order_by(identifier)
464+
460465
# always apply limit and offset
461466
return [str(total), self._get_repo_filter(query).limit(
462467
maxrecords).offset(startposition).all()]

pycsw/server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,8 @@ def dispatch(self, writer=sys.stdout, write_headers=True):
417417
self.context,
418418
self.environ.get('local.app_root', None),
419419
self.config['repository'].get('table'),
420-
repo_filter
420+
repo_filter,
421+
self.config['repository'].get('stable_sort', False)
421422
)
422423
LOGGER.debug(
423424
'Repository loaded (local): %s.' % self.repository.dbtype)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# =================================================================
2+
#
3+
# Authors: Tom Kralidis <tomkralidis@gmail.com>
4+
#
5+
# Copyright (c) 2024 Tom Kralidis
6+
#
7+
# Permission is hereby granted, free of charge, to any person
8+
# obtaining a copy of this software and associated documentation
9+
# files (the "Software"), to deal in the Software without
10+
# restriction, including without limitation the rights to use,
11+
# copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
# copies of the Software, and to permit persons to whom the
13+
# Software is furnished to do so, subject to the following
14+
# conditions:
15+
#
16+
# The above copyright notice and this permission notice shall be
17+
# included in all copies or substantial portions of the Software.
18+
#
19+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26+
# OTHER DEALINGS IN THE SOFTWARE.
27+
#
28+
# =================================================================
29+
30+
server:
31+
url: http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.yml
32+
mimetype: application/xml; charset=UTF-8
33+
encoding: UTF-8
34+
language: en-US
35+
maxrecords: 10
36+
pretty_print: true
37+
38+
logging:
39+
level: DEBUG
40+
41+
federatedcatalogues:
42+
- http://geo.data.gov/geoportal/csw/discovery
43+
44+
manager:
45+
transactions: false
46+
allowed_ips:
47+
- 127.0.0.1
48+
49+
metadata:
50+
identification:
51+
title: pycsw Geospatial Catalogue
52+
description: pycsw is an OARec and OGC CSW server implementation written in Python
53+
keywords:
54+
- catalogue
55+
- discovery
56+
keywords_type: theme
57+
fees: None
58+
accessconstraints: None
59+
provider:
60+
name: pycsw
61+
url: https://pycsw.org/
62+
contact:
63+
name: Kralidis, Tom
64+
position: Senior Systems Scientist
65+
address: TBA
66+
city: Toronto
67+
stateorprovince: Ontario
68+
postalcode: M9C 3Z9
69+
country: Canada
70+
phone: +01-416-xxx-xxxx
71+
fax: +01-416-xxx-xxxx
72+
email: tomkralidis@gmail.com
73+
url: http://kralidis.ca/
74+
hours: 0800h - 1600h EST
75+
instructions: During hours of service. Off on weekends.
76+
role: pointOfContact
77+
78+
inspire:
79+
enabled: false
80+
languages_supported:
81+
- eng
82+
- gre
83+
default_language: eng
84+
date: 2011-03-29
85+
gemet_keywords:
86+
- Utility and governmental services
87+
conformity_service: notEvaluated
88+
contact_name: National Technical University of Athens
89+
contact_email: tzotsos@gmail.com
90+
temp_extent:
91+
begin: 2011-02-01
92+
end: 2011-03-30
93+
94+
repository:
95+
# sqlite
96+
database: sqlite:///tests/functionaltests/suites/cite/data/cite.db
97+
table: records
98+
stable_sort: true
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<!-- PYCSW_VERSION -->
3+
<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
4+
<csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
5+
<csw:SearchResults numberOfRecordsMatched="12" numberOfRecordsReturned="4" nextRecord="5" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
6+
<csw:Record>
7+
<dc:identifier>urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493</dc:identifier>
8+
<dc:title>Maecenas enim</dc:title>
9+
<dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
10+
<dc:format>application/xhtml+xml</dc:format>
11+
<dc:subject>Marine sediments</dc:subject>
12+
<dct:abstract>Pellentesque tempus magna non sapien fringilla blandit.</dct:abstract>
13+
</csw:Record>
14+
<csw:Record>
15+
<dc:identifier>urn:uuid:784e2afd-a9fd-44a6-9a92-a3848371c8ec</dc:identifier>
16+
<dc:title>Aliquam fermentum purus quis arcu</dc:title>
17+
<dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
18+
<dc:subject>Hydrography--Dictionaries</dc:subject>
19+
<dc:format>application/pdf</dc:format>
20+
<dc:date>2006-05-12</dc:date>
21+
<dct:abstract>Vestibulum quis ipsum sit amet metus imperdiet vehicula. Nulla scelerisque cursus mi.</dct:abstract>
22+
</csw:Record>
23+
<csw:Record>
24+
<dc:identifier>urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db</dc:identifier>
25+
<dc:type>http://purl.org/dc/dcmitype/Text</dc:type>
26+
<dc:title>Fuscé vitae ligulä</dc:title>
27+
<dc:date>2003-05-09</dc:date>
28+
<dc:subject>Land titles</dc:subject>
29+
<dc:format>text/rtf</dc:format>
30+
<dct:abstract>Morbi ultriçes, dui suscipit vestibulum prètium, velit ante pretium tortor, egët tincidunt pede odio ac nulla.</dct:abstract>
31+
</csw:Record>
32+
<csw:Record>
33+
<dc:identifier>urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd</dc:identifier>
34+
<dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
35+
<dct:abstract>Proin sit amet justo. In justo. Aenean adipiscing nulla id tellus.</dct:abstract>
36+
<ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326">
37+
<ows:LowerCorner>60.042 13.754</ows:LowerCorner>
38+
<ows:UpperCorner>68.410 17.920</ows:UpperCorner>
39+
</ows:BoundingBox>
40+
</csw:Record>
41+
</csw:SearchResults>
42+
</csw:GetRecordsResponse>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<!-- PYCSW_VERSION -->
3+
<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
4+
<csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
5+
<csw:SearchResults numberOfRecordsMatched="12" numberOfRecordsReturned="4" nextRecord="9" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
6+
<csw:Record>
7+
<dc:identifier>urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4</dc:identifier>
8+
<dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
9+
<dc:title>Ut facilisis justo ut lacus</dc:title>
10+
<dc:subject scheme="http://www.digest.org/2.1">Vegetation</dc:subject>
11+
<dc:relation>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:relation>
12+
</csw:Record>
13+
<csw:Record>
14+
<dc:identifier>urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a</dc:identifier>
15+
<dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
16+
<dc:subject scheme="http://www.digest.org/2.1">Physiography</dc:subject>
17+
<dct:abstract>Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam.</dct:abstract>
18+
<dc:relation>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:relation>
19+
</csw:Record>
20+
<csw:Record>
21+
<dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
22+
<dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
23+
<dc:format>image/svg+xml</dc:format>
24+
<dc:title>Lorem ipsum</dc:title>
25+
<dct:spatial>GR-22</dct:spatial>
26+
<dc:subject>Tourism--Greece</dc:subject>
27+
<dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
28+
</csw:Record>
29+
<csw:Record>
30+
<dc:identifier>urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e</dc:identifier>
31+
<dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
32+
<dc:format>image/jp2</dc:format>
33+
<dc:title>Vestibulum massa purus</dc:title>
34+
<dc:relation>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:relation>
35+
</csw:Record>
36+
</csw:SearchResults>
37+
</csw:GetRecordsResponse>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<!-- PYCSW_VERSION -->
3+
<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0.2" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd">
4+
<csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
5+
<csw:SearchResults numberOfRecordsMatched="12" numberOfRecordsReturned="4" nextRecord="0" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full">
6+
<csw:Record>
7+
<dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
8+
<dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
9+
<dc:title>Lorem ipsum dolor sit amet</dc:title>
10+
<dc:format>image/jpeg</dc:format>
11+
<dct:spatial>IT-FI</dct:spatial>
12+
</csw:Record>
13+
<csw:Record>
14+
<dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
15+
<dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
16+
<dc:subject scheme="http://www.digest.org/2.1">Physiography-Landforms</dc:subject>
17+
<dct:spatial>FI-ES</dct:spatial>
18+
<dct:abstract>Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</dct:abstract>
19+
</csw:Record>
20+
<csw:Record>
21+
<dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
22+
<dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
23+
<dc:title>Mauris sed neque</dc:title>
24+
<dc:subject scheme="http://www.digest.org/2.1">Vegetation-Cropland</dc:subject>
25+
<dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
26+
<dc:date>2006-03-26</dc:date>
27+
<ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326">
28+
<ows:LowerCorner>47.595 -4.097</ows:LowerCorner>
29+
<ows:UpperCorner>51.217 0.889</ows:UpperCorner>
30+
</ows:BoundingBox>
31+
</csw:Record>
32+
<csw:Record>
33+
<dc:identifier>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dc:identifier>
34+
<dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
35+
<dc:title>Ñunç elementum</dc:title>
36+
<dc:subject scheme="http://www.digest.org/2.1">Hydrography-Oceanographic</dc:subject>
37+
<dc:date>2005-10-24</dc:date>
38+
<ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326">
39+
<ows:LowerCorner>44.792 -6.171</ows:LowerCorner>
40+
<ows:UpperCorner>51.126 -2.228</ows:UpperCorner>
41+
</ows:BoundingBox>
42+
</csw:Record>
43+
</csw:SearchResults>
44+
</csw:GetRecordsResponse>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
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
2+
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
3+
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

0 commit comments

Comments
 (0)