示例#1
0
class CreateDB:
    def __init__(self, db, cAppl=None, createDataBase=False, info=False):
        self.db = db
        self.cAppl = cAppl
        self.createDataBase = createDataBase
        self.info = info
        self.aplicacao = Aplicacao(self.db, self.cAppl)
        self.applId = self.aplicacao.getApplId()
        self.modeloDb = self.aplicacao.getModeloDb()
        self.entidades = Entidades(self.db, cAppl=self.cAppl)
        self.colunas = Colunas(db, cAppl=self.cAppl)
        self.colunasEntidades = ColunasEntidades(self.db, self.cAppl)
        self.ColEntRef = ColunasEntidadesReferenciadas(self.db)
        self.primaryKeys = PrimaryKeys(self.db)
        self.foreignKeys = ForeignKeys(self.db)
        self.OrigemColunasAplicacao = OrigemColunasAplicacao(self.db)
        self.regrasColunas = RegrasColunas(self.db)
        self.mensagens = Mensagens(self.db, cAppl=self.cAppl)
        self.parametros = self.db.parametros
        self.parms = self.db(self.parametros).select()[0]
        self.checkListPrototipo = self.db.checkListPrototipo
        self.database = Database(db, cAppl=self.cAppl)
        self.databaseCreated = False

        App = os.path.join('\\\\', '127.0.0.1', 'c$', 'web2py', 'applications',
                           self.applId)

        self.dbApp = os.path.join(App, 'models', 'db.py')

        self.settings = os.path.join(App, 'models', 'settings_local.db')

        self.databases = os.path.join(App, 'databases')

        Template = os.path.join('\\\\', '127.0.0.1', 'c$', 'web2py',
                                'applications', self.parms.soag, 'Template',
                                'web2py', 'models')

        self.dbTemplate = os.path.join(Template, 'db.py')

        self.settingsTemplate = os.path.join(Template, 'settings_local.db')

    def createDB(self):

        try:
            if self.createDataBase:
                if modeloDB[self.modeloDb] == 'Soag':
                    command = 'dropdb --username=postgres -w {}'.format(
                        self.applId)
                    try:
                        os.system(command)
                    except:
                        pass

                    command = 'createdb --username=postgres -w {}'.format(
                        self.applId)
                    os.system(command)
                else:
                    retorno, returned = self.tryEngine()
                    if not retorno:
                        return retorno, returned
                    engine = returned

                    retorno, returned = self.metaSchema(engine)
                    if not retorno:
                        return retorno, returned
                    schm = returned

                    for tbl in [
                            u'controle', u'mensagens', u'auth_cas',
                            u'auth_event', u'auth_permission',
                            u'auth_membership', u'auth_group', u'auth_user'
                    ]:
                        try:
                            table = schm.tables[tbl]
                            table.drop(engine)
                        except:
                            pass

            settings = open(self.settings, 'w')
            settingsTemplate = open(self.settingsTemplate).readlines()
            settingsTemplate = change({'@applId': self.applId},
                                      settingsTemplate)
            settings.writelines(settingsTemplate)
            settings.close()

            if self.createDataBase:
                try:
                    shutil.rmtree(self.databases)
                except:
                    pass
                os.mkdir(self.databases)
                self.databaseCreated = True

            dbApp = open(self.dbApp, 'w')
            dbApp.writelines(open(self.dbTemplate).readlines())

            retEntidade = self.entidades.selectEntidadesBycodigoAplicacao()
            if not retEntidade[0]:
                return False, retEntidade[1]
            entidades = retEntidade[1]
            dicEntidades = {entidade.id: entidade for entidade in entidades}

            retColunas = self.colunas.selectColunasByCodigoAplicacao()
            colunas = retColunas[1]
            dicColunas = {col.id: col for col in colunas}

            gerados = 0
            lisWrite = []  # Lista com a ordem de gravação das entidades
            dicWrite = {}  # Dicionario com as linhas de gravação por entidade
            dicRefer = {}  # Dicionario com as entidades referenciadas

            for entidade in entidades:
                lookups = ''
                lisAppWrite = []
                lisAppWrite.append("\ndb.define_table('{}'\n".format(
                    entidade.nomeFisico))
                retColunasEntidades = self.colunasEntidades.selectColunasEntidadesResolvidasByCodigoEntidade(
                    entidade.id)
                if not retColunasEntidades[0]:
                    if retColunasEntidades[1]:
                        return False, retColunasEntidades[2]
                    else:
                        return False, None
                gerados += 1
                colunasEntidade = retColunasEntidades[1]
                retPrimaryKeys = self.primaryKeys.selectPrimaryKeysByCodigoEntidade(
                    entidade.id)
                if not retPrimaryKeys:
                    return [0, retPrimaryKeys[1]]
                primaryKeys = retPrimaryKeys
                dicFKs = self.foreignKeys.selectForeignKeysByCodigoEntidade(
                    entidade.id)
                dicRefer[entidade.id] = list(
                    set([
                        dicFKs[k][0] for k in dicFKs
                        if dicFKs[k][0] != entidade.id
                    ]))
                retColEntRef = self.ColEntRef.selectColunasEntidadesReferenciadasByCodigoEntidade(
                    entidade.id)
                colEntRef = retColEntRef[1]
                lc = len(colunasEntidade)
                for n, col in enumerate(colunasEntidade):
                    foreignKey = ''
                    if (col.colunas.id in dicFKs
                            and dicFKs[col.colunas.id][0] != entidade.id):
                        foreignKey = ', {}'.format(
                            dicEntidades[dicFKs[col.colunas.id][0]].nomeFisico)

                    dttp = dicDataTypes[col.datatypes.descricao]
                    if dttp == "'decimal'":
                        dttp = ", 'decimal({},{})'".format(
                            col.colunas.tamanhoColuna, col.colunas.decimais)
                    elif not dttp:
                        dttp = ", length={}".format(col.colunas.tamanhoColuna)
                    else:
                        dttp = ', {}'.format(dttp)
                    if modeloDB[self.modeloDb] == 'Soag':
                        fpar = ')\n' if n + 1 == lc else ''
                    else:
                        fpar = ''
                    lisAppWrite.append("{:>24}{}'{}{}){}\n".format(
                        ", Field('", col.colunas.columnName, foreignKey, dttp,
                        fpar))

                if modeloDB[self.modeloDb] == 'legacy':
                    lisAppWrite.append('{:15}{}\n'.format(
                        '', ', primarykey=[{}]'.format(', '.join([
                            "'" + dicColunas[c].columnName + "'"
                            for c in primaryKeys.keys()
                        ]))))
                    lisAppWrite.append('{:15}{}\n'.format(
                        '', ', migrate=False)'))

                lisAppWrite.append("{0:50}= db['{0}']\n\n".format(
                    entidade.nomeFisico))
                if modeloDB[self.modeloDb] == 'Soag':
                    lisAppWrite.append('{:50}= False\n'.format(
                        '{}.id.writable'.format(entidade.nomeFisico)))
                for col in colunasEntidade:
                    entCol = '{}.{}'.format(entidade.nomeFisico,
                                            col.colunas.columnName)
                    origem = self.origemColuna(col)
                    ###### Label
                    lisAppWrite.append("{:50}= '{}'\n".format(
                        '{}.label'.format(entCol), col.colunas.label))
                    if (col.colunas.id in primaryKeys
                            and primaryKeys[col.colunas.id] == 3):
                        lisAppWrite.append('{:50}= True\n'.format(
                            '{}.readonly'.format(entCol)))
                        lisAppWrite.append('if  widgets:\n')
                        lisAppWrite.append('    {:46}= widgets.text\n'.format(
                            '{}.widget'.format(entCol)))
                    elif origem:
                        lisAppWrite.append('{:50}= True\n'.format(
                            '{}.readonly'.format(entCol)))
                        lisAppWrite.append('if  widgets:\n')
                        lisAppWrite.append('    {:46}= widgets.text\n'.format(
                            '{}.widget'.format(entCol)))
                    else:
                        lisAppWrite.append('{:50}= True\n'.format(
                            '{}.writable'.format(entCol)))
                        isindb = False
                        requires = '{}.requires'.format(entCol)
                        if (col.colunas.id in dicFKs
                                and dicFKs[col.colunas.id][0] != entidade.id):
                            isindb = True
                            entRef = dicEntidades[dicFKs[col.colunas.id]
                                                  [0]].nomeFisico
                            entRefId = dicEntidades[dicFKs[col.colunas.id]
                                                    [0]].id
                            colName = dicColunas[dicFKs[col.colunas.id]
                                                 [1]].columnName
                            colRef = colName
                            for cer in colEntRef:
                                if (cer.colunasEntidadesReferenciadas.
                                        entidadeReferenciada == dicFKs[
                                            col.colunas.id][0]):
                                    if cer.colunasEntidadesReferenciadas.consultaSaida:
                                        colRef = dicColunas[
                                            cer.colunasEntidadesReferenciadas.
                                            codigoColuna].columnName
                                    if cer.colunasEntidadesReferenciadas.listaSaida:
                                        lookups = self.montaLookups(
                                            lookups, entidade.nomeFisico,
                                            col.colunas.columnName, entRef,
                                            dicColunas[
                                                cer.
                                                colunasEntidadesReferenciadas.
                                                codigoColuna].columnName)
                                    break
                            lisAppWrite.append(
                                '{:50}= IS_IN_DB(db, {}.{}\n'.format(
                                    requires, entRef, colName))
                            lisAppWrite.append(
                                "{:>52},'%({})s', zero='-- Selecione --'\n".
                                format('', colRef))
                            message = self.montaMensagem(
                                entRefId, 'E', 'E', 'C')
                            lisAppWrite.append(
                                "{:>52},error_message=msgGet(db,'{}'))\n".
                                format('', message))
                        else:
                            lisRegras = []
                            al = '['
                            eq = '='
                            retRegras = self.regrasColunas.selectRegrasColunasByColumnId(
                                col.colunas.id)
                            if not retRegras[0] and retRegras[1]:
                                if self.info:
                                    return False, traceback.format_exc(
                                        sys.exc_info)
                                else:
                                    return False, None
                            regras = retRegras[1]

                            if col.colunasEntidades.ehNotNull:
                                message = self.montaMensagem(col.colunas.id,
                                                             'C',
                                                             'E',
                                                             'PR',
                                                             nova=1)
                                lisRegras.append(
                                    "{:50}{} {}IS_NOT_EMPTY(error_message=msgGet(db,'{}'))\n"
                                    .format(requires, eq, al, message))
                                requires = ''
                                al = ','
                                eq = ' '

                            natureza = col.datatypes.descricao
                            if natureza in 'DECIMAL NUMERIC' and col.colunas.decimais == 0:
                                natureza = 'INTEGER'

                            if dicNatureza[natureza][0]:
                                message = self.montaMensagem(
                                    col.colunas.id,
                                    'C',
                                    'E',
                                    dicNatureza[natureza][1],
                                    nova=1)
                                lisRegras.append(
                                    "{:50}{} {}{}(error_message=msgGet(db,'{}'))\n"
                                    .format(requires, eq, al,
                                            dicNatureza[natureza][0], message))
                                requires = ''
                                al = ','
                                eq = ' '

                            if regras:
                                regras = regras[0]
                                regra = regras.regras.regra
                                message = self.montaMensagem(col.colunas.id,
                                                             'C',
                                                             'E',
                                                             regra,
                                                             nova=1)
                                lisRegras.append(
                                    tratarRegras(regra, regras, col, requires,
                                                 eq, al, message))

                            lr = len(lisRegras)
                            for n, l in enumerate(lisRegras):
                                if n + 1 == lr:
                                    l = l[:-1] + ']\n'
                                lisAppWrite.append(l)

                        if dicWidgets[col.datatypes.descricao] and not isindb:
                            lisAppWrite.append('if  widgets:\n')
                            lisAppWrite.append(
                                '    {:46}= widgets.text\n'.format(
                                    '{}.widget'.format(entCol)))

                if lookups:
                    lisAppWrite.append(lookups[:-1] + '}\n')
                dicWrite[entidade.id] = lisAppWrite

            while len(dicRefer) > 0:
                lisKeys = sorted(dicRefer.keys(
                ))  # Lista com as keys do dicRefer para deleção dos vazios
                # Cada key deletada do dicRefer entra na lisWrite
                for k in lisKeys:
                    if not dicRefer[k]:
                        lisWrite.append(k)
                        del dicRefer[k]
                for ent in lisWrite:
                    for k in dicRefer.keys():
                        if ent in dicRefer[k]:
                            dicRefer[k].remove(ent)

            for ent in lisWrite:
                dbApp.writelines(dicWrite[ent])

            dbApp.close()
            clp = self.atualizaCheckListPrototipo()
            if not clp:
                return clp
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        return True, 'Entidades Geradas = ' + str(gerados)

    def origemColuna(self, col):
        origem = self.OrigemColunasAplicacao.selectOrigemColunasAplicacaoByCodigoColuna(
            col.colunas.id)
        if origem[0] and origem[1]:
            return True
        else:
            return False

    def montaMensagem(self,
                      codigoEntCol,
                      origemMsg,
                      tipoMsg,
                      regra,
                      nova=None):
        retMessage = self.mensagens.getMensagem(codigoEntCol, origemMsg,
                                                tipoMsg, regra, nova)
        if retMessage[0]:
            return '{}{:04}'.format(self.applId, retMessage[1])
        else:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None

    def montaLookups(self, lookups, entidade, coluna, entRef, colRef):
        if lookups:
            lkp = ''
            eqs = ' '
            ach = ','
        else:
            lkp = '{}.lookups'.format(entidade)
            eqs = '='
            ach = '{'
        lookups += "{:50}{} {}'{}': ['{}', ['{}'] ,False]\n".format(
            lkp, eqs, ach, coluna, entRef, colRef)
        return lookups

    def atualizaCheckListPrototipo(self):
        try:
            if self.databaseCreated:
                self.db(self.checkListPrototipo.codigoAplicacao ==
                        self.cAppl).update(model=True, database=True)
            else:
                self.db(self.checkListPrototipo.codigoAplicacao ==
                        self.cAppl).update(model=True)
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        self.db.commit()
        return True, None

    def tryEngine(self):
        config = self.database.getConfig()
        sgdbDB = config.sgdb.sgdb
        userDB = config.database.userDB
        passDB = config.database.passDB
        hostDB = config.database.hostDB
        portDB = config.database.portDB
        nameDB = config.database.nameDB

        if sgdbDB == 'DB2':
            import ibm_db_sa
        try:
            engine = eval("{}.{}('{}://{}:{}@{}:{}/{}')".format(
                'sqlalchemy', 'create_engine', sgdbDB, userDB, passDB, hostDB,
                portDB, nameDB))
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        return True, engine

    def metaSchema(self, engine):
        try:
            schm = sqlalchemy.schema.MetaData(bind=engine)
            schm.reflect()
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        return True, schm
示例#2
0
class CreateController(object):

    def __init__(self, db, cAppl=0, info=False):
        self.db = db
        self.cAppl = cAppl
        self.info = info
        self.aplicacao = Aplicacao(self.db, self.cAppl)
        self.applId = self.aplicacao.getApplId()
        modeloDB = {0:'Soag', 1:'legacy'}
        self.modeloDb = modeloDB[self.aplicacao.getModeloDb()]
        self.entidades = Entidades(self.db, cAppl=self.cAppl)
        self.colunasEntidades = ColunasEntidades(self.db)
        self.primaryKeys = PrimaryKeys(self.db)
        self.OrigemColunasAplicacao = OrigemColunasAplicacao(self.db)
        self.mensagens = Mensagens(self.db, cAppl=self.cAppl)
        self.menu = self.db.menu
        self.parametros = self.db.parametros
        self.parms = self.db(self.parametros).select()[0]
        self.checkListPrototipo = self.db.checkListPrototipo
        self.pathApp = os.path.join('\\\\', '127.0.0.1', 'c$', 'web2py', 'applications', self.applId)
        self.pathTempl = os.path.join( '\\\\', '127.0.0.1', 'c$', 'web2py', 'applications', self.parms.soag
                                      , 'Template', 'web2py', 'templates')

    def createController(self):
        try:
            template = open(os.path.join(self.pathTempl, 'controller.py')).read()
            query=self.db(self.menu.codigoAplicacao == self.cAppl).select()
            labelController = ''
            nomeController = ''
            for q in query:
                if  q.url == 0:
                    continue

                retEntidade = self.entidades.selectEntidadesByEntidadeId(q.url)
                if  not retEntidade[0]:
                    if  self.info:
                        return False, traceback.format_exc(sys.exc_info)
                    else:
                        return False, None
                ent = retEntidade[1][0]

                if  ent.pgmExclusao:
                    deletable = ', deletable=True'
                    optionDelete= 'True'
                    msgexcluida = self.montaMensagem(ent.id, 'E', 'S', 'E')
                else:
                    deletable = ', deletable=False'
                    optionDelete= 'False'
                    msgexcluida = ''
                if  ent.pgmAlteracao:
                    msgalterada = self.montaMensagem(ent.id, 'E', 'S', 'A')
                else:
                    msgalterada = ''
                if  ent.pgmInclusao:
                    msgincluida = self.montaMensagem(ent.id, 'E', 'S', 'I')
                else:
                    msgincluida = ''

                auto = False
                dicPK = {}
                retPK = self.primaryKeys.selectPrimaryKeysByCodigoEntidade(ent.id)
                if  retPK:
                    dicPK = retPK

                campos, lengths, dicOrigIncl, dicOrigAlt, dicCols, pks, lisCols = self.colunasEntidade(ent.id, dicPK)

                importDatetime = importNumAuto = False
                inclusao = alteracao = imports = ''

                sp = 12

                for k in dicPK.keys():
                    if  dicPK[k] == 3 and dicCols[k].datatypes.descricao != 'TIMESTAMP':
                        auto = True

                if  auto:
                    where = ''
                    spn = sp
                    imports += 'from numAuto import numAuto\n'
                    if  len(dicPK) == 1:
                        where += '{:{}}where = ({})\n'.format('', sp, ent.nomeFisico)
                        column = dicCols[dicPK.keys()[0]].colunas.columnName
                        campo = '{:{}}campo = ({}.{})\n'.format('', sp, ent.nomeFisico, column)
                    else:
                        ifap = 'if  ('
                        for k in lisCols:
                            if  k not in dicPK.keys() or dicPK[k] == 3:
                                continue
                            column = dicCols[k].colunas.columnName
                            inclusao += '{:{}}{}request.vars.{} and\n'.format('', sp, ifap, column)
                            ifap = '     '
                        inclusao = inclusao[:-5] + '):\n'
                        spn += 4
                        lAnd  = 'where = ('
                        for k in lisCols:
                            if  k not in dicPK.keys():
                                continue
                            column = dicCols[k].colunas.columnName
                            if  dicPK[k] != 3:
                                where += '{0:{1}}{2}({3}.{4}==int(request.vars.{4}))\n'.format(''
                                                                                              , spn
                                                                                              , lAnd
                                                                                              ,ent.nomeFisico
                                                                                              ,column)
                                lAnd  = '        &'
                            else:
                                campo = '{:{}}campo = ({}.{})\n'.format('', spn, ent.nomeFisico, column)
                        where=where[:-1] + ')\n'
                    nAuto = '{0:{1}}form.vars.{2} = request.vars.{2} = numAuto(db, campo, where)\n'.format(''
                                                                                                          , spn
                                                                                                          , column)
                    inclusao += where
                    inclusao += campo
                    inclusao += nAuto

                if  dicOrigIncl:
                    for k, v in dicOrigIncl.items():
                        if  v[0] == 'PARTITIONH' or v[0] == 'PARTITIONV':
                            inclusao += self.montaPartition(k, pks, v, sp)
                        else:
                            inclusao += '{0:{1}}form.vars.{2} = request.vars.{2} = {3}\n'.format('', sp, k, v[0])
                            if  'datetime' in v[0]:
                                importDatetime = True

                if  not inclusao:
                    inclusao = '{:>{}}\n'.format('pass', sp+4)

                if  dicOrigAlt:
                    for k, v in dicOrigAlt.items():
                        alteracao += '{0:{1}}form.vars.{2} = request.vars.{2} = {3}\n'.format('', sp, k, v[0])
                        if  'datetime' in v[0]:
                            importDatetime = True
                else:
                    alteracao = '{:>{}}\n'.format('pass', sp+4)

                if  importDatetime:
                    imports += 'import datetime\n'

                dic = {'@IMPORTS\n':imports
                      ,'@INCLUSAO\n':inclusao
                      ,'@ALTERACAO\n':alteracao
                      ,'@MSGEXCLUIDA':msgexcluida
                      ,'@MSGALTERADA':msgalterada
                      ,'@MSGINCLUIDA':msgincluida
                      ,'@DELETABLE':deletable
                      ,'@OPTIONDELETE':optionDelete
                      ,'@ENTIDADE':ent.nomeFisico
                      ,'@LABEL'   :q.descricao
                      ,'@QUERYID':'.id > 0' if self.modeloDb == 'Soag' else ''
                      ,'@FIELDSID':"'id'," if self.modeloDb == 'Soag' else ''
                      ,'@SCROLL':"'5%'," if self.modeloDb == 'Soag' else ''
                      ,'@CAMPOS'  :campos
                      ,'@LENGTHS' :lengths}

                nomeController = ''.join(Capitalize(ent.nomeFisico.replace('_',' ')).split())
                controller = open(os.path.join( self.pathApp
                                              , 'controllers'
                                              , nomeController + '.py'), 'w')
                controller.write(change(dic, template))
                controller.close()
                viewOrig = os.path.join(self.pathTempl, 'viewController')
                viewDest = os.path.join(self.pathApp, 'views', nomeController)
                try:
                    shutil.rmtree(viewDest)
                except:
                    pass
                shutil.copytree(viewOrig, viewDest)
        except:
            if  self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        return self.atualizaCheckListPrototipo()

    def colunasEntidade(self, entidadeId, dicPK):
        retColunasEntidades = self.colunasEntidades.selectColunasEntidadesResolvidasByCodigoEntidade(entidadeId)
        if  not retColunasEntidades[0]:
            if  retColunasEntidades[1]:
                if  self.info:
                    return False, traceback.format_exc(sys.exc_info)
                else:
                    return False, None
            else:
                return [False, 'Nao existem colunas para esta Entidade']
        colunasEntidade = retColunasEntidades[1]
        dicOrigIncl = {}
        dicOrigAlt = {}
        dicCols = {}
        lisCols = []
        pks = []
        columns = ''
        n = 0
        for col in colunasEntidade:
            if  col.colunasEntidades.consultaSaida:
                n += 1
                if  n < 6:
                    columns += "'{}',".format(col.colunas.columnName)
                    nc = n
            dicCols[col.colunas.id]=col
            lisCols.append(col.colunas.id)
            origCol = self.origemColuna(col)
            if  origCol:
                if  origCol[0] == 'I':
                    dicOrigIncl[col.colunas.columnName]=[origCol[1], col.colunas.tamanhoColuna]
                elif origCol[0] == 'A':
                    dicOrigAlt[col.colunas.columnName]=[origCol[1], col.colunas.tamanhoColuna]
            if  col.colunas.id in dicPK.keys():
                pks.append(col.colunas.columnName)

        percent = 95 if self.modeloDb == 'Soag' else 100
        lengths = '{}'.format("'{:d}%',".format(int(percent/nc))*nc)[:-1]
        return columns, lengths, dicOrigIncl, dicOrigAlt, dicCols, pks, lisCols

    def origemColuna(self, col):
        origem = self.OrigemColunasAplicacao.selectOrigemColunasAplicacaoByCodigoColuna(col.colunas.id)
        if  origem[0] and origem[1]:
            return [origem[1][0].regras.regra, origem[1][0].origemColunasApoio.controller]
        else:
            return []

    def montaMensagem(self, codigoEntCol, origemMsg, tipoMsg, regra, nova=None):
        retMessage = self.mensagens.getMensagem(codigoEntCol, origemMsg, tipoMsg, regra, nova)
        if  retMessage[0]:
            return '{}{:04}'.format(self.applId, retMessage[1])
        else:
            if  self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None

    def montaPartition(self, column, pks, pl, sp):
        partition = pl[0]
        lenCol = pl[1]
        pks = pks[:lenCol]
        iPk = iterInv(pks) if partition[-1] == 'V' else iter(pks)
        ifap = 'if  ('
        ret = ''
        for pk in iPk:
            ret += '{:{}}{}request.vars.{} and\n'.format('', sp, ifap, pk)
            ifap = '     '
        ret = ret[:-5] + '):\n'
        sp += 4
        retmp = "{0:{1}}form.vars.{2} = request.vars.{2} = '{3}'.format(".format(''
                                                                                , sp
                                                                                , column
                                                                                , '{}'.format('{}'* lenCol))
        lenRet = len(retmp)-1
        ret += retmp
        space = 1
        comma = ''
        iPk = iterInv(pks) if partition[-1] == 'V' else iter(pks)
        for pk in iPk:
            ret += '{:{}}{}int(request.vars.{}[-1])\n'.format('', space, comma, pk)
            space = lenRet
            comma = ', '
        for x in xrange(lenCol - len(pks)):
            ret += '{:{}}{}{}\n'.format('', space, comma, 0)
        ret = ret[:-1] + ')\n'
        return ret

    def atualizaCheckListPrototipo(self):
        try:
            self.db(self.checkListPrototipo.codigoAplicacao == self.cAppl).update(controllers = True)
        except:
            if  self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        self.db.commit()
        return True, None
