Exemple #1
0
def query_S(s, direct, contexts):
    """ Construct :class:`surf.query.Query` with `?p`, `?v` and `?g`, `?c` as
    unknowns. """
    s, v = direct and (s, '?v') or ('?v', s)
    query = select('?p', '?v', '?c', '?g').distinct()
    # Get predicate, objects and optionally rdf:type & named graph of
    # subject rdf:type and object rdf:type
    # TODO fails under Virtuoso as V. doesn't allow ?g to be bound to two
    # optional matches
    query.where((s, '?p', v)).optional_group(('?v', a, '?c'))\
                             .optional_group(named_group('?g', (s, a, v)))\
                             .optional_group(named_group('?g', ('?v', a, '?c')))
    if contexts:
        query.from_(*contexts)
        query.from_named(*contexts)

    return query
Exemple #2
0
def query_Ask(subject, context):
    """ Construct :class:`surf.query.Query` of type **ASK**. """

    query = ask()
    if context:
        pattern = named_group(context, (subject, '?p', '?o'))
        query.where(pattern)
    else:
        query.where((subject, '?p', '?o'))

    return query
Exemple #3
0
def query_Ask(subject, context):
    """ Construct :class:`surf.query.Query` of type **ASK**. """

    query = ask()
    if context:
        pattern = named_group(context, (subject, '?p', '?o'))
        query.where(pattern)
    else:
        query.where((subject, '?p', '?o'))

    return query
Exemple #4
0
def query_SP(s, p, direct, contexts):
    """ Construct :class:`surf.query.Query` with `?v` and `?g`, `?c` as
    unknowns. """

    s, v = direct and (s, '?v') or ('?v', s)
    query = select('?v', '?c', '?g').distinct()
    query.where((s, p, v)).optional_group(('?v', a, '?c'))\
                          .optional_group(named_group('?g', ('?v', a, '?c')))
    if contexts:
        query.from_(*contexts)
        query.from_named(*contexts)

    return query
Exemple #5
0
def query_ask(s, context):
    """
    Construct :class:`surf.query.Query` of type **ASK**.

    :param s: the `subject`
    :param context: the context
    :return: the query
    :rtype: :class:`surf.query.Query`
    """
    query = ask()
    if context:
        pattern = named_group(context, (s, '?p', '?o'))
        query.where(pattern)
    else:
        query.where((s, '?p', '?o'))

    return query
Exemple #6
0
def query_ask(s, context):
    """
    Construct :class:`surf.query.Query` of type **ASK**.

    :param s: the `subject`
    :param context: the context
    :return: the query
    :rtype: :class:`surf.query.Query`
    """
    query = ask()
    if context:
        pattern = named_group(context, (s, '?p', '?o'))
        query.where(pattern)
    else:
        query.where((s, '?p', '?o'))

    return query
Exemple #7
0
def query_P_S(c, p, direct, context):
    """ Construct :class:`surf.query.Query` with `?s` and `?g`, `?c` as
    unknowns. """

    query = select('?s', '?c', '?g').distinct()
    if context:
        query.from_(context)
        query.from_named(context)

    for i in range(len(p)):
        s, v = direct and  ('?s', '?v%d' % i) or ('?v%d' % i, '?s')
        if type(p[i]) is URIRef:
            query.where((s, p[i], v))

    query.optional_group(('?s', a, '?c'))
    query.optional_group(named_group('?g', ('?s', a, '?c')))

    return query
Exemple #8
0
    def _get_by(self, params):
        # Decide which loading strategy to use
        if "full" in params:
            if self.use_subqueries:
                return self.__get_by_subquery(params)
            else:
                return self.__get_by_n_queries(params)

        # No details, just subjects and classes
        query = select("?s", "?c", "?g")
        self.__apply_limit_offset_order_get_by_filter(params, query)
        query.optional_group(("?s", a, "?c"))
        # Query for the same tuple to get the named graph if obtainable
        query.optional_group(named_group("?g", ("?s", a, "?c")))

        contexts = params.get("contexts", None)
        if contexts:
            query.from_(*contexts)
            query.from_named(*contexts)

        # Load just subjects and their types
        table = self._to_table(self._execute(query))

        # Create response structure, preserve order, don't include
        # duplicate subjects if some subject has multiple types
        subjects = {}
        results = []
        for match in table:
            subject = match["s"]
            if not subject in subjects:
                instance_data = {"direct" : {a : {}}}
                subjects[subject] = instance_data
                results.append((subject, instance_data))

            # "context" comes from an optional group and is missing if the
            # triple is stored in the unamed graph
            context = match.get("g")

            if "c" in match:
                concept = match["c"]
                subjects[subject]["direct"][a][concept] = {context: []}

        return results
Exemple #9
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