Skip to content

Commit bdf77ac

Browse files
troopa81nyalldawson
authored andcommittedJan 23, 2019
fixes #20893 : Update virtual layer when referenced layer update its fields
1 parent eb47288 commit bdf77ac

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed
 

‎src/providers/virtual/qgsvirtuallayerprovider.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ bool QgsVirtualLayerProvider::loadSourceLayers()
132132
connect( vl, &QgsVectorLayer::featureAdded, this, &QgsVirtualLayerProvider::invalidateStatistics );
133133
connect( vl, &QgsVectorLayer::featureDeleted, this, &QgsVirtualLayerProvider::invalidateStatistics );
134134
connect( vl, &QgsVectorLayer::geometryChanged, this, &QgsVirtualLayerProvider::invalidateStatistics );
135+
connect( vl, &QgsVectorLayer::updatedFields, this, [ = ] { createVirtualTable( vl, layer.name() ); } );
135136
}
136137
else
137138
{
@@ -302,8 +303,7 @@ bool QgsVirtualLayerProvider::createIt()
302303
QString vname = mLayers.at( i ).name;
303304
if ( vlayer )
304305
{
305-
QString createStr = QStringLiteral( "DROP TABLE IF EXISTS \"%1\"; CREATE VIRTUAL TABLE \"%1\" USING QgsVLayer(%2);" ).arg( vname, vlayer->id() );
306-
Sqlite::Query::exec( mSqlite.get(), createStr );
306+
createVirtualTable( vlayer, vname );
307307
}
308308
else
309309
{
@@ -455,6 +455,12 @@ bool QgsVirtualLayerProvider::createIt()
455455
return true;
456456
}
457457

458+
void QgsVirtualLayerProvider::createVirtualTable( QgsVectorLayer *vlayer, const QString &vname )
459+
{
460+
QString createStr = QStringLiteral( "DROP TABLE IF EXISTS \"%1\"; CREATE VIRTUAL TABLE \"%1\" USING QgsVLayer(%2);" ).arg( vname, vlayer->id() );
461+
Sqlite::Query::exec( mSqlite.get(), createStr );
462+
}
463+
458464
bool QgsVirtualLayerProvider::cancelReload()
459465
{
460466
return mSqlite.interrupt();

‎src/providers/virtual/qgsvirtuallayerprovider.h

+2
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,13 @@ class QgsVirtualLayerProvider: public QgsVectorDataProvider
111111
bool openIt();
112112
bool createIt();
113113
bool loadSourceLayers();
114+
void createVirtualTable( QgsVectorLayer *vlayer, const QString &name );
114115

115116
friend class QgsVirtualLayerFeatureSource;
116117

117118
private slots:
118119
void invalidateStatistics();
120+
119121
};
120122

121123
// clazy:excludeall=qstring-allocations

‎tests/src/python/test_provider_virtual.py

+34
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,40 @@ def testFiltersWithoutUid(self):
977977

978978
QgsProject.instance().removeMapLayer(ml)
979979

980+
def testUpdatedFields(self):
981+
"""Test when referenced layer update its fields
982+
https://issues.qgis.org/issues/20893
983+
"""
984+
985+
ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem", "memory")
986+
self.assertEqual(ml.isValid(), True)
987+
QgsProject.instance().addMapLayer(ml)
988+
989+
ml.startEditing()
990+
f1 = QgsFeature(ml.fields())
991+
f1.setGeometry(QgsGeometry.fromWkt('POINT(2 3)'))
992+
ml.addFeatures([f1])
993+
ml.commitChanges()
994+
995+
vl = QgsVectorLayer("?query=select a, geometry from mem", "vl", "virtual")
996+
self.assertEqual(vl.isValid(), True)
997+
998+
# add one more field
999+
ml.dataProvider().addAttributes([QgsField('newfield', QVariant.Int)])
1000+
ml.updateFields()
1001+
1002+
self.assertEqual(ml.featureCount(), vl.featureCount())
1003+
self.assertEqual(vl.fields().count(), 1)
1004+
1005+
geometry = next(vl.getFeatures()).geometry()
1006+
self.assertTrue(geometry)
1007+
1008+
point = geometry.asPoint()
1009+
self.assertEqual(point.x(), 2)
1010+
self.assertEqual(point.y(), 3)
1011+
1012+
QgsProject.instance().removeMapLayer(ml)
1013+
9801014

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

0 commit comments

Comments
 (0)
Please sign in to comment.