[OGR] Defer repacking while in explicit updateMode

This commit is contained in:
Sandro Mani 2017-09-20 18:08:34 +02:00
parent 54ea029de8
commit 59ed19fff0
3 changed files with 40 additions and 5 deletions

View File

@ -428,6 +428,7 @@ QgsOgrProvider::QgsOgrProvider( QString const &uri )
, mDynamicWriteAccess( false ) , mDynamicWriteAccess( false )
, mShapefileMayBeCorrupted( false ) , mShapefileMayBeCorrupted( false )
, mUpdateModeStackDepth( 0 ) , mUpdateModeStackDepth( 0 )
, mDeferRepack( false )
, mCapabilities( 0 ) , mCapabilities( 0 )
{ {
QgsApplication::registerOgrDrivers(); QgsApplication::registerOgrDrivers();
@ -1971,11 +1972,14 @@ bool QgsOgrProvider::doInitialActionsForEdition()
if ( !mValid ) if ( !mValid )
return false; return false;
if ( !mWriteAccess && mWriteAccessPossible && mDynamicWriteAccess ) // If mUpdateModeStackDepth > 0, it means that an updateMode is already active and that we have write access
if ( mUpdateModeStackDepth == 0 )
{ {
QgsDebugMsg( "Enter update mode implictly" ); QgsDebugMsg( "Enter update mode implictly" );
if ( !enterUpdateMode() ) if ( !enterUpdateMode() )
return false; return false;
// For implicitly entered updateMode, don't defer repacking
mDeferRepack = false;
} }
return true; return true;
@ -3416,10 +3420,13 @@ bool QgsOgrProvider::syncToDisc()
pushError( tr( "OGR error syncing to disk: %1" ).arg( CPLGetLastErrorMsg() ) ); pushError( tr( "OGR error syncing to disk: %1" ).arg( CPLGetLastErrorMsg() ) );
} }
if ( mShapefileMayBeCorrupted ) if ( !mDeferRepack )
repack(); {
if ( mShapefileMayBeCorrupted )
repack();
mShapefileMayBeCorrupted = false; mShapefileMayBeCorrupted = false;
}
QgsOgrConnPool::instance()->ref( dataSourceUri() ); QgsOgrConnPool::instance()->ref( dataSourceUri() );
if ( shapeIndex ) if ( shapeIndex )
@ -3844,6 +3851,7 @@ bool QgsOgrProvider::enterUpdateMode()
} }
} }
++mUpdateModeStackDepth; ++mUpdateModeStackDepth;
mDeferRepack = true;
return true; return true;
} }
@ -3860,6 +3868,15 @@ bool QgsOgrProvider::leaveUpdateMode()
mUpdateModeStackDepth = 0; mUpdateModeStackDepth = 0;
return false; return false;
} }
if ( mDeferRepack && mUpdateModeStackDepth == 0 )
{
// Only repack once update mode is inactive
if ( mShapefileMayBeCorrupted )
repack();
mShapefileMayBeCorrupted = false;
mDeferRepack = false;
}
if ( !mDynamicWriteAccess ) if ( !mDynamicWriteAccess )
{ {
return true; return true;

View File

@ -252,6 +252,8 @@ class QgsOgrProvider : public QgsVectorDataProvider
int mUpdateModeStackDepth; int mUpdateModeStackDepth;
bool mDeferRepack;
void computeCapabilities(); void computeCapabilities();
QgsVectorDataProvider::Capabilities mCapabilities; QgsVectorDataProvider::Capabilities mCapabilities;

View File

@ -459,7 +459,23 @@ class TestPyQgsShapefileProvider(unittest.TestCase, ProviderTestCase):
# Test the content of the shapefile while it is still opened # Test the content of the shapefile while it is still opened
ds = osgeo.ogr.Open(datasource) ds = osgeo.ogr.Open(datasource)
# Test repacking has been done # Test repacking has been done
self.assertTrue(ds.GetLayer(0).GetFeatureCount(), feature_count - 1) self.assertTrue(ds.GetLayer(0).GetFeatureCount() == feature_count - 1)
ds = None
# Delete another feature while in update mode
self.assertTrue(2 == 2)
vl.dataProvider().enterUpdateMode()
vl.dataProvider().deleteFeatures([0])
# Test that repacking has not been done (since in update mode)
ds = osgeo.ogr.Open(datasource)
self.assertTrue(ds.GetLayer(0).GetFeatureCount() == feature_count - 1)
ds = None
# Test that repacking was performed when leaving updateMode
vl.dataProvider().leaveUpdateMode()
ds = osgeo.ogr.Open(datasource)
self.assertTrue(ds.GetLayer(0).GetFeatureCount() == feature_count - 2)
ds = None ds = None
vl = None vl = None