Exemplo n.º 1
0
    def test_visit_SelectQuery(self):
        st2 = Triple(Variable("d"), Variable("e"), Variable("f"))
        helper = SelectQueryHelper()
        expected = "SELECT WHERE{}"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result) 

        helper.set_limit("50")
        expected = "SELECT WHERE{}LIMIT 50"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result) 

        helper.add_triple_variables(st2)
        helper.add_filter(FunCall("regex", Variable("var"), '"regex"'))
        expected = "SELECT?e?f?d WHERE{?d ?e ?f.FILTER(regex(?var,\"regex\"))}LIMIT 50"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result) 
        self.assertNotEqual(None, Parse(result))

        helper.set_offset("2")
        expected = "SELECT?e?f?d WHERE{?d ?e ?f.FILTER(regex(?var,\"regex\"))}LIMIT 50 OFFSET 2"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result) 
        self.assertNotEqual(None, Parse(result))

        helper.add_optional(st2, st2)
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.add_union([st2, st2], [st2], [st2])
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.set_orderby("e")
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.set_orderby("e")
        helper.query.modifiers = []
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.add_filter_notbound(Variable("e")) 
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.add_or_filter_regex({Variable("a"): "r1", Variable("b"): "r2"})
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))
Exemplo n.º 2
0
    def test_visit_SelectQuery(self):
        st2 = Triple(Variable("d"), Variable("e"), Variable("f"))
        helper = SelectQueryHelper()
        expected = "SELECT WHERE{}"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result)

        helper.set_limit("50")
        expected = "SELECT WHERE{}LIMIT 50"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result)

        helper.add_triple_variables(st2)
        helper.add_filter(FunCall("regex", Variable("var"), '"regex"'))
        expected = "SELECT?e?f?d WHERE{?d ?e ?f.FILTER(regex(?var,\"regex\"))}LIMIT 50"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result)
        self.assertNotEqual(None, Parse(result))

        helper.set_offset("2")
        expected = "SELECT?e?f?d WHERE{?d ?e ?f.FILTER(regex(?var,\"regex\"))}LIMIT 50 OFFSET 2"
        result = self.v.visit(helper.query)
        self.assertEqual(expected, result)
        self.assertNotEqual(None, Parse(result))

        helper.add_optional(st2, st2)
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.add_union([st2, st2], [st2], [st2])
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.set_orderby("e")
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.set_orderby("e")
        helper.query.modifiers = []
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.add_filter_notbound(Variable("e"))
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))

        helper.add_or_filter_regex({Variable("a"): "r1", Variable("b"): "r2"})
        result = self.v.visit(helper.query, True)
        self.assertNotEqual(None, Parse(result))
