def __get_by_subquery(self, params): context = params.get("context", None) inner_query = select("?s") inner_params = params.copy() if "order" in params: # "order" needs to stay in subquery, # but doesn't do anything useful in main query del params["order"] self.__apply_limit_offset_order_get_by_filter(inner_params, inner_query) query = select("?s", "?p", "?v", "?c").distinct() query.group(('?s', '?p', '?v'), optional_group(('?v', a, '?c'))) query.where(inner_query) if not (context is None): query.from_(context) # Need ordering in outer query if "order" in params: if params["order"] == True: # Order by subject URI query.order_by("?s") else: # Match another variable, order by it query.optional_group(("?s", params["order"], "?order")) query.order_by("?order") table = self._to_table(self._execute(query)) subjects = {} results = [] for match in table: # Make sure subject and predicate are URIs (they have to be!), # this works around bug in Virtuoso -- it sometimes returns # URIs as Literals. subject = URIRef(match["s"]) predicate = URIRef(match["p"]) value = match["v"] # Add subject to result list if it's not there if not subject in subjects: instance_data = {"direct" : {}} subjects[subject] = instance_data results.append((subject, instance_data)) # Add predicate to subject's direct predicates if it's not there direct_attributes = subjects[subject]["direct"] if not predicate in direct_attributes: direct_attributes[predicate] = {} # Add value to subject->predicate if ... predicate_values = direct_attributes[predicate] if not value in predicate_values: predicate_values[value] = [] # Add RDF type of the value to subject->predicate->value list if "c" in match: predicate_values[value].append(match["c"]) return results
def _get_by_subquery(self, params): context = params.get("context", None) inner_query = select("?s") inner_params = params.copy() if "order" in params: # "order" needs to stay in subquery, # but doesn't do anything useful in main query del params["order"] _apply_solution_modifiers(inner_params, inner_query) if params.get('direct_only'): query = select("?s", "?p", "?v", "?c").distinct() query.group(('?s', '?p', '?v'), optional_group(('?v', a, '?c'))) else: direct_query = select("?s", "?p", "?v", "?c", '("0" AS ?i)') direct_query.distinct() direct_query.group(('?s', '?p', '?v'), optional_group(('?v', a, '?c'))) indirect_query = select("?s", "?p", "?v", "?c", '("1" AS ?i)') indirect_query.distinct() indirect_query.group(('?v', '?p', '?s'), optional_group(('?v', a, '?c'))) query = select("?s", "?p", "?v", "?c", "?i") query.union(direct_query, indirect_query) query.where(inner_query) if not (context is None): query.from_(context) # Need ordering in outer query if "order" in params: if params["order"]: # Order by subject URI query.order_by("?s") else: # Match another variable, order by it query.optional_group(("?s", params["order"], "?order")) query.order_by("?order") table = self._to_table(self._execute(query)) subjects = {} results = [] for match in table: # Make sure subject and predicate are URIs (they have to be!), # this works around bug in Virtuoso -- it sometimes returns # URIs as Literals. subject = URIRef(match["s"]) predicate = URIRef(match["p"]) value = match["v"] # Inverse given if direct_only is False inverse = match.get("i") == "1" # Add subject to result list if it's not there if subject not in subjects: instance_data = {"direct": {}, "inverse": {}} subjects[subject] = instance_data results.append((subject, instance_data)) if inverse: attributes = subjects[subject]["inverse"] else: attributes = subjects[subject]["direct"] # Add predicate to subject's predicates if it's not there if predicate not in attributes: attributes[predicate] = {} # Add value to subject->predicate if ... predicate_values = attributes[predicate] if value not in predicate_values: predicate_values[value] = [] # Add RDF type of the value to subject->predicate->value list if "c" in match: predicate_values[value].append(match["c"]) return results
def __get_by_subquery(self, params): contexts = params.get("contexts", None) inner_query = select("?s") inner_params = params.copy() if "order" in params: # "order" needs to stay in subquery, # but doesn't do anything useful in main query del params["order"] self.__apply_limit_offset_order_get_by_filter(inner_params, inner_query) query = select("?s", "?p", "?v", "?c", "?g").distinct() # Get values with object type & context # TODO we need to query both contexts, from ?s -> rdf_type & ?v -> rdf_type but Virtuoso does not bind ?g twice. Bug or feature? query.group(('?s', '?p', '?v'), optional_group(('?v', a, '?c')), optional_group(named_group("?g", ("?s", a, "?v")))) #optional_group(named_group("?g", ("?v", a, "?c")))) query.where(inner_query) if contexts: query.from_(*contexts) query.from_named(*contexts) # Need ordering in outer query if "order" in params: if params["order"] == True: # Order by subject URI query.order_by("?s") else: # Match another variable, order by it query.optional_group(("?s", params["order"], "?order")) query.order_by("?order") table = self._to_table(self._execute(query)) subjects = {} results = [] for match in table: # Make sure subject and predicate are URIs (they have to be!), # this works around bug in Virtuoso -- it sometimes returns # URIs as Literals. subject = URIRef(match["s"]) predicate = URIRef(match["p"]) value = match["v"] # Add subject to result list if it's not there if not subject in subjects: instance_data = {"direct" : {}} subjects[subject] = instance_data results.append((subject, instance_data)) # Add predicate to subject's direct predicates if it's not there direct_attributes = subjects[subject]["direct"] if not predicate in direct_attributes: direct_attributes[predicate] = {} # "context" comes from an optional group and is missing if the # triple is stored in the unamed graph context = match.get("g") # Add value to subject->predicate if ... predicate_values = direct_attributes[predicate] if not value in predicate_values: predicate_values[value] = {context: []} # Add RDF type of the value to subject->predicate->value list if "c" in match: predicate_values[value][context].append(match["c"]) return results