示例#1
0
    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
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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