Exemplo n.º 3
0
class SPARQLQueryBuilder:
    def __init__(self):
        self.helper = SelectQueryHelper()

    def create_query_from_form(self, formdata):
        self.params = formdata
        self._add_base_elements()
        self._add_from()
        self._consume_distribution()
        self._consume_area()
        self._consume_sort()
        self._consume_homepage()
        self._consume_maintainer()
        self._consume_version()
        self._consume_priority()
        self._consume_comaintainer()
        self._consume_vcs()
        self._consume_section()
        self._consume_buildessential()
        self._consume_essential()
        self._consume_dmuploadallowed()
        self._consume_popcon()
        self._consume_filter()
        self.helper.set_limit(RESULTS_PER_PAGE)
        self.helper.set_distinct()
        return self.helper.__str__()

    def binary_search(self):
        if "searchtype" in self.params:
            type = self.params["searchtype"]
            if type in ("BINARY", "BINARYEXT"):
                return True
            elif type in ("SOURCE"):
                return False
            else:
                raise SPARQLQueryBuilderUnexpectedFieldValueError("searchtype")
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("searchtype")

    def source_search(self):
        return not self.binary_search()

    def wants_json(self):
        if "tojson" in self.params:
            return self.params["tojson"]
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("json")

    def wants_html(self):
        # For the moment json/html are dual parameters
        return not self.wants_json()

    def _extended_binary_search(self):
        if "searchtype" in self.params:
            if self.params["searchtype"] == "BINARYEXT":
                return True
            else:
                return False
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("searchtype")

    def _add_base_elements(self):
        self.helper.push_triple_variables(Variable("source"), RDF.type, DEB.Source)
        self.helper.push_triple_variables(Variable("unversionedsource"), DEB.version, Variable("source"))
        self.helper.push_triple(Variable("source"), DEB.maintainer, Variable("maint"))
        self.helper.push_triple_variables(Variable("maint"), FOAF.mbox, Variable("maintmail"))
        self.helper.push_triple_variables(Variable("source"), DEB.versionNumber, Variable("sourceversion"))
        self.helper.push_triple_variables(Variable("sourceversion"), DEB.fullVersion, Variable("sourcefullversion"))
        self.helper.push_triple_variables(Variable("source"), DEB.packageName, Variable("sourcename"))

        if self.binary_search() or self._extended_binary_search():
            self.helper.push_triple_variables(Variable("binary"), RDF.type, DEB.Binary)
            self.helper.push_triple_variables(Variable("source"), DEB.binary, Variable("binary"))
            self.helper.push_triple_variables(Variable("binary"), DEB.packageName, Variable("binaryname"))
            self.helper.push_triple_variables(Variable("unversionedbinary"), DEB.version, Variable("binary"))
            self.helper.push_triple_variables(Variable("binary"), DEB.synopsis, Variable("synopsis"))
            self.helper.push_triple_variables(Variable("binary"), DEB.versionNumber, Variable("binaryversion"))
            self.helper.push_triple_variables(Variable("binaryversion"), DEB.fullVersion, Variable("binaryfullversion"))

    def _consume_filter(self):
        filter = self.params["filter"]
        if filter:
            filter = re.escape(filter).replace("\\", "\\\\")
            if self.params["exactmatch"]:
                filter = "".join(["^", filter, "$"])
            if self.binary_search():
                if self._extended_binary_search():
                    self.helper.push_triple(Variable("binary"), DEB.extendedDescription, Variable("desc"))
                    restrictions = {Variable("desc"): filter, Variable("binaryname"): filter}
                    self.helper.add_or_filter_regex(restrictions)
                else:
                    self.helper.add_or_filter_regex({Variable("binaryname"): filter})
            elif self.source_search():
                self.helper.add_or_filter_regex({Variable("sourcename"): filter})

    def _consume_distribution(self):
        distribution = self.params["distribution"]
        if distribution == "ANY":
            self.helper.push_triple_variables(Variable("source"), DEB.distribution, Variable("distribution"))
        else:
            self.helper.push_triple(Variable("source"), DEB.distribution, URIRef(distribution))

    def _consume_area(self):
        area = self.params["area"]
        if area == "ANY":
            self.helper.push_triple_variables(Variable("source"), DEB.area, Variable("area"))
        else:
            self.helper.push_triple(Variable("source"), DEB.area, URIRef(area))

    def _consume_sort(self):
        sort = self.params["sort"]
        if sort == "MAINTMAIL":
            self.helper.set_orderby("maintmail")
        elif sort == "PACKAGE":
            if self.binary_search():
                self.helper.set_orderby("binaryname")
            else:
                self.helper.set_orderby("sourcename")
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("sort")

    def _consume_homepage(self):
        if self.params["homepage"]:
            self.helper.add_variable("homepage")
            triple = Triple(Variable("source"), FOAF.page, Variable("homepage"))
            self.helper.add_optional(triple)

    def _consume_maintainer(self):
        option = self.params["maintainer"]
        if option == "TEAM":
            self.helper.push_triple(Variable("maint"), RDF.type, FOAF.Group)
        elif option == "DEBIAN":
            self.helper.add_or_filter_regex({Variable("maintmail"): "@debian.org$"})
        elif option == "QA":
            uriref = URIRef(RES_BASEURI + "/team/packages%40qa.debian.org")
            self.helper.push_triple(Variable("source"), DEB.maintainer, uriref)
        elif option == "CUSTOM":
            self._consume_maintainer_filter()
        elif option == "ALL":
            pass
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("maintainer")

    def _consume_version(self):
        options = self.params["version"]
        if "NATIVE" in options or "NMU" in options:
            triple = Triple(Variable("sourceversion"), DEB.debianRevision, Variable("debianRevision"))
            self.helper.add_optional(triple)
        if "NATIVE" in options:
            self.helper.add_filter_notbound(Variable("debianRevision"))
        if "NMU" in options:
            self.helper.push_triple(Variable("sourceversion"), DEB.upstreamVersion, Variable("upstreamVersion"))
            restrictions = {Variable("debianRevision"): ".*\\\..*", Variable("upstreamVersion"): ".*\\\+nmu.*"}
            self.helper.add_or_filter_regex(restrictions)
        if "EPOCH" in options:
            self.helper.push_triple(Variable("sourceversion"), DEB.epoch, Variable("epoch"))

    def _consume_priority(self):
        option = self.params["priority"]
        if option == "ANY":
            self.helper.add_variable("priority")
            if self.binary_search():
                triple = Triple(Variable("binary"), DEB.priority, Variable("priority"))
            elif self.source_search():
                triple = Triple(Variable("source"), DEB.priority, Variable("priority"))
            else:
                raise Exception()  # FIXME
            self.helper.add_optional(triple)
        else:
            if self.binary_search():
                self.helper.push_triple(Variable("binary"), DEB.priority, URIRef(option))
            elif self.source_search():
                self.helper.push_triple(Variable("source"), DEB.priority, URIRef(option))
            else:
                raise Exception()  # FIXME

    def _consume_section(self):
        keyword = self.params["section"]
        if keyword:
            keyword = re.escape(keyword).replace("\\", "\\\\")
            if self.binary_search():
                self.helper.push_triple(Variable("binary"), DEB.section, Variable("section"))
            elif self.source_search():
                self.helper.push_triple(Variable("source"), DEB.section, Variable("section"))
            else:
                raise Exception()  # FIXME
            self.helper.push_triple_variables(Variable("section"), DEB.sectionName, Variable("sectionname"))
            self.helper.add_or_filter_regex({Variable("sectionname"): keyword})
        else:
            self.helper.add_variable("section")
            self.helper.add_variable("sectionname")
            if self.binary_search():
                triple1 = Triple(Variable("binary"), DEB.section, Variable("section"))
            elif self.source_search():
                triple1 = Triple(Variable("source"), DEB.section, Variable("section"))
            else:
                raise Exception()  # FIXME
            triple2 = Triple(Variable("section"), DEB.sectionName, Variable("sectionname"))
            self.helper.add_optional(triple1, triple2)

    def _consume_comaintainer(self):
        option = self.params["comaintainer"]
        if option == "WITH":
            self.helper.push_triple(Variable("source"), DEB.uploader, Variable("uploader"))
        elif option == "WITHOUT":
            triple = Triple(Variable("source"), DEB.uploader, Variable("uploader"))
            self.helper.add_optional(triple)
            self.helper.add_filter_notbound(Variable("uploader"))
        elif option == "ALL":
            pass
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("comaintainer")

    def _consume_vcs(self):
        options = self.params["vcs"]
        if options:
            self.helper.push_triple(Variable("source"), DEB.repository, Variable("repobnode"))
            graphpatterns = []
            if "SVN" in options:
                graphpatterns.append([Triple(Variable("repobnode"), RDF.type, DOAP.SVNRepository)])
            if "GIT" in options:
                graphpatterns.append([Triple(Variable("repobnode"), RDF.type, DOAP.GitRepository)])
            if "CVS" in options:
                graphpatterns.append([Triple(Variable("repobnode"), RDF.type, DOAP.CVSRepository)])
            if "HG" in options:
                graphpatterns.append([Triple(Variable("repobnode"), RDF.type, DOAP.HgRepository)])

            if len(graphpatterns) == 1:
                self.helper.add_triple(graphpatterns[0][0])
            else:
                self.helper.add_union(*graphpatterns)

    def _consume_essential(self):
        if self.binary_search() and self.params["essential"]:
            self.helper.push_triple(Variable("binary"), RDF.type, DEB.EssentialBinary)

    def _consume_buildessential(self):
        if self.binary_search() and self.params["buildessential"]:
            self.helper.push_triple(Variable("binary"), RDF.type, DEB.BuildEssentialBinary)

    def _consume_dmuploadallowed(self):
        if self.source_search() and self.params["dmuploadallowed"]:
            self.helper.push_triple(Variable("source"), RDF.type, DEB.DMUploadAllowedSource)

    def _consume_popcon(self):
        if self.binary_search() and self.params["popcon"]:
            triple = Triple(Variable("unversionedbinary"), DEB.popconInstalled, Variable("?popconinstalled"))
            self.helper.add_variable("popconinstalled")
            self.helper.add_optional(triple)

            triple = Triple(Variable("unversionedbinary"), DEB.popconUsedRegularly, Variable("?popconused"))
            self.helper.add_variable("popconused")
            self.helper.add_optional(triple)

            triple = Triple(Variable("unversionedbinary"), DEB.popconInstalledButNotInUse, Variable("?popconnotinuse"))
            self.helper.add_variable("popconnotinuse")
            self.helper.add_optional(triple)

            triple = Triple(Variable("unversionedbinary"), DEB.popconUpgradedRecently, Variable("?popconupgraded"))
            self.helper.add_variable("popconupgraded")
            self.helper.add_optional(triple)

    def _consume_maintainer_filter(self):
        filter = self.params["maintainerfilter"]
        if filter:
            filter = re.escape(filter).replace("\\", "\\\\")
            self.helper.push_triple(Variable("maint"), FOAF.name, Variable("maintname"))
            restrictions = {Variable("maintmail"): filter, Variable("maintname"): filter}
            self.helper.add_or_filter_regex(restrictions)

    def _add_from(self):
        if FROM_GRAPH is not None:
            self.helper.set_from(FROM_GRAPH)

    def create_binaries_query(self, source, version):
        if re.match("^[-a-zA-Z0-9+.]+$", source) is None:
            raise SPARQLQueryBuilderPackageNameSchemeError()

        self.binary_search = lambda: True  # Kind of a hack :/
        self._add_base_elements()
        sourceuri = "%s/source/%s/%s" % (RES_BASEURI, urlquote_plus(source), urlquote_plus(version))
        self.helper.add_filter_regex_str_var(Variable("source"), sourceuri)
        return self.helper.__str__()
