Exemple #1
0
 def getAllEdgvDomainsFromTableName(self, table):
     """
     EDGV databases deployed by DSGTools have a set of domain tables. Gets the value map from such DB.
     It checks for all attributes found.
     :param table: (str) layer to be checked for its EDGV mapping.
     :param table: (QgsVectorLayer) overloaded method - layer to be checked for its EDGV mapping.
     :param field: (str) field to be checked.
     :return: (dict) value map for all attributes that have one.
     """
     ret = defaultdict(dict)
     currentLayer = table if isinstance(table, QgsVectorLayer) else self.layerByName(table)
     if currentLayer.isValid():
         try:
             uri = currentLayer.dataProvider().uri()
             if uri.host() == '':
                 db = QSqlDatabase('QSQLITE')
                 db.setDatabaseName(
                     uri.uri().split("|")[0].strip() if uri.uri().split("|")[0].strip().endswith(".gpkg") \
                         else uri.database()
                 )
                 sql = 'select code, code_name from dominios_{field} order by code'
             else:
                 db = QSqlDatabase('QPSQL')
                 db.setHostName(uri.host())
                 db.setPort(int(uri.port()))
                 db.setDatabaseName(uri.database())
                 db.setUserName(uri.username())
                 db.setPassword(uri.password())
                 sql = 'select code, code_name from dominios.{field} order by code'
             if not db.open():
                 db.close()
                 return ret
             for field in currentLayer.fields():
                 fieldName = field.name()
                 if fieldName in self.specialEdgvAttributes():
                     # EDGV "special" attributes that are have different domains depending on 
                     # which class it belongs to
                     if self.edgvVersion(db) in ("2.1.3 Pro", "3.0 Pro"):
                         cat = table if isinstance(table, str) else table.name()
                         # Pro versions now follow the logic "{attribute}_{CLASS_NAME}"
                         cat = cat.rsplit("_", 1)[0].split("_", 1)[-1]
                     else:
                         cat = (table if isinstance(table, str) else table.name()).split("_")[0]
                     fieldN = "{attribute}_{cat}".format(attribute=fieldName, cat=cat)
                     query = QSqlQuery(sql.format(field=fieldN), db)
                 else:
                     query = QSqlQuery(sql.format(field=fieldName), db)
                 if not query.isActive():
                     continue
                 while query.next():
                     code = str(query.value(0))
                     code_name = query.value(1)
                     ret[fieldName][code_name] = code    
             db.close()
         except:
             pass
     return ret
Exemple #2
0
 def getEdgvDomainsFromTableName(self, table, field=None):
     """
     EDGV databases deployed by DSGTools have a set of domain tables. Gets the value map from such DB.
     :param table: (str) layer to be checked for its EDGV mapping.
     :param table: (QgsVectorLayer) overloaded method - layer to be checked for its EDGV mapping.
     :param field: (str) field to be checked.
     :return: (dict) value map.
     """
     ret = dict()
     currentLayer = table if isinstance(
         table, QgsVectorLayer) else self.layerByName(table)
     if currentLayer.isValid():
         try:
             uri = currentLayer.dataProvider().uri()
             field = field or self.currentField()
             if field in self.specialEdgvAttributes():
                 # EDGV "special" attributes that are have different domains depending on
                 # which class it belongs to
                 category = self.currentLayerName().split("_")[0]
                 field = "{attribute}_{cat}".format(attribute=field,
                                                    cat=category)
             if uri.host() == '':
                 db = QSqlDatabase('QSQLITE')
                 db.setDatabaseName(
                     uri.uri().split("|")[0].strip() if uri.uri().split("|")[0].strip().endswith(".gpkg") \
                         else uri.database()
                 )
                 sql = 'select code, code_name from dominios_{field} order by code'.format(
                     field=field)
             else:
                 db = QSqlDatabase('QPSQL')
                 db.setHostName(uri.host())
                 db.setPort(int(uri.port()))
                 db.setDatabaseName(uri.database())
                 db.setUserName(uri.username())
                 db.setPassword(uri.password())
                 sql = 'select code, code_name from dominios.{field} order by code'.format(
                     field=field)
             if not db.open():
                 db.close()
                 return ret
             query = QSqlQuery(sql, db)
             if not query.isActive():
                 return ret
             while query.next():
                 code = str(query.value(0))
                 code_name = query.value(1)
                 ret[code_name] = code
             db.close()
         except:
             pass
     return ret
