comparison planemo/lib/python3.7/site-packages/rdflib/plugins/sparql/update.py @ 1:56ad4e20f292 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:32:28 -0400
parents
children
comparison
equal deleted inserted replaced
0:d30785e31577 1:56ad4e20f292
1 """
2
3 Code for carrying out Update Operations
4
5 """
6
7 from rdflib import Graph, Variable
8
9 from rdflib.plugins.sparql.sparql import QueryContext
10 from rdflib.plugins.sparql.evalutils import _fillTemplate, _join
11 from rdflib.plugins.sparql.evaluate import evalBGP, evalPart
12
13
14 def _graphOrDefault(ctx, g):
15 if g == 'DEFAULT':
16 return ctx.graph
17 else:
18 return ctx.dataset.get_context(g)
19
20
21 def _graphAll(ctx, g):
22 """
23 return a list of graphs
24 """
25 if g == 'DEFAULT':
26 return [ctx.graph]
27 elif g == 'NAMED':
28 return [c for c in ctx.dataset.contexts()
29 if c.identifier != ctx.graph.identifier]
30 elif g == 'ALL':
31 return list(ctx.dataset.contexts())
32 else:
33 return [ctx.dataset.get_context(g)]
34
35
36 def evalLoad(ctx, u):
37 """
38 http://www.w3.org/TR/sparql11-update/#load
39 """
40
41 if u.graphiri:
42 ctx.load(u.iri, default=False, publicID=u.graphiri)
43 else:
44 ctx.load(u.iri, default=True)
45
46
47 def evalCreate(ctx, u):
48 """
49 http://www.w3.org/TR/sparql11-update/#create
50 """
51 g = ctx.datset.get_context(u.graphiri)
52 if len(g) > 0:
53 raise Exception("Graph %s already exists." % g.identifier)
54 raise Exception("Create not implemented!")
55
56
57 def evalClear(ctx, u):
58 """
59 http://www.w3.org/TR/sparql11-update/#clear
60 """
61
62 for g in _graphAll(ctx, u.graphiri):
63 g.remove((None, None, None))
64
65 def evalDrop(ctx, u):
66 """
67 http://www.w3.org/TR/sparql11-update/#drop
68 """
69 if ctx.dataset.store.graph_aware:
70 for g in _graphAll(ctx, u.graphiri):
71 ctx.dataset.store.remove_graph(g)
72 else:
73 evalClear(ctx, u)
74
75
76 def evalInsertData(ctx, u):
77 """
78 http://www.w3.org/TR/sparql11-update/#insertData
79 """
80 # add triples
81 g = ctx.graph
82 g += u.triples
83
84 # add quads
85 # u.quads is a dict of graphURI=>[triples]
86 for g in u.quads:
87 cg = ctx.dataset.get_context(g)
88 cg += u.quads[g]
89
90
91 def evalDeleteData(ctx, u):
92 """
93 http://www.w3.org/TR/sparql11-update/#deleteData
94 """
95 # remove triples
96 g = ctx.graph
97 g -= u.triples
98
99 # remove quads
100 # u.quads is a dict of graphURI=>[triples]
101 for g in u.quads:
102 cg = ctx.dataset.get_context(g)
103 cg -= u.quads[g]
104
105
106 def evalDeleteWhere(ctx, u):
107 """
108 http://www.w3.org/TR/sparql11-update/#deleteWhere
109 """
110
111 res = evalBGP(ctx, u.triples)
112 for g in u.quads:
113 cg = ctx.dataset.get_context(g)
114 c = ctx.pushGraph(cg)
115 res = _join(res, list(evalBGP(c, u.quads[g])))
116
117 for c in res:
118 g = ctx.graph
119 g -= _fillTemplate(u.triples, c)
120
121 for g in u.quads:
122 cg = ctx.dataset.get_context(c.get(g))
123 cg -= _fillTemplate(u.quads[g], c)
124
125
126 def evalModify(ctx, u):
127
128 originalctx = ctx
129
130 # Using replaces the dataset for evaluating the where-clause
131 if u.using:
132 otherDefault = False
133 for d in u.using:
134 if d.default:
135
136 if not otherDefault:
137 # replace current default graph
138 dg = Graph()
139 ctx = ctx.pushGraph(dg)
140 otherDefault = True
141
142 ctx.load(d.default, default=True)
143
144 elif d.named:
145 g = d.named
146 ctx.load(g, default=False)
147
148 # "The WITH clause provides a convenience for when an operation
149 # primarily refers to a single graph. If a graph name is specified
150 # in a WITH clause, then - for the purposes of evaluating the
151 # WHERE clause - this will define an RDF Dataset containing a
152 # default graph with the specified name, but only in the absence
153 # of USING or USING NAMED clauses. In the presence of one or more
154 # graphs referred to in USING clauses and/or USING NAMED clauses,
155 # the WITH clause will be ignored while evaluating the WHERE
156 # clause."
157 if not u.using and u.withClause:
158 g = ctx.dataset.get_context(u.withClause)
159 ctx = ctx.pushGraph(g)
160
161 res = evalPart(ctx, u.where)
162
163 if u.using:
164 if otherDefault:
165 ctx = originalctx # restore original default graph
166 if u.withClause:
167 g = ctx.dataset.get_context(u.withClause)
168 ctx = ctx.pushGraph(g)
169
170 for c in res:
171 dg = ctx.graph
172 if u.delete:
173 dg -= _fillTemplate(u.delete.triples, c)
174
175 for g, q in u.delete.quads.items():
176 cg = ctx.dataset.get_context(c.get(g))
177 cg -= _fillTemplate(q, c)
178
179 if u.insert:
180 dg += _fillTemplate(u.insert.triples, c)
181
182 for g, q in u.insert.quads.items():
183 cg = ctx.dataset.get_context(c.get(g))
184 cg += _fillTemplate(q, c)
185
186
187 def evalAdd(ctx, u):
188 """
189
190 add all triples from src to dst
191
192 http://www.w3.org/TR/sparql11-update/#add
193 """
194 src, dst = u.graph
195
196 srcg = _graphOrDefault(ctx, src)
197 dstg = _graphOrDefault(ctx, dst)
198
199 if srcg.identifier == dstg.identifier:
200 return
201
202 dstg += srcg
203
204
205 def evalMove(ctx, u):
206 """
207
208 remove all triples from dst
209 add all triples from src to dst
210 remove all triples from src
211
212 http://www.w3.org/TR/sparql11-update/#move
213 """
214
215 src, dst = u.graph
216
217 srcg = _graphOrDefault(ctx, src)
218 dstg = _graphOrDefault(ctx, dst)
219
220 if srcg.identifier == dstg.identifier:
221 return
222
223 dstg.remove((None, None, None))
224
225 dstg += srcg
226
227 if ctx.dataset.store.graph_aware:
228 ctx.dataset.store.remove_graph(srcg)
229 else:
230 srcg.remove((None, None, None))
231
232
233 def evalCopy(ctx, u):
234 """
235
236 remove all triples from dst
237 add all triples from src to dst
238
239 http://www.w3.org/TR/sparql11-update/#copy
240 """
241
242 src, dst = u.graph
243
244 srcg = _graphOrDefault(ctx, src)
245 dstg = _graphOrDefault(ctx, dst)
246
247 if srcg.identifier == dstg.identifier:
248 return
249
250 dstg.remove((None, None, None))
251
252 dstg += srcg
253
254
255 def evalUpdate(graph, update, initBindings={}):
256 """
257
258 http://www.w3.org/TR/sparql11-update/#updateLanguage
259
260 'A request is a sequence of operations [...] Implementations MUST
261 ensure that operations of a single request are executed in a
262 fashion that guarantees the same effects as executing them in
263 lexical order.
264
265 Operations all result either in success or failure.
266
267 If multiple operations are present in a single request, then a
268 result of failure from any operation MUST abort the sequence of
269 operations, causing the subsequent operations to be ignored.'
270
271 This will return None on success and raise Exceptions on error
272
273 """
274
275 for u in update:
276
277 initBindings = dict( ( Variable(k),v ) for k,v in initBindings.items() )
278
279 ctx = QueryContext(graph, initBindings=initBindings)
280 ctx.prologue = u.prologue
281
282
283 try:
284 if u.name == 'Load':
285 evalLoad(ctx, u)
286 elif u.name == 'Clear':
287 evalClear(ctx, u)
288 elif u.name == 'Drop':
289 evalDrop(ctx, u)
290 elif u.name == 'Create':
291 evalCreate(ctx, u)
292 elif u.name == 'Add':
293 evalAdd(ctx, u)
294 elif u.name == 'Move':
295 evalMove(ctx, u)
296 elif u.name == 'Copy':
297 evalCopy(ctx, u)
298 elif u.name == 'InsertData':
299 evalInsertData(ctx, u)
300 elif u.name == 'DeleteData':
301 evalDeleteData(ctx, u)
302 elif u.name == 'DeleteWhere':
303 evalDeleteWhere(ctx, u)
304 elif u.name == 'Modify':
305 evalModify(ctx, u)
306 else:
307 raise Exception('Unknown update operation: %s' % (u,))
308 except:
309 if not u.silent:
310 raise