Exemplo n.º 4
0
class SelectQueryHelperTest(unittest.TestCase):
    def setUp(self):
        self.s = SelectQueryHelper()
        self.triple1 = Triple()
        self.triple1.subject = Variable("var1")
        self.triple1.property = RDFS.type
        self.triple1.object = DEB.Source
        self.triple2 = Triple()
        self.triple2.subject = Variable("var2")
        self.triple2.property = RDFS.type
        self.triple2.object = DEB.Binary
        self.triple3 = Triple()
        self.triple3.subject = Variable("var3")
        self.triple3.property = RDFS.type
        self.triple3.object = Variable("var4")

    def test_add_variable(self):
        self.s.add_variable("varname")
        self.s.add_variable("varname")
        self.assertEqual([Variable("varname")], self.s.query.variables)

    def test_add_triple(self):
        self.s.add_triple(self.triple1)
        self.s.add_triple(self.triple1)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple1, self.s.query.whereclause.stmts[0])
        self.s.add_triple(self.triple2)
        self.assertEqual(2, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple2, self.s.query.whereclause.stmts[1])

    def test_add_triple_variables(self):
        self.s.add_triple(self.triple3)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple3, self.s.query.whereclause.stmts[0])
        varlist = [Variable("var3"), Variable("var4")]
        self.assertEqual(varlist.sort(), self.s.query.variables.sort())

    def test_push_triple(self):
        self.s.push_triple(\
            Variable("var1"), RDFS.type, DEB.Source)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple1, self.s.query.whereclause.stmts[0])

    def test_push_triple_variables(self):
        self.s.push_triple_variables(\
            Variable("var3"), RDFS.type, Variable("var4"))
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple3, self.s.query.whereclause.stmts[0])
        varlist = [Variable("var3"), Variable("var4")]
        self.assertEqual(varlist.sort(), self.s.query.variables.sort())

    def test_add_optional(self):
        self.s.add_optional(self.triple1)
        opt1 = Optional(self.triple1)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(opt1, self.s.query.whereclause.stmts[0])

        self.s.add_optional(self.triple1, self.triple2)
        opt2 = Optional(self.triple1, self.triple2)
        self.assertEqual(2, len(self.s.query.whereclause.stmts))
        self.assertEqual(opt2, self.s.query.whereclause.stmts[1])

    def test_add_filter(self):
        f1 = FunCall("regex", "arg1", "arg2")
        f2 = FunCall("regex", "arg3", "arg4")
        binexp = BinaryExpression(f1, "||", f2)
        self.s.add_filter(binexp)

    def test_add_union(self):
        st1 = Triple(Variable("a"), Variable("b"), Variable("c"))
        st2 = Triple(Variable("d"), Variable("e"), Variable("f"))
        gp1 = [st1, st2]
        gp2 = [st1]
        self.s.add_union(gp1, gp2)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(2, len(self.s.query.whereclause.stmts[0].graphpatterns))
        self.assertEqual(2, len(self.s.query.whereclause.stmts[0].graphpatterns[0]))
        self.assertEqual(1, len(self.s.query.whereclause.stmts[0].graphpatterns[1]))
        self.assertRaises(Exception, self.s.add_union, gp1)

    def test_add_triple_variables(self):
        st1 = Triple(Variable("a"), Variable("b"), Variable("c"))
        self.s.add_triple_variables(st1)
        self.assertEqual(3, len(self.s.query.variables))

    def test_set_limit_and_offset(self):
        self.s.set_limit("2")
        self.s.set_offset("2")
        self.assertEqual(["2", "2"], [limit.value for limit in self.s.query.modifiers])

    def test_set_orderby(self):
        self.s.set_orderby("var")
        self.assertEqual(Variable("var"), self.s.query.orderby.variable)

    def test_set_from(self):
        uri = "http://some.where/graphs/graph"
        self.s.set_from(uri)
        self.assertEqual(URIRef(uri), self.s.query.fromgraph)
    
    def test_set_distinct(self):
        self.s.set_distinct()
        self.assertEqual(True, self.s.query.distinct)

    def test_str(self):
        expected = "SELECT WHERE{}"
        self.assertEqual(expected, str(self.s))

    def test_add_or_filter_regex(self):
        self.s.add_or_filter_regex({"a": "a1", "b": "b1", "c": "c1"})
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        b2 = BinaryExpression(FunCall("regex", "c", '"c1"', '"i"'), "||",\
                              FunCall("regex", "a", '"a1"', '"i"'))
        b1 = BinaryExpression(FunCall("regex", "b", '"b1"', '"i"'), "||", b2)
        f1 = Filter(b1)
        self.assertEqual(f1, self.s.query.whereclause.stmts[0])

        self.s.add_or_filter_regex({"a": "a1"})
        fc1 = FunCall("regex", "a", '"a1"', "\"i\"")
        f2 = Filter(fc1)
        self.assertEqual(2, len(self.s.query.whereclause.stmts))
        self.assertEqual(f2, self.s.query.whereclause.stmts[1])

    def test_add_filter_notbound(self):
        self.s.add_filter_notbound(Variable("a")) 
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        u1 = UnaryExpression(FunCall("bound", Variable("a")), "!")
        f1 = Filter(u1)
        self.assertEqual(f1, self.s.query.whereclause.stmts[0])

    def test_add_filter_regex_str_var(self):
        self.s.add_filter_regex_str_var(Variable("var"), "regex")
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        str = FunCall("str", Variable("var"))
        regex = FunCall("regex", str, '"regex"')
        f1 = Filter(regex)
        self.assertEqual(f1, self.s.query.whereclause.stmts[0])
