Example #1
0
    def _print_symbol_index_page(self):
        debug_message('print symbols index page')
        text = []
        text.append(self.html.page_header("Schema Objects Index"))
        local_nav_bar = []

        keys = self.index.keys()
        keys.sort()
        letter = ""
        for key in keys:
            if (key[:1] != letter):
                letter = key[:1]
                local_nav_bar.append((letter,letter))
        text.append(self.html.context_bar(local_nav_bar))

        letter = ""
        for key in keys:
            if (key[:1] != letter):
                letter = key[:1]
                text.append(self.html.heading(letter, 3) + self.html.anchor(letter))
            for entry in self.index[key]:
                text.append('%s %s<br/>' % entry)
        text.append(self.html.page_footer())
        file_name = path.join(self.cfg.output_dir, "symbol-index.html")
        self._write(''.join(text), file_name)
Example #2
0
    def _copy_css(self):
        """copy the css file to the output_dir"""
        debug_message('copying CSS stylesheet to output_dir')
        css = self.cfg.css
        output_dir = self.cfg.output_dir
        csspath = self.cfg.csspath
        try:
            copy(path.join(csspath, css), output_dir)
            debug_message('css: done')

        except IOError, (errno, errmsg):
            msg = path.join(csspath, css) + ' not fround. ' \
                        'Trying to find another.  Error copying CSS style. ' \
                        'You are running precompiled version propably.\n' \
                        'Related info: (%s) %s' % (errno, errmsg)
            debug_message(msg)
            try:
                debug_message('Trying: ' + path.join(path.dirname(
                        sys.executable), 'css', css))
                copy(path.join(path.dirname(sys.executable),
                    'css', css), output_dir)
                debug_message('css: done')
            except IOError:
                print 'Error: (%s) %s' % (errno, errmsg)
                print 'Please copy some css style into output directory manually.'
Example #3
0
 def write(self):
     """write out the xml files to the file system"""
     xml_file = file_name = os.path.join(self.cfg.output_dir,
             self.cfg.xml_file)
     debug_message('Creating XML file:  %s' % xml_file)
     f = open(xml_file, 'w')
     f.write(self.cfg.schema.getXML())
     f.close()
Example #4
0
    def _print_list_page(self, title, ht_table, file_name):
        # print list pages
        debug_message('print %s list page' % title)
        text = self.html.page_header(title)
        text = text + self.html.context_bar( None)
        text = text + ht_table
        text = text + self.html.page_footer()

        file_name = path.join(self.cfg.output_dir, file_name.replace("/", "-"))
        self._write(text, file_name)
Example #5
0
 def _print_index_frame(self, header, item_list, file_name):
     # generic procedure to print index frame on left side
     # excpects:
     #          header    - title string, i.e "Tables"
     #          item_list - list of names with html links
     #          file_name - relative file name
     debug_message('index frame for %s' % header)
     text = []
     text.append(self.html.frame_header(header))
     text.append(self.html.href('nav.html', 'Categories'))
     for row in item_list:
         text.append(row)
     text.append(self.html.frame_footer())
     #java sources contain simbol / inside name, in file_names should be replaced with "-"
     f_name = path.join(self.cfg.output_dir, file_name.replace("/","-"))
     self._write(''.join(text), f_name)
