123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- """
- /***************************************************************************
- Name : DB Manager plugin for virtual layers
- Date : December 2015
- copyright : (C) 2015 by Hugo Mercier
- email : hugo dot mercier at oslandia dot 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. *
- * *
- ***************************************************************************/
- """
- # this will disable the dbplugin if the connector raise an ImportError
- from .connector import VLayerConnector
- from qgis.PyQt.QtCore import QCoreApplication
- from qgis.PyQt.QtGui import QIcon
- from qgis.core import QgsApplication, QgsVectorLayer, QgsProject, QgsVirtualLayerDefinition
- from ..plugin import DBPlugin, Database, Table, VectorTable, TableField
- def classFactory():
- return VLayerDBPlugin
- class VLayerDBPlugin(DBPlugin):
- @classmethod
- def icon(self):
- return QgsApplication.getThemeIcon("/mIconVirtualLayer.svg")
- def connectionIcon(self):
- return QgsApplication.getThemeIcon("/providerQgis.svg")
- @classmethod
- def typeName(self):
- return 'vlayers'
- @classmethod
- def typeNameString(self):
- return QCoreApplication.translate('db_manager', 'Virtual Layers')
- @classmethod
- def providerName(self):
- return 'virtual'
- @classmethod
- def connectionSettingsKey(self):
- return 'vlayers'
- @classmethod
- def connections(self):
- return [VLayerDBPlugin(QCoreApplication.translate('db_manager', 'Project layers'))]
- def databasesFactory(self, connection, uri):
- return FakeDatabase(connection, uri)
- def database(self):
- return self.db
- # def info( self ):
- def connect(self, parent=None):
- self.connectToUri("qgis")
- return True
- class FakeDatabase(Database):
- def __init__(self, connection, uri):
- Database.__init__(self, connection, uri)
- def connectorsFactory(self, uri):
- return VLayerConnector(uri)
- def dataTablesFactory(self, row, db, schema=None):
- return LTable(row, db, schema)
- def vectorTablesFactory(self, row, db, schema=None):
- return LVectorTable(row, db, schema)
- def rasterTablesFactory(self, row, db, schema=None):
- return None
- def info(self):
- from .info_model import LDatabaseInfo
- return LDatabaseInfo(self)
- def sqlResultModel(self, sql, parent):
- from .data_model import LSqlResultModel
- return LSqlResultModel(self, sql, parent)
- def sqlResultModelAsync(self, sql, parent):
- from .data_model import LSqlResultModelAsync
- return LSqlResultModelAsync(self, sql, parent)
- def toSqlLayer(self, sql, geomCol, uniqueCol, layerName="QueryLayer", layerType=None, avoidSelectById=False, _filter=""):
- df = QgsVirtualLayerDefinition()
- df.setQuery(sql)
- if uniqueCol is not None:
- uniqueCol = uniqueCol.strip('"').replace('""', '"')
- df.setUid(uniqueCol)
- if geomCol is not None:
- df.setGeometryField(geomCol)
- vl = QgsVectorLayer(df.toString(), layerName, "virtual")
- if _filter:
- vl.setSubsetString(_filter)
- return vl
- def registerDatabaseActions(self, mainWindow):
- return
- def runAction(self, action):
- return
- def uniqueIdFunction(self):
- return None
- def explicitSpatialIndex(self):
- return True
- def spatialIndexClause(self, src_table, src_column, dest_table, dest_column):
- return '"%s"._search_frame_ = "%s"."%s"' % (src_table, dest_table, dest_column)
- def supportsComment(self):
- return False
- class LTable(Table):
- def __init__(self, row, db, schema=None):
- Table.__init__(self, db, None)
- self.name, self.isView, self.isSysTable = row
- def tableFieldsFactory(self, row, table):
- return LTableField(row, table)
- def tableDataModel(self, parent):
- from .data_model import LTableDataModel
- return LTableDataModel(self, parent)
- def canBeAddedToCanvas(self):
- return False
- class LVectorTable(LTable, VectorTable):
- def __init__(self, row, db, schema=None):
- LTable.__init__(self, row[:-5], db, schema)
- VectorTable.__init__(self, db, schema)
- # SpatiaLite does case-insensitive checks for table names, but the
- # SL provider didn't do the same in QGIS < 1.9, so self.geomTableName
- # stores the table name like stored in the geometry_columns table
- self.geomTableName, self.geomColumn, self.geomType, self.geomDim, self.srid = row[
- -5:]
- def uri(self):
- uri = self.database().uri()
- uri.setDataSource('', self.geomTableName, self.geomColumn)
- return uri
- def hasSpatialIndex(self, geom_column=None):
- return True
- def createSpatialIndex(self, geom_column=None):
- return
- def deleteSpatialIndex(self, geom_column=None):
- return
- def refreshTableEstimatedExtent(self):
- self.extent = self.database().connector.getTableExtent(
- ("id", self.geomTableName), None)
- def runAction(self, action):
- return
- def toMapLayer(self, geometryType=None, crs=None):
- return QgsProject.instance().mapLayer(self.geomTableName)
- class LTableField(TableField):
- def __init__(self, row, table):
- TableField.__init__(self, table)
- self.num, self.name, self.dataType, self.notNull, self.default, self.primaryKey = row
- self.hasDefault = self.default
|