Exemple #1
0
    def _delayed_edge(key: str, progenitor: pydot.Dot, old_source: str,
                      new_source: str) -> str:
        """Draw a specific edge between two nodes, modifying the old label if applicable.

        Args:
            key: The key associated with the edge.
            progenitor: The parent cluster.
            old_source: The edge source.
            new_source: The edge sync.

        Returns:
            The `new_source`.
        """
        edge = progenitor.get_edge(old_source, new_source)
        if edge:
            edge = edge[0]
            label = f"{edge.get_label()}, {key}"
            edge.set_label(label)
        else:
            progenitor.add_edge(
                pydot.Edge(src=old_source, dst=new_source, label=f" {key}"))
        return new_source
Exemple #2
0
class Grafo:
    def __init__(self, vertices, use_pydot=False):
        self.__verts__ = vertices
        self.__adjmx__ = [[] for i in range(vertices)]
        self.__arest__ = 0
        if use_pydot:
            self.__graph__ = Dot(graph_type='graph')
            for i in range(vertices):
                self.__graph__.add_node(Node(str(i)))
        else:
            self.__graph__ = None

    def aresta(self, v1, v2):
        if v2 in self.__adjmx__[v1]:
            return False
        self.__adjmx__[v1].append(v2)
        self.__adjmx__[v2].append(v1)
        self.__arest__ = self.__arest__ + 1
        if self.__graph__ is not None:
            self.__graph__.add_edge(Edge(str(v1), str(v2)))
        return True

    def aresta_aleat(self):
        done = False
        while not done:
            v1 = __random_gen__.randint(self.__verts__)
            v2 = v1
            while v2 == v1:
                v2 = __random_gen__.randint(self.__verts__)
            done = self.aresta(v1, v2)

    def conecta(self, alfa):
        max_art = (self.__verts__ * (self.__verts__ - 1)) // 2
        arestas = round(alfa * max_art)
        for _ in range(arestas):
            self.aresta_aleat()

    def show(self):
        if self.__graph__ is not None:
            from IPython.display import Image
            return Image(self.__graph__.create(format='png'))

    def contemC4(self):
        for v in range(self.__verts__):
            tem_caminho = [False] * self.__verts__

            for w in self.__adjmx__[v]:
                for u in self.__adjmx__[w]:
                    if u != v:
                        if tem_caminho[u]:
                            return v
                        else:
                            tem_caminho[u] = True
        return -1

    def testeC4(self, vert):
        def mostra_C4(v):
            if self.__graph__ is not None:
                for i in range(len(v)):
                    self.__graph__.get_node(str(v[i]))[0].set_style('filled')
                    self.__graph__.get_edge(str(v[i]), str(
                        v[(i + 1) % len(v)]))[0].set_style('bold')

        for v in self.__adjmx__[vert]:
            for w in self.__adjmx__[v]:
                if w != vert:
                    for u in self.__adjmx__[w]:
                        if u != vert and u != v:
                            for z in self.__adjmx__[u]:
                                if z == vert:
                                    mostra_C4([vert, v, w, u])
                                    return True
        return False
Exemple #3
0
def pkgTree(db, packageName):
    """Creates the call tree of internal package functions and procedures"""

    # Tries to import pydot module
    try:
        from pydot import find_graphviz, Dot, Edge, Node
    except ImportError:
        message = _("Function not available because pydot module is not installed.\n\t")
        message += _("Go to http://dkbza.org/pydot.html to get it.")
        raise PysqlException(message)

    # Reads conf
    conf = PysqlConf.getConfig()
    format = conf.get("graph_format") # Output format of the picture
    fontname = conf.get("graph_fontname") # Font used for functions names
    fontsize = conf.get("graph_fontsize") # Font size for functions names
    fontcolor = conf.get("graph_fontcolor") # Color of functions names

    # Gets picture generator
    prog = getProg(find_graphviz(), conf.get("graph_program"), "fdp")

    package = OraObject(objectName=packageName)
    package.guessInfos(db)

    graph = Dot(overlap="false", splines="true")

    # Lists of function or procedure
    verbs = []

    # Tries to resolve synonym and describe the target
    #TODO: factorise this code!!
    if package.getType() == "SYNONYM":
        package = package.getTarget(db)
        if package.getType() == "SYNONYM":
            raise PysqlException(_("Too much synonym recursion"))

    if package.getType() not in ("PACKAGE", "PACKAGE BODY"):
        raise PysqlException(_("This is not a package or package not found"))

    # Gets package body content
    package.setType(u"PACKAGE BODY")
    print CYAN + _("Extracting package source...") + RESET
    content = package.getSQLAsList(db)

    # Removes comments
    print CYAN + _("Parsing source and building graph...") + RESET
    newContent = []
    comment = False
    for line in content:
        line, comment = removeComment(line, comment)
        newContent.append(line)
    content = newContent

    # Gets procedures and functions
    for line in content:
        result = re.match("\s*(FUNCTION|PROCEDURE)\s+(.+?)[\s|\(]+", line, re.I)
        if result:
            verbs.append(re.escape(result.group(2)))
            graph.add_node(Node(result.group(2).upper(), shape="box", label=result.group(2).upper(), \
                                fontsize=str(fontsize), fontname=fontname, fontcolor=fontcolor))

    if not verbs:
        raise PysqlException(_("This package does not have any readable function or procedure"))

    verbs = "|".join(verbs)
    # Gets call of functions/procedure inside each other
    currentVerb = ""
    for line in content:
        # Doesn't pay attention to end lines
        if re.match("\s*END.*;", line, re.I):
            continue
        # Marks the function/procedure we are parsing
        result = re.match("\s*(FUNCTION|PROCEDURE)\s+(.+?)[\s|\(]+", line, re.I)
        if result:
            currentVerb = result.group(2)
            continue # else we get a circular reference below ;-)
        result = re.match(".*\s(%s).*" % verbs, line, re.I)
        if result:
            if graph.get_edge(currentVerb.upper(), result.group(1).upper()) is None:
                graph.add_edge(Edge(src=currentVerb.upper(), dst=result.group(1).upper()))

    filename = package.getName() + "_dep." + format
    generateImage(graph, filename, prog, format)
    viewImage(filename)