def test_argsinrel(self):
        """Teste le fonctionnement de la fonction argsinrel"""

        # erreur de type sur rel et args
        rel = {}
        args = "a"
        with self.assertRaises(ErrorType):
            argsinrel(rel, args)

        # erreur de type sur args
        rel = Relation("rel", {"a": [1], "b": [2]})
        with self.assertRaises(ErrorType):
            argsinrel(rel, args)

        # erreur de type sur rel
        rel = {}
        args = ["a"]
        with self.assertRaises(ErrorType):
            argsinrel(rel, args)

        # affichera à la console:
        # L'argument c n'appartient pas à la relation rel.
        rel = Relation("rel", {"a": [1], "b": [2]})
        args = ["c"]
        print("\ntest_argsinrel")
        self.assertFalse(argsinrel(rel, args))

        # résultat
        rel = Relation("rel", {"a": [1], "b": [2]})
        args = ["a"]
        self.assertTrue(argsinrel(rel, args))
Beispiel #2
0
    def test_join(self):
        """Teste le fonctionnement de la fonction join"""

        # erreur d'attribut sur rel1 et rel2: pas d'attribut en commun
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"c": [1], "d": [2]})
        with self.assertRaises(AttributesError):
            join(rel1, rel2)

        # résultat
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"b": [1], "c": [2]})
        self.assertEqual(type(join(rel1, rel2)), Relation)
        self.assertEqual(
            join(rel1, rel2).name, "(SELECT * FROM rel1 NATURAL JOIN rel2)")
        for attribute in ["a", "b", "c"]:
            if attribute == "a":
                self.assertEqual(
                    type(join(rel1, rel2).attributes[attribute][0]),
                    type(rel1.attributes[attribute][0]))
            elif attribute == "c":
                self.assertEqual(
                    type(join(rel1, rel2).attributes[attribute][0]),
                    type(rel2.attributes[attribute][0]))
            else:
                self.assertEqual(
                    type(join(rel1, rel2).attributes[attribute][0]),
                    type(rel1.attributes[attribute][0]))
    def test_select(self):
        """Teste le fonctionnement de la fonction select"""

        # erreur de comparateur: cmp ne fait pas partie de la liste des comparators
        rel = Relation("Personne", {
            'ID': [1, 2, 3],
            'Nom': ["alice", "bob", "gildas"]
        })
        attr = 'Nom'
        const = "alice"
        cmp = '*'
        with self.assertRaises(ComparatorError):
            select(rel, cmp, attr, const, 0)

        # erreur d'attribut: attr ne fait pas partie de rel
        cmp = '='
        attr = "alice"
        with self.assertRaises(AttributesError):
            select(rel, cmp, attr, const, 0)

        # erreur d'attribut: const ne fait pas partie de rel
        attr = 'Nom'
        with self.assertRaises(AttributesError):
            select(rel, cmp, attr, const, 1)

        # erreur de type: argument const incompatible avec argument de attr
        const = 1
        with self.assertRaises(ErrorType):
            select(rel, cmp, attr, const, 0)

        # résultat
        const = "alice"
        self.assertEqual(
            select(rel, cmp, attr, const, 0).name,
            "(SELECT * FROM Personne WHERE Nom='alice')")
        for attribute in rel.attributes:
            self.assertEqual(
                type(
                    select(rel, cmp, attr, const, 0).attributes[attribute][0]),
                type(rel.attributes[attribute][0]))
        rel = Relation('Bénéfice', {
            'Prixdevente': [10, 20, 30],
            "Prixdachat": [30, 20, 10]
        })
        attr = 'Prixdevente'
        const = "Prixdachat"
        self.assertEqual(
            select(rel, cmp, attr, const, 1).name, "(SELECT * FROM Bénéfice "
            "WHERE Prixdevente=Prixdachat)")
        for attribute in rel.attributes:
            self.assertEqual(
                type(
                    select(rel, cmp, attr, const, 1).attributes[attribute][0]),
                type(rel.attributes[attribute][0]))
    def test_havesameattributes(self):
        """Teste le fonctionnement de la fonction havesameattributes"""

        rel1 = "1"
        rel2 = "2"
        with self.assertRaises(ErrorType):
            havesameattributes(rel1, rel2)

        # nombres d'attributs différents
        rel1 = Relation("rel1", {"a": [1], "b": [2], "c": [3]})
        rel2 = Relation("rel2", {"a": [1], "b": [2]})
        self.assertFalse(havesameattributes(rel1, rel2))

        # attribut différent
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"a": [1], "c": [2]})
        self.assertFalse(havesameattributes(rel1, rel2))

        # type différent de valeur dans un attribut de même nom
        # affichera à la console:
        # Format Incompatible: <class 'str'> différent de <class 'int'>
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"a": ["a"], "b": [2]})
        print("\ntest_havesameattributes")
        self.assertFalse(havesameattributes(rel1, rel2))

        # résultat
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"a": [1], "b": [2]})
        self.assertTrue(havesameattributes(rel1, rel2))
