Fix bug comment on postgres and others management

This commit is contained in:
Ailurupoda 2019-02-06 10:53:56 +01:00
parent 7f0ab8b9ff
commit dff185355d
15 changed files with 102 additions and 108 deletions

View File

@ -233,3 +233,8 @@ class DBConnector(object):
def getQueryBuilderDictionary(self):
return {}
def setField(self, fld, tablename=None, db=None):
if fld is None:
return
return fld.name, fld.dataType, str(fld.modifier), fld.notNull, fld.default, None

View File

@ -644,7 +644,7 @@ class GPKGDBConnector(DBConnector):
return lyr.DeleteField(idx) == 0
return False
def updateTableColumn(self, table, column, new_name, new_data_type=None, new_not_null=None, new_default=None, new_comment=None):
def updateTableColumn(self, table, column, new_name, new_data_type=None, new_not_null=None, new_default=None, comment=None):
if self.isGeometryColumn(table, column):
return False

View File

@ -177,6 +177,9 @@ class GPKGDatabase(Database):
vl.setSubsetString(sql)
return vl
def searchClass(self):
return "GPKGDatabase"
class GPKGTable(Table):
@ -301,10 +304,6 @@ class GPKGTableField(TableField):
self.num, self.name, self.dataType, self.notNull, self.default, self.primaryKey = row
self.hasDefault = self.default
def getComment(self):
"""Returns the comment for a field"""
return ''
class GPKGTableIndex(TableIndex):

View File

@ -475,16 +475,16 @@ class OracleDBConnector(DBConnector):
def singleGeomTypes(self, geomtypes, srids):
"""Intelligent wkbtype grouping (multi with non multi)"""
if (QgsWkbTypes.Polygon in geomtypes
and QgsWkbTypes.MultiPolygon in geomtypes):
if (QgsWkbTypes.Polygon in geomtypes and
QgsWkbTypes.MultiPolygon in geomtypes):
srids.pop(geomtypes.index(QgsWkbTypes.Polygon))
geomtypes.pop(geomtypes.index(QgsWkbTypes.Polygon))
if (QgsWkbTypes.Point in geomtypes
and QgsWkbTypes.MultiPoint in geomtypes):
if (QgsWkbTypes.Point in geomtypes and
QgsWkbTypes.MultiPoint in geomtypes):
srids.pop(geomtypes.index(QgsWkbTypes.Point))
geomtypes.pop(geomtypes.index(QgsWkbTypes.Point))
if (QgsWkbTypes.LineString in geomtypes
and QgsWkbTypes.MultiLineString in geomtypes):
if (QgsWkbTypes.LineString in geomtypes and
QgsWkbTypes.MultiLineString in geomtypes):
srids.pop(geomtypes.index(QgsWkbTypes.LineString))
geomtypes.pop(geomtypes.index(QgsWkbTypes.LineString))
if QgsWkbTypes.Unknown in geomtypes and len(geomtypes) > 1:

View File

@ -91,8 +91,7 @@ class OracleDBPlugin(DBPlugin):
uri = QgsDataSourceUri()
settingsList = ["host", "port", "database", "username", "password"]
host, port, database, username, password = [
settings.value(x, "", type=str) for x in settingsList]
host, port, database, username, password = [settings.value(x, "", type=str) for x in settingsList]
# get all of the connexion options
@ -203,8 +202,7 @@ class ORDatabase(Database):
uri = self.uri()
con = self.database().connector
uri.setDataSource(u"", u"({}\n)".format(
sql), geomCol, filter, uniqueCol.strip(u'"'))
uri.setDataSource(u"", u"({}\n)".format(sql), geomCol, filter, uniqueCol.strip(u'"'))
if avoidSelectById:
uri.disableSelectAtId(True)
provider = self.dbplugin().providerName()
@ -263,6 +261,9 @@ class ORDatabase(Database):
mainWindow.registerAction(action, QApplication.translate(
"DBManagerPlugin", "&Table"), self.emptyTableActionSlot)
def searchClass(self):
return "ORDatabase"
class ORSchema(Schema):
@ -524,7 +525,7 @@ class ORTableField(TableField):
def type2String(self):
if (u"TIMESTAMP" in self.dataType or
self.dataType in [u"DATE", u"SDO_GEOMETRY",
u"BINARY_FLOAT", u"BINARY_DOUBLE"]):
u"BINARY_FLOAT", u"BINARY_DOUBLE"]):
return u"{}".format(self.dataType)
if self.charMaxLen in [None, -1]:
return u"{}".format(self.dataType)
@ -559,10 +560,6 @@ class ORTableField(TableField):
self.table().refreshIndexes()
return ret
def getComment(self):
"""Returns the comment for a field"""
return ''
class ORTableConstraint(TableConstraint):