示例#3
0
class CreateDB:
    def __init__(self, db, cAppl=None, createDataBase=False, info=False):
        self.db = db
        self.cAppl = cAppl
        self.createDataBase = createDataBase
        self.info = info
        self.aplicacao = Aplicacao(self.db, self.cAppl)
        self.applId = self.aplicacao.getApplId()
        self.modeloDb = self.aplicacao.getModeloDb()
        self.entidades = Entidades(self.db, cAppl=self.cAppl)
        self.colunas = Colunas(db, cAppl=self.cAppl)
        self.colunasEntidades = ColunasEntidades(self.db, self.cAppl)
        self.ColEntRef = ColunasEntidadesReferenciadas(self.db)
        self.primaryKeys = PrimaryKeys(self.db)
        self.foreignKeys = ForeignKeys(self.db)
        self.OrigemColunasAplicacao = OrigemColunasAplicacao(self.db)
        self.regrasColunas = RegrasColunas(self.db)
        self.mensagens = Mensagens(self.db, cAppl=self.cAppl)
        self.parametros = self.db.parametros
        self.parms = self.db(self.parametros).select()[0]
        self.checkListPrototipo = self.db.checkListPrototipo
        self.database = Database(db, cAppl=self.cAppl)
        self.databaseCreated = False

        App = os.path.join("\\\\", "127.0.0.1", "c$", "web2py", "applications", self.applId)

        self.dbApp = os.path.join(App, "models", "db.py")

        self.settings = os.path.join(App, "models", "settings_local.db")

        self.databases = os.path.join(App, "databases")

        Template = os.path.join(
            "\\\\", "127.0.0.1", "c$", "web2py", "applications", self.parms.soag, "Template", "web2py", "models"
        )

        self.dbTemplate = os.path.join(Template, "db.py")

        self.settingsTemplate = os.path.join(Template, "settings_local.db")

    def createDB(self):

        try:
            if self.createDataBase:
                if modeloDB[self.modeloDb] == "Soag":
                    command = "dropdb --username=postgres -w {}".format(self.applId)
                    try:
                        os.system(command)
                    except:
                        pass

                    command = "createdb --username=postgres -w {}".format(self.applId)
                    os.system(command)
                else:
                    retorno, returned = self.tryEngine()
                    if not retorno:
                        return retorno, returned
                    engine = returned

                    retorno, returned = self.metaSchema(engine)
                    if not retorno:
                        return retorno, returned
                    schm = returned

                    for tbl in [
                        u"controle",
                        u"mensagens",
                        u"auth_cas",
                        u"auth_event",
                        u"auth_permission",
                        u"auth_membership",
                        u"auth_group",
                        u"auth_user",
                    ]:
                        try:
                            table = schm.tables[tbl]
                            table.drop(engine)
                        except:
                            pass

            settings = open(self.settings, "w")
            settingsTemplate = open(self.settingsTemplate).readlines()
            settingsTemplate = change({"@applId": self.applId}, settingsTemplate)
            settings.writelines(settingsTemplate)
            settings.close()

            if self.createDataBase:
                try:
                    shutil.rmtree(self.databases)
                except:
                    pass
                os.mkdir(self.databases)
                self.databaseCreated = True

            dbApp = open(self.dbApp, "w")
            dbApp.writelines(open(self.dbTemplate).readlines())

            retEntidade = self.entidades.selectEntidadesBycodigoAplicacao()
            if not retEntidade[0]:
                return False, retEntidade[1]
            entidades = retEntidade[1]
            dicEntidades = {entidade.id: entidade for entidade in entidades}

            retColunas = self.colunas.selectColunasByCodigoAplicacao()
            colunas = retColunas[1]
            dicColunas = {col.id: col for col in colunas}

            gerados = 0
            lisWrite = []  # Lista com a ordem de gravação das entidades
            dicWrite = {}  # Dicionario com as linhas de gravação por entidade
            dicRefer = {}  # Dicionario com as entidades referenciadas

            for entidade in entidades:
                lookups = ""
                lisAppWrite = []
                lisAppWrite.append("\ndb.define_table('{}'\n".format(entidade.nomeFisico))
                retColunasEntidades = self.colunasEntidades.selectColunasEntidadesResolvidasByCodigoEntidade(
                    entidade.id
                )
                if not retColunasEntidades[0]:
                    if retColunasEntidades[1]:
                        return False, retColunasEntidades[2]
                    else:
                        return False, None
                gerados += 1
                colunasEntidade = retColunasEntidades[1]
                retPrimaryKeys = self.primaryKeys.selectPrimaryKeysByCodigoEntidade(entidade.id)
                if not retPrimaryKeys:
                    return [0, retPrimaryKeys[1]]
                primaryKeys = retPrimaryKeys
                dicFKs = self.foreignKeys.selectForeignKeysByCodigoEntidade(entidade.id)
                dicRefer[entidade.id] = list(set([dicFKs[k][0] for k in dicFKs if dicFKs[k][0] != entidade.id]))
                retColEntRef = self.ColEntRef.selectColunasEntidadesReferenciadasByCodigoEntidade(entidade.id)
                colEntRef = retColEntRef[1]
                lc = len(colunasEntidade)
                for n, col in enumerate(colunasEntidade):
                    foreignKey = ""
                    if col.colunas.id in dicFKs and dicFKs[col.colunas.id][0] != entidade.id:
                        foreignKey = ", {}".format(dicEntidades[dicFKs[col.colunas.id][0]].nomeFisico)

                    dttp = dicDataTypes[col.datatypes.descricao]
                    if dttp == "'decimal'":
                        dttp = ", 'decimal({},{})'".format(col.colunas.tamanhoColuna, col.colunas.decimais)
                    elif not dttp:
                        dttp = ", length={}".format(col.colunas.tamanhoColuna)
                    else:
                        dttp = ", {}".format(dttp)
                    if modeloDB[self.modeloDb] == "Soag":
                        fpar = ")\n" if n + 1 == lc else ""
                    else:
                        fpar = ""
                    lisAppWrite.append(
                        "{:>24}{}'{}{}){}\n".format(", Field('", col.colunas.columnName, foreignKey, dttp, fpar)
                    )

                if modeloDB[self.modeloDb] == "legacy":
                    lisAppWrite.append(
                        "{:15}{}\n".format(
                            "",
                            ", primarykey=[{}]".format(
                                ", ".join(["'" + dicColunas[c].columnName + "'" for c in primaryKeys.keys()])
                            ),
                        )
                    )
                    lisAppWrite.append("{:15}{}\n".format("", ", migrate=False)"))

                lisAppWrite.append("{0:50}= db['{0}']\n\n".format(entidade.nomeFisico))
                if modeloDB[self.modeloDb] == "Soag":
                    lisAppWrite.append("{:50}= False\n".format("{}.id.writable".format(entidade.nomeFisico)))
                for col in colunasEntidade:
                    entCol = "{}.{}".format(entidade.nomeFisico, col.colunas.columnName)
                    origem = self.origemColuna(col)
                    ###### Label
                    lisAppWrite.append("{:50}= '{}'\n".format("{}.label".format(entCol), col.colunas.label))
                    if col.colunas.id in primaryKeys and primaryKeys[col.colunas.id] == 3:
                        lisAppWrite.append("{:50}= True\n".format("{}.readonly".format(entCol)))
                        lisAppWrite.append("if  widgets:\n")
                        lisAppWrite.append("    {:46}= widgets.text\n".format("{}.widget".format(entCol)))
                    elif origem:
                        lisAppWrite.append("{:50}= True\n".format("{}.readonly".format(entCol)))
                        lisAppWrite.append("if  widgets:\n")
                        lisAppWrite.append("    {:46}= widgets.text\n".format("{}.widget".format(entCol)))
                    else:
                        lisAppWrite.append("{:50}= True\n".format("{}.writable".format(entCol)))
                        isindb = False
                        requires = "{}.requires".format(entCol)
                        if col.colunas.id in dicFKs and dicFKs[col.colunas.id][0] != entidade.id:
                            isindb = True
                            entRef = dicEntidades[dicFKs[col.colunas.id][0]].nomeFisico
                            entRefId = dicEntidades[dicFKs[col.colunas.id][0]].id
                            colName = dicColunas[dicFKs[col.colunas.id][1]].columnName
                            colRef = colName
                            for cer in colEntRef:
                                if cer.colunasEntidadesReferenciadas.entidadeReferenciada == dicFKs[col.colunas.id][0]:
                                    if cer.colunasEntidadesReferenciadas.consultaSaida:
                                        colRef = dicColunas[cer.colunasEntidadesReferenciadas.codigoColuna].columnName
                                    if cer.colunasEntidadesReferenciadas.listaSaida:
                                        lookups = self.montaLookups(
                                            lookups,
                                            entidade.nomeFisico,
                                            col.colunas.columnName,
                                            entRef,
                                            dicColunas[cer.colunasEntidadesReferenciadas.codigoColuna].columnName,
                                        )
                                    break
                            lisAppWrite.append("{:50}= IS_IN_DB(db, {}.{}\n".format(requires, entRef, colName))
                            lisAppWrite.append("{:>52},'%({})s', zero='-- Selecione --'\n".format("", colRef))
                            message = self.montaMensagem(entRefId, "E", "E", "C")
                            lisAppWrite.append("{:>52},error_message=msgGet(db,'{}'))\n".format("", message))
                        else:
                            lisRegras = []
                            al = "["
                            eq = "="
                            retRegras = self.regrasColunas.selectRegrasColunasByColumnId(col.colunas.id)
                            if not retRegras[0] and retRegras[1]:
                                if self.info:
                                    return False, traceback.format_exc(sys.exc_info)
                                else:
                                    return False, None
                            regras = retRegras[1]

                            if col.colunasEntidades.ehNotNull:
                                message = self.montaMensagem(col.colunas.id, "C", "E", "PR", nova=1)
                                lisRegras.append(
                                    "{:50}{} {}IS_NOT_EMPTY(error_message=msgGet(db,'{}'))\n".format(
                                        requires, eq, al, message
                                    )
                                )
                                requires = ""
                                al = ","
                                eq = " "

                            natureza = col.datatypes.descricao
                            if natureza in "DECIMAL NUMERIC" and col.colunas.decimais == 0:
                                natureza = "INTEGER"

                            if dicNatureza[natureza][0]:
                                message = self.montaMensagem(col.colunas.id, "C", "E", dicNatureza[natureza][1], nova=1)
                                lisRegras.append(
                                    "{:50}{} {}{}(error_message=msgGet(db,'{}'))\n".format(
                                        requires, eq, al, dicNatureza[natureza][0], message
                                    )
                                )
                                requires = ""
                                al = ","
                                eq = " "

                            if regras:
                                regras = regras[0]
                                regra = regras.regras.regra
                                message = self.montaMensagem(col.colunas.id, "C", "E", regra, nova=1)
                                lisRegras.append(tratarRegras(regra, regras, col, requires, eq, al, message))

                            lr = len(lisRegras)
                            for n, l in enumerate(lisRegras):
                                if n + 1 == lr:
                                    l = l[:-1] + "]\n"
                                lisAppWrite.append(l)

                        if dicWidgets[col.datatypes.descricao] and not isindb:
                            lisAppWrite.append("if  widgets:\n")
                            lisAppWrite.append("    {:46}= widgets.text\n".format("{}.widget".format(entCol)))

                if lookups:
                    lisAppWrite.append(lookups[:-1] + "}\n")
                dicWrite[entidade.id] = lisAppWrite

            while len(dicRefer) > 0:
                lisKeys = sorted(dicRefer.keys())  # Lista com as keys do dicRefer para deleção dos vazios
                # Cada key deletada do dicRefer entra na lisWrite
                for k in lisKeys:
                    if not dicRefer[k]:
                        lisWrite.append(k)
                        del dicRefer[k]
                for ent in lisWrite:
                    for k in dicRefer.keys():
                        if ent in dicRefer[k]:
                            dicRefer[k].remove(ent)

            for ent in lisWrite:
                dbApp.writelines(dicWrite[ent])

            dbApp.close()
            clp = self.atualizaCheckListPrototipo()
            if not clp:
                return clp
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        return True, "Entidades Geradas = " + str(gerados)

    def origemColuna(self, col):
        origem = self.OrigemColunasAplicacao.selectOrigemColunasAplicacaoByCodigoColuna(col.colunas.id)
        if origem[0] and origem[1]:
            return True
        else:
            return False

    def montaMensagem(self, codigoEntCol, origemMsg, tipoMsg, regra, nova=None):
        retMessage = self.mensagens.getMensagem(codigoEntCol, origemMsg, tipoMsg, regra, nova)
        if retMessage[0]:
            return "{}{:04}".format(self.applId, retMessage[1])
        else:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None

    def montaLookups(self, lookups, entidade, coluna, entRef, colRef):
        if lookups:
            lkp = ""
            eqs = " "
            ach = ","
        else:
            lkp = "{}.lookups".format(entidade)
            eqs = "="
            ach = "{"
        lookups += "{:50}{} {}'{}': ['{}', ['{}'] ,False]\n".format(lkp, eqs, ach, coluna, entRef, colRef)
        return lookups

    def atualizaCheckListPrototipo(self):
        try:
            if self.databaseCreated:
                self.db(self.checkListPrototipo.codigoAplicacao == self.cAppl).update(model=True, database=True)
            else:
                self.db(self.checkListPrototipo.codigoAplicacao == self.cAppl).update(model=True)
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        self.db.commit()
        return True, None

    def tryEngine(self):
        config = self.database.getConfig()
        sgdbDB = config.sgdb.sgdb
        userDB = config.database.userDB
        passDB = config.database.passDB
        hostDB = config.database.hostDB
        portDB = config.database.portDB
        nameDB = config.database.nameDB

        if sgdbDB == "DB2":
            import ibm_db_sa
        try:
            engine = eval(
                "{}.{}('{}://{}:{}@{}:{}/{}')".format(
                    "sqlalchemy", "create_engine", sgdbDB, userDB, passDB, hostDB, portDB, nameDB
                )
            )
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        return True, engine

    def metaSchema(self, engine):
        try:
            schm = sqlalchemy.schema.MetaData(bind=engine)
            schm.reflect()
        except:
            if self.info:
                return False, traceback.format_exc(sys.exc_info)
            else:
                return False, None
        return True, schm