From d220e97b42c0931635d20242724f50e0d8fb4250 Mon Sep 17 00:00:00 2001 From: Graham Higgins Date: Sat, 25 Dec 2021 14:07:19 +0000 Subject: [PATCH] Fix for issue #272 --- rdflib/plugins/sparql/__init__.py | 2 +- rdflib/plugins/sparql/algebra.py | 4 +-- rdflib/plugins/sparql/processor.py | 9 +++++++ rdflib/plugins/sparql/sparql.py | 10 +++++++ rdflib/plugins/sparql/update.py | 2 +- test/test_sparql_prepare.py | 43 ++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 test/test_sparql_prepare.py diff --git a/rdflib/plugins/sparql/__init__.py b/rdflib/plugins/sparql/__init__.py index eb9230bf1..97d8c56aa 100644 --- a/rdflib/plugins/sparql/__init__.py +++ b/rdflib/plugins/sparql/__init__.py @@ -35,7 +35,7 @@ from . import operators from . import parserutils -from .processor import prepareQuery, processUpdate +from .processor import prepareQuery, prepareUpdate, processUpdate assert parser assert operators diff --git a/rdflib/plugins/sparql/algebra.py b/rdflib/plugins/sparql/algebra.py index b3d1a3bae..805e62a80 100644 --- a/rdflib/plugins/sparql/algebra.py +++ b/rdflib/plugins/sparql/algebra.py @@ -13,7 +13,7 @@ from rdflib import Literal, Variable, URIRef, BNode -from rdflib.plugins.sparql.sparql import Prologue, Query +from rdflib.plugins.sparql.sparql import Prologue, Query, Update from rdflib.plugins.sparql.parserutils import CompValue, Expr from rdflib.plugins.sparql.operators import ( and_, @@ -761,7 +761,7 @@ def translateUpdate(q, base=None, initNs=None): res.append(translateUpdate1(u, prologue)) - return res + return Update(prologue, res) def translateQuery(q, base=None, initNs=None): diff --git a/rdflib/plugins/sparql/processor.py b/rdflib/plugins/sparql/processor.py index 84e8c8231..febb47758 100644 --- a/rdflib/plugins/sparql/processor.py +++ b/rdflib/plugins/sparql/processor.py @@ -26,6 +26,15 @@ def prepareQuery(queryString, initNs={}, base=None): return ret +def prepareUpdate(updateString, initNs={}, base=None): + """ + Parse and translate a SPARQL Update + """ + ret = translateUpdate(parseUpdate(updateString), base, initNs) + ret._original_args = (updateString, initNs, base) + return ret + + def processUpdate(graph, updateString, initBindings={}, initNs={}, base=None): """ Process a SPARQL Update Request diff --git a/rdflib/plugins/sparql/sparql.py b/rdflib/plugins/sparql/sparql.py index eedc9e746..526203c47 100644 --- a/rdflib/plugins/sparql/sparql.py +++ b/rdflib/plugins/sparql/sparql.py @@ -408,3 +408,13 @@ class Query: def __init__(self, prologue, algebra): self.prologue = prologue self.algebra = algebra + + +class Update: + """ + A parsed and translated update + """ + + def __init__(self, prologue, algebra): + self.prologue = prologue + self.algebra = algebra diff --git a/rdflib/plugins/sparql/update.py b/rdflib/plugins/sparql/update.py index f979c3872..ef4b46b95 100644 --- a/rdflib/plugins/sparql/update.py +++ b/rdflib/plugins/sparql/update.py @@ -273,7 +273,7 @@ def evalUpdate(graph, update, initBindings={}): """ - for u in update: + for u in update.algebra: initBindings = dict((Variable(k), v) for k, v in initBindings.items()) diff --git a/test/test_sparql_prepare.py b/test/test_sparql_prepare.py new file mode 100644 index 000000000..3a0f51324 --- /dev/null +++ b/test/test_sparql_prepare.py @@ -0,0 +1,43 @@ +import os +from rdflib.plugins.sparql import prepareUpdate, prepareQuery +from rdflib.namespace import FOAF +from rdflib import ( + Graph, + URIRef, +) + + +def test_prepare_update(): + + q = prepareUpdate( + """\ +PREFIX dc: +INSERT DATA +{ dc:title "A new book" ; + dc:creator "A.N.Other" . + } ; +""", + initNs={}, + ) + + g = Graph() + g.update(q, initBindings={}) + assert len(g) == 2 + + +def test_prepare_query(): + + q = prepareQuery( + "SELECT ?name WHERE { ?person foaf:knows/foaf:name ?name . }", + initNs={"foaf": FOAF}, + ) + + g = Graph() + g.parse( + location=os.path.join(os.path.dirname(__file__), "..", "examples", "foaf.n3"), + format="n3", + ) + + tim = URIRef("http://www.w3.org/People/Berners-Lee/card#i") + + assert len(list(g.query(q, initBindings={"person": tim}))) == 50