123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- """
- /***************************************************************************
- 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", "<warning> 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", '<warning> {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", '<warning> 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",
- '<warning> 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 (<a href="action:rows/count">find out</a>)'))
- ]
- 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)s (<a href="action:trigger/%(name)s/%(action)s">%(action)s</a>)' % {"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", '<warning> 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) (<a href="action:extent/get">find out</a>)')
- 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", "<warning> 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",
- '<warning> No spatial index defined (<a href="action:spatialindex/create">create it</a>)')))
- 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) (<a href="action:extent/get">find out</a>)')
- tbl.append((QApplication.translate("DBManagerPlugin", "Extent:"), extent_str))
- ret.append(HtmlTable(tbl))
- return ret
|