Skip to content
Permalink
Browse files
[OGR provider] Make changeGeometryValues() return false when an error…
… occurs
  • Loading branch information
rouault authored and nyalldawson committed May 23, 2021
1 parent 554cef4 commit 56257d3f2e5005a418f3eb8b06645121c796c5a1
Showing with 29 additions and 1 deletion.
  1. +4 −1 src/core/providers/ogr/qgsogrprovider.cpp
  2. +25 −0 tests/src/python/test_provider_ogr_gpkg.py
@@ -2565,6 +2565,7 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
if ( !theOGRFeature )
{
pushError( tr( "OGR error changing geometry: feature %1 not found" ).arg( it.key() ) );
returnvalue = false;
continue;
}

@@ -2587,13 +2588,14 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
{
pushError( tr( "OGR error creating geometry for feature %1: %2" ).arg( it.key() ).arg( CPLGetLastErrorMsg() ) );
OGR_G_DestroyGeometry( newGeometry );
newGeometry = nullptr;
returnvalue = false;
continue;
}

if ( !newGeometry )
{
pushError( tr( "OGR error in feature %1: geometry is null" ).arg( it.key() ) );
returnvalue = false;
continue;
}

@@ -2607,6 +2609,7 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
// Shouldn't happen normally. If it happens, ownership of the geometry
// may be not really well defined, so better not destroy it, but just
// the feature.
returnvalue = false;
continue;
}

@@ -1973,6 +1973,31 @@ def testRollback(self):
self.assertEqual(features[0].attributes(), [1, -1, 123])
self.assertEqual(features[1].attributes(), [2, -4, 125])

def testRejectedGeometryUpdate(self):
"""Test that we correctly behave when a geometry update fails"""
tmpfile = os.path.join(self.basetestpath, 'testRejectedGeometryUpdate.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbUnknown)
f = ogr.Feature(lyr.GetLayerDefn())
f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON ((0 0,0 1,1 1,1 0,0 0))'))
lyr.CreateFeature(f)
ds.ExecuteSQL("CREATE TRIGGER rejectGeometryUpdate BEFORE UPDATE OF geom ON test FOR EACH ROW BEGIN SELECT RAISE(ABORT, 'update forbidden'); END;")
f = None
ds = None

vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
self.assertTrue(vl.isValid())

self.assertTrue(vl.startEditing())
self.assertTrue(vl.changeGeometry(1, QgsGeometry.fromWkt('Point (0 0)')))
self.assertFalse(vl.commitChanges())

vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
self.assertTrue(vl.isValid())

g = [f.geometry() for f in vl.getFeatures()][0]
self.assertEqual(g.asWkt(), 'Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))')


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

0 comments on commit 56257d3

Please sign in to comment.