Beispiel #5
0
def rename(relation, old_name, new_name):
    """Fonction qui retourne une relation dont le name est la traduction du Renomage de SPJRUD en SQL,
    old_name est l'ancien nom d'attribut et new_name est le nouveau nom à attribuer

    :param relation: Une instance de Relation
    :param old_name: Un attribut de la relation
    :param new_name: Le nouveau nom que nous voulons attribuer à cet attribut
    :return: new_rel: Une instance de Relation dont le name est une requête en SQL
    :raise AttributesError
    """

    if not isarginrel(old_name, relation):
        raise AttributesError(f"{old_name} n'est pas un attribut de la relation {relation}")
    s = ", "
    l = list(relation.attributes.keys())
    l.remove(old_name)
    for i in range(len(l)-1):
        s += l[i] + ", "
    s += l[-1]
    name = f"(SELECT {old_name} AS {new_name}{s}  FROM {relation.name})"
    attributes = copy.deepcopy(relation.attributes)
    attributes[new_name] = attributes[old_name]
    del attributes[old_name]
    new_rel = Relation(name, attributes)
    return new_rel
Beispiel #6
0
def project(relation, *args):
    """Fonction qui retourne une relation dont le name est la traduction de la projection en SPJRUD en SQL
    et le attributes est un dictionnaire qui décrit superficiellement la relation obtenue par la projection
    (mêmes attributs et types de valeurs)

    :param relation: Une instance de Relation
    :param args: Des clés du dictionnaire relation.attributes
    :return: new_rel: Une instance de Relation dont le name est une requête en SQL
    """

    args = removeduplicate(args)
    argsinrel(relation, args)
    name = "(SELECT "
    for i in range(len(args)):
        if i != len(args) - 1:
            name += args[i] + ", "
        else:
            name += args[i] + f" FROM {relation.name})"
    attributes = {}
    for arg in args:
        if type(relation.attributes[arg][0]) == int:
            attributes[arg] = [1]
        elif type(relation.attributes[arg][0]) == float:
            attributes[arg] = [1.0]
        elif type(relation.attributes[arg][0]) == str:
            attributes[arg] = ["a"]
        else:
            attributes[arg] = []
    new_rel = Relation(name, attributes)
    return new_rel
Beispiel #7
0
    def test_union(self):
        """Teste le fonctionnement de la fonction union"""
        # erreur d'attribut sur rel1 et rel2: attributs différents
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"c": [1], "d": [2]})
        with self.assertRaises(AttributesError):
            union(rel1, rel2)

        # résultat
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"a": [1], "b": [2]})
        self.assertEqual(type(union(rel1, rel2)), Relation)
        self.assertEqual(
            union(rel1, rel2).name,
            "(SELECT * FROM rel1 UNION SELECT * FROM rel2)")
        for attribute in ["a", "b"]:
            self.assertEqual(type(union(rel1, rel2).attributes[attribute][0]),
                             type(rel1.attributes[attribute][0]))
    def test_joinable(self):
        """Teste le fonctionnement de la fonction joinable"""

        # erreur de type sur rel1 et rel2
        rel1 = "1"
        rel2 = "2"
        with self.assertRaises(ErrorType):
            joinable(rel1, rel2)

        # pas d'attribut en commun
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"c": [1], "d": [2]})
        self.assertFalse(joinable(rel1, rel2))

        # résultat
        rel1 = Relation("rel1", {"a": [1], "b": [2]})
        rel2 = Relation("rel2", {"b": [1], "c": [2]})
        self.assertTrue(joinable(rel1, rel2))
    def test_isarginrel(self):
        """Teste le fonctionnement de la fonction isarginrel"""

        # erreur de type sur rel
        rel = "rel"
        arg = "a"
        with self.assertRaises(ErrorType):
            isarginrel(arg, rel)

        # arg n'est pas un attribut de rel
        rel = Relation("rel", {"b": [1, 2]})
        self.assertFalse(isarginrel(arg, rel))

        # arg est une valeur dans un attribut de rel
        rel = Relation("rel", {"c": ["a", "b"]})
        self.assertFalse(isarginrel(arg, rel))

        # résultat
        rel = Relation("rel", {"a": [1, 2]})
        self.assertTrue(isarginrel(arg, rel))
    def test_project(self):
        """Teste le fonctionnement de la fonction project"""

        # résultat
        rel = Relation("rel", {'a': [1], 'b': [2]})
        self.assertEqual(type(project(rel, 'a', 'b', 'b')), Relation)
        self.assertEqual(
            project(rel, 'a', 'b', 'b').name, "(SELECT a, b FROM rel)")
        for attribute in ["a", "b"]:
            self.assertEqual(
                type(project(rel, 'a', 'b', 'b').attributes[attribute][0]),
                type(rel.attributes[attribute][0]))
