def test_limit_offset(self): req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT ?name WHERE { ?x foaf:name ?name } ' 'LIMIT 20') ast = parse(req) self.assertEquals(ast.limit, 20) req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT ?name WHERE { ?x foaf:name ?name } ' 'ORDER BY ?name LIMIT 5 OFFSET 10') ast = parse(req) self.assertEquals(ast.limit, 5) self.assertEquals(ast.offset, 10)
def test_select_distinct_or_reduced(self): req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT ?name WHERE { ?x foaf:name ?name }') ast = parse(req) self.assertEquals(ast.distinct, False) self.assertEquals(ast.reduced, False) req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT DISTINCT ?name WHERE { ?x foaf:name ?name }') ast = parse(req) self.assertEquals(ast.distinct, True) self.assertEquals(ast.reduced, False) req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT REDUCED ?name WHERE { ?x foaf:name ?name }') ast = parse(req) self.assertEquals(ast.distinct, False) self.assertEquals(ast.reduced, True)
def translate(self, sparql): sparqlst = parse(sparql) if sparqlst.type != 'select': raise UnsupportedQuery() qi = QueryInfo(sparqlst) for subj, predicate, obj in sparqlst.where: if not isinstance(subj, ast.SparqlVar): raise UnsupportedQuery() # make a valid rql var name subjvar = subj.name.upper() if predicate in [('', 'a'), ('http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'type')]: # special 'is' relation if not isinstance(obj, tuple): raise UnsupportedQuery() # restrict possible types for the subject variable qi.set_possible_types(subjvar, xy.yeq(':'.join(obj), isentity=True)) else: # 'regular' relation (eg not 'is') if not isinstance(predicate, tuple): raise UnsupportedQuery() # list of 3-uple # (yams etype (subject), yams rtype, yams etype (object)) # where subject / object entity type may '*' if not specified yams_predicates = xy.yeq(':'.join(predicate)) qi.infer_types_info.append((yams_predicates, subjvar, obj)) if not isinstance(obj, (ast.SparqlLiteral, ast.SparqlVar)): raise UnsupportedQuery() qi.infer_types() qi.build_restrictions() return qi
def test_select_star(self): req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT * ' 'WHERE { ' ' ?x foaf:name ?name; ' ' foaf:mbox ?mbox. }') ast = parse(req) self.assertEquals(ast.type, 'select') self.assertEquals(ast.prefixes, {'foaf': FOAF}) self.assertEquals(ast.selected, ['*'])
def test_one_var_one_triple(self): req = ('PREFIX doap: <http://usefulinc.com/ns/doap#> ' 'SELECT ?project ' 'WHERE { ?project a doap:Project }') ast = parse(req) self.assertEquals(ast.type, 'select') self.assertEquals(ast.prefixes, {'doap': DOAP}) self.assertEquals(ast.selected, [SparqlVar('project')]) self.assertEquals(ast.variables, {'project':SparqlVar('project')}) self.assertEquals(ast.where, [(SparqlVar('project'), ('','a'), (DOAP,'Project'))])
def test_orderby(self): req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT ?name WHERE { ?x foaf:name ?name } ' 'ORDER BY ?name') ast = parse(req) self.assertEquals(ast.orderby, [(SparqlVar('name'), 'asc')]) req = ('PREFIX : <http://example.org/ns#> ' 'PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> ' 'SELECT ?name WHERE { ?x foaf:name ?name ; :empId ?emp } ' 'ORDER BY DESC(?emp)') ast = parse(req) self.assertEquals(ast.orderby, [(SparqlVar('emp'), 'desc')]) req = ('PREFIX : <http://example.org/ns#> ' 'PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT ?name WHERE { ?x foaf:name ?name ; :empId ?emp } ' 'ORDER BY ?name DESC(?emp)') ast = parse(req) self.assertEquals(ast.orderby, [(SparqlVar('name'), 'asc'), (SparqlVar('emp'), 'desc')])
def test_one_var_two_sametriples(self): req = ('PREFIX doap: <http://usefulinc.com/ns/doap#> ' 'SELECT ?project ' 'WHERE { ?project a doap:Project; ' ' doap:name "fyzz-y". ' '}') ast = parse(req) self.assertEquals(ast.type, 'select') self.assertEquals(ast.prefixes, {'doap': DOAP}) self.assertEquals(ast.selected, [SparqlVar('project')]) self.assertEquals(ast.variables, {'project':SparqlVar('project')}) self.assertEquals(ast.where, [(SparqlVar('project'), ('','a'), (DOAP,'Project')), (SparqlVar('project'), (DOAP,'name'), SparqlLiteral('fyzz-y'))])
def test_two_vars_two_sametriples(self): req = ('PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' 'SELECT ?name ?mbox ' 'WHERE { ' ' ?x foaf:name ?name; ' ' foaf:mbox ?mbox. }') ast = parse(req) self.assertEquals(ast.type, 'select') self.assertEquals(ast.prefixes, {'foaf': FOAF}) self.assertEquals(ast.selected, [SparqlVar('name'),SparqlVar('mbox')]) self.assertEquals(ast.variables, {'name':SparqlVar('name'), 'mbox':SparqlVar('mbox'), 'x':SparqlVar('x')}) self.assertEquals(ast.where, [(SparqlVar('x'), (FOAF,'name'), SparqlVar('name')), (SparqlVar('x'), (FOAF,'mbox'), SparqlVar('mbox'))])
def handle_subscribe_request(self, msg_dict): # sparql subscription if msg_dict["enc"].lower() == "sparql": # create the LUTT lutt = [] # take the triple patterns from the SPARQL query parsed_query = parse(msg_dict["qt"]) for pattern in parsed_query.where: lutt_row = [] for i in xrange(3): if pattern[i].__class__.__name__ == "SparqlVar": # substitute the variable with a wildcard lutt_row.append(None) # (URIRef(SIB_ANY_URI)) else: # determine if it is a URI or Literal # TODO: support for BNodes? field = ''.join(pattern[i]) if self.server.urivalidator(field): if URIRef(field) == SIB_ANY_URI: lutt_row.append(None) else: lutt_row.append(URIRef(field)) else: lutt_row.append(Literal(field)) lutt.append(lutt_row) # create a new ID for the new subscription new_sub_uuid = str(uuid.uuid4()) # create a structure for the subscription self.server.subscriptions[new_sub_uuid] = {} self.server.subscriptions[new_sub_uuid]["graph"] = Graph() self.server.subscriptions[new_sub_uuid]["lutt"] = lutt self.server.subscriptions[new_sub_uuid]["type"] = "sparql" self.server.subscriptions[new_sub_uuid]["query"] = msg_dict["qt"] self.server.subscriptions[new_sub_uuid]["indication_sequence"] = 0 # use the triple patterns in the LUTT to perform an RDF # query in order to fill the local copy of the graph for row in lutt: self.server.subscriptions[new_sub_uuid]["graph"] += self.server.graph.triples(row) # execute the SPARQL query then save and return the results results = self.server.graph.query(msg_dict["qt"]) # save the results self.server.subscriptions[new_sub_uuid]["query_results"] = results # build the reply message variables = results.vars json_results = [] c = 0 for result in results: result_element = {} for element in result: var = variables[result.index(element)] result_element[str(var)] = {} result_element[str(var)]["value"] = str(element) result_element[str(var)]["type"] = element.__class__.__name__ json_results.append(result_element) c += 1 # build the reply message reply_dict = { "tt" : "SUBSCRIBE", "mt" : "CONFIRM", "tid" : int(msg_dict["tid"]), "sid" : msg_dict["sid"], "nid" : msg_dict["nid"], "code" : "m3:Success", "results" : json_results, "subid" : new_sub_uuid } return self.server.builder.build(reply_dict) # rdf subscription elif msg_dict["enc"].lower() == "rdf": # create the LUTT lutt = [] triple_patterns = map(self.extract_members, msg_dict["tl"]) for pattern in triple_patterns: lutt.append(pattern) # triple_pattern = self.extract_members(msg_dict["tl"]) # lutt.append(triple_pattern) # register the new subscription new_sub_uuid = str(uuid.uuid4()) # execute the RDF query res_graph = Graph() for pattern in triple_patterns: res_graph += self.server.graph.triples(pattern) # create a structure for the subscription self.server.subscriptions[new_sub_uuid] = {} self.server.subscriptions[new_sub_uuid]["graph"] = res_graph self.server.subscriptions[new_sub_uuid]["lutt"] = lutt self.server.subscriptions[new_sub_uuid]["type"] = "rdf" self.server.subscriptions[new_sub_uuid]["query"] = triple_patterns self.server.subscriptions[new_sub_uuid]["query_results"] = Graph() self.server.subscriptions[new_sub_uuid]["query_results"] += res_graph # self.server.graph.triples(triple_pattern) self.server.subscriptions[new_sub_uuid]["indication_sequence"] = 0 # build the structure containing the results json_results = [] for res in res_graph: json_result = {} json_result["subject"] = {"value" : str(res[0]), "type" : str(res[0].__class__.__name__)} json_result["predicate"] = {"value" : str(res[1]), "type" : str(res[1].__class__.__name__)} json_result["object"] = {"value" : str(res[2]), "type" : str(res[2].__class__.__name__)} json_results.append(json_result) # build the reply message reply_dict = { "tt" : "SUBSCRIBE", "mt" : "CONFIRM", "tid" : int(msg_dict["tid"]), "sid" : msg_dict["sid"], "nid" : msg_dict["nid"], "code" : "m3:Success", "results" : json_results, "subid" : new_sub_uuid } return self.server.builder.build(reply_dict)
def parse_file(self, filename): text = file(filename).read() return parse(text)