Exemple #3
0
class SpatialiteDb(AbstractDb):
    def __init__(self):
        '''
        Constructor
        '''
        super(SpatialiteDb, self).__init__()
        self.db = QSqlDatabase('QSQLITE')
        self.gen = SqlGeneratorFactory().createSqlGenerator(
            driver=DsgEnums.DriverSpatiaLite)

    def closeDatabase(self):
        if self.db is not None and self.db.isOpen():
            self.db.close()

    def getDatabaseName(self):
        '''
        Gets the database name
        '''
        return self.db.databaseName().split('.sqlite')[0].split('/')[-1]

    def connectDatabase(self, conn=None):
        '''
        Connects to database
        conn: Database name
        '''
        if conn is None:
            self.connectDatabaseWithGui()
        else:
            self.db.setDatabaseName(conn)

    def connectDatabaseWithGui(self):
        '''
        Connects to database using user interface dialog
        '''
        fd = QFileDialog()
        filename = fd.getOpenFileName(
            caption=self.tr('Select a DSGTools Spatialite file'),
            filter=self.tr('Spatialite file databases (*.sqlite)'))
        filename = filename[0] if isinstance(filename, tuple) else filename
        self.db.setDatabaseName(filename)

    def listGeomClassesFromDatabase(self, primitiveFilter=[]):
        '''
        Gets a list with geometry classes from database
        '''
        self.checkAndOpenDb()
        classList = []
        sql = self.gen.getTablesFromDatabase()
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            self.db.close()
            raise Exception(
                self.tr("Problem listing geom classes: ") +
                query.lastError().text())
        while query.next():
            tableName = str(query.value(0))
            layerName = tableName
            if tableName[-2:].lower() in ["_p", "_l", "_a"]:
                classList.append(layerName)
        return classList

    def listComplexClassesFromDatabase(self):
        '''
        Gets a list with complex classes from database
        '''
        self.checkAndOpenDb()
        classList = []
        sql = self.gen.getTablesFromDatabase()
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            self.db.close()
            raise Exception(
                self.tr("Problem listing complex classes: ") +
                query.lastError().text())
        while query.next():
            tableName = str(query.value(0))
            layerName = tableName
            tableSchema = layerName.split('_')[0]
            if tableSchema == 'complexos':
                classList.append(layerName)
        return classList

    def getStructureDict(self):
        '''
        Gets database structure according to the edgv version
        '''
        self.checkAndOpenDb()
        classDict = dict()
        sql = self.gen.getStructure(self.getDatabaseVersion())
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            self.db.close()
            raise Exception(
                self.tr("Problem getting database structure: ") +
                query.lastError().text())
        while query.next():
            className = str(query.value(0))
            classSql = str(query.value(1))
            if className.split('_')[0] == 'complexos' or className.split(
                    '_')[-1] in ['p', 'l', 'a']:
                if className not in list(classDict.keys()):
                    classDict[className] = dict()
                classSql = classSql.split(className)[1]
                sqlList = classSql.replace('(', '').replace(')', '').replace(
                    '\"', '').replace('\'', '').split(',')
                for s in sqlList:
                    fieldName = str(s.strip().split(' ')[0])
                    classDict[className][fieldName] = fieldName

                if 'GEOMETRY' in list(classDict[className].keys()):
                    classDict[className]['GEOMETRY'] = 'geom'
                if 'geometry' in list(classDict[className].keys()):
                    classDict[className]['geometry'] = 'geom'
                if 'OGC_FID' in list(classDict[className].keys()):
                    classDict[className]['OGC_FID'] = 'id'

        return classDict

    def makeOgrConn(self):
        '''
        Makes a connection string for spatialite databases (e.g just the name)
        '''
        constring = self.db.databaseName()
        return constring

    def validateWithOutputDatabaseSchema(self, outputAbstractDb):
        '''
        Validates the conversion with the output database.
        It generates a dictionary (invalidated) that stores conversion problems
        '''
        self.checkAndOpenDb()
        invalidated = self.buildInvalidatedDict()
        inputdbStructure = self.getStructureDict()
        outputdbStructure = outputAbstractDb.getStructureDict()
        domainDict = outputAbstractDb.getDomainDict()
        classes = self.listClassesWithElementsFromDatabase()
        notNullDict = outputAbstractDb.getNotNullDict()

        for inputClass in list(classes.keys()):
            outputClass = self.translateAbstractDbLayerNameToOutputFormat(
                inputClass, outputAbstractDb)
            (schema, className) = self.getTableSchema(inputClass)
            if outputClass in list(outputdbStructure.keys()):
                outputAttrList = self.reorderTupleList(
                    list(outputdbStructure[outputClass].keys()))
                inputAttrList = self.reorderTupleList(
                    list(inputdbStructure[inputClass].keys()))

                sql = self.gen.getFeaturesWithSQL(inputClass, inputAttrList)
                query = QSqlQuery(sql, self.db)
                if not query.isActive():
                    self.db.close()
                    raise Exception(
                        self.tr("Problem executing query: ") +
                        query.lastError().text())

                while query.next():
                    id = query.value(0)
                    #detects null lines
                    for i in range(len(inputAttrList)):
                        nullLine = True
                        value = query.value(i)
                        if value != None:
                            nullLine = False
                            break
                    if nullLine:
                        if cl not in list(invalidated['nullLine'].keys()):
                            invalidated['nullLine'][inputClass] = 0
                        invalidated['nullLine'][inputClass] += 1

                    #validates pks
                    if id == None and (not nullLine):
                        if cl not in list(invalidated['nullPk'].keys()):
                            invalidated['nullPk'][inputClass] = 0
                        invalidated['nullPk'][inputClass] += 1

                    for i in range(len(inputAttrList)):
                        value = query.value(i)
                        #validates domain
                        if outputClass in list(domainDict.keys()):
                            if inputAttrList[i] in list(
                                    domainDict[outputClass].keys()):
                                if value not in domainDict[outputClass][
                                        inputAttrList[i]] and (not nullLine):
                                    invalidated = self.utils.buildNestedDict(
                                        invalidated, [
                                            'notInDomain', inputClass, id,
                                            inputAttrList[i]
                                        ], value)
                        #validates not nulls
                        if outputClass in list(notNullDict.keys()):
                            if outputClass in list(domainDict.keys()):
                                if inputAttrList[i] in notNullDict[
                                        outputClass] and inputAttrList[
                                            i] not in list(
                                                domainDict[outputClass].keys(
                                                )):
                                    if (value == None) and (not nullLine) and (
                                            inputAttrList[i] not in list(
                                                domainDict[outputClass].keys())
                                    ):
                                        invalidated = self.utils.buildNestedDict(
                                            invalidated, [
                                                'nullAttribute', inputClass,
                                                id, inputAttrList[i]
                                            ], value)
                            else:
                                if inputAttrList[i] in notNullDict[
                                        outputClass]:
                                    try:
                                        if value.isNull():
                                            invalidated = self.utils.buildNestedDict(
                                                invalidated, [
                                                    'nullAttribute',
                                                    inputClass, id,
                                                    inputAttrList[i]
                                                ], value)
                                    except:
                                        if (value == None) and (
                                                not nullLine
                                        ) and (inputAttrList[i] not in list(
                                                domainDict[outputClass].keys())
                                               ):
                                            invalidated = self.utils.buildNestedDict(
                                                invalidated, [
                                                    'nullAttribute',
                                                    inputClass, id,
                                                    inputAttrList[i]
                                                ], value)
                        if outputClass in list(domainDict.keys()):
                            if (inputAttrList[i] not in [
                                    'geom', 'GEOMETRY', 'geometry', 'id',
                                    'OGC_FID'
                            ] and schema != 'complexos') or (
                                    schema == 'complexos'
                                    and inputAttrList[i] != 'id'):
                                if inputAttrList[i] not in list(
                                        outputdbStructure[outputClass].keys()):
                                    invalidated = self.utils.buildNestedDict(
                                        invalidated, [
                                            'attributeNotFoundInOutput',
                                            inputClass
                                        ], [inputAttrList[i]])
                        #validates fk field
                        if 'id_' == inputAttrList[0:3]:
                            if not self.validateUUID(value):
                                if inputAttrList[i] not in list(
                                        outputdbStructure[outputClass].keys()):
                                    invalidated = self.utils.buildNestedDict(
                                        invalidated,
                                        ['nullComplexFk', inputClass],
                                        [inputAttrList[i]])
            else:
                invalidated['classNotFoundInOutput'].append(inputAttrList)
        return invalidated

    def translateAbstractDbLayerNameToOutputFormat(self, lyr,
                                                   outputAbstractDb):
        '''
        Translates abstractdb layer name to output format
        lyr: layer name that will be translated
        outputAbstractDb: output database
        '''
        if outputAbstractDb.db.driverName() == 'QSQLITE':
            return lyr
        if outputAbstractDb.db.driverName() == 'QPSQL':
            return str(lyr.split('_')[0] + '.' + '_'.join(lyr.split('_')[1::]))

    def translateOGRLayerNameToOutputFormat(self, lyr, ogrOutput):
        '''
        Translates ogr layer name to output format
        lyr: layer name that will be translated
        ogrOutput: ogr output
        '''
        if ogrOutput.GetDriver().name == 'SQLite':
            return lyr
        if ogrOutput.GetDriver().name == 'PostgreSQL':
            return str(lyr.split('_')[0] + '.' + '_'.join(lyr.split('_')[1::]))

    def getTableSchema(self, lyr):
        '''
        Gets the table schema
        lyr: layer name
        '''
        schema = lyr.split('_')[0]
        className = '_'.join(lyr.split('_')[1::])
        return (schema, className)

    def convertToPostgis(self, outputAbstractDb, type=None):
        '''
        Converts this to a postgis database
        outputAbstractDb: postgis output
        type: conversion type
        '''
        (inputOgrDb, outputOgrDb, fieldMap, inputLayerList,
         errorDict) = self.prepareForConversion(outputAbstractDb)
        invalidated = self.validateWithOutputDatabaseSchema(outputAbstractDb)
        hasErrors = self.makeValidationSummary(invalidated)
        if type == 'untouchedData':
            if hasErrors:
                self.signals.updateLog.emit('\n\n\n' + self.tr(
                    'Conversion not perfomed due to validation errors! Check log above for more information.'
                ))
                return False
            else:
                status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap,
                                          inputLayerList, errorDict)
                return status
        if type == 'fixData':
            if hasErrors:
                status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap,
                                          inputLayerList, errorDict,
                                          invalidated)
                return status
            else:
                status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap,
                                          inputLayerList, errorDict)
                return status
        return False

    def getDatabaseVersion(self):
        '''
        Gets the database version
        '''
        self.checkAndOpenDb()
        version = '2.1.3'
        sql = self.gen.getEDGVVersion()
        query = QSqlQuery(sql, self.db)
        # if not query.isActive():
        #     raise Exception(self.tr("Problem getting database version: ")+query.lastError().text())
        while query.next():
            version = query.value(0)
        return version

    def obtainLinkColumn(self, complexClass, aggregatedClass):
        '''
        Obtains the link column between complex and aggregated class
        complexClass: complex class name
        aggregatedClass: aggregated class name
        '''
        self.checkAndOpenDb()
        #query to obtain the link column between the complex and the feature layer
        sql = self.gen.getLinkColumn(complexClass.replace('complexos_', ''),
                                     aggregatedClass)
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            self.db.close()
            raise Exception(
                self.tr("Problem obtaining link column: ") +
                query.lastError().text())
        column_name = ""
        while query.next():
            column_name = query.value(0)
        return column_name

    def loadAssociatedFeatures(self, complex):
        '''
        Loads all the features associated to the complex 
        complex: complex class name
        '''
        self.checkAndOpenDb()
        associatedDict = dict()
        #query to get the possible links to the selected complex in the combobox
        complexName = complex.replace('complexos_', '')
        sql = self.gen.getComplexLinks(complexName)
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            self.db.close()
            raise Exception(
                self.tr("Problem loading associated features: ") +
                query.lastError().text())

        while query.next():
            #setting the variables
            complex_schema = query.value(0)
            complex = query.value(1)
            aggregated_schema = query.value(2)
            aggregated_class = query.value(3)
            column_name = query.value(4)

            if aggregated_class.split('_')[-1] not in ['p', 'l', 'a']:
                continue

            #query to obtain the created complexes
            sql = self.gen.getComplexData(complex_schema, complex)
            complexQuery = QSqlQuery(sql, self.db)
            if not complexQuery.isActive():
                self.db.close()
                raise Exception(
                    self.tr("Problem executing query: ") +
                    complexQuery.lastError().text())

            while next(complexQuery):
                complex_uuid = complexQuery.value(0)
                name = complexQuery.value(1)

                if not (complex_uuid and name):
                    continue

                associatedDict = self.utils.buildNestedDict(
                    associatedDict, [name, complex_uuid, aggregated_class], [])

                #query to obtain the id of the associated feature
                sql = self.gen.getAssociatedFeaturesData(
                    aggregated_schema, aggregated_class, column_name,
                    complex_uuid)
                associatedQuery = QSqlQuery(sql, self.db)
                if not associatedQuery.isActive():
                    self.db.close()
                    raise Exception(
                        self.tr("Problem executing query: ") +
                        associatedQuery.lastError().text())

                while next(associatedQuery):
                    ogc_fid = associatedQuery.value(0)
                    associatedDict = self.utils.buildNestedDict(
                        associatedDict, [name, complex_uuid, aggregated_class],
                        [ogc_fid])
        return associatedDict

    def isComplexClass(self, className):
        '''
        Checks if a class is a complex class
        className: class name to be checked
        '''
        self.checkAndOpenDb()
        #getting all complex tables
        query = QSqlQuery(self.gen.getComplexTablesFromDatabase(), self.db)
        if not query.isActive():
            self.db.close()
            raise Exception(
                self.tr("Problem executing query: ") +
                query.lastError().text())

        while query.next():
            if query.value(0) == 'complexos_' + className:
                return True
        return False

    def disassociateComplexFromComplex(self, aggregated_class, link_column,
                                       id):
        '''
        Disassociates a complex from another complex
        aggregated_class: aggregated class that will be disassociated
        link_column: link column between complex and its aggregated class
        id: complex id (uid) to be disassociated
        '''
        sql = self.gen.disassociateComplexFromComplex(
            'complexos_' + aggregated_class, link_column, id)
        query = QSqlQuery(self.db)
        if not query.exec_(sql):
            self.db.close()
            raise Exception(
                self.tr('Problem disassociating complex from complex: ') +
                '\n' + query.lastError().text())

    def getTablesFromDatabase(self):
        '''
        Gets all tables from database
        '''
        self.checkAndOpenDb()
        ret = []

        sql = self.gen.getTablesFromDatabase()
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            self.db.close()
            raise Exception(
                self.tr("Problem getting tables from database: ") +
                query.lastError().text())

        while query.next():
            #table name
            ret.append(query.value(0))
        return ret

    def getFrameLayerName(self):
        '''
        Gets the frame layer name
        '''
        return 'public_aux_moldura_a'

    def getOrphanGeomTablesWithElements(self, loading=False):
        return []

    def getOrphanGeomTables(self):
        return []

    def checkAndCreateStyleTable(self):
        return None

    def getStylesFromDb(self, dbVersion):
        return None

    def getGeomTypeDict(self, loadCentroids=False):
        self.checkAndOpenDb()
        edgvVersion = self.getDatabaseVersion()
        sql = self.gen.getGeomByPrimitive(edgvVersion)
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            raise Exception(
                self.tr("Problem getting geom types from db: ") +
                query.lastError().text())
        geomDict = dict()
        while query.next():
            if edgvVersion in ('2.1.3', 'FTer_2a_Ed'):
                type = query.value(0)
            else:
                type = self.getResolvedGeomType(query.value(0))
            tableName = query.value(1)
            layerName = '_'.join(tableName.split('_')[1::])
            if type not in list(geomDict.keys()):
                geomDict[type] = []
            if layerName not in geomDict[type]:
                geomDict[type].append(layerName)
        return geomDict

    def getGeomDict(self, getCentroids=False):
        '''
        returns a dict like this:
        {'tablePerspective' : {
            'layerName' :
        '''
        self.checkAndOpenDb()
        edgvVersion = self.getDatabaseVersion()
        sql = self.gen.getGeomTablesFromGeometryColumns(edgvVersion)
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            raise Exception(
                self.tr("Problem getting geom tables from db: ") +
                query.lastError().text())
        geomDict = dict()
        geomDict['primitivePerspective'] = self.getGeomTypeDict()
        geomDict['tablePerspective'] = dict()
        while query.next():
            isCentroid = False
            srid = query.value(0)
            if edgvVersion in ('2.1.3', 'FTer_2a_Ed'):
                geometryType = query.value(2)
            else:
                geometryType = self.getResolvedGeomType(query.value(2))
            tableName = query.value(3)
            tableSchema = tableName.split('_')[0]
            geometryColumn = query.value(1)
            layerName = '_'.join(tableName.split('_')[1::])
            if layerName not in list(geomDict['tablePerspective'].keys()):
                geomDict['tablePerspective'][layerName] = dict()
                geomDict['tablePerspective'][layerName]['schema'] = tableSchema
                geomDict['tablePerspective'][layerName]['srid'] = str(srid)
                geomDict['tablePerspective'][layerName][
                    'geometryColumn'] = geometryColumn
                geomDict['tablePerspective'][layerName][
                    'geometryType'] = geometryType
                geomDict['tablePerspective'][layerName][
                    'tableName'] = tableName
        return geomDict

    def getGeomColumnDict(self):
        '''
        Dict in the form 'geomName':[-list of table names-]
        '''
        self.checkAndOpenDb()
        sql = self.gen.getGeomColumnDict()
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            raise Exception(
                self.tr("Problem getting geom column dict: ") +
                query.lastError().text())
        geomDict = dict()
        while query.next():
            geomColumn = query.value(0)
            tableName = query.value(1)
            lyrName = '_'.join(tableName.split('_')[1::])
            if geomColumn not in list(geomDict.keys()):
                geomDict[geomColumn] = []
            geomDict[geomColumn].append(lyrName)
        return geomDict

    def createFrame(self, type, scale, param, paramDict=dict()):
        mi, inom, frame = self.prepareCreateFrame(type, scale, param)
        self.insertFrame(scale, mi, inom, frame.asWkb())
        return frame

    def insertFrame(self, scale, mi, inom, frame):
        self.checkAndOpenDb()
        srid = self.findEPSG()
        geoSrid = QgsCoordinateReferenceSystem(
            int(srid)).geographicCRSAuthId().split(':')[-1]
        ogr.UseExceptions()
        outputDS = self.buildOgrDatabase()
        outputLayer = outputDS.GetLayerByName('public_aux_moldura_a')
        newFeat = ogr.Feature(outputLayer.GetLayerDefn())
        auxGeom = ogr.CreateGeometryFromWkb(frame)
        #set geographic srid from frame
        geoSrs = ogr.osr.SpatialReference()
        geoSrs.ImportFromEPSG(int(geoSrid))
        auxGeom.AssignSpatialReference(geoSrs)
        #reproject geom
        outSpatialRef = outputLayer.GetSpatialRef()
        coordTrans = osr.CoordinateTransformation(geoSrs, outSpatialRef)
        auxGeom.Transform(coordTrans)
        newFeat.SetGeometry(auxGeom)
        newFeat.SetField('mi', mi)
        newFeat.SetField('inom', inom)
        newFeat.SetField('escala', str(scale))
        out = outputLayer.CreateFeature(newFeat)
        outputDS.Destroy()

    def getTableSchemaFromDb(self, table):
        self.checkAndOpenDb()
        sql = self.gen.getFullTablesName(table)
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            raise Exception(
                self.tr("Problem getting full table name: ") +
                query.lastError().text())
        while query.next():
            return query.value(0).split('_')[0]

    def getGeomColumnTupleList(self, showViews=False):
        """
        list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)]
        centroids are hidden by default
        """
        self.checkAndOpenDb()
        edgvVersion = self.getDatabaseVersion()
        sql = self.gen.getGeomColumnTupleList(edgvVersion)
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            raise Exception(
                self.tr("Problem getting geom tuple list: ") +
                query.lastError().text())
        geomList = []
        while query.next():
            if edgvVersion in ['2.1.3', 'FTer_2a_Ed']:
                geomList.append((query.value(0).split('_')[0],
                                 '_'.join(query.value(0).split('_')[1::]),
                                 query.value(1), query.value(2), 'BASE TABLE'))
            else:
                geomList.append(
                    (query.value(0).split('_')[0],
                     '_'.join(query.value(0).split('_')[1::]), query.value(1),
                     self.getResolvedGeomType(int(query.value(2))),
                     'BASE TABLE'))
        return geomList

    def getResolvedGeomType(self, geometryType):
        geomDict = {
            0: 'GEOMETRY',
            1: 'POINT',
            2: 'LINESTRING',
            3: 'POLYGON',
            4: 'MULTIPOINT',
            5: 'MULTILINESTRING',
            6: 'MULTIPOLYGON',
            7: 'GEOMETRYCOLLECTION',
            8: 'CIRCULARSTRING',
            9: 'COMPOUNDCURVE',
            10: 'CURVEPOLYGON',
            11: 'MULTICURVE',
            12: 'MULTISURFACE',
            13: 'CURVE',
            14: 'SURFACE'
        }
        return geomDict[geometryType]

    def databaseInfo(self):
        """
        Gives information about all tables present in the database. Output is composed by
        schema, layer, geometry column, geometry type and srid, in that order.
        :return: (list-of-dict) database information.
        """
        self.checkAndOpenDb()
        sql = self.gen.databaseInfo()
        query = QSqlQuery(sql, self.db)
        if not query.isActive():
            raise Exception(
                self.tr("Problem getting geom schemas from db: ") +
                query.lastError().text())
        out = []
        while query.next():
            rowDict = dict()
            rowDict['schema'] = query.value(0).split('_')[0]
            rowDict['layer'] = query.value(0)[len(rowDict['schema']) + 1:]
            rowDict['geomCol'] = query.value(1)
            rowDict['geomType'] = query.value(2)
            rowDict['srid'] = str(query.value(3))
            out.append(rowDict)
        return out