11from abc import ABC , abstractmethod
2- from rdflib import URIRef , BNode , Dataset , Graph
2+ from rdflib import URIRef , Literal , BNode , Dataset , Graph
33from SPARQLWrapper import SPARQLWrapper
44import requests
55import warnings
@@ -26,7 +26,7 @@ class AbstractTripleStore(ABC):
2626
2727 """Must implement SPARQL Query"""
2828 @abstractmethod
29- def query (self , query ):
29+ def query (self , query , format ):
3030 pass
3131
3232 """Import"""
@@ -67,10 +67,11 @@ def __client(self, query):
6767 client .setQuery (self .prefixes + query )
6868 return client
6969
70- def query (self , query ):
70+ def query (self , query , format = 'sparql' ):
7171 client = self .__client (query )
7272 try :
73- return client .queryAndConvert ()["results" ]["bindings" ]
73+ result = client .queryAndConvert ()["results" ]["bindings" ]
74+ return convert_query_result (result , convert_sparql_term , format )
7475 except Exception as e :
7576 raise ServerError (f"SPARQL Query failed: { e } " )
7677
@@ -97,28 +98,17 @@ class InternalTripleStore(AbstractTripleStore):
9798 def __init__ (self ):
9899 self .ds = Dataset (default_union = True )
99100
100- def query (self , query ):
101- def term (t ):
102- if isinstance (t , URIRef ):
103- return {"type" : "uri" , "value" : str (t )}
104- if isinstance (t , BNode ):
105- return {"type" : "bnode" , "value" : str (t )}
106- literal = {"type" : "literal" , "value" : str (t )}
107- if t .language :
108- literal ["xml:lang" ] = t .language
109- if t .datatype :
110- literal ["datatype" ] = str (t .datatype )
111- return literal
112-
101+ def query (self , query , format = 'sparql' ):
113102 def map_row (row ):
114- return {str (k ): term ( v ) for k , v in row .items ()}
103+ return {str (k ): convert_rdflib_term ( v , format ) for k , v in row .items ()}
115104
116105 query = self .prefixes + query
117106
118107 # RDFLib raises warning, see <https://github.com/RDFLib/rdflib/issues/3361>
119108 with warnings .catch_warnings ():
120109 warnings .filterwarnings ("ignore" , category = DeprecationWarning )
121- return [map_row (row ) for row in self .ds .query (query ).bindings ]
110+ result = self .ds .query (query ).bindings
111+ return convert_query_result (result , convert_rdflib_term , format )
122112
123113 def _update (self , query ):
124114 self .ds .update (self .prefixes + query )
@@ -133,3 +123,50 @@ def store_file(self, graph, file):
133123 for triple in data :
134124 graph .add (triple )
135125 return True
126+
127+
128+ def convert_query_result (result , mapper , target ):
129+ """Convert a SPARQL Query result to target form (sparql, rdflib, n3, nq, ttl)."""
130+
131+ if target == "nq" or target == "ttl" :
132+ result = convert_query_result (result , mapper , "n3" )
133+ return "\n " .join ([
134+ " " .join ([row .get (f ) for f in ['g' , 's' , 'p' , 'o' ] if f in row ]) + " ."
135+ for row in result ])
136+
137+ return [{str (k ): mapper (v , target ) for k , v in row .items ()} for row in result ]
138+
139+
140+ def convert_sparql_term (term , format ):
141+ if format == "rdflib" or format == "n3" :
142+ if term ['type' ] == 'uri' :
143+ term = URIRef (term ['value' ])
144+ elif term ['type' ] == 'bnode' :
145+ term = BNode (term ['value' ])
146+ elif term ['type' ] == 'literal' :
147+ if 'datatype' in term :
148+ term = Literal (term ['value' ], datatype = URIRef (term ['datatype' ]))
149+ elif 'xml:lang' in term :
150+ term = Literal (term ['value' ], lang = term ['xml:lang' ])
151+ else :
152+ term = Literal (term ['value' ])
153+ if format == "n3" :
154+ return term .n3 ()
155+ return term
156+
157+
158+ def convert_rdflib_term (term , format ):
159+ if format == "rdflib" :
160+ return term
161+ if format == "n3" :
162+ return term .n3 ()
163+ if isinstance (term , URIRef ):
164+ return {"type" : "uri" , "value" : str (term )}
165+ if isinstance (term , BNode ):
166+ return {"type" : "bnode" , "value" : str (term )}
167+ literal = {"type" : "literal" , "value" : str (term )}
168+ if term .language :
169+ literal ["xml:lang" ] = term .language
170+ if term .datatype :
171+ literal ["datatype" ] = str (term .datatype )
172+ return literal
0 commit comments