# -*- coding: utf-8 -*- """ /*************************************************************************** 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 ..info_model import TableInfo, VectorTableInfo, RasterTableInfo, DatabaseInfo from ..html_elems import HtmlSection, HtmlParagraph, HtmlTable, HtmlTableHeader, HtmlTableCol class PGDatabaseInfo(DatabaseInfo): def connectionDetails(self): tbl = [ (QApplication.translate("DBManagerPlugin", "Host:"), self.db.connector.host), (QApplication.translate("DBManagerPlugin", "User:"), self.db.connector.user), (QApplication.translate("DBManagerPlugin", "Database:"), self.db.connector.dbname) ] return HtmlTable(tbl) class PGTableInfo(TableInfo): def __init__(self, table): self.table = table def generalInfo(self): ret = [] # if the estimation is less than 100 rows, try to count them - it shouldn't take long time if self.table.rowCount is None and self.table.estimatedRowCount < 100: # 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._relationType == 'v' else QApplication.translate("DBManagerPlugin", "Materialized view") if self.table._relationType == 'm' else QApplication.translate("DBManagerPlugin", "Table")), (QApplication.translate("DBManagerPlugin", "Owner:"), self.table.owner) ] if self.table.comment: tbl.append((QApplication.translate("DBManagerPlugin", "Comment:"), self.table.comment)) tbl.extend([ (QApplication.translate("DBManagerPlugin", "Pages:"), self.table.pages), (QApplication.translate("DBManagerPlugin", "Rows (estimation):"), self.table.estimatedRowCount) ]) # privileges # has the user access to this schema? schema_priv = self.table.database().connector.getSchemaPrivileges( self.table.schemaName()) if self.table.schema() else None if schema_priv is None: pass elif not schema_priv[1]: # no usage privileges on the schema tbl.append((QApplication.translate("DBManagerPlugin", "Privileges:"), QApplication.translate("DBManagerPlugin", " This user doesn't have usage privileges for this schema!"))) else: table_priv = self.table.database().connector.getTablePrivileges((self.table.schemaName(), self.table.name)) privileges = [] if table_priv[0]: privileges.append("select") if self.table.rowCount is not None or self.table.rowCount >= 0: tbl.append((QApplication.translate("DBManagerPlugin", "Rows (counted):"), self.table.rowCount if self.table.rowCount is not None else QApplication.translate( "DBManagerPlugin", 'Unknown (find out)'))) if table_priv[1]: privileges.append("insert") if table_priv[2]: privileges.append("update") if table_priv[3]: privileges.append("delete") priv_string = u", ".join(privileges) if len(privileges) > 0 else QApplication.translate("DBManagerPlugin", ' This user has no privileges!') tbl.append((QApplication.translate("DBManagerPlugin", "Privileges:"), priv_string)) ret.append(HtmlTable(tbl)) if schema_priv is not None and schema_priv[1]: if table_priv[0] and not table_priv[1] and not table_priv[2] and not table_priv[3]: ret.append(HtmlParagraph( QApplication.translate("DBManagerPlugin", " This user has read-only privileges."))) if not self.table.isView: if self.table.rowCount is not None: if abs(self.table.estimatedRowCount - self.table.rowCount) > 1 and \ (self.table.estimatedRowCount > 2 * self.table.rowCount or self.table.rowCount > 2 * self.table.estimatedRowCount): ret.append(HtmlParagraph(QApplication.translate("DBManagerPlugin", " There's a significant difference between estimated and real row count. " 'Consider running VACUUM ANALYZE.'))) # primary key defined? if not self.table.isView: if len([fld for fld in self.table.fields() if fld.primaryKey]) <= 0: ret.append(HtmlParagraph( QApplication.translate("DBManagerPlugin", " No primary key defined for this table!"))) return ret def getSpatialInfo(self): ret = [] info = self.db.connector.getSpatialInfo() if info is None: return tbl = [ (QApplication.translate("DBManagerPlugin", "Library:"), info[0]), (QApplication.translate("DBManagerPlugin", "Scripts:"), info[3]), ("GEOS:", info[1]), ("Proj:", info[2]) ] ret.append(HtmlTable(tbl)) if info[1] is not None and info[1] != info[2]: ret.append(HtmlParagraph(QApplication.translate("DBManagerPlugin", " Version of installed scripts doesn't match version of released scripts!\n" "This is probably a result of incorrect PostGIS upgrade."))) 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."))) elif not self.db.connector.has_geometry_columns_access: ret.append(HtmlParagraph(QApplication.translate("DBManagerPlugin", " This user doesn't have privileges to read contents of geometry_columns table!\n" "This table is essential for many GIS applications for enumeration of tables."))) return ret def fieldsDetails(self): tbl = [] # define the table header header = ( "#", QApplication.translate("DBManagerPlugin", "Name"), QApplication.translate("DBManagerPlugin", "Type"), QApplication.translate("DBManagerPlugin", "Length"), QApplication.translate("DBManagerPlugin", "Null"), QApplication.translate("DBManagerPlugin", "Default")) tbl.append(HtmlTableHeader(header)) # add table contents for fld in self.table.fields(): char_max_len = fld.charMaxLen if fld.charMaxLen is not None and fld.charMaxLen != -1 else "" 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(), char_max_len, is_null_txt, fld.default2String())) return HtmlTable(tbl, {"class": "header"}) def triggersDetails(self): if self.table.triggers() is None or len(self.table.triggers()) <= 0: return None ret = [] tbl = [] # define the table header header = ( QApplication.translate("DBManagerPlugin", "Name"), QApplication.translate("DBManagerPlugin", "Function"), QApplication.translate("DBManagerPlugin", "Type"), QApplication.translate("DBManagerPlugin", "Enabled")) tbl.append(HtmlTableHeader(header)) # add table contents for trig in self.table.triggers(): name = u'%(name)s (%(action)s)' % {"name": trig.name, "action": "delete"} (enabled, action) = (QApplication.translate("DBManagerPlugin", "Yes"), "disable") if trig.enabled else ( QApplication.translate("DBManagerPlugin", "No"), "enable") txt_enabled = u'%(enabled)s (%(action)s)' % { "name": trig.name, "action": action, "enabled": enabled} tbl.append((name, trig.function, trig.type2String(), txt_enabled)) ret.append(HtmlTable(tbl, {"class": "header"})) ret.append(HtmlParagraph(QApplication.translate("DBManagerPlugin", 'Enable all triggers / Disable all triggers'))) return ret def rulesDetails(self): if self.table.rules() is None or len(self.table.rules()) <= 0: return None tbl = [] # define the table header header = ( QApplication.translate("DBManagerPlugin", "Name"), QApplication.translate("DBManagerPlugin", "Definition")) tbl.append(HtmlTableHeader(header)) # add table contents for rule in self.table.rules(): name = u'%(name)s (%(action)s)' % {"name": rule.name, "action": "delete"} tbl.append((name, rule.definition)) return HtmlTable(tbl, {"class": "header"}) def getTableInfo(self): ret = TableInfo.getTableInfo(self) # rules rules_details = self.rulesDetails() if rules_details is None: pass else: ret.append(HtmlSection(QApplication.translate("DBManagerPlugin", 'Rules'), rules_details)) return ret class PGVectorTableInfo(PGTableInfo, VectorTableInfo): def __init__(self, table): VectorTableInfo.__init__(self, table) PGTableInfo.__init__(self, table) def spatialInfo(self): return VectorTableInfo.spatialInfo(self) class PGRasterTableInfo(PGTableInfo, RasterTableInfo): def __init__(self, table): RasterTableInfo.__init__(self, table) PGTableInfo.__init__(self, table) def spatialInfo(self): return RasterTableInfo.spatialInfo(self)