diff --git a/docs/source/publishing/ogcapi-features.rst b/docs/source/publishing/ogcapi-features.rst index 3a1c2e9e5..5646f1a7b 100644 --- a/docs/source/publishing/ogcapi-features.rst +++ b/docs/source/publishing/ogcapi-features.rst @@ -625,6 +625,7 @@ Must have PostGIS installed. id_field: osm_id table: hotosm_bdi_waterways geom_field: foo_geom + count: true # Optional; Default true; Enable/disable count for improved performance. A number of database connection options can be also configured in the provider in order to adjust properly the sqlalchemy engine client. These are optional and if not specified, the default from the engine will be used. Please see also `SQLAlchemy docs `_. @@ -662,6 +663,7 @@ These are optional and if not specified, the default from the engine will be use id_field: osm_id table: hotosm_bdi_waterways geom_field: foo_geom + count: true # Optional; Default true; Enable/disable count for improved performance. The PostgreSQL provider is also able to connect to Cloud SQL databases. @@ -677,6 +679,7 @@ The PostgreSQL provider is also able to connect to Cloud SQL databases. password: postgres id_field: id table: states + count: true # Optional; Default true; Enable/disable count for improved performance. This is what a configuration for `Google Cloud SQL`_ connection looks like. The ``host`` block contains the necessary socket connection information. diff --git a/pygeoapi/provider/base.py b/pygeoapi/provider/base.py index b1ccb9c43..3dd4c5a18 100644 --- a/pygeoapi/provider/base.py +++ b/pygeoapi/provider/base.py @@ -57,6 +57,8 @@ def __init__(self, provider_def): :returns: pygeoapi.provider.base.BaseProvider """ + from pygeoapi.util import str2bool + try: self.name = provider_def['name'] self.type = provider_def['type'] @@ -65,6 +67,7 @@ def __init__(self, provider_def): raise RuntimeError('name/type/data are required') self.editable = provider_def.get('editable', False) + self.count = str2bool(provider_def.get('count', True)) self.options = provider_def.get('options') self.id_field = provider_def.get('id_field') self.uri_field = provider_def.get('uri_field') diff --git a/pygeoapi/provider/sql.py b/pygeoapi/provider/sql.py index 631d41c99..a955f06db 100644 --- a/pygeoapi/provider/sql.py +++ b/pygeoapi/provider/sql.py @@ -91,7 +91,6 @@ ProviderQueryError, ProviderItemNotFoundError ) -from pygeoapi.util import str2bool LOGGER = logging.getLogger(__name__) @@ -128,7 +127,6 @@ def __init__( self.id_field = provider_def['id_field'] self.geom = provider_def.get('geom_field', 'geom') self.driver_name = driver_name - self.count = str2bool(provider_def.get('count', True)) LOGGER.debug(f'Name: {self.name}') LOGGER.debug(f'Table: {self.table}') @@ -214,18 +212,20 @@ def query( .options(selected_properties) ) - matched = results.count() - - LOGGER.debug(f'Found {matched} result(s)') - LOGGER.debug('Preparing response') response = { 'type': 'FeatureCollection', 'features': [], - 'numberMatched': matched, 'numberReturned': 0 } + if self.count or resulttype == 'hits': + matched = results.count() + response['numberMatched'] = matched + LOGGER.debug(f'Found {matched} result(s)') + else: + LOGGER.debug('Count disabled') + if resulttype == 'hits' or not results: return response diff --git a/tests/provider/test_postgresql_provider.py b/tests/provider/test_postgresql_provider.py index da3d0f99e..c27660caf 100644 --- a/tests/provider/test_postgresql_provider.py +++ b/tests/provider/test_postgresql_provider.py @@ -908,3 +908,38 @@ def test_transaction_create_handles_invalid_input_data(pg_api_, data): headers, code, content = manage_collection_item( pg_api_, req, action='create', dataset='hot_osm_waterways') assert 'generic error' in content + + +def test_provider_count_default_value(config): + # Arrange + provider = PostgreSQLProvider(config) + + # Act + results = provider.query() + + # Assert + assert results['numberMatched'] == 14776 + + +def test_provider_count_false(config): + # Arrange + config['count'] = 'false' + provider = PostgreSQLProvider(config) + + # Act + results = provider.query() + + # Assert + assert 'numberMatched' not in results + + +def test_provider_count_false_with_resulttype_hits(config): + # Arrange + config['count'] = 'false' + provider = PostgreSQLProvider(config) + + # Act + results = provider.query(resulttype="hits") + + # Assert + assert results['numberMatched'] == 14776