View File

@ -1096,22 +1096,7 @@ class TableField(TableSubItemObject):
return txt
def getComment(self):
"""Returns the comment for a field"""
tab = self.table()
# SQL Query checking if a comment exists for the field
sql_cpt = "Select count(*) from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (tab.name, self.name)
# SQL Query that return the comment of the field
sql = "Select pd.description from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (tab.name, self.name)
c = tab.database().connector._execute(None, sql_cpt) # Execute Check query
res = tab.database().connector._fetchone(c)[0] # Store result
if res == 1:
# When a comment exists
c = tab.database().connector._execute(None, sql) # Execute query
res = tab.database().connector._fetchone(c)[0] # Store result
tab.database().connector._close_cursor(c) # Close cursor
return res # Return comment
else:
return ''
return ''
def delete(self):
return self.table().deleteField(self)

View File

@ -511,6 +511,25 @@ class PostGisDBConnector(DBConnector):
self._close_cursor(c)
return res
def setField(self, fld, tablename, db):
if fld is None:
return
print (tablename)
# Check with SQL query if a comment exists for the field
sql_cpt = "Select count(*) from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (tablename, fld.name)
# Get the comment for the field with SQL Query
sql = "Select pd.description from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (tablename, fld.name)
c = db.connector._execute(None, sql_cpt) # Execute check query
res = db.connector._fetchone(c)[0] # Fetch data
# Check if result is 1 then it's ok, else we don't want to get a value
if res == 1:
c = db.connector._execute(None, sql) # Execute query returning the comment value
res2 = db.connector._fetchone(c)[0] # Fetch the comment value
db.connector._close_cursor(c) # Close cursor
else :
res2 = None
return fld.name, fld.dataType, str(fld.modifier), fld.notNull, fld.default, res2
def getTableIndexes(self, table):
""" get info about table's indexes. ignore primary key constraint index, they get listed in constraints """
schema, tablename = self.getSchemaTableName(table)
@ -857,7 +876,7 @@ class PostGisDBConnector(DBConnector):
sql = u"ALTER TABLE %s DROP %s" % (self.quoteId(table), self.quoteId(column))
self._execute_and_commit(sql)
def updateTableColumn(self, table, column, new_name=None, data_type=None, not_null=None, default=None, comment=None):
def updateTableColumn(self, table, column, new_name=None, data_type=None, not_null=None, default=None, comment=None, test=None):
if new_name is None and data_type is None and not_null is None and default is None and comment is None:
return

View File

@ -181,6 +181,9 @@ class PGDatabase(Database):
def hasLowercaseFieldNamesOption(self):
return True
def searchClass(self):
return "PGDatabase"
class PGSchema(Schema):
@ -396,6 +399,24 @@ class PGTableField(TableField):
if con.type == TableConstraint.TypePrimaryKey and self.num in con.columns:
self.primaryKey = True
break
def getComment(self):
"""Returns the comment for a field"""
tab = self.table()
# SQL Query checking if a comment exists for the field
sql_cpt = "Select count(*) from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (tab.name, self.name)
# SQL Query that return the comment of the field
sql = "Select pd.description from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (tab.name, self.name)
c = tab.database().connector._execute(None, sql_cpt) # Execute Check query
res = tab.database().connector._fetchone(c)[0] # Store result
if res == 1:
# When a comment exists
c = tab.database().connector._execute(None, sql) # Execute query
res = tab.database().connector._fetchone(c)[0] # Store result
tab.database().connector._close_cursor(c) # Close cursor
return res # Return comment
else:
return ''
class PGTableConstraint(TableConstraint):

View File

@ -465,8 +465,6 @@ class SpatiaLiteDBConnector(DBConnector):
self._execute(c, sql)
self._commit()
return True
def emptyTable(self, table):
""" delete all rows from table """
if self.isRasterTable(table):
@ -496,7 +494,6 @@ class SpatiaLiteDBConnector(DBConnector):
self._execute(c, sql)
self._commit()
return True
def moveTable(self, table, new_table, new_schema=None):
return self.renameTable(table, new_table)
@ -574,16 +571,7 @@ class SpatiaLiteDBConnector(DBConnector):
def addTableColumn(self, table, field_def):
""" add a column to table """
sql = u"ALTER TABLE %s ADD %s" % (self.quoteId(table), field_def)
self._execute(None, sql)
sql = u"SELECT InvalidateLayerStatistics(%s)" % (self.quoteId(table))
self._execute(None, sql)
sql = u"SELECT UpdateLayerStatistics(%s)" % (self.quoteId(table))
self._execute(None, sql)
self._commit()
return True
self._execute_and_commit(sql)
def deleteTableColumn(self, table, column):
""" delete column from a table """
@ -595,7 +583,7 @@ class SpatiaLiteDBConnector(DBConnector):
sql = u"SELECT DiscardGeometryColumn(%s, %s)" % (self.quoteString(tablename), self.quoteString(column))
self._execute_and_commit(sql)
def updateTableColumn(self, table, column, new_name, new_data_type=None, new_not_null=None, new_default=None, new_comment=None):
def updateTableColumn(self, table, column, new_name, new_data_type=None, new_not_null=None, new_default=None, comment=None):
return False # column editing not supported
def renameTableColumn(self, table, column, new_name):

