def test_remove_one_line_comment_with_sql(self):
     for answer, question in (("sql ", "sql -- lala"),
                              ("sql ", "sql --lala"),
                              ("sql", "sql--lala"),
                              ("sql ", "sql --"),
                              ("sql", "sql--"),
                              ("sql", "sql--------"),
                              ("sql", "sql-- lala --")):
         unCommentedLine, comment = pysqlhelpers.removeComment(question)
         self.assertFalse(comment)
         self.failUnlessEqual(unCommentedLine, answer)
 def test_remove_multiline_comment(self):
     for anwser, lines in (("sql  sql", ("sql /*", "nice comment", "another comment */", "sql")),
                           ("sql  sql sql", ("sql /* begin of comment", "blabla / * ", "*/sql", "sql")),
                           ("sql  sql", ("sql /*", "lala -- ", "comment */", "sql")),
                           ("sql", ("/*", "nice comment", "*/", "sql")),
                           ("sql /*+ smart hint */ sql", ("sql /*+ smart hint */", "sql")),
                           ("sql   /*+ smart hint */  sql", ("sql /* bla */ /*+ smart hint */ /*", "*/", "sql"))):
         result = []
         comment = False
         for line in lines:
             unCommentedLine, comment = pysqlhelpers.removeComment(line, comment)
             if unCommentedLine:
                 result.append(unCommentedLine)
         self.failUnlessEqual(" ".join(result), anwser)
 def test_remove_one_line_comment(self):
     for line in ("--foo", "-- foo", "--foo ", "--foo--", "--foo --", "--", "-- ", "---", "----", "---- foo ",
                  "/**/", "/* */", "/** */", "/* **/", "/***/", "/* lala */", "/*lala */", "/* lala*/", "/*lala*/"):
         unCommentedLine, comment = pysqlhelpers.removeComment(line)
         self.assertFalse(comment)
         self.failUnlessEqual(unCommentedLine.strip(), "")
示例#4
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)