Skip to content

Commit

Permalink
[ogr] Only call repack when closing a data provider
Browse files Browse the repository at this point in the history
Fix #8822
  • Loading branch information
m-kuhn committed Dec 6, 2013
1 parent b92e124 commit ba76c99
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 50 deletions.
108 changes: 58 additions & 50 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -124,6 +124,62 @@ bool QgsOgrProvider::convertField( QgsField &field, const QTextCodec &encoding )
return true;
}

void QgsOgrProvider::repack()
{
if ( ogrDriverName != "ESRI Shapefile" )
return;

QByteArray layerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrOrigLayer ) );

// run REPACK on shape files
if ( mDeletedFeatures )
{
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
QgsDebugMsg( QString( "SQL: %1" ).arg( FROM8( sql ) ) );
OGR_DS_ExecuteSQL( ogrDataSource, sql.constData(), NULL, NULL );

if ( mFilePath.endsWith( ".shp", Qt::CaseInsensitive ) || mFilePath.endsWith( ".dbf", Qt::CaseInsensitive ) )
{
QString packedDbf( mFilePath.left( mFilePath.size() - 4 ) + "_packed.dbf" );
if ( QFile::exists( packedDbf ) )
{
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 );

OGR_DS_Destroy( ogrDataSource );
ogrLayer = ogrOrigLayer = 0;

ogrDataSource = OGROpen( TO8F( mFilePath ), true, NULL );
if ( ogrDataSource )
{
if ( mLayerName.isNull() )
{
ogrOrigLayer = OGR_DS_GetLayer( ogrDataSource, mLayerIndex );
}
else
{
ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mLayerName ) );
}

if ( !ogrOrigLayer )
{
QgsMessageLog::logMessage( tr( "Original layer could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
valid = false;
}

ogrLayer = ogrOrigLayer;
}
else
{
QgsMessageLog::logMessage( tr( "Original datasource could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
valid = false;
}
}
}

mDeletedFeatures = false;
}
}


QgsVectorLayerImport::ImportError QgsOgrProvider::createEmptyLayer(
const QString& uri,
Expand Down Expand Up @@ -382,6 +438,8 @@ QgsOgrProvider::~QgsOgrProvider()
OGR_DS_ReleaseResultSet( ogrDataSource, ogrLayer );
}

repack();

OGR_DS_Destroy( ogrDataSource );
ogrDataSource = 0;

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

QgsCPLErrorHandler handler;

QByteArray layerName = OGR_FD_GetName( OGR_L_GetLayerDefn( ogrOrigLayer ) );

// run REPACK on shape files
if ( mDeletedFeatures )
{
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
QgsDebugMsg( QString( "SQL: %1" ).arg( FROM8( sql ) ) );
OGR_DS_ExecuteSQL( ogrDataSource, sql.constData(), NULL, NULL );

if ( mFilePath.endsWith( ".shp", Qt::CaseInsensitive ) || mFilePath.endsWith( ".dbf", Qt::CaseInsensitive ) )
{
QString packedDbf( mFilePath.left( mFilePath.size() - 4 ) + "_packed.dbf" );
if ( QFile::exists( packedDbf ) )
{
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 );

OGR_DS_Destroy( ogrDataSource );
ogrLayer = ogrOrigLayer = 0;

ogrDataSource = OGROpen( TO8F( mFilePath ), true, NULL );
if ( ogrDataSource )
{
if ( mLayerName.isNull() )
{
ogrOrigLayer = OGR_DS_GetLayer( ogrDataSource, mLayerIndex );
}
else
{
ogrOrigLayer = OGR_DS_GetLayerByName( ogrDataSource, TO8( mLayerName ) );
}

if ( !ogrOrigLayer )
{
QgsMessageLog::logMessage( tr( "Original layer could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
valid = false;
}

ogrLayer = ogrOrigLayer;
}
else
{
QgsMessageLog::logMessage( tr( "Original datasource could not be reopened." ), tr( "OGR" ), QgsMessageLog::CRITICAL );
valid = false;
}
}
}

mDeletedFeatures = false;
}

if ( ogrDataSource )
{
QByteArray sql = "CREATE SPATIAL INDEX ON " + quotedIdentifier( layerName ); // quote the layer name so spaces are handled
Expand Down
3 changes: 3 additions & 0 deletions src/providers/ogr/qgsogrprovider.h
Expand Up @@ -275,6 +275,9 @@ class QgsOgrProvider : public QgsVectorDataProvider
/** convert a QgsField to work with OGR */
static bool convertField( QgsField &field, const QTextCodec &encoding );

/** Clean shapefile from features which are marked as deleted */
void repack();

private:
unsigned char *getGeometryPointer( OGRFeatureH fet );
QString ogrWkbGeometryTypeName( OGRwkbGeometryType type ) const;
Expand Down

0 comments on commit ba76c99

Please sign in to comment.