Skip to content

Commit ba76c99

Browse files
committedDec 6, 2013
[ogr] Only call repack when closing a data provider
Fix #8822
1 parent b92e124 commit ba76c99

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,
@@ -382,6 +438,8 @@ QgsOgrProvider::~QgsOgrProvider()
382438
OGR_DS_ReleaseResultSet( ogrDataSource, ogrLayer );
383439
}
384440

441+
repack();
442+
385443
OGR_DS_Destroy( ogrDataSource );
386444
ogrDataSource = 0;
387445

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

1236-
QgsCPLErrorHandler handler;
1237-
12381294
QByteArray layerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrOrigLayer ) );
12391295

1240-
// run REPACK on shape files
1241-
if ( mDeletedFeatures )
1242-
{
1243-
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
1244-
QgsDebugMsg( QString( "SQL: %1" ).arg( FROM8( sql ) ) );
1245-
OGR_DS_ExecuteSQL( ogrDataSource, sql.constData(), NULL, NULL );
1246-
1247-
if ( mFilePath.endsWith( ".shp", Qt::CaseInsensitive ) || mFilePath.endsWith( ".dbf", Qt::CaseInsensitive ) )
1248-
{
1249-
QString packedDbf( mFilePath.left( mFilePath.size() - 4 ) + "_packed.dbf" );
1250-
if ( QFile::exists( packedDbf ) )
1251-
{
1252-
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 );
1253-
1254-
OGR_DS_Destroy( ogrDataSource );
1255-
ogrLayer = ogrOrigLayer = 0;
1256-
1257-
ogrDataSource = OGROpen( TO8F( mFilePath ), true, NULL );
1258-
if ( ogrDataSource )
1259-
{
1260-
if ( mLayerName.isNull() )
1261-
{
1262-
ogrOrigLayer = OGR_DS_GetLayer( ogrDataSource, mLayerIndex );
1263-
}
1264-
else
1265-
{
1266-
ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mLayerName ) );
1267-
}
1268-
1269-
if ( !ogrOrigLayer )
1270-
{
1271-
QgsMessageLog::logMessage( tr( "Original layer could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
1272-
valid = false;
1273-
}
1274-
1275-
ogrLayer = ogrOrigLayer;
1276-
}
1277-
else
1278-
{
1279-
QgsMessageLog::logMessage( tr( "Original datasource could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
1280-
valid = false;
1281-
}
1282-
}
1283-
}
1284-
1285-
mDeletedFeatures = false;
1286-
}
1287-
12881296
if ( ogrDataSource )
12891297
{
12901298
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)
Please sign in to comment.