View File

@ -175,6 +175,9 @@ class SLDatabase(Database):
def spatialIndexClause(self, src_table, src_column, dest_table, dest_column):
return u""" "%s".ROWID IN (\nSELECT ROWID FROM SpatialIndex WHERE f_table_name='%s' AND search_frame="%s"."%s") """ % (src_table, src_table, dest_table, dest_column)
def searchClass(self):
return "SLDatabase"
class SLTable(Table):
@ -294,10 +297,6 @@ class SLTableField(TableField):
self.num, self.name, self.dataType, self.notNull, self.default, self.primaryKey = row
self.hasDefault = self.default
def getComment(self):
"""Returns the comment for a field"""
return ''
class SLTableIndex(TableIndex):

View File

@ -349,7 +349,7 @@ class VLayerConnector(DBConnector):
def deleteTableColumn(self, table, column):
print("**unimplemented** deleteTableColumn")
def updateTableColumn(self, table, column, new_name, new_data_type=None, new_not_null=None, new_default=None, new_comment=None):
def updateTableColumn(self, table, column, new_name, new_data_type=None, new_not_null=None, new_default=None, comment=None):
print("**unimplemented** updateTableColumn")
def renameTableColumn(self, table, column, new_name):

View File

@ -132,6 +132,9 @@ class FakeDatabase(Database):
def spatialIndexClause(self, src_table, src_column, dest_table, dest_column):
return '"%s"._search_frame_ = "%s"."%s"' % (src_table, dest_table, dest_column)
def searchClass(self):
return "FakeDatabase"
class LTable(Table):
@ -192,7 +195,3 @@ class LTableField(TableField):
TableField.__init__(self, table)
self.num, self.name, self.dataType, self.notNull, self.default, self.primaryKey = row
self.hasDefault = self.default
def getComment(self):
"""Returns the comment for a field"""
return ''

View File

@ -27,7 +27,6 @@ __revision__ = '$Format:%H$'
from qgis.PyQt.QtWidgets import QDialog, QMessageBox
from .db_plugins.plugin import TableField
from .ui.ui_DlgFieldProperties import Ui_DbManagerDlgFieldProperties as Ui_Dialog
@ -42,38 +41,23 @@ class DlgFieldProperties(QDialog, Ui_Dialog):
for item in self.db.connector.fieldTypes():
self.cboType.addItem(item)
self.setField(self.fld)
objClass = self.db.searchClass()
if objClass != "PGDatabase":
self.label_6.setVisible(False)
self.editCom.setVisible(False)
name, dataType, modifier, chkNull, hasDefault, chkCom = self.db.connector.setField(self.fld, self.table.name, self.db)
self.editName.setText(name)
self.cboType.setEditText(dataType)
self.editLength.setText(modifier)
self.chkNull.setChecked(not chkNull)
self.editDefault.setText(hasDefault)
self.editCom.setText(chkCom)
self.buttonBox.accepted.connect(self.onOK)
def setField(self, fld):
if fld is None:
return
self.editName.setText(fld.name)
self.cboType.setEditText(fld.dataType)
if fld.modifier:
self.editLength.setText(str(fld.modifier))
self.chkNull.setChecked(not fld.notNull)
if fld.hasDefault:
self.editDefault.setText(fld.default)
# This is an ugly patch, but the comments PR https://github.com/qgis/QGIS/pull/8831 added
# support for postgres only and broke all the others :(
try:
# Check with SQL query if a comment exists for the field
sql_cpt = "Select count(*) from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (self.table.name, self.editName.text())
# Get the comment for the field with SQL Query
sql = "Select pd.description from pg_description pd, pg_class pc, pg_attribute pa where relname = '%s' and attname = '%s' and pa.attrelid = pc.oid and pd.objoid = pc.oid and pd.objsubid = pa.attnum" % (self.table.name, self.editName.text())
c = self.db.connector._execute(None, sql_cpt) # Execute check query
res = self.db.connector._fetchone(c)[0] # Fetch data
# Check if result is 1 then it's ok, else we don't want to get a value
if res == 1:
c = self.db.connector._execute(None, sql) # Execute query returning the comment value
res = self.db.connector._fetchone(c)[0] # Fetch the comment value
self.db.connector._close_cursor(c) # Close cursor
self.editCom.setText(res) # Set comment value
except:
self.editCom.setEnabled(False)
def getField(self, newCopy=False):
fld = TableField(self.table) if not self.fld or newCopy else self.fld
fld.name = self.editName.text()

