Skip to content

Commit 6149d34

Browse files
committed
run REPACK after deleting features (fixes #8317)
1 parent 79a524f commit 6149d34

File tree

3 files changed

+50
-13
lines changed

3 files changed

+50
-13
lines changed

src/core/qgsvectorlayereditbuffer.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList& commitErrors )
245245

246246
QgsFields oldFields = L->pendingFields();
247247

248+
bool hadPendingDeletes = !mDeletedFeatureIds.isEmpty();
249+
248250
//
249251
// delete attributes
250252
//
@@ -435,6 +437,13 @@ bool QgsVectorLayerEditBuffer::commitChanges( QStringList& commitErrors )
435437
}
436438
}
437439

440+
// for shapes run a REPACK after each transaction
441+
// TODO: enhance provider interface to allow moving this there
442+
if ( success && hadPendingDeletes && L->providerType() == "ogr" && L->storageType() == "ESRI Shapefile" )
443+
{
444+
provider->createSpatialIndex();
445+
}
446+
438447
if ( !success && provider->hasErrors() )
439448
{
440449
commitErrors << tr( "\n Provider errors:" );

src/providers/ogr/qgsogrprovider.cpp

+38-13
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
209209
, ogrDriver( 0 )
210210
, valid( false )
211211
, featuresCounted( -1 )
212+
, mDeletedFeatures( false )
212213
{
213214
QgsCPLErrorHandler handler;
214215

@@ -1212,15 +1213,16 @@ bool QgsOgrProvider::changeGeometryValues( QgsGeometryMap & geometry_map )
12121213

12131214
bool QgsOgrProvider::createSpatialIndex()
12141215
{
1216+
if ( ogrDriverName != "ESRI Shapefile" )
1217+
return false;
1218+
12151219
QgsCPLErrorHandler handler;
12161220

12171221
QString layerName = FROM8( OGR_FD_GetName( OGR_L_GetLayerDefn( ogrOrigLayer ) ) );
12181222

12191223
// run REPACK on shape files
1220-
if ( ogrDriverName == "ESRI Shapefile" )
1224+
if ( mDeletedFeatures )
12211225
{
1222-
QString layerName = FROM8( OGR_FD_GetName( OGR_L_GetLayerDefn( ogrOrigLayer ) ) );
1223-
12241226
QString sql = QString( "REPACK %1" ).arg( layerName ); // don't quote the layer name as it works with spaces in the name and won't work if the name is quoted
12251227
QgsDebugMsg( QString( "SQL: %1" ).arg( sql ) );
12261228
OGR_DS_ExecuteSQL( ogrDataSource, mEncoding->fromUnicode( sql ).constData(), NULL, NULL );
@@ -1233,26 +1235,45 @@ bool QgsOgrProvider::createSpatialIndex()
12331235
QgsMessageLog::logMessage( tr( "Possible corruption after REPACK detected. %1 still exists. This may point to a permission or locking problem of the original DBF." ).arg( packedDbf ), tr( "OGR" ), QgsMessageLog::CRITICAL );
12341236

12351237
OGR_DS_Destroy( ogrDataSource );
1238+
ogrLayer = ogrOrigLayer = 0;
12361239

12371240
ogrDataSource = OGROpen( TO8F( mFilePath ), true, NULL );
1238-
1239-
if ( mLayerName.isNull() )
1241+
if ( ogrDataSource )
12401242
{
1241-
ogrOrigLayer = OGR_DS_GetLayer( ogrDataSource, mLayerIndex );
1243+
if ( mLayerName.isNull() )
1244+
{
1245+
ogrOrigLayer = OGR_DS_GetLayer( ogrDataSource, mLayerIndex );
1246+
}
1247+
else
1248+
{
1249+
ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mLayerName ) );
1250+
}
1251+
1252+
if ( !ogrOrigLayer )
1253+
{
1254+
QgsMessageLog::logMessage( tr( "Original layer could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
1255+
valid = false;
1256+
}
1257+
1258+
ogrLayer = ogrOrigLayer;
12421259
}
12431260
else
12441261
{
1245-
ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mLayerName ) );
1262+
QgsMessageLog::logMessage( tr( "Original datasource could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
1263+
valid = false;
12461264
}
1247-
1248-
ogrLayer = ogrOrigLayer;
12491265
}
12501266
}
1267+
1268+
mDeletedFeatures = false;
12511269
}
12521270

1253-
QString sql = QString( "CREATE SPATIAL INDEX ON %1" ).arg( quotedIdentifier( layerName ) ); // quote the layer name so spaces are handled
1254-
QgsDebugMsg( QString( "SQL: %1" ).arg( sql ) );
1255-
OGR_DS_ExecuteSQL( ogrDataSource, mEncoding->fromUnicode( sql ).constData(), OGR_L_GetSpatialFilter( ogrOrigLayer ), "" );
1271+
if ( ogrDataSource )
1272+
{
1273+
QString sql = QString( "CREATE SPATIAL INDEX ON %1" ).arg( quotedIdentifier( layerName ) ); // quote the layer name so spaces are handled
1274+
QgsDebugMsg( QString( "SQL: %1" ).arg( sql ) );
1275+
OGR_DS_ExecuteSQL( ogrDataSource, mEncoding->fromUnicode( sql ).constData(), OGR_L_GetSpatialFilter( ogrOrigLayer ), "" );
1276+
}
12561277

12571278
QFileInfo fi( mFilePath ); // to get the base name
12581279
//find out, if the .qix file is there
@@ -1281,7 +1302,11 @@ bool QgsOgrProvider::deleteFeatures( const QgsFeatureIds & id )
12811302
bool returnvalue = true;
12821303
for ( QgsFeatureIds::const_iterator it = id.begin(); it != id.end(); ++it )
12831304
{
1284-
if ( !deleteFeature( *it ) )
1305+
if ( deleteFeature( *it ) )
1306+
{
1307+
mDeletedFeatures = true;
1308+
}
1309+
else
12851310
{
12861311
returnvalue = false;
12871312
}

src/providers/ogr/qgsogrprovider.h

+3
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ class QgsOgrProvider : public QgsVectorDataProvider
321321
int geomType;
322322
long featuresCounted;
323323

324+
//! There are deleted feature - REPACK before creating a spatialindex
325+
bool mDeletedFeatures;
326+
324327
mutable QStringList mSubLayerList;
325328

326329
/** Flag whether OGR will return fields required by nextFeature() calls.

0 commit comments

Comments
 (0)