99from pygit2 import GIT_MERGE_ANALYSIS_NORMAL
1010from pygit2 import GIT_SORT_REVERSE , GIT_RESET_HARD , GIT_STATUS_CURRENT
1111
12+ import rdflib
1213from rdflib import Graph , ConjunctiveGraph , BNode , Literal , URIRef
14+ import rdflib .plugins .parsers .ntriples as ntriples
15+
1316import re
1417
1518from quit .conf import Feature , QuitGraphConfiguration
@@ -189,7 +192,12 @@ def instance(self, reference, force=False):
189192 for blob in self .getFilesForCommit (commit ):
190193 try :
191194 (name , oid ) = blob
192- (f , context ) = self .getFileReferenceAndContext (blob , commit )
195+ result = self .getFileReferenceAndContext (blob , commit )
196+ try :
197+ (f , context , nameMap ) = result
198+ except ValueError :
199+ print (result )
200+
193201 internal_identifier = context .identifier + '-' + str (oid )
194202
195203 if force or not self .config .hasFeature (Feature .Persistence ):
@@ -330,13 +338,15 @@ def changeset(self, commit):
330338 blob = (entity .name , entity .oid )
331339
332340 try :
333- f , context = self .getFileReferenceAndContext (blob , commit )
341+ f , context , nameMap = self .getFileReferenceAndContext (blob , commit )
334342 except KeyError :
335343 graph = Graph (identifier = graphUri )
336- graph .parse (data = entity .content , format = 'nt' )
344+ parserGraph = ntriples .W3CNTriplesParser (ntriples .NTGraphSink (graph ))
345+ source = rdflib .parser .create_input_source (data = entity .content )
346+ parserGraph .parse (source .getCharacterStream ())
337347
338348 self ._blobs .set (
339- blob , (FileReference (entity .name , entity .content ), graph )
349+ blob , (FileReference (entity .name , entity .content ), graph , {} )
340350 )
341351
342352 private_uri = QUIT ["graph-{}" .format (entity .oid )]
@@ -413,16 +423,62 @@ def getFileReferenceAndContext(self, blob, commit):
413423 content = commit .node (path = name ).content
414424 graphUri = self ._graphconfigs .get (commit .id ).getgraphuriforfile (name )
415425 graph = Graph (identifier = URIRef (graphUri ))
416- graph .parse (data = content , format = 'nt' )
417- quitWorkingData = (FileReference (name , content ), graph )
426+ parserGraph = ntriples .W3CNTriplesParser (ntriples .NTGraphSink (graph ))
427+ source = rdflib .parser .create_input_source (data = content )
428+ parserGraph .parse (source .getCharacterStream ())
429+ nameMap = {v : k for k , v in parserGraph ._bnode_ids .items ()}
430+ quitWorkingData = (FileReference (name , content ), graph , nameMap )
418431 self ._blobs .set (blob , quitWorkingData )
419432 return quitWorkingData
420433 return self ._blobs .get (blob )
421434
435+
436+ def _replaceLabledBlankNodes (self , parsedQuery , parent_commit_ref ):
437+ def replaceBlankNode (parsedQuery , nameMap ):
438+ nameMap = {v : k for k , v in nameMap .items ()}
439+ for update in parsedQuery :
440+ for graphURI in update ['quads' ]:
441+ new_triples = []
442+ for triple in update ['quads' ][graphURI ]:
443+ new_triple_subj = None
444+ new_triple_obj = None
445+ if isinstance (triple [0 ], rdflib .BNode ):
446+ bNode_key = triple [0 ].n3 ()
447+ bNode_key = bNode_key [2 :]
448+ if bNode_key in nameMap :
449+ new_triple_subj = nameMap [bNode_key ]
450+ else :
451+ new_triple_subj = triple [0 ]
452+ nameMap [bNode_key ] = triple [0 ]
453+ else :
454+ new_triple_subj = triple [0 ]
455+ if isinstance (triple [2 ], rdflib .BNode ):
456+ bNode_key = triple [2 ].n3 ()
457+ bNode_key = bNode_key [2 :]
458+ if bNode_key in nameMap :
459+ new_triple_obj = nameMap [bNode_key ]
460+ else :
461+ new_triple_obj = triple [2 ]
462+ nameMap [bNode_key ] = triple [2 ]
463+ else :
464+ new_triple_obj = triple [2 ]
465+ new_triples .append ((new_triple_subj , triple [1 ], new_triple_obj ))
466+ update ['quads' ][graphURI ] = new_triples
467+
468+ parent_commit = self .repository .revision (parent_commit_ref )
469+ blobs = self .getFilesForCommit (parent_commit )
470+ for blob in blobs :
471+ (name , oid ) = blob
472+ if (name == "graph.nt" ):
473+ file_reference , context , nameMap = self .getFileReferenceAndContext (blob , parent_commit )
474+ replaceBlankNode (parsedQuery , nameMap )
475+
476+
422477 def applyQueryOnCommit (self , parsedQuery , parent_commit_ref , target_ref , query = None ,
423478 default_graph = [], named_graph = []):
424479 """Apply an update query on the graph and the git repository."""
425480 graph , commitid = self .instance (parent_commit_ref )
481+ self ._replaceLabledBlankNodes (parsedQuery , parent_commit_ref )
426482 resultingChanges , exception = graph .update (parsedQuery )
427483 if exception :
428484 # TODO need to revert or invalidate the graph at this point.
@@ -494,7 +550,7 @@ def commit(self, graph, delta, message, parent_commit_ref, target_ref, query=Non
494550
495551 # Update Cache and add new contexts to store
496552 blob = fileReference .path , index .stash [fileReference .path ][0 ]
497- self ._blobs .set (blob , (fileReference , graph .store .get_context (identifier )))
553+ self ._blobs .set (blob , (fileReference , graph .store .get_context (identifier ), {} ))
498554 blobs_new .add (blob )
499555 if graphconfig .mode == 'configuration' :
500556 index .add ('config.ttl' , new_config .graphconf .serialize (format = 'turtle' ).decode ())
@@ -546,7 +602,7 @@ def _applyKnownGraphs(self, delta, blobs, parent_commit, index):
546602 for blob in blobs :
547603 (fileName , oid ) = blob
548604 try :
549- file_reference , context = self .getFileReferenceAndContext (blob , parent_commit )
605+ file_reference , context , nameMap = self .getFileReferenceAndContext (blob , parent_commit )
550606 for entry in delta :
551607 changeset = entry ['delta' ].get (context .identifier , None )
552608
@@ -558,7 +614,7 @@ def _applyKnownGraphs(self, delta, blobs, parent_commit, index):
558614
559615 self ._blobs .remove (blob )
560616 blob = fileName , index .stash [file_reference .path ][0 ]
561- self ._blobs .set (blob , (file_reference , context ))
617+ self ._blobs .set (blob , (file_reference , context , nameMap ))
562618 blobs_new .add (blob )
563619 except KeyError :
564620 pass
0 commit comments