Example #6
0
def main():
    """parse the command line args and run the formatting/writing of
       the documentation

    """
    parser = argparse.ArgumentParser(description='Parse command line args.')

    # add all the possible arguments we expect to handle via the cli
    parser.add_argument('-u', dest='username', action='store', required=True,
            help='db schema')
    parser.add_argument('-p', dest='password', action='store', required=True,
            help='Password for the db schema')
    parser.add_argument('-t', dest='tsn', action='store', required=True,
            help='Network TSN alias')
    parser.add_argument('-o', dest='output_dir', action='store', required=True,
            help='Output directory for doc generation, for sphinx '\
                    'documentation this is the same name as the schema '\
                    'name so that links can be made between schemas.')
    parser.add_argument('-n', dest='name', action='store', required=False,
            default=False, help='DB Project name')
    parser.add_argument('-v', dest='verbose', action='store_true',
            default=False, help='Display verbose "build" text when running.')
    parser.add_argument('-s', dest='syntax_highlighting', action='store_true',
            default=False,
            help='When formatting as html, turn on syntax highlighting.')
    parser.add_argument('--css', dest='css', action='store',
            help='When formatting as html, path to custom css file')
    parser.add_argument('--noddl', dest='noddl', action='store_true',
            default=False, help='Diasble ddl generation')
    parser.add_argument('--dia', dest='dia', action='store_true',
            default=False, help='Enable dia uml output')
    parser.add_argument('--dia_conf_file', dest='dia_conf_file',
            action='store', help='Path to the dia conf table file.  Only '\
                    'create dia diagrams of tables in conf file')
    parser.add_argument('--desc', dest='description', action='store',
            help='Project description added to the documentation index')
    parser.add_argument('--dia-table-list', dest='dia-table-list',
            action='append', help='Filename for dia table lists')
    parser.add_argument('--not-nulls', dest='notnulls', action='store_true',
            default=False, help='Do not Write out the not null contraints')
    parser.add_argument('--pb', dest='pb', action='store_true',
            default=False, help='Do not write out the package bodies')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--html', dest='html', action='store_true',
            default=False, help='Format output as javadoc html files')
    group.add_argument('--rest', dest='rest', action='store_true',
            default=False, help='Format output as reST files')
    group.add_argument('--xml-file', dest='xml', action='store',
            help='Generate output into xml file')

    # create global config file - hanger passed around to various apps...
    # bleagh - but how it is in first fork....
    cfg = OSDConfig()

    pargs = parser.parse_args()

    # username/schema
    username = pargs.username

    # do we want to generate ddl?
    cfg.allowDDL = not pargs.noddl

    # Just stick these as they are....
    cfg.dia_conf_file = cfg.dia_conf_file
    name = pargs.name
    cfg.name = name and name or upper(username)
    cfg.notNulls = pargs.notnulls
    cfg.pb = pargs.pb
    cfg.xml_file = pargs.xml
    verbose = cfg.verbose = pargs.verbose
    set_verbose_mode(verbose)

    # make sure the dia conf file exists if set.
    if cfg.dia_conf_file:
        if not os.path.exists(cfg.cfg.dia_conf_file):
            cfg.dia_conf_file = None

    css = pargs.css
    if css:
        if not os.path.exists(os.path.join(cfg.csspath, css)):
            msg = '\nWARNING: %s doesn\'t exists. Using default instead.\n' % \
                    value
            debug_message(msg)
        else:
            cfg.css = css

    #if opt == '--schema':
    #    cfg.useOwners = True
    #    if len(value) > 0:
    #        cfg.owners = value.split(',')

    # output dir is the dir the directory is created - based on::
    # db.schema_name format - so /tmp/foo.username
    output_dir = os.path.join(os.path.abspath(pargs.output_dir),
                              '%s.%s' % (pargs.tsn, username))
    cfg.output_dir = output_dir

    # check if output_dir exsits, if not try to create one.
    if os.access(cfg.output_dir, os.F_OK) != 1:
        try:
            os.makedirs(cfg.output_dir)
        except os.error, e:
            print 'ERROR: Cannot create directory ', cfg.output_dir
            exit(2)
Example #7
0
        exit(2)

    # XXX effectively also the schema
    cfg.currentUser = connect_string[:connect_string.find('/')].upper()

    # know encoding we will use
    oraenc = OracleNLSCharset()
    encoding = oraenc.getClientNLSCharset()
    cfg.ora_encoding = oraenc.getOracleNLSCharacterset(cfg.connection)
    if encoding == None:
        encoding = oraenc.getPythonEncoding(cfg.ora_encoding)
    else:
        encoding = oraenc.getPythonEncoding(encoding)

    cfg.encoding = encoding
    debug_message('Using codec: %s' % cfg.encoding)
    debug_message('HTML encoding: %s\n' % cfg.webEncoding)

    # make sure that the name and desc. are encoded
    if cfg.desc != None:
        cfg.desc = cfg.desc.encode(encoding)

    cfg.name = cfg.name.encode(encoding)

    cfg.dictionary = OraSchemaDataDictionary(cfg)
    cfg.schema = OracleSchema(cfg)

    if pargs.html:
        cfg.syntaxHighlighting = pargs.syntax
        # all the magic is in this formatter's __init__ for now
        HTMLFormatter(cfg)
Example #8
0
 def _write(self, text, file_name):
     # write file to fs
     debug_message("debug: writing file %s" % file_name)
     f = open(file_name, 'w')
     f.write(text)
     f.close()
