This is an automated email from the git hooks/post-receive script. kalxas-guest pushed a commit to branch master in repository pycsw.
commit a618b56bbfaadaf319d4beca520cb5a5d75e1361 Author: Angelos Tzotsos <gcpp.kal...@gmail.com> Date: Tue Oct 18 21:48:47 2016 +0300 Imported Upstream version 2.0.2+dfsg --- VERSION.txt | 2 +- pycsw/__init__.py | 2 +- pycsw/ogc/csw/cql.py | 113 +++++++++++++++++++++ pycsw/ogc/csw/csw2.py | 45 +++++--- pycsw/ogc/csw/csw3.py | 45 +++++--- ...get_GetRecords-filter-cql-title-or-abstract.xml | 23 +++++ ...tes_default_get_GetRecords-filter-cql-title.xml | 23 +++++ ...ault_post_GetRecords-cql-title-and-abstract.xml | 12 +++ tests/index.html | 3 + tests/suites/default/get/requests.txt | 2 + .../post/GetRecords-cql-title-and-abstract.xml | 9 ++ 11 files changed, 251 insertions(+), 28 deletions(-) diff --git a/VERSION.txt b/VERSION.txt index 38f77a6..e9307ca 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -2.0.1 +2.0.2 diff --git a/pycsw/__init__.py b/pycsw/__init__.py index d5581df..d595567 100644 --- a/pycsw/__init__.py +++ b/pycsw/__init__.py @@ -28,4 +28,4 @@ # # ================================================================= -__version__ = '2.0.1' +__version__ = '2.0.2' diff --git a/pycsw/ogc/csw/cql.py b/pycsw/ogc/csw/cql.py new file mode 100644 index 0000000..a0e8d40 --- /dev/null +++ b/pycsw/ogc/csw/cql.py @@ -0,0 +1,113 @@ +# -*- coding: utf-8 -*- +# ================================================================= +# +# Authors: Tom Kralidis <tomkrali...@gmail.com> +# +# Copyright (c) 2016 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. +# +# ================================================================= + +import logging + +from pycsw.core.etree import etree +from pycsw.core import util +from pycsw.ogc.fes.fes1 import MODEL as fes1_model + +LOGGER = logging.getLogger(__name__) + + +def cql2fes1(cql, namespaces): + """transforms Common Query Language (CQL) query into OGC fes1 syntax""" + + filters = [] + tmp_list = [] + logical_op = None + + LOGGER.debug('CQL: %s', cql) + + if ' or ' in cql: + logical_op = etree.Element(util.nspath_eval('ogc:Or', namespaces)) + tmp_list = cql.split(' or ') + elif ' OR ' in cql: + logical_op = etree.Element(util.nspath_eval('ogc:Or', namespaces)) + tmp_list = cql.split(' OR ') + elif ' and ' in cql: + logical_op = etree.Element(util.nspath_eval('ogc:And', namespaces)) + tmp_list = cql.split(' and ') + elif ' AND ' in cql: + logical_op = etree.Element(util.nspath_eval('ogc:And', namespaces)) + tmp_list = cql.split(' AND ') + + if tmp_list: + LOGGER.debug('Logical operator found (AND/OR)') + else: + tmp_list.append(cql) + + for t in tmp_list: + filters.append(_parse_condition(t)) + + root = etree.Element(util.nspath_eval('ogc:Filter', namespaces)) + + if logical_op is not None: + root.append(logical_op) + + for flt in filters: + condition = etree.Element(util.nspath_eval(flt[0], namespaces)) + + etree.SubElement( + condition, + util.nspath_eval('ogc:PropertyName', namespaces)).text = flt[1] + + etree.SubElement( + condition, + util.nspath_eval('ogc:Literal', namespaces)).text = flt[2] + + if logical_op is not None: + logical_op.append(condition) + else: + root.append(condition) + + LOGGER.debug('Resulting OGC Filter: %s', + etree.tostring(root, pretty_print=1)) + + return root + + +def _parse_condition(condition): + """parses a single condition""" + + LOGGER.debug('condition: %s', condition) + + property_name, operator, literal = condition.split() + + literal = literal.replace('"', '').replace('\'', '') + + for k, v in fes1_model['ComparisonOperators'].items(): + if v['opvalue'] == operator: + fes1_predicate = k + + LOGGER.debug('parsed condition: %s %s %s', property_name, fes1_predicate, + literal) + + return (fes1_predicate, property_name, literal) diff --git a/pycsw/ogc/csw/csw2.py b/pycsw/ogc/csw/csw2.py index bd8a11e..f8c64c4 100644 --- a/pycsw/ogc/csw/csw2.py +++ b/pycsw/ogc/csw/csw2.py @@ -38,6 +38,7 @@ from six import StringIO from six.moves.configparser import SafeConfigParser from pycsw.core.etree import etree from pycsw import oaipmh, opensearch, sru +from pycsw.ogc.csw.cql import cql2fes1 from pycsw.plugins.profiles import profile as pprofile import pycsw.plugins.outputschemas from pycsw.core import config, log, metadata, util @@ -732,12 +733,20 @@ class Csw2(object): % self.parent.kvp['constraintlanguage']) if self.parent.kvp['constraintlanguage'] == 'CQL_TEXT': tmp = self.parent.kvp['constraint'] - self.parent.kvp['constraint'] = {} - self.parent.kvp['constraint']['type'] = 'cql' - self.parent.kvp['constraint']['where'] = \ - self.parent._cql_update_queryables_mappings(tmp, - self.parent.repository.queryables['_all']) - self.parent.kvp['constraint']['values'] = {} + try: + LOGGER.debug('Transforming CQL into fes1') + LOGGER.debug('CQL: %s', tmp) + self.parent.kvp['constraint'] = {} + self.parent.kvp['constraint']['type'] = 'filter' + cql = cql2fes1(tmp, self.parent.context.namespaces) + self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = fes1.parse(cql, + self.parent.repository.queryables['_all'], self.parent.repository.dbtype, + self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) + except Exception as err: + LOGGER.error('Invalid CQL query %s', tmp) + LOGGER.error('Error message: %s', err, exc_info=True) + return self.exceptionreport('InvalidParameterValue', + 'constraint', 'Invalid Filter syntax') elif self.parent.kvp['constraintlanguage'] == 'FILTER': # validate filter XML try: @@ -815,8 +824,10 @@ class Csw2(object): maxrecords=self.parent.kvp['maxrecords'], startposition=int(self.parent.kvp['startposition'])-1) except Exception as err: + LOGGER.debug('Invalid query syntax. Query: %s', self.parent.kvp['constraint']) + LOGGER.debug('Invalid query syntax. Result: %s', err) return self.exceptionreport('InvalidParameterValue', 'constraint', - 'Invalid query: %s' % err) + 'Invalid query syntax') dsresults = [] @@ -1375,7 +1386,7 @@ class Csw2(object): existing_records = [str(i.identifier) for i in service_results] deleted = set(existing_records) - set(fresh_records) - LOGGER.debug('Records to delete: %s' % str(deleted)) + LOGGER.debug('Records to delete: %s', deleted) for to_delete in deleted: delete_constraint = { @@ -1536,13 +1547,21 @@ class Csw2(object): self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) except Exception as err: return 'Invalid Filter request: %s' % err + tmp = element.find(util.nspath_eval('csw:CqlText', self.parent.context.namespaces)) if tmp is not None: - LOGGER.debug('CQL specified: %s.' % tmp.text) - query['type'] = 'cql' - query['where'] = self.parent._cql_update_queryables_mappings(tmp.text, - self.parent.repository.queryables['_all']) - query['values'] = {} + LOGGER.debug('CQL specified: %s.', tmp.text) + try: + LOGGER.debug('Transforming CQL into OGC Filter') + query['type'] = 'filter' + cql = cql2fes1(tmp.text, self.parent.context.namespaces) + query['where'], query['values'] = fes1.parse(cql, + self.parent.repository.queryables['_all'], self.parent.repository.dbtype, + self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) + except Exception as err: + LOGGER.error('Invalid CQL request: %s', tmp.text) + LOGGER.error('Error message: %s', err, exc_info=True) + return 'Invalid CQL request' return query def parse_postdata(self, postdata): diff --git a/pycsw/ogc/csw/csw3.py b/pycsw/ogc/csw/csw3.py index 587777c..f1e6b5c 100644 --- a/pycsw/ogc/csw/csw3.py +++ b/pycsw/ogc/csw/csw3.py @@ -36,6 +36,7 @@ from six.moves.urllib.parse import quote, unquote from six import StringIO from six.moves.configparser import SafeConfigParser from pycsw.core.etree import etree +from pycsw.ogc.csw.cql import cql2fes1 from pycsw import oaipmh, opensearch, sru from pycsw.plugins.profiles import profile as pprofile import pycsw.plugins.outputschemas @@ -759,12 +760,20 @@ class Csw3(object): % self.parent.kvp['constraintlanguage']) if self.parent.kvp['constraintlanguage'] == 'CQL_TEXT': tmp = self.parent.kvp['constraint'] - self.parent.kvp['constraint'] = {} - self.parent.kvp['constraint']['type'] = 'cql' - self.parent.kvp['constraint']['where'] = \ - self.parent._cql_update_queryables_mappings(tmp, - self.parent.repository.queryables['_all']) - self.parent.kvp['constraint']['values'] = {} + try: + LOGGER.debug('Transforming CQL into fes1') + LOGGER.debug('CQL: %s', tmp) + self.parent.kvp['constraint'] = {} + self.parent.kvp['constraint']['type'] = 'filter' + cql = cql2fes1(tmp, self.parent.context.namespaces) + self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = fes1.parse(cql, + self.parent.repository.queryables['_all'], self.parent.repository.dbtype, + self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) + except Exception as err: + LOGGER.error('Invalid CQL query %s', tmp) + LOGGER.error('Error message: %s', err, exc_info=True) + return self.exceptionreport('InvalidParameterValue', + 'constraint', 'Invalid Filter syntax') elif self.parent.kvp['constraintlanguage'] == 'FILTER': # validate filter XML try: @@ -851,8 +860,10 @@ class Csw3(object): maxrecords=self.parent.kvp['maxrecords'], startposition=int(self.parent.kvp['startposition'])-1) except Exception as err: + LOGGER.debug('Invalid query syntax. Query: %s', self.parent.kvp['constraint']) + LOGGER.debug('Invalid query syntax. Result: %s', err) return self.exceptionreport('InvalidParameterValue', 'constraint', - 'Invalid query: %s' % err) + 'Invalid query syntax') if int(matched) == 0: returned = nextrecord = '0' @@ -1436,7 +1447,7 @@ class Csw3(object): existing_records = [str(i.identifier) for i in service_results] deleted = set(existing_records) - set(fresh_records) - LOGGER.debug('Records to delete: %s' % str(deleted)) + LOGGER.debug('Records to delete: %s', deleted) for to_delete in deleted: delete_constraint = { @@ -1616,13 +1627,21 @@ class Csw3(object): self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) except Exception as err: return 'Invalid Filter request: %s' % err + tmp = element.find(util.nspath_eval('csw30:CqlText', self.parent.context.namespaces)) if tmp is not None: - LOGGER.debug('CQL specified: %s.' % tmp.text) - query['type'] = 'cql' - query['where'] = self.parent._cql_update_queryables_mappings(tmp.text, - self.parent.repository.queryables['_all']) - query['values'] = {} + LOGGER.debug('CQL specified: %s.', tmp.text) + try: + LOGGER.debug('Transforming CQL into OGC Filter') + query['type'] = 'filter' + cql = cql2fes1(tmp.text, self.parent.context.namespaces) + query['where'], query['values'] = fes1.parse(cql, + self.parent.repository.queryables['_all'], self.parent.repository.dbtype, + self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts) + except Exception as err: + LOGGER.error('Invalid CQL request: %s', tmp.text) + LOGGER.error('Error message: %s', err, exc_info=True) + return 'Invalid CQL request' return query def parse_postdata(self, postdata): diff --git a/tests/expected/suites_default_get_GetRecords-filter-cql-title-or-abstract.xml b/tests/expected/suites_default_get_GetRecords-filter-cql-title-or-abstract.xml new file mode 100644 index 0000000..2b1accd --- /dev/null +++ b/tests/expected/suites_default_get_GetRecords-filter-cql-title-or-abstract.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- PYCSW_VERSION --> +<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-di [...] + <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/> + <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full"> + <csw:Record> + <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier> + <dc:type>http://purl.org/dc/dcmitype/Image</dc:type> + <dc:format>image/svg+xml</dc:format> + <dc:title>Lorem ipsum</dc:title> + <dct:spatial>GR-22</dct:spatial> + <dc:subject>Tourism--Greece</dc:subject> + <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract> +</csw:Record> + <csw:Record> + <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier> + <dc:type>http://purl.org/dc/dcmitype/Image</dc:type> + <dc:title>Lorem ipsum dolor sit amet</dc:title> + <dc:format>image/jpeg</dc:format> + <dct:spatial>IT-FI</dct:spatial> +</csw:Record> + </csw:SearchResults> +</csw:GetRecordsResponse> diff --git a/tests/expected/suites_default_get_GetRecords-filter-cql-title.xml b/tests/expected/suites_default_get_GetRecords-filter-cql-title.xml new file mode 100644 index 0000000..2b1accd --- /dev/null +++ b/tests/expected/suites_default_get_GetRecords-filter-cql-title.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- PYCSW_VERSION --> +<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-di [...] + <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/> + <csw:SearchResults nextRecord="0" numberOfRecordsMatched="2" numberOfRecordsReturned="2" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="full"> + <csw:Record> + <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier> + <dc:type>http://purl.org/dc/dcmitype/Image</dc:type> + <dc:format>image/svg+xml</dc:format> + <dc:title>Lorem ipsum</dc:title> + <dct:spatial>GR-22</dct:spatial> + <dc:subject>Tourism--Greece</dc:subject> + <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract> +</csw:Record> + <csw:Record> + <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier> + <dc:type>http://purl.org/dc/dcmitype/Image</dc:type> + <dc:title>Lorem ipsum dolor sit amet</dc:title> + <dc:format>image/jpeg</dc:format> + <dct:spatial>IT-FI</dct:spatial> +</csw:Record> + </csw:SearchResults> +</csw:GetRecordsResponse> diff --git a/tests/expected/suites_default_post_GetRecords-cql-title-and-abstract.xml b/tests/expected/suites_default_post_GetRecords-cql-title-and-abstract.xml new file mode 100644 index 0000000..4ed61a2 --- /dev/null +++ b/tests/expected/suites_default_post_GetRecords-cql-title-and-abstract.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- PYCSW_VERSION --> +<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-di [...] + <csw:SearchStatus timestamp="PYCSW_TIMESTAMP"/> + <csw:SearchResults nextRecord="0" numberOfRecordsMatched="1" numberOfRecordsReturned="1" recordSchema="http://www.opengis.net/cat/csw/2.0.2" elementSet="brief"> + <csw:BriefRecord> + <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier> + <dc:title>Lorem ipsum</dc:title> + <dc:type>http://purl.org/dc/dcmitype/Image</dc:type> + </csw:BriefRecord> + </csw:SearchResults> +</csw:GetRecordsResponse> diff --git a/tests/index.html b/tests/index.html index b107ca2..50f6651 100644 --- a/tests/index.html +++ b/tests/index.html @@ -190,6 +190,7 @@ <option value="tests/suites/default/default.cfg,suites/default/post/GetRecords-all-sortby-bbox.xml">suites/default/post/GetRecords-all-sortby-bbox.xml</option> <option value="tests/suites/default/default.cfg,suites/default/post/GetRecords-all.xml">suites/default/post/GetRecords-all.xml</option> <option value="tests/suites/default/default.cfg,suites/default/post/GetRecords-bbox-filter-crs84.xml">suites/default/post/GetRecords-bbox-filter-crs84.xml</option> + <option value="tests/suites/default/default.cfg,suites/default/post/GetRecords-cql-title-and-abstract.xml">suites/default/post/GetRecords-cql-title-and-abstract.xml</option> <option value="tests/suites/default/default.cfg,suites/default/post/GetRecords-cql-title.xml">suites/default/post/GetRecords-cql-title.xml</option> <option value="tests/suites/default/default.cfg,suites/default/post/GetRecords-distributedsearch.xml">suites/default/post/GetRecords-distributedsearch.xml</option> <option value="tests/suites/default/default.cfg,suites/default/post/GetRecords-elementname.xml">suites/default/post/GetRecords-elementname.xml</option> @@ -426,6 +427,8 @@ <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:titlei:A">GetRecords-sortby-invalid-propertyname</a></li> <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:FOO">GetRecords-sortby-invalid-order</a></li> <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=FILTER&constraint=%3Cogc%3AFilter%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3Cogc%3APropertyIsEqualTo%3E%3Cogc%3APropertyName%3Edc%3Atitle%3C%2Fogc%3APropertyName%3E%3Cogc%3ALiteral%3ELorem%20ipsum%3C%2Fogc%3ALiteral%3E%3C%2Fogc%3APropertyIsEqualTo%3E%3C% [...] +<li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27">GetRecords-filter-cql-title</a></li> +<li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%25%27">GetRecords-filter-cql-title-or-abstract</a></li> <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&maxrecords=">GetRecords-empty-maxrecords</a></li> <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63">GetRepositoryItem</a></li> <li><a href="../csw.py?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=NOTFOUND">Exception-GetRepositoryItem-notfound</a></li> diff --git a/tests/suites/default/get/requests.txt b/tests/suites/default/get/requests.txt index c75edbd..97daa7a 100644 --- a/tests/suites/default/get/requests.txt +++ b/tests/suites/default/get/requests.txt @@ -6,6 +6,8 @@ GetRecords-sortby-desc,PYCSW_SERVER?config=tests/suites/default/default.cfg&serv GetRecords-sortby-invalid-propertyname,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:titlei:A GetRecords-sortby-invalid-order,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:FOO GetRecords-filter,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=FILTER&constraint=%3Cogc%3AFilter%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3Cogc%3APropertyIsEqualTo%3E%3Cogc%3APropertyName%3Edc%3Atitle%3C%2Fogc%3APropertyName%3E%3Cogc%3ALiteral%3ELorem%20ipsum%3C%2Fogc%3ALiteral%3E%3C%2Fogc%3APropertyIsEqualTo%3E%3C%2Fogc%3AFilter%3E +GetRecords-filter-cql-title,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27 +GetRecords-filter-cql-title-or-abstract,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%25%27 GetRecords-empty-maxrecords,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&maxrecords= GetRepositoryItem,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63 Exception-GetRepositoryItem-notfound,PYCSW_SERVER?config=tests/suites/default/default.cfg&service=CSW&version=2.0.2&request=GetRepositoryItem&id=NOTFOUND diff --git a/tests/suites/default/post/GetRecords-cql-title-and-abstract.xml b/tests/suites/default/post/GetRecords-cql-title-and-abstract.xml new file mode 100644 index 0000000..9bdb579 --- /dev/null +++ b/tests/suites/default/post/GetRecords-cql-title-and-abstract.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> +<csw:GetRecords xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:ogc="http://www.opengis.net/ogc" service="CSW" version="2.0.2" resultType="results" startPosition="1" maxRecords="5" outputFormat="application/xml" outputSchema="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd"> + <csw:Query typeNames="csw:Record"> + <csw:ElementSetName>brief</csw:ElementSetName> + <csw:Constraint version="1.1.0"> + <csw:CqlText>dc:title like '%ips%' and dct:abstract like '%pharetra%'</csw:CqlText> + </csw:Constraint> + </csw:Query> +</csw:GetRecords> -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pycsw.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel