# HG changeset patch # User Sylvain Thénault # Date 1248346029 -7200 # Node ID 93c061eac6475aa251393b7e9874d80efbc800c2 # Parent 7d9ed6c740ecd35890b74487065b0d5b3a9e5153 sparql support for limit/offset/orderby diff -r 7d9ed6c740ec -r 93c061eac647 spa2rql.py --- a/spa2rql.py Thu Jul 23 12:08:39 2009 +0200 +++ b/spa2rql.py Thu Jul 23 12:47:09 2009 +0200 @@ -15,6 +15,17 @@ class UnsupportedQuery(Exception): pass +def order_limit_offset(sparqlst): + addons = '' + if sparqlst.orderby: + sortterms = ', '.join('%s %s' % (var.name.upper(), ascdesc.upper()) + for var, ascdesc in sparqlst.orderby) + addons += ' ORDERBY %s' % sortterms + if sparqlst.limit: + addons += ' LIMIT %s' % sparqlst.limit + if sparqlst.offset: + addons += ' OFFSET %s' % sparqlst.offset + return addons class QueryInfo(object): """wrapper class containing necessary information to generate a RQL query @@ -49,15 +60,22 @@ unions = thisunions else: unions = zip(*make_domains([unions, thisunions])) - baserql = 'Any %s WHERE %s' % (', '.join(self.selection), - ', '.join(self.restrictions)) - if self.sparqlst.distinct: - baserql = 'DISTINCT ' + baserql + selection = 'Any ' + ', '.join(self.selection) + sparqlst = self.sparqlst + if sparqlst.distinct: + selection = 'DISTINCT ' + selection if not unions: - return baserql + return '%s%s WHERE %s' % (selection, order_limit_offset(sparqlst), + ', '.join(self.restrictions)) + baserql = '%s WHERE %s' % (selection, ', '.join(self.restrictions)) rqls = ['(%s, %s)' % (baserql, ', '.join(unionrestrs)) for unionrestrs in unions] - return ' UNION '.join(rqls) + rql = ' UNION '.join(rqls) + if sparqlst.orderby or sparqlst.limit or sparqlst.offset: + rql = '%s%s WITH %s BEING (%s)' % ( + selection, order_limit_offset(sparqlst), + ', '.join(self.selection), rql) + return rql def set_possible_types(self, var, varpossibletypes): """set/restrict possible types for the given variable. diff -r 7d9ed6c740ec -r 93c061eac647 test/unittest_spa2rql.py --- a/test/unittest_spa2rql.py Thu Jul 23 12:08:39 2009 +0200 +++ b/test/unittest_spa2rql.py Thu Jul 23 12:47:09 2009 +0200 @@ -24,6 +24,7 @@ def XXX_test_base_01(self): self._test('SELECT * WHERE { }', 'Any X') + def test_base_is(self): self._test(''' PREFIX doap: @@ -42,6 +43,7 @@ doap:created ?created. }''', 'Any CREATED WHERE PROJECT creation_date CREATED, PROJECT is Project') + def test_base_attr_sel_distinct(self): self._test(''' PREFIX doap: @@ -51,6 +53,7 @@ doap:name ?name. }''', 'DISTINCT Any NAME WHERE PROJECT name NAME, PROJECT is Project') + def test_base_attr_sel_reduced(self): self._test(''' PREFIX doap: @@ -61,6 +64,37 @@ }''', 'Any NAME WHERE PROJECT name NAME, PROJECT is Project') + def test_base_attr_sel_limit_offset(self): + self._test(''' + PREFIX doap: + SELECT ?name + WHERE { + ?project a doap:Project; + doap:name ?name. + } + LIMIT 20''', 'Any NAME LIMIT 20 WHERE PROJECT name NAME, PROJECT is Project') + self._test(''' + PREFIX doap: + SELECT ?name + WHERE { + ?project a doap:Project; + doap:name ?name. + } + LIMIT 20 OFFSET 10''', 'Any NAME LIMIT 20 OFFSET 10 WHERE PROJECT name NAME, PROJECT is Project') + + + def test_base_attr_sel_orderby(self): + self._test(''' + PREFIX doap: + SELECT ?name + WHERE { + ?project a doap:Project; + doap:name ?name; + doap:created ?created. + } + ORDER BY ?name DESC(?created)''', 'Any NAME ORDERBY NAME ASC, CREATED DESC WHERE PROJECT name NAME, PROJECT creation_date CREATED, PROJECT is Project') + + def test_base_any_attr_sel(self): self._test(''' PREFIX dc: @@ -69,6 +103,7 @@ ?x dc:date ?cd; }''', 'Any X, CD WHERE X creation_date CD') + def test_base_any_attr_sel_amb(self): xy.add_equivalence('Version publication_date', 'doap:Version dc:date') try: @@ -81,6 +116,34 @@ finally: xy.remove_equivalence('Version publication_date', 'doap:Version dc:date') + + def test_base_any_attr_sel_amb_limit_offset(self): + xy.add_equivalence('Version publication_date', 'doap:Version dc:date') + try: + self._test(''' + PREFIX dc: + SELECT ?x ?cd + WHERE { + ?x dc:date ?cd; + } + LIMIT 20 OFFSET 10''', 'Any X, CD LIMIT 20 OFFSET 10 WITH X, CD BEING ((Any X, CD WHERE , X creation_date CD) UNION (Any X, CD WHERE , X publication_date CD, X is Version))') + finally: + xy.remove_equivalence('Version publication_date', 'doap:Version dc:date') + + + def test_base_any_attr_sel_amb_orderby(self): + xy.add_equivalence('Version publication_date', 'doap:Version dc:date') + try: + self._test(''' + PREFIX dc: + SELECT ?x ?cd + WHERE { + ?x dc:date ?cd; + } + ORDER BY DESC(?cd)''', 'Any X, CD ORDERBY CD DESC WITH X, CD BEING ((Any X, CD WHERE , X creation_date CD) UNION (Any X, CD WHERE , X publication_date CD, X is Version))') + finally: + xy.remove_equivalence('Version publication_date', 'doap:Version dc:date') + # # Two elements in the group # PREFIX : # SELECT *