def difference(rel1, rel2):
    """Fonction qui retourne une relation dont le name est la traduction de la différence en SPJRUD en SQL
    et le attributes est le attributes d'une des relations en paramètre

    :param rel1: Une instance de Relation
    :param rel2: Une instance de Relation
    :return: new_rel: Une instance de Relation dont le name est une requête en SQL
    :raise AttributesError
    """

    if havesameattributes(rel1, rel2):
        name = f"(SELECT * FROM {rel1.name} EXCEPT SELECT * FROM {rel2.name})"
    else:
        raise AttributesError(
            f"Différence impossible car attributs de {rel1.name} différent de {rel2.name} "
        )
    new_rel = Relation(name, rel1.attributes)
    return new_rel
    def test_rename(self):
        """Teste le fonctionnement de la fonction rename"""

        # erreur d'attribut: old_name ne fait pas partie de rel
        rel = Relation('Personne', {
            'ID': [1, 2, 3],
            'Nom': ['alice', 'bob', 'gildas']
        })
        old_name = 'alice'
        new_name = 'Login'
        with self.assertRaises(AttributesError):
            rename(rel, old_name, new_name)

        # résultat
        old_name = 'Nom'
        ren = rename(rel, old_name, new_name)
        self.assertEqual(ren.name, "(SELECT Nom AS Login, ID  FROM Personne)")
        self.assertFalse(old_name in ren.attributes)
        self.assertTrue(new_name in ren.attributes)
Beispiel #13
0
def select(relation, cmp, attrib, const, counter):
    """Fonction qui retourne une relation dont le name est la traduction de la selection en SPJRUD en SQL
    et le attributes est le attributes de la relation en paramètre

    :param relation: Une instance de Relation
    :param cmp:  '=', '<', '>', '<=', '>=' ou '!='
    :param attrib: Une clé du dictionnaire relation.attributes
    :param const: Une valeur ou une clé du dictionnaire relation.attributes (selon counter)
    :param counter: counter=1 => const est une clé sinon une valeur
    :return: new_rel: Une instance de Relation dont le name est une requête en SQL
    :raise ComparatorError
    :raise AttributesError
    :raise ErrorType
    """

    comparators = ['=', '<', '>', '<=', '>=', '!=']
    isarelation(relation.attributes)
    if comparators.count(cmp) == 0:
        raise ComparatorError("L'élément " + cmp + " est invalide pour cette operation. " +
                              f"Veuillez utiliser un des comparateurs suivants:{comparators}")
    if not isarginrel(attrib, relation):
        raise AttributesError(f"{attrib} n'est pas un attribut de la relation {relation.attributes}")

    # counter !=1 => attribut égal constante
    # counter=1 => attribut égal attribut
    if counter == 1:
        if not isarginrel(const, relation):
            raise AttributesError(f"{const} n'est pas un attribut de la relation {relation}")
        args = [relation.attributes[attrib][0], relation.attributes[const][0]]
        havesametype(args)

    else:
        if type(relation.attributes[attrib][0]) != type(const):
            raise ErrorType(
                f"Dans les attributs: {relation.attributes[attrib][0]} et {const} doivent etre du meme type")
    if counter != 1 and type(const) == str:
        name = f"(SELECT * FROM {relation.name} WHERE {attrib}{cmp}'{const}')"
    else:
        name = f"(SELECT * FROM {relation.name} WHERE {attrib}{cmp}{const})"
    new_rel = Relation(name, relation.attributes)
    return new_rel
def join(rel1, rel2):
    """Fonction qui retourne une relation dont le name est la traduction de la jonction en SPJRUD en SQL
    et le attributes est un dictionnaire qui décrit superficiellement la relation obtenue par la jonction
    (mêmes attributs et types de valeurs)

    :param rel1: Une instance de Relation
    :param rel2: Une instance de Relation
    :return: new_rel: Une instance de Relation dont le name est une requête en SQL
    :raise AttributesError
    """

    if joinable(rel1, rel2):
        name = f"(SELECT * FROM {rel1.name} NATURAL JOIN {rel2.name})"
    else:
        raise AttributesError(
            "Jonction impossible car aucun attribut en commun")

    attributes = {}
    for arg in rel1.attributes:
        if type(rel1.attributes[arg][0]) == int:
            attributes[arg] = [1]
        elif type(rel1.attributes[arg][0]) == str:
            attributes[arg] = ["a"]
        else:
            attributes[arg] = []

    for arg in rel2.attributes:
        if not isarginrel(arg, rel1):
            if type(rel2.attributes[arg][0]) == int:
                attributes[arg] = [1]
            elif type(rel2.attributes[arg][0]) == str:
                attributes[arg] = ["a"]
            else:
                attributes[arg] = []

    new_rel = Relation(name, attributes)
    return new_rel