""" /*************************************************************************** Name : DB Manager Description : Database manager plugin for QGIS Date : May 23, 2011 copyright : (C) 2011 by Giuseppe Sucameli email : brush.tyler@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ """ from qgis.PyQt.QtWidgets import QApplication from .html_elems import ( HtmlContent, HtmlSection, HtmlParagraph, HtmlList, HtmlTable, HtmlTableHeader, HtmlTableCol, ) class DatabaseInfo: def __init__(self, db): self.db = db def __del__(self): self.db = None def generalInfo(self): info = self.db.connector.getInfo() tbl = [(QApplication.translate("DBManagerPlugin", "Server version: "), info[0])] return HtmlTable(tbl) def connectionDetails(self): tbl = [ ( QApplication.translate("DBManagerPlugin", "Host:"), self.db.connector.host, ), ( QApplication.translate("DBManagerPlugin", "User:"), self.db.connector.user, ), ] return HtmlTable(tbl) def spatialInfo(self): ret = [] info = self.db.connector.getSpatialInfo() if info is None: return tbl = [ (QApplication.translate("DBManagerPlugin", "Library:"), info[0]), ("GEOS:", info[1]), ("Proj:", info[2]), ] ret.append(HtmlTable(tbl)) if not self.db.connector.has_geometry_columns: ret.append( HtmlParagraph( QApplication.translate( "DBManagerPlugin", " geometry_columns table doesn't exist!\n" "This table is essential for many GIS applications for enumeration of tables.", ) ) ) return ret def privilegesDetails(self): details = self.db.connector.getDatabasePrivileges() lst = [] if details[0]: lst.append(QApplication.translate("DBManagerPlugin", "create new schemas")) if details[1]: lst.append( QApplication.translate("DBManagerPlugin", "create temporary tables") ) return HtmlList(lst) def toHtml(self): if self.db is None: return HtmlSection( QApplication.translate("DBManagerPlugin", " Not connected") ).toHtml() ret = [] # connection details conn_details = self.connectionDetails() if conn_details is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Connection details"), conn_details, ) ) # database information general_info = self.generalInfo() if general_info is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "General info"), general_info, ) ) # has spatial enabled? spatial_info = self.spatialInfo() if spatial_info is None: pass else: typename = self.db.connection().typeNameString() spatial_info = HtmlContent(spatial_info) if not spatial_info.hasContents(): spatial_info = QApplication.translate( "DBManagerPlugin", " {0} support not enabled!" ).format(typename) ret.append(HtmlSection(typename, spatial_info)) # privileges priv_details = self.privilegesDetails() if priv_details is None: pass else: priv_details = HtmlContent(priv_details) if not priv_details.hasContents(): priv_details = QApplication.translate( "DBManagerPlugin", " This user has no privileges!" ) else: priv_details = [ QApplication.translate("DBManagerPlugin", "User has privileges:"), priv_details, ] ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Privileges"), priv_details, ) ) return HtmlContent(ret).toHtml() class SchemaInfo: def __init__(self, schema): self.schema = schema def __del__(self): self.schema = None def generalInfo(self): tbl = [ # ("Tables:", self.schema.tableCount) ] if self.schema.owner: tbl.append( (QApplication.translate("DBManagerPlugin", "Owner:"), self.schema.owner) ) if self.schema.comment: tbl.append( ( QApplication.translate("DBManagerPlugin", "Comment:"), self.schema.comment, ) ) return HtmlTable(tbl) def privilegesDetails(self): details = self.schema.database().connector.getSchemaPrivileges(self.schema.name) lst = [] if details[0]: lst.append(QApplication.translate("DBManagerPlugin", "create new objects")) if details[1]: lst.append(QApplication.translate("DBManagerPlugin", "access objects")) return HtmlList(lst) def toHtml(self): ret = [] general_info = self.generalInfo() if general_info is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Schema details"), general_info, ) ) priv_details = self.privilegesDetails() if priv_details is None: pass else: priv_details = HtmlContent(priv_details) if not priv_details.hasContents(): priv_details = QApplication.translate( "DBManagerPlugin", " This user has no privileges to access this schema!", ) else: priv_details = [ QApplication.translate("DBManagerPlugin", "User has privileges:"), priv_details, ] ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Privileges"), priv_details, ) ) return HtmlContent(ret).toHtml() class TableInfo: def __init__(self, table): self.table = table def __del__(self): self.table = None def generalInfo(self): if self.table.rowCount is None: # row count information is not displayed yet, so just block # table signals to avoid double refreshing (infoViewer->refreshRowCount->tableChanged->infoViewer) self.table.blockSignals(True) self.table.refreshRowCount() self.table.blockSignals(False) tbl = [ ( QApplication.translate("DBManagerPlugin", "Relation type:"), ( QApplication.translate("DBManagerPlugin", "View") if self.table.isView else QApplication.translate("DBManagerPlugin", "Table") ), ), ( QApplication.translate("DBManagerPlugin", "Rows:"), ( self.table.rowCount if self.table.rowCount is not None else QApplication.translate( "DBManagerPlugin", 'Unknown (find out)', ) ), ), ] if self.table.comment: tbl.append( ( QApplication.translate("DBManagerPlugin", "Comment:"), self.table.comment, ) ) return HtmlTable(tbl) def spatialInfo(self): # implemented in subclasses return None def fieldsDetails(self): tbl = [] # define the table header header = ( "#", QApplication.translate("DBManagerPlugin", "Name"), QApplication.translate("DBManagerPlugin", "Type"), QApplication.translate("DBManagerPlugin", "Null"), QApplication.translate("DBManagerPlugin", "Default"), ) tbl.append(HtmlTableHeader(header)) # add table contents for fld in self.table.fields(): is_null_txt = "N" if fld.notNull else "Y" # make primary key field underlined attrs = {"class": "underline"} if fld.primaryKey else None name = HtmlTableCol(fld.name, attrs) tbl.append( (fld.num, name, fld.type2String(), is_null_txt, fld.default2String()) ) return HtmlTable(tbl, {"class": "header"}) def constraintsDetails(self): if self.table.constraints() is None or len(self.table.constraints()) <= 0: return None tbl = [] # define the table header header = ( QApplication.translate("DBManagerPlugin", "Name"), QApplication.translate("DBManagerPlugin", "Type"), QApplication.translate("DBManagerPlugin", "Column(s)"), ) tbl.append(HtmlTableHeader(header)) # add table contents for con in self.table.constraints(): # get the fields the constraint is defined on cols = [ p[1].name if p[1] is not None else "??? (#%d)" % p[0] for p in iter(list(con.fields().items())) ] tbl.append((con.name, con.type2String(), "\n".join(cols))) return HtmlTable(tbl, {"class": "header"}) def indexesDetails(self): if self.table.indexes() is None or len(self.table.indexes()) <= 0: return None tbl = [] # define the table header header = ( QApplication.translate("DBManagerPlugin", "Name"), QApplication.translate("DBManagerPlugin", "Column(s)"), ) tbl.append(HtmlTableHeader(header)) # add table contents for idx in self.table.indexes(): # get the fields the index is defined on cols = [ p[1].name if p[1] is not None else "??? (#%d)" % p[0] for p in iter(list(idx.fields().items())) ] tbl.append((idx.name, "\n".join(cols))) return HtmlTable(tbl, {"class": "header"}) def triggersDetails(self): if self.table.triggers() is None or len(self.table.triggers()) <= 0: return None tbl = [] # define the table header header = ( QApplication.translate("DBManagerPlugin", "Name"), QApplication.translate("DBManagerPlugin", "Function"), ) tbl.append(HtmlTableHeader(header)) # add table contents for trig in self.table.triggers(): name = ( '{name} ({action})'.format( name=trig.name, action="delete" ) ) tbl.append((name, trig.function.replace("<", "<"))) return HtmlTable(tbl, {"class": "header"}) def getViewDefinition(self): if not self.table.isView: return None return self.table.database().connector.getViewDefinition( (self.table.schemaName(), self.table.name) ) def getTableInfo(self): ret = [] general_info = self.generalInfo() if general_info is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "General info"), general_info, ) ) # spatial info spatial_info = self.spatialInfo() if spatial_info is None: pass else: spatial_info = HtmlContent(spatial_info) if not spatial_info.hasContents(): spatial_info = QApplication.translate( "DBManagerPlugin", " This is not a spatial table." ) ret.append( HtmlSection( self.table.database().connection().typeNameString(), spatial_info ) ) # fields fields_details = self.fieldsDetails() if fields_details is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Fields"), fields_details ) ) # constraints constraints_details = self.constraintsDetails() if constraints_details is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Constraints"), constraints_details, ) ) # indexes indexes_details = self.indexesDetails() if indexes_details is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Indexes"), indexes_details, ) ) # triggers triggers_details = self.triggersDetails() if triggers_details is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "Triggers"), triggers_details, ) ) return ret def getViewInfo(self): if not self.table.isView: return [] ret = self.getTableInfo() # view definition view_def = self.getViewDefinition() if view_def is None: pass else: ret.append( HtmlSection( QApplication.translate("DBManagerPlugin", "View definition"), view_def, ) ) return ret def toHtml(self): if self.table.isView: ret = self.getViewInfo() else: ret = self.getTableInfo() return HtmlContent(ret).toHtml() class VectorTableInfo(TableInfo): def __init__(self, table): TableInfo.__init__(self, table) def spatialInfo(self): ret = [] if self.table.geomType is None: return ret tbl = [ ( QApplication.translate("DBManagerPlugin", "Column:"), self.table.geomColumn, ), ( QApplication.translate("DBManagerPlugin", "Geometry:"), self.table.geomType, ), ] # only if we have info from geometry_columns if self.table.geomDim: tbl.append( ( QApplication.translate("DBManagerPlugin", "Dimension:"), self.table.geomDim, ) ) srid = self.table.srid if self.table.srid not in (None, 0) else -1 sr_info = ( self.table.database().connector.getSpatialRefInfo(srid) if srid != -1 else QApplication.translate("DBManagerPlugin", "Undefined") ) if sr_info: tbl.append( ( QApplication.translate("DBManagerPlugin", "Spatial ref:"), "%s (%d)" % (sr_info, srid), ) ) # estimated extent if not self.table.isView: if self.table.estimatedExtent is None: # estimated extent information is not displayed yet, so just block # table signals to avoid double refreshing (infoViewer->refreshEstimatedExtent->tableChanged->infoViewer) self.table.blockSignals(True) self.table.refreshTableEstimatedExtent() self.table.blockSignals(False) if ( self.table.estimatedExtent is not None and self.table.estimatedExtent[0] is not None ): if isinstance(self.table.estimatedExtent, list): estimated_extent_str = ", ".join( "%.5f" % e for e in self.table.estimatedExtent ) else: estimated_extent_str = ( "%.5f, %.5f - %.5f, %.5f" % self.table.estimatedExtent ) tbl.append( ( QApplication.translate("DBManagerPlugin", "Estimated extent:"), estimated_extent_str, ) ) # extent if self.table.extent is not None and self.table.extent[0] is not None: if isinstance(self.table.extent, list): extent_str = ", ".join("%.5f" % e for e in self.table.extent) else: extent_str = "%.5f, %.5f - %.5f, %.5f" % self.table.extent else: extent_str = QApplication.translate( "DBManagerPlugin", '(unknown) (find out)', ) tbl.append((QApplication.translate("DBManagerPlugin", "Extent:"), extent_str)) ret.append(HtmlTable(tbl)) # is there an entry in geometry_columns? if self.table.geomType.lower() == "geometry": ret.append( HtmlParagraph( QApplication.translate( "DBManagerPlugin", " There is no entry in geometry_columns!", ) ) ) # find out whether the geometry column has spatial index on it if not self.table.isView: if not self.table.hasSpatialIndex(): ret.append( HtmlParagraph( QApplication.translate( "DBManagerPlugin", ' No spatial index defined (create it)', ) ) ) return ret class RasterTableInfo(TableInfo): def __init__(self, table): TableInfo.__init__(self, table) def spatialInfo(self): ret = [] if self.table.geomType is None: return ret tbl = [ ( QApplication.translate("DBManagerPlugin", "Column:"), self.table.geomColumn, ), ( QApplication.translate("DBManagerPlugin", "Geometry:"), self.table.geomType, ), ] # only if we have info from geometry_columns srid = self.table.srid if self.table.srid is not None else -1 sr_info = ( self.table.database().connector.getSpatialRefInfo(srid) if srid != -1 else QApplication.translate("DBManagerPlugin", "Undefined") ) if sr_info: tbl.append( ( QApplication.translate("DBManagerPlugin", "Spatial ref:"), "%s (%d)" % (sr_info, srid), ) ) # extent if self.table.extent is not None and self.table.extent[0] is not None: extent_str = "%.5f, %.5f - %.5f, %.5f" % self.table.extent else: extent_str = QApplication.translate( "DBManagerPlugin", '(unknown) (find out)', ) tbl.append((QApplication.translate("DBManagerPlugin", "Extent:"), extent_str)) ret.append(HtmlTable(tbl)) return ret