diff --git a/src/providers/virtual/qgsvirtuallayerprovider.cpp b/src/providers/virtual/qgsvirtuallayerprovider.cpp index 2812bbd814ce..9d545862b687 100644 --- a/src/providers/virtual/qgsvirtuallayerprovider.cpp +++ b/src/providers/virtual/qgsvirtuallayerprovider.cpp @@ -600,6 +600,17 @@ QgsAttributeList QgsVirtualLayerProvider::pkAttributeIndexes() return QgsAttributeList(); } +QSet QgsVirtualLayerProvider::layerDependencies() const +{ + QSet deps; + foreach ( const QgsVirtualLayerDefinition::SourceLayer& l, mDefinition.sourceLayers() ) + { + if ( l.isReferenced() ) + deps << l.reference(); + } + return deps; +} + /** * Class factory to return a pointer to a newly created * QgsSpatiaLiteProvider object diff --git a/src/providers/virtual/qgsvirtuallayerprovider.h b/src/providers/virtual/qgsvirtuallayerprovider.h index d10f46e09029..bc8a87c33204 100644 --- a/src/providers/virtual/qgsvirtuallayerprovider.h +++ b/src/providers/virtual/qgsvirtuallayerprovider.h @@ -89,6 +89,9 @@ class QgsVirtualLayerProvider: public QgsVectorDataProvider /** Return list of indexes of fields that make up the primary key */ QgsAttributeList pkAttributeIndexes() override; + /** Get the list of layer ids on which this layer depends */ + QSet layerDependencies() const override; + private: // file on disk diff --git a/tests/src/python/test_provider_virtual.py b/tests/src/python/test_provider_virtual.py index 247fc90b55b0..b00b431bf251 100644 --- a/tests/src/python/test_provider_virtual.py +++ b/tests/src/python/test_provider_virtual.py @@ -30,6 +30,7 @@ QgsProviderRegistry, QgsVirtualLayerDefinition, QgsWKBTypes + QgsProject ) from utilities import (unitTestDataPath, @@ -664,5 +665,43 @@ def test_queryOnMemoryLayer(self): ml.addFeatures([f3]) self.assertEqual(ml.featureCount(), vl.featureCount()) + def test_ProjectDependencies(self): + # make a virtual layer with living references and save it to a project + l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False) + self.assertEqual(l1.isValid(), True) + QgsMapLayerRegistry.instance().addMapLayer(l1) + + query = QUrl.toPercentEncoding("SELECT * FROM france_parts") + l2 = QgsVectorLayer("?query=%s" % query, "aa", "virtual", False) + self.assertEqual(l2.isValid(), True) + QgsMapLayerRegistry.instance().addMapLayer(l2) + + self.assertEqual(len(l2.layerDependencies()), 1) + self.assertEqual(l2.layerDependencies()[0].startswith('france_parts'), True) + + query = QUrl.toPercentEncoding("SELECT t1.objectid, t2.name_0 FROM france_parts as t1, aa as t2") + l3 = QgsVectorLayer("?query=%s" % query, "bb", "virtual", False) + self.assertEqual(l3.isValid(), True) + QgsMapLayerRegistry.instance().addMapLayer(l3) + + self.assertEqual(len(l2.layerDependencies()), 1) + self.assertEqual(l2.layerDependencies()[0].startswith('france_parts'), True) + + self.assertEqual(len(l3.layerDependencies()), 2) + + temp = os.path.join(tempfile.gettempdir(), "qgstestproject.qgs") + + QgsProject.instance().setFileName(temp) + QgsProject.instance().write() + + QgsMapLayerRegistry.instance().removeMapLayers([l1, l2]) + QgsProject.instance().clear() + + QgsProject.instance().setFileName(temp) + QgsProject.instance().read() + + # make sure the 3 layers are loaded back + self.assertEqual(len(QgsMapLayerRegistry.instance().mapLayers()), 3) + if __name__ == '__main__': unittest.main()