Skip to content

Commit b995973

Browse files
committed
[ogr] Only call repack when closing a data provider
Fix #8822
1 parent e0e287b commit b995973

File tree

2 files changed

+61
-50
lines changed

2 files changed

+61
-50
lines changed

src/providers/ogr/qgsogrprovider.cpp

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,62 @@ bool QgsOgrProvider::convertField( QgsField &field, const QTextCodec &encoding )
124124
return true;
125125
}
126126

127+
void QgsOgrProvider::repack()
128+
{
129+
if ( ogrDriverName != "ESRI Shapefile" )
130+
return;
131+
132+
QByteArray layerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrOrigLayer ) );
133+
134+
// run REPACK on shape files
135+
if ( mDeletedFeatures )
136+
{
137+
QByteArray sql = QByteArray( "REPACK " ) + layerName; // don't quote the layer name as it works with spaces in the name and won't work if the name is quoted
138+
QgsDebugMsg( QString( "SQL: %1" ).arg( FROM8( sql ) ) );
139+
OGR_DS_ExecuteSQL( ogrDataSource, sql.constData(), NULL, NULL );
140+
141+
if ( mFilePath.endsWith( ".shp", Qt::CaseInsensitive ) || mFilePath.endsWith( ".dbf", Qt::CaseInsensitive ) )
142+
{
143+
QString packedDbf( mFilePath.left( mFilePath.size() - 4 ) + "_packed.dbf" );
144+
if ( QFile::exists( packedDbf ) )
145+
{
146+
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 );
147+
148+
OGR_DS_Destroy( ogrDataSource );
149+
ogrLayer = ogrOrigLayer = 0;
150+
151+
ogrDataSource = OGROpen( TO8F( mFilePath ), true, NULL );
152+
if ( ogrDataSource )
153+
{
154+
if ( mLayerName.isNull() )
155+
{
156+
ogrOrigLayer = OGR_DS_GetLayer( ogrDataSource, mLayerIndex );
157+
}
158+
else
159+
{
160+
ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mLayerName ) );
161+
}
162+
163+
if ( !ogrOrigLayer )
164+
{
165+
QgsMessageLog::logMessage( tr( "Original layer could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
166+
valid = false;
167+
}
168+
169+
ogrLayer = ogrOrigLayer;
170+
}
171+
else
172+
{
173+
QgsMessageLog::logMessage( tr( "Original datasource could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
174+
valid = false;
175+
}
176+
}
177+
}
178+
179+
mDeletedFeatures = false;
180+
}
181+
}
182+
127183

128184
QgsVectorLayerImport::ImportError QgsOgrProvider::createEmptyLayer(
129185
const QString& uri,
@@ -381,6 +437,8 @@ QgsOgrProvider::~QgsOgrProvider()
381437
OGR_DS_ReleaseResultSet( ogrDataSource, ogrLayer );
382438
}
383439

440+
repack();
441+
384442
OGR_DS_Destroy( ogrDataSource );
385443
ogrDataSource = 0;
386444

@@ -1232,58 +1290,8 @@ bool QgsOgrProvider::createSpatialIndex()
12321290
if ( ogrDriverName != "ESRI Shapefile" )
12331291
return false;
12341292

1235-
QgsCPLErrorHandler handler;
1236-
12371293
QByteArray layerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrOrigLayer ) );
12381294

1239-
// run REPACK on shape files
1240-
if ( mDeletedFeatures )
1241-
{
1242-
QByteArray sql = QByteArray( "REPACK " ) + layerName; // don't quote the layer name as it works with spaces in the name and won't work if the name is quoted
1243-
QgsDebugMsg( QString( "SQL: %1" ).arg( FROM8( sql ) ) );
1244-
OGR_DS_ExecuteSQL( ogrDataSource, sql.constData(), NULL, NULL );
1245-
1246-
if ( mFilePath.endsWith( ".shp", Qt::CaseInsensitive ) || mFilePath.endsWith( ".dbf", Qt::CaseInsensitive ) )
1247-
{
1248-
QString packedDbf( mFilePath.left( mFilePath.size() - 4 ) + "_packed.dbf" );
1249-
if ( QFile::exists( packedDbf ) )
1250-
{
1251-
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 );
1252-
1253-
OGR_DS_Destroy( ogrDataSource );
1254-
ogrLayer = ogrOrigLayer = 0;
1255-
1256-
ogrDataSource = OGROpen( TO8F( mFilePath ), true, NULL );
1257-
if ( ogrDataSource )
1258-
{
1259-
if ( mLayerName.isNull() )
1260-
{
1261-
ogrOrigLayer = OGR_DS_GetLayer( ogrDataSource, mLayerIndex );
1262-
}
1263-
else
1264-
{
1265-
ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mLayerName ) );
1266-
}
1267-
1268-
if ( !ogrOrigLayer )
1269-
{
1270-
QgsMessageLog::logMessage( tr( "Original layer could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
1271-
valid = false;
1272-
}
1273-
1274-
ogrLayer = ogrOrigLayer;
1275-
}
1276-
else
1277-
{
1278-
QgsMessageLog::logMessage( tr( "Original datasource could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
1279-
valid = false;
1280-
}
1281-
}
1282-
}
1283-
1284-
mDeletedFeatures = false;
1285-
}
1286-
12871295
if ( ogrDataSource )
12881296
{
12891297
QByteArray sql = "CREATE SPATIAL INDEX ON " + quotedIdentifier( layerName ); // quote the layer name so spaces are handled

src/providers/ogr/qgsogrprovider.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,9 @@ class QgsOgrProvider : public QgsVectorDataProvider
275275
/** convert a QgsField to work with OGR */
276276
static bool convertField( QgsField &field, const QTextCodec &encoding );
277277

278+
/** Clean shapefile from features which are marked as deleted */
279+
void repack();
280+
278281
private:
279282
unsigned char *getGeometryPointer( OGRFeatureH fet );
280283
QString ogrWkbGeometryTypeName( OGRwkbGeometryType type ) const;

0 commit comments

Comments
 (0)