[DBManager] Add a 'create view' button

This commit is contained in:
Hugo Mercier 2015-04-01 17:49:29 +02:00
parent 00276e2be1
commit e440dee1bd
5 changed files with 80 additions and 2 deletions

View File

@ -57,6 +57,8 @@ class DBConnector:
def hasTableColumnEditingSupport(self): def hasTableColumnEditingSupport(self):
return False return False
def hasCreateSpatialViewSupport( self ):
return False
def execution_error_types(self): def execution_error_types(self):
raise Exception("DBConnector.execution_error_types() is an abstract method") raise Exception("DBConnector.execution_error_types() is an abstract method")

View File

@ -176,6 +176,8 @@ class PostGisDBConnector(DBConnector):
def hasTableColumnEditingSupport(self): def hasTableColumnEditingSupport(self):
return True return True
def hasCreateSpatialViewSupport( self ):
return True
def fieldTypes(self): def fieldTypes(self):
return [ return [
@ -761,6 +763,9 @@ class PostGisDBConnector(DBConnector):
sql = u"CREATE VIEW %s AS %s" % (self.quoteId(view), query) sql = u"CREATE VIEW %s AS %s" % (self.quoteId(view), query)
self._execute_and_commit(sql) self._execute_and_commit(sql)
def createSpatialView(self, view, query):
self.createView(view, query)
def deleteView(self, view): def deleteView(self, view):
sql = u"DROP VIEW %s" % self.quoteId(view) sql = u"DROP VIEW %s" % self.quoteId(view)
self._execute_and_commit(sql) self._execute_and_commit(sql)

View File

@ -122,6 +122,8 @@ class SpatiaLiteDBConnector(DBConnector):
def hasTableColumnEditingSupport(self): def hasTableColumnEditingSupport(self):
return False return False
def hasCreateSpatialViewSupport(self):
return True
def fieldTypes(self): def fieldTypes(self):
return [ return [
@ -468,13 +470,61 @@ class SpatiaLiteDBConnector(DBConnector):
self._execute_and_commit(sql) self._execute_and_commit(sql)
def deleteView(self, view): def deleteView(self, view):
c = self._get_cursor()
sql = u"DROP VIEW %s" % self.quoteId(view) sql = u"DROP VIEW %s" % self.quoteId(view)
self._execute_and_commit(sql) self._execute(c, sql)
# update geometry_columns
if self.has_geometry_columns:
sql = u"DELETE FROM geometry_columns WHERE f_table_name = %s" % self.quoteString(view)
self._execute(c, sql)
self._commit()
def renameView(self, view, new_name): def renameView(self, view, new_name):
""" rename view """ """ rename view """
return self.renameTable(view, new_name) return self.renameTable(view, new_name)
def createSpatialView(self, view, query):
self.createView(view, query)
# get type info about the view
sql = u"PRAGMA table_info(%s)" % self.quoteString(view)
c = self._execute( None, sql )
geom_col = None
for r in c.fetchall():
if r[2].upper() in ('POINT', 'LINESTRING', 'POLYGON',
'MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON'):
geom_col = r[1]
break
if geom_col is None:
return
# get geometry type and srid
sql = u"SELECT geometrytype(%s), srid(%s) FROM %s LIMIT 1" % (self.quoteId(geom_col), self.quoteId(geom_col), self.quoteId(view))
c = self._execute( None, sql )
r = c.fetchone()
if r is None:
return
gtype, gsrid = r
gdim = 'XY'
if ' ' in gtype:
zm = gtype.split(' ')[1]
gtype = gtype.split(' ')[0]
gdim += zm
try:
wkbType = ('POINT', 'LINESTRING', 'POLYGON', 'MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON').index(gtype) + 1
except:
wkbType = 0
if 'Z' in gdim:
wkbType += 1000
if 'M' in gdim:
wkbType += 2000
sql = u"""INSERT INTO geometry_columns (f_table_name, f_geometry_column, geometry_type, coord_dimension, srid, spatial_index_enabled)
VALUES (%s, %s, %s, %s, %s, 0)""" % (self.quoteId(view), self.quoteId(geom_col), wkbType, len(gdim), gsrid)
self._execute_and_commit(sql)
def runVacuum(self): def runVacuum(self):
""" run vacuum on the db """ """ run vacuum on the db """

View File

@ -23,7 +23,7 @@ The content of this file is based on
""" """
from PyQt4.QtCore import Qt, QObject, QSettings, QByteArray, SIGNAL from PyQt4.QtCore import Qt, QObject, QSettings, QByteArray, SIGNAL
from PyQt4.QtGui import QDialog, QAction, QKeySequence, QDialogButtonBox, QApplication, QCursor, QMessageBox, QClipboard from PyQt4.QtGui import QDialog, QAction, QKeySequence, QDialogButtonBox, QApplication, QCursor, QMessageBox, QClipboard, QInputDialog
from PyQt4.Qsci import QsciAPIs from PyQt4.Qsci import QsciAPIs
from qgis.core import QgsProject from qgis.core import QgsProject
@ -89,6 +89,11 @@ class DlgSqlWindow(QDialog, Ui_Dialog):
self.connect(self.loadAsLayerGroup, SIGNAL("toggled(bool)"), self.loadAsLayerToggled) self.connect(self.loadAsLayerGroup, SIGNAL("toggled(bool)"), self.loadAsLayerToggled)
self.loadAsLayerToggled(False) self.loadAsLayerToggled(False)
self._createViewAvailable = self.db.connector.hasCreateSpatialViewSupport()
self.btnCreateView.setVisible( self._createViewAvailable )
if self._createViewAvailable:
self.connect( self.btnCreateView, SIGNAL("clicked()"), self.createView )
self.queryBuilderFirst = True self.queryBuilderFirst = True
self.connect( self.queryBuilderBtn, SIGNAL("clicked()"), self.displayQueryBuilder ) self.connect( self.queryBuilderBtn, SIGNAL("clicked()"), self.displayQueryBuilder )
@ -338,3 +343,12 @@ class DlgSqlWindow(QDialog, Ui_Dialog):
if r == QDialog.Accepted: if r == QDialog.Accepted:
self.editSql.setText( dlg.query ) self.editSql.setText( dlg.query )
def createView( self ):
name, ok = QInputDialog.getText(None, "View name", "View name")
if ok:
try:
self.db.connector.createSpatialView( name, self.editSql.text() )
except BaseError as e:
DlgDbError.showError(e, self)

View File

@ -102,6 +102,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="btnCreateView">
<property name="text">
<string>Create a view</string>
</property>
</widget>
</item>
<item> <item>
<spacer> <spacer>
<property name="orientation"> <property name="orientation">