Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fixes #20893 : Update virtual layer when referenced layer update its …
…fields
  • Loading branch information
troopa81 authored and nyalldawson committed Jan 23, 2019
1 parent 551d7e8 commit 8ce8ee0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/providers/virtual/qgsvirtuallayerprovider.cpp
Expand Up @@ -132,6 +132,7 @@ bool QgsVirtualLayerProvider::loadSourceLayers()
connect( vl, &QgsVectorLayer::featureAdded, this, &QgsVirtualLayerProvider::invalidateStatistics );
connect( vl, &QgsVectorLayer::featureDeleted, this, &QgsVirtualLayerProvider::invalidateStatistics );
connect( vl, &QgsVectorLayer::geometryChanged, this, &QgsVirtualLayerProvider::invalidateStatistics );
connect( vl, &QgsVectorLayer::updatedFields, this, [ = ] { createVirtualTable( vl, layer.name() ); } );
}
else
{
Expand Down Expand Up @@ -302,8 +303,7 @@ bool QgsVirtualLayerProvider::createIt()
QString vname = mLayers.at( i ).name;
if ( vlayer )
{
QString createStr = QStringLiteral( "DROP TABLE IF EXISTS \"%1\"; CREATE VIRTUAL TABLE \"%1\" USING QgsVLayer(%2);" ).arg( vname, vlayer->id() );
Sqlite::Query::exec( mSqlite.get(), createStr );
createVirtualTable( vlayer, vname );
}
else
{
Expand Down Expand Up @@ -455,6 +455,12 @@ bool QgsVirtualLayerProvider::createIt()
return true;
}

void QgsVirtualLayerProvider::createVirtualTable( QgsVectorLayer *vlayer, const QString &vname )
{
QString createStr = QStringLiteral( "DROP TABLE IF EXISTS \"%1\"; CREATE VIRTUAL TABLE \"%1\" USING QgsVLayer(%2);" ).arg( vname, vlayer->id() );
Sqlite::Query::exec( mSqlite.get(), createStr );
}

bool QgsVirtualLayerProvider::cancelReload()
{
return mSqlite.interrupt();
Expand Down
2 changes: 2 additions & 0 deletions src/providers/virtual/qgsvirtuallayerprovider.h
Expand Up @@ -111,11 +111,13 @@ class QgsVirtualLayerProvider: public QgsVectorDataProvider
bool openIt();
bool createIt();
bool loadSourceLayers();
void createVirtualTable( QgsVectorLayer *vlayer, const QString &name );

friend class QgsVirtualLayerFeatureSource;

private slots:
void invalidateStatistics();

};

// clazy:excludeall=qstring-allocations
Expand Down
34 changes: 34 additions & 0 deletions tests/src/python/test_provider_virtual.py
Expand Up @@ -977,6 +977,40 @@ def testFiltersWithoutUid(self):

QgsProject.instance().removeMapLayer(ml)

def testUpdatedFields(self):
"""Test when referenced layer update its fields
https://issues.qgis.org/issues/20893
"""

ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem", "memory")
self.assertEqual(ml.isValid(), True)
QgsProject.instance().addMapLayer(ml)

ml.startEditing()
f1 = QgsFeature(ml.fields())
f1.setGeometry(QgsGeometry.fromWkt('POINT(2 3)'))
ml.addFeatures([f1])
ml.commitChanges()

vl = QgsVectorLayer("?query=select a, geometry from mem", "vl", "virtual")
self.assertEqual(vl.isValid(), True)

# add one more field
ml.dataProvider().addAttributes([QgsField('newfield', QVariant.Int)])
ml.updateFields()

self.assertEqual(ml.featureCount(), vl.featureCount())
self.assertEqual(vl.fields().count(), 1)

geometry = next(vl.getFeatures()).geometry()
self.assertTrue(geometry)

point = geometry.asPoint()
self.assertEqual(point.x(), 2)
self.assertEqual(point.y(), 3)

QgsProject.instance().removeMapLayer(ml)


if __name__ == '__main__':
unittest.main()

0 comments on commit 8ce8ee0

Please sign in to comment.