Exemplo n.º 5
0
class SelectQueryHelperTest(unittest.TestCase):
    def setUp(self):
        self.s = SelectQueryHelper()
        self.triple1 = Triple()
        self.triple1.subject = Variable("var1")
        self.triple1.property = RDFS.type
        self.triple1.object = DEB.Source
        self.triple2 = Triple()
        self.triple2.subject = Variable("var2")
        self.triple2.property = RDFS.type
        self.triple2.object = DEB.Binary
        self.triple3 = Triple()
        self.triple3.subject = Variable("var3")
        self.triple3.property = RDFS.type
        self.triple3.object = Variable("var4")

    def test_add_variable(self):
        self.s.add_variable("varname")
        self.s.add_variable("varname")
        self.assertEqual([Variable("varname")], self.s.query.variables)

    def test_add_triple(self):
        self.s.add_triple(self.triple1)
        self.s.add_triple(self.triple1)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple1, self.s.query.whereclause.stmts[0])
        self.s.add_triple(self.triple2)
        self.assertEqual(2, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple2, self.s.query.whereclause.stmts[1])

    def test_add_triple_variables(self):
        self.s.add_triple(self.triple3)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple3, self.s.query.whereclause.stmts[0])
        varlist = [Variable("var3"), Variable("var4")]
        self.assertEqual(varlist.sort(), self.s.query.variables.sort())

    def test_push_triple(self):
        self.s.push_triple(\
            Variable("var1"), RDFS.type, DEB.Source)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple1, self.s.query.whereclause.stmts[0])

    def test_push_triple_variables(self):
        self.s.push_triple_variables(\
            Variable("var3"), RDFS.type, Variable("var4"))
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(self.triple3, self.s.query.whereclause.stmts[0])
        varlist = [Variable("var3"), Variable("var4")]
        self.assertEqual(varlist.sort(), self.s.query.variables.sort())

    def test_add_optional(self):
        self.s.add_optional(self.triple1)
        opt1 = Optional(self.triple1)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(opt1, self.s.query.whereclause.stmts[0])

        self.s.add_optional(self.triple1, self.triple2)
        opt2 = Optional(self.triple1, self.triple2)
        self.assertEqual(2, len(self.s.query.whereclause.stmts))
        self.assertEqual(opt2, self.s.query.whereclause.stmts[1])

    def test_add_filter(self):
        f1 = FunCall("regex", "arg1", "arg2")
        f2 = FunCall("regex", "arg3", "arg4")
        binexp = BinaryExpression(f1, "||", f2)
        self.s.add_filter(binexp)

    def test_add_union(self):
        st1 = Triple(Variable("a"), Variable("b"), Variable("c"))
        st2 = Triple(Variable("d"), Variable("e"), Variable("f"))
        gp1 = [st1, st2]
        gp2 = [st1]
        self.s.add_union(gp1, gp2)
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        self.assertEqual(2,
                         len(self.s.query.whereclause.stmts[0].graphpatterns))
        self.assertEqual(
            2, len(self.s.query.whereclause.stmts[0].graphpatterns[0]))
        self.assertEqual(
            1, len(self.s.query.whereclause.stmts[0].graphpatterns[1]))
        self.assertRaises(Exception, self.s.add_union, gp1)

    def test_add_triple_variables(self):
        st1 = Triple(Variable("a"), Variable("b"), Variable("c"))
        self.s.add_triple_variables(st1)
        self.assertEqual(3, len(self.s.query.variables))

    def test_set_limit_and_offset(self):
        self.s.set_limit("2")
        self.s.set_offset("2")
        self.assertEqual(["2", "2"],
                         [limit.value for limit in self.s.query.modifiers])

    def test_set_orderby(self):
        self.s.set_orderby("var")
        self.assertEqual(Variable("var"), self.s.query.orderby.variable)

    def test_set_from(self):
        uri = "http://some.where/graphs/graph"
        self.s.set_from(uri)
        self.assertEqual(URIRef(uri), self.s.query.fromgraph)

    def test_set_distinct(self):
        self.s.set_distinct()
        self.assertEqual(True, self.s.query.distinct)

    def test_str(self):
        expected = "SELECT WHERE{}"
        self.assertEqual(expected, str(self.s))

    def test_add_or_filter_regex(self):
        self.s.add_or_filter_regex({"a": "a1", "b": "b1", "c": "c1"})
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        b2 = BinaryExpression(FunCall("regex", "c", '"c1"', '"i"'), "||",\
                              FunCall("regex", "a", '"a1"', '"i"'))
        b1 = BinaryExpression(FunCall("regex", "b", '"b1"', '"i"'), "||", b2)
        f1 = Filter(b1)
        self.assertEqual(f1, self.s.query.whereclause.stmts[0])

        self.s.add_or_filter_regex({"a": "a1"})
        fc1 = FunCall("regex", "a", '"a1"', "\"i\"")
        f2 = Filter(fc1)
        self.assertEqual(2, len(self.s.query.whereclause.stmts))
        self.assertEqual(f2, self.s.query.whereclause.stmts[1])

    def test_add_filter_notbound(self):
        self.s.add_filter_notbound(Variable("a"))
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        u1 = UnaryExpression(FunCall("bound", Variable("a")), "!")
        f1 = Filter(u1)
        self.assertEqual(f1, self.s.query.whereclause.stmts[0])

    def test_add_filter_regex_str_var(self):
        self.s.add_filter_regex_str_var(Variable("var"), "regex")
        self.assertEqual(1, len(self.s.query.whereclause.stmts))
        str = FunCall("str", Variable("var"))
        regex = FunCall("regex", str, '"regex"')
        f1 = Filter(regex)
        self.assertEqual(f1, self.s.query.whereclause.stmts[0])