Example #9
0
    def _sanity_check(self):
        debug_message('print sanity check page')
        problems = False
        text = []
        text.append(self.html.page_header("Sanity Check"))
        local_nav_bar = []
        local_nav_bar.append(("FK indexes", "fk-ix"))
        local_nav_bar.append(("Invalid objects", "inv"))
        text.append(self.html.context_bar(local_nav_bar))

        text.append(self.html.heading("Sanity Check", 1))

        scheck = SchemaAnalyzer(self.cfg.connection, self.cfg.schema)
        if scheck.fk_no_indexes:
            text.append(self.html.anchor("fk-ix"))
            text.append(self.html.heading("No indexes on columns involved in foreign key constraints",2))
            text.append('''<p>You should almost always index foreign keys. The only exception is when
                        the matching unique or primary key is never updated or deleted. For
                        more information take a look on
                        <a href="http://oradoc.photo.net/ora817/DOC/server.817/a76965/c24integ.htm#2299">
                        Concurrency Control, Indexes, and Foreign Keys</a>.</p>
                        <p>The sql file which will
                        generate these indexes is <a href="fk-indexes.sql">created for you</a></p>''')

            title = '"Unindexed" foreign keys'
            headers = "Table Name", "Constraint name", "Columns"
            rows = []
            for constraint in scheck.fk_no_indexes:
                row=[]
                row.append( self.html.href_to_table(constraint.table_name))
                row.append( self.html.href_to_constraint(constraint.name, constraint.table_name, constraint.name))
                columns = ''
                columns_count = len(constraint.columns)
                i=0
                for j in constraint.columns.keys():
                    columns += constraint.columns[j]
                    i +=1
                    if i != columns_count:
                        columns += ', '
                row.append(columns)
                rows.append(row)
                #write sql
            file_name = path.join(self.cfg.output_dir, "fk-indexes.sql")
            self._write(scheck.fk_no_indexes_sql,file_name)
            text.append(self.html.table(title,headers,rows))
            problems = True

        if len(scheck.invalids) != 0:
            problems = True
            text.append(self.html.anchor("inv"))
            text.append(self.html.heading('Invalid objects', 2))
            text.append('''<p>Invalid object does not mean a problem sometimes. Sometimes will
                    fix itself as is is executed or accessed.  But if there is an error in
                    USER_ERRORS table, you are in trouble then...</p>
                    <p>The sql file which will compile these objects is
                    <a href="compile-objects.sql">created for you</a>.</p>''')
            self._write(scheck.invalids_sql, path.join(self.cfg.output_dir, 'compile-objects.sql'))
            invalids = scheck.invalids
            for i in invalids:
                if i[1] == 'PACKAGE' or i[1] == 'PACKAGE BODY':
                    i[0] = self.html.href_to_package(i[0])
                if i[1] == 'PROCEDURE':
                    i[0] = self.html.href_to_procedure(i[0])
                if i[1] == 'FUNCTION':
                    i[0] = self.html.href_to_function(i[0])
                if i[1] == 'VIEW':
                    i[0] = self.html.href_to_view(i[0])
                if i[1] == 'TRIGGER':
                    for j in self.cfg.schema.triggers:
                        if j.name == i[0]:
                            i[0] = self.html.href_to_trigger(i[0], j.table_name, i[0], self.triggerAnchorType(j))
                            break
                i[2] = self.html._quotehtml(i[2])
            text.append(self.html.table('Invalids', ['Object name', 'Type', 'Error', 'At line'], invalids))

        if problems == False:
            # no checks
            text.append(self.html.p('No known problems.'))
        text.append(self.html.page_footer())
        file_name = path.join(self.cfg.output_dir, "sanity-check.html")
        self._write(''.join(text), file_name)
Example #10
0
    def __init__(self, cfg):
        set_verbose_mode(cfg.verbose_mode)
        self.syntaxHighlighter = SqlHighlighter(
                highlight=cfg.syntaxHighlighting)
        self.dotEngine = Dot(cfg.output_dir)
        self.cfg = cfg
        self.html = HtmlWidgets(cfg.name, cfg.css, cfg.webEncoding,
                cfg.notNulls)
        self.index = {}

        # print html files
        debug_message('\nCreating HTML output')
        self._print_index_frames()
        self._print_list_pages()
        self._sanity_check()
        self._print_common_pages()

        debug_message('print tables')
        for table in cfg.schema.tables:
            self._print_table(table)

        debug_message('print views')
        for view in cfg.schema.views:
            self._print_view(view)

        debug_message('print materialized views')
        for mview in cfg.schema.mviews:
            self._print_mview(mview)

        debug_message('print functions')
        for function in cfg.schema.functions:
            self._print_function(function)

        debug_message('print procedures')
        for procedure in cfg.schema.procedures:
            self._print_procedure(procedure)

        debug_message('print packages')
        for package in cfg.schema.packages:
            self._print_package(package)

        debug_message('print java sources')
        for jsource in cfg.schema.java_sources:
            self._print_java_source(jsource)

        self._print_symbol_index_page()