View File

@ -25,7 +25,8 @@ from builtins import str
from builtins import range
from qgis.PyQt.QtCore import Qt, QFileInfo
from qgis.PyQt.QtWidgets import QDialog, QFileDialog, QMessageBox
from qgis.PyQt.QtWidgets import QDialog, QFileDialog, QMessageBox, QApplication
from qgis.PyQt.QtGui import QCursor
from qgis.core import (QgsDataSourceUri,
QgsVectorLayer,
@ -51,6 +52,11 @@ class DlgImportVector(QDialog, Ui_Dialog):
self.outUri = outUri
self.setupUi(self)
objClass = self.db.searchClass()
if objClass != "PGDatabase":
self.chkCom.setVisible(False)
self.editCom.setVisible(False)
self.default_pk = "id"
self.default_geom = "geom"
@ -368,9 +374,9 @@ class DlgImportVector(QDialog, Ui_Dialog):
self.db.connector.createSpatialIndex((schema, table), geom)
# add comment on table
if self.chkCom.isEnabled() and self.chkCom.isChecked():
if self.chkCom.isEnabled() and self.chkCom.isChecked() and objClass == "PGDatabase":
# using connector executing COMMENT ON TABLE query (with editCome.text() value)
self.db.connector._execute(None, 'COMMENT ON TABLE "{0}"."{1}" IS E\'{2}E\''.format(schema, table, self.editCom.text()))
self.db.connector._execute(None, 'COMMENT ON TABLE "{0}"."{1}" IS E\'{2}\''.format(schema, table, self.editCom.text()))
self.db.connection().reconnect()
self.db.refresh()

View File

@ -29,7 +29,7 @@ from qgis.PyQt.QtWidgets import QDialog, QMessageBox, QApplication
from qgis.utils import OverrideCursor
from .db_plugins.data_model import TableFieldsModel, TableConstraintsModel, TableIndexesModel
from .db_plugins.plugin import BaseError, DbError
from .db_plugins.plugin import BaseError
from .dlg_db_error import DlgDbError
from .dlg_field_properties import DlgFieldProperties
@ -50,6 +50,10 @@ class DlgTableProperties(QDialog, Ui_Dialog):
self.db = self.table.database()
objClass = self.db.searchClass()
if objClass != "PGDatabase":
self.tabs.removeTab(3)
m = TableFieldsModel(self)
self.viewFields.setModel(m)
@ -333,37 +337,25 @@ class DlgTableProperties(QDialog, Ui_Dialog):
DlgDbError.showError(e, self)
def createComment(self):
"""Adds a comment to the selected table"""
#Function that add a comment to the selected table
try:
#Using the db connector, executing de SQL query Comment on table
self.db.connector._execute(None, 'COMMENT ON TABLE "{0}"."{1}" IS E\'{2}\';'.format(self.table.schema().name, self.table.name, self.viewComment.text()))
except DbError as e:
DlgDbError.showError(e, self)
return
except Exception as e:
# This is an ugly patch, but the comments PR https://github.com/qgis/QGIS/pull/8831 added
# support for postgres only and broke all the others :(
QMessageBox.information(self, self.tr("Add comment"), self.tr("Comments are not supported for this database."))
return
self.refresh()
#Display successful message
QMessageBox.information(self, self.tr("Add comment"), self.tr("Table successfully commented"))
def deleteComment(self):
"""Drops the comment on the selected table"""
#Function that drop the comment to the selected table
try:
#Using the db connector, executing de SQL query Comment on table using the NULL definition
self.db.connector._execute(None, 'COMMENT ON TABLE "{0}"."{1}" IS NULL;'.format(self.table.schema().name, self.table.name))
except DbError as e:
DlgDbError.showError(e, self)
return
except Exception as e:
# This is an ugly patch, but the comments PR https://github.com/qgis/QGIS/pull/8831 added
# support for postgres only and broke all the others :(
QMessageBox.information(self, self.tr("Add comment"), self.tr("Comments are not supported for this database."))
return
self.refresh()
#Refresh line edit, put a void comment
self.viewComment.setText('')