Exemplo n.º 6
0
class SPARQLQueryBuilder():
    def __init__(self):
        self.helper = SelectQueryHelper()

    def create_query_from_form(self, formdata):
        self.params = formdata
        self._add_base_elements()
        self._add_from()
        self._consume_distribution()
        self._consume_area()
        self._consume_sort()
        self._consume_homepage()
        self._consume_maintainer()
        self._consume_version()
        self._consume_priority()
        self._consume_comaintainer()
        self._consume_vcs()
        self._consume_section()
        self._consume_buildessential()
        self._consume_essential()
        self._consume_dmuploadallowed()
        self._consume_popcon()
        self._consume_filter()
        self.helper.set_limit(RESULTS_PER_PAGE)
        self.helper.set_distinct()
        return self.helper.__str__()

    def binary_search(self):
        if 'searchtype' in self.params:
            type = self.params['searchtype']
            if type in ('BINARY', 'BINARYEXT'):
                return True
            elif type in ('SOURCE'):
                return False
            else:
                raise SPARQLQueryBuilderUnexpectedFieldValueError("searchtype")
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("searchtype")

    def source_search(self):
        return not self.binary_search()

    def wants_json(self):
        if 'tojson' in self.params:
            return self.params['tojson']
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("json")

    def wants_html(self):
        # For the moment json/html are dual parameters
        return not self.wants_json()

    def _extended_binary_search(self):
        if 'searchtype' in self.params:
            if self.params['searchtype'] == 'BINARYEXT':
                return True
            else:
                return False
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("searchtype")

    def _add_base_elements(self):
        self.helper.push_triple_variables(\
            Variable("source"), RDF.type, DEB.Source)
        self.helper.push_triple_variables(\
            Variable("unversionedsource"), DEB.version, Variable("source"))
        self.helper.push_triple(\
            Variable("source"), DEB.maintainer, Variable("maint"))
        self.helper.push_triple_variables(\
            Variable("maint"), FOAF.mbox, Variable("maintmail"))
        self.helper.push_triple_variables(\
            Variable("source"), DEB.versionNumber, Variable("sourceversion"))
        self.helper.push_triple_variables(\
            Variable("sourceversion"), DEB.fullVersion, Variable("sourcefullversion"))
        self.helper.push_triple_variables(\
            Variable("source"), DEB.packageName, Variable("sourcename"))

        if self.binary_search() or self._extended_binary_search():
            self.helper.push_triple_variables(\
                Variable("binary"), RDF.type, DEB.Binary)
            self.helper.push_triple_variables(\
                Variable("source"), DEB.binary, Variable("binary"))
            self.helper.push_triple_variables(\
                Variable("binary"), DEB.packageName, Variable("binaryname"))
            self.helper.push_triple_variables(\
                Variable("unversionedbinary"), DEB.version, Variable("binary"))
            self.helper.push_triple_variables(\
                Variable("binary"), DEB.synopsis, Variable("synopsis"))
            self.helper.push_triple_variables(\
                Variable("binary"), DEB.versionNumber, Variable("binaryversion"))
            self.helper.push_triple_variables(\
                Variable("binaryversion"), DEB.fullVersion, Variable("binaryfullversion"))

    def _consume_filter(self):
        filter = self.params['filter']
        if filter:
            filter = re.escape(filter).replace("\\", "\\\\")
            if self.params['exactmatch']:
                filter = ''.join(['^', filter, '$'])
            if self.binary_search():
                if self._extended_binary_search():
                    self.helper.push_triple(\
                        Variable("binary"), DEB.extendedDescription, Variable("desc"))
                    restrictions = {
                        Variable("desc"): filter,
                        Variable("binaryname"): filter
                    }
                    self.helper.add_or_filter_regex(restrictions)
                else:
                    self.helper.add_or_filter_regex(
                        {Variable("binaryname"): filter})
            elif self.source_search():
                self.helper.add_or_filter_regex(
                    {Variable("sourcename"): filter})

    def _consume_distribution(self):
        distribution = self.params['distribution']
        if distribution == 'ANY':
            self.helper.push_triple_variables(Variable("source"),
                                              DEB.distribution,
                                              Variable("distribution"))
        else:
            self.helper.push_triple(Variable("source"), DEB.distribution,
                                    URIRef(distribution))

    def _consume_area(self):
        area = self.params['area']
        if area == 'ANY':
            self.helper.push_triple_variables(Variable("source"), DEB.area,
                                              Variable("area"))
        else:
            self.helper.push_triple(Variable("source"), DEB.area, URIRef(area))

    def _consume_sort(self):
        sort = self.params['sort']
        if sort == 'MAINTMAIL':
            self.helper.set_orderby("maintmail")
        elif sort == 'PACKAGE':
            if self.binary_search():
                self.helper.set_orderby("binaryname")
            else:
                self.helper.set_orderby("sourcename")
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("sort")

    def _consume_homepage(self):
        if self.params['homepage']:
            self.helper.add_variable("homepage")
            triple = Triple(\
                 Variable("source"), FOAF.page, Variable("homepage"))
            self.helper.add_optional(triple)

    def _consume_maintainer(self):
        option = self.params['maintainer']
        if option == 'TEAM':
            self.helper.push_triple(Variable("maint"), RDF.type, FOAF.Group)
        elif option == 'DEBIAN':
            self.helper.add_or_filter_regex(
                {Variable("maintmail"): "@debian.org$"})
        elif option == 'QA':
            uriref = URIRef(RES_BASEURI + "/team/packages%40qa.debian.org")
            self.helper.push_triple(Variable("source"), DEB.maintainer, uriref)
        elif option == 'CUSTOM':
            self._consume_maintainer_filter()
        elif option == 'ALL':
            pass
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("maintainer")

    def _consume_version(self):
        options = self.params['version']
        if 'NATIVE' in options or 'NMU' in options:
            triple = Triple(\
                Variable("sourceversion"), DEB.debianRevision, Variable("debianRevision"))
            self.helper.add_optional(triple)
        if 'NATIVE' in options:
            self.helper.add_filter_notbound(Variable("debianRevision"))
        if 'NMU' in options:
            self.helper.push_triple(\
                Variable("sourceversion"), DEB.upstreamVersion, Variable("upstreamVersion"))
            restrictions = {Variable("debianRevision"): ".*\\\..*",\
                            Variable("upstreamVersion"): ".*\\\+nmu.*"}
            self.helper.add_or_filter_regex(restrictions)
        if 'EPOCH' in options:
            self.helper.push_triple(Variable("sourceversion"), DEB.epoch,
                                    Variable("epoch"))

    def _consume_priority(self):
        option = self.params['priority']
        if option == 'ANY':
            self.helper.add_variable("priority")
            if self.binary_search():
                triple = Triple(\
                    Variable("binary"), DEB.priority, Variable("priority"))
            elif self.source_search():
                triple = Triple(\
                    Variable("source"), DEB.priority, Variable("priority"))
            else:
                raise Exception()  # FIXME
            self.helper.add_optional(triple)
        else:
            if self.binary_search():
                self.helper.push_triple(\
                    Variable("binary"), DEB.priority, URIRef(option))
            elif self.source_search():
                self.helper.push_triple(\
                    Variable("source"), DEB.priority, URIRef(option))
            else:
                raise Exception()  # FIXME

    def _consume_section(self):
        keyword = self.params['section']
        if keyword:
            keyword = re.escape(keyword).replace("\\", "\\\\")
            if self.binary_search():
                self.helper.push_triple(\
                    Variable("binary"), DEB.section, Variable("section"))
            elif self.source_search():
                self.helper.push_triple(\
                    Variable("source"), DEB.section, Variable("section"))
            else:
                raise Exception()  # FIXME
            self.helper.push_triple_variables(\
                 Variable("section"), DEB.sectionName, Variable("sectionname"))
            self.helper.add_or_filter_regex({Variable("sectionname"): keyword})
        else:
            self.helper.add_variable("section")
            self.helper.add_variable("sectionname")
            if self.binary_search():
                triple1 = Triple(\
                     Variable("binary"), DEB.section, Variable("section"))
            elif self.source_search():
                triple1 = Triple(\
                     Variable("source"), DEB.section, Variable("section"))
            else:
                raise Exception()  # FIXME
            triple2 = Triple(\
                 Variable("section"), DEB.sectionName, Variable("sectionname"))
            self.helper.add_optional(triple1, triple2)

    def _consume_comaintainer(self):
        option = self.params['comaintainer']
        if option == 'WITH':
            self.helper.push_triple(\
                Variable("source"), DEB.uploader, Variable("uploader"))
        elif option == 'WITHOUT':
            triple = Triple(\
                Variable("source"), DEB.uploader, Variable("uploader"))
            self.helper.add_optional(triple)
            self.helper.add_filter_notbound(Variable("uploader"))
        elif option == 'ALL':
            pass
        else:
            raise SPARQLQueryBuilderUnexpectedFieldValueError("comaintainer")

    def _consume_vcs(self):
        options = self.params['vcs']
        if options:
            self.helper.push_triple(\
                Variable("source"), DEB.repository, Variable("repobnode"))
            graphpatterns = []
            if 'SVN' in options:
                graphpatterns.append(\
                    [Triple(Variable("repobnode"), RDF.type, DOAP.SVNRepository)])
            if 'GIT' in options:
                graphpatterns.append(\
                    [Triple(Variable("repobnode"), RDF.type, DOAP.GitRepository)])
            if 'CVS' in options:
                graphpatterns.append(\
                    [Triple(Variable("repobnode"), RDF.type, DOAP.CVSRepository)])
            if 'HG' in options:
                graphpatterns.append(\
                    [Triple(Variable("repobnode"), RDF.type, DOAP.HgRepository)])

            if len(graphpatterns) == 1:
                self.helper.add_triple(graphpatterns[0][0])
            else:
                self.helper.add_union(*graphpatterns)

    def _consume_essential(self):
        if self.binary_search() and self.params['essential']:
            self.helper.push_triple(\
                Variable("binary"), RDF.type, DEB.EssentialBinary)

    def _consume_buildessential(self):
        if self.binary_search() and self.params['buildessential']:
            self.helper.push_triple(\
                Variable("binary"), RDF.type, DEB.BuildEssentialBinary)

    def _consume_dmuploadallowed(self):
        if self.source_search() and self.params['dmuploadallowed']:
            self.helper.push_triple(\
                Variable("source"), RDF.type, DEB.DMUploadAllowedSource)

    def _consume_popcon(self):
        if self.binary_search() and self.params['popcon']:
            triple = Triple(Variable("unversionedbinary"), \
                            DEB.popconInstalled, Variable("?popconinstalled"))
            self.helper.add_variable("popconinstalled")
            self.helper.add_optional(triple)

            triple = Triple(Variable("unversionedbinary"), \
                            DEB.popconUsedRegularly, Variable("?popconused"))
            self.helper.add_variable("popconused")
            self.helper.add_optional(triple)

            triple = Triple(Variable("unversionedbinary"), \
                            DEB.popconInstalledButNotInUse, Variable("?popconnotinuse"))
            self.helper.add_variable("popconnotinuse")
            self.helper.add_optional(triple)

            triple = Triple(Variable("unversionedbinary"), \
                            DEB.popconUpgradedRecently, Variable("?popconupgraded"))
            self.helper.add_variable("popconupgraded")
            self.helper.add_optional(triple)

    def _consume_maintainer_filter(self):
        filter = self.params['maintainerfilter']
        if filter:
            filter = re.escape(filter).replace("\\", "\\\\")
            self.helper.push_triple(\
                Variable("maint"), FOAF.name, Variable("maintname"))
            restrictions = {
                Variable("maintmail"): filter,
                Variable("maintname"): filter
            }
            self.helper.add_or_filter_regex(restrictions)

    def _add_from(self):
        if FROM_GRAPH is not None:
            self.helper.set_from(FROM_GRAPH)

    def create_binaries_query(self, source, version):
        if re.match("^[-a-zA-Z0-9+.]+$", source) is None:
            raise SPARQLQueryBuilderPackageNameSchemeError()

        self.binary_search = lambda: True  # Kind of a hack :/
        self._add_base_elements()
        sourceuri = "%s/source/%s/%s" % (RES_BASEURI, urlquote_plus(source),\
                    urlquote_plus(version))
        self.helper.add_filter_regex_str_var(Variable("source"), sourceuri)
        return self.helper.__str__()