Skip to content

Commit c130f9f

Browse files
committed
[OGR provider] Avoid (harmless) OGR errors when trying to convert GeoPackage from WAL to DELETE mode
1 parent 32852fb commit c130f9f

File tree

2 files changed

+51
-31
lines changed

2 files changed

+51
-31
lines changed

src/providers/ogr/qgsogrprovider.cpp

+47-30
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ QMap< QgsOgrProviderUtils::DatasetIdentification,
9999
100100
QMap< QString, int > QgsOgrProviderUtils::mapCountOpenedDS;
101101
102+
QMap< GDALDatasetH, bool> QgsOgrProviderUtils::mapDSHandleToUpdateMode;
103+
102104
QMap< QString, QDateTime > QgsOgrProviderUtils::mapDSNameToLastModifiedDate;
103105
104106
bool QgsOgrProvider::convertField( QgsField &field, const QTextCodec &encoding )
@@ -3222,6 +3224,7 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp
32223224
}
32233225

32243226
QString filePath( QString::fromUtf8( pszPath ) );
3227+
bool bIsLocalGpkg = false;
32253228
if ( QFileInfo( filePath ).suffix().compare( QLatin1String( "gpkg" ), Qt::CaseInsensitive ) == 0 &&
32263229
IsLocalFile( filePath ) &&
32273230
!CPLGetConfigOption( "OGR_SQLITE_JOURNAL", nullptr ) &&
@@ -3233,6 +3236,7 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp
32333236
// But only do that on a local file since WAL is advertized not to work
32343237
// on network shares
32353238
CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", "WAL" );
3239+
bIsLocalGpkg = true;
32363240
}
32373241

32383242
const int nOpenFlags = GDAL_OF_VECTOR | ( bUpdate ? GDAL_OF_UPDATE : 0 );
@@ -3248,10 +3252,11 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp
32483252
return nullptr;
32493253
}
32503254
GDALDriverH hDrv = GDALGetDatasetDriver( hDS );
3251-
if ( strcmp( GDALGetDriverShortName( hDrv ), "GPKG" ) == 0 )
3255+
if ( bIsLocalGpkg && strcmp( GDALGetDriverShortName( hDrv ), "GPKG" ) == 0 )
32523256
{
32533257
QMutexLocker locker( &globalMutex );
32543258
mapCountOpenedDS[ filePath ]++;
3259+
mapDSHandleToUpdateMode[ hDS ] = bUpdate;
32553260
}
32563261
if ( phDriver )
32573262
*phDriver = hDrv;
@@ -3308,53 +3313,65 @@ void QgsOgrProviderUtils::GDALCloseWrapper( GDALDatasetH hDS )
33083313
IsLocalFile( datasetName ) &&
33093314
!CPLGetConfigOption( "OGR_SQLITE_JOURNAL", nullptr ) )
33103315
{
3316+
bool openedAsUpdate = false;
33113317
bool tryReturnToWall = false;
33123318
{
33133319
QMutexLocker locker( &globalMutex );
33143320
mapCountOpenedDS[ datasetName ] --;
33153321
if ( mapCountOpenedDS[ datasetName ] == 0 )
3322+
{
3323+
mapCountOpenedDS.remove( datasetName );
3324+
openedAsUpdate = mapDSHandleToUpdateMode[hDS];
33163325
tryReturnToWall = true;
3326+
}
3327+
mapDSHandleToUpdateMode.remove( hDS );
33173328
}
33183329
if ( tryReturnToWall )
33193330
{
3320-
// We need to reset all iterators on layers, otherwise we will not
3321-
// be able to change journal_mode.
3322-
int layerCount = GDALDatasetGetLayerCount( hDS );
3323-
for ( int i = 0; i < layerCount; i ++ )
3324-
{
3325-
OGR_L_ResetReading( GDALDatasetGetLayer( hDS, i ) );
3326-
}
3327-
3328-
CPLPushErrorHandler( CPLQuietErrorHandler );
3329-
QgsDebugMsg( "GPKG: Trying to return to delete mode" );
33303331
bool bSuccess = false;
3331-
OGRLayerH hSqlLyr = GDALDatasetExecuteSQL( hDS,
3332-
"PRAGMA journal_mode = delete",
3333-
nullptr, nullptr );
3334-
if ( hSqlLyr )
3332+
if ( openedAsUpdate )
33353333
{
3336-
OGRFeatureH hFeat = OGR_L_GetNextFeature( hSqlLyr );
3337-
if ( hFeat )
3334+
// We need to reset all iterators on layers, otherwise we will not
3335+
// be able to change journal_mode.
3336+
int layerCount = GDALDatasetGetLayerCount( hDS );
3337+
for ( int i = 0; i < layerCount; i ++ )
33383338
{
3339-
const char *pszRet = OGR_F_GetFieldAsString( hFeat, 0 );
3340-
bSuccess = EQUAL( pszRet, "delete" );
3341-
QgsDebugMsg( QString( "Return: %1" ).arg( pszRet ) );
3342-
OGR_F_Destroy( hFeat );
3339+
OGR_L_ResetReading( GDALDatasetGetLayer( hDS, i ) );
33433340
}
3341+
3342+
CPLPushErrorHandler( CPLQuietErrorHandler );
3343+
QgsDebugMsg( "GPKG: Trying to return to delete mode" );
3344+
OGRLayerH hSqlLyr = GDALDatasetExecuteSQL( hDS,
3345+
"PRAGMA journal_mode = delete",
3346+
nullptr, nullptr );
3347+
if ( hSqlLyr )
3348+
{
3349+
OGRFeatureH hFeat = OGR_L_GetNextFeature( hSqlLyr );
3350+
if ( hFeat )
3351+
{
3352+
const char *pszRet = OGR_F_GetFieldAsString( hFeat, 0 );
3353+
bSuccess = EQUAL( pszRet, "delete" );
3354+
QgsDebugMsg( QString( "Return: %1" ).arg( pszRet ) );
3355+
OGR_F_Destroy( hFeat );
3356+
}
3357+
}
3358+
else if ( CPLGetLastErrorType() != CE_None )
3359+
{
3360+
QgsDebugMsg( QString( "Return: %1" ).arg( CPLGetLastErrorMsg() ) );
3361+
}
3362+
GDALDatasetReleaseResultSet( hDS, hSqlLyr );
3363+
CPLPopErrorHandler();
33443364
}
3345-
else if ( CPLGetLastErrorType() != CE_None )
3346-
{
3347-
QgsDebugMsg( QString( "Return: %1" ).arg( CPLGetLastErrorMsg() ) );
3348-
}
3349-
GDALDatasetReleaseResultSet( hDS, hSqlLyr );
3350-
CPLPopErrorHandler();
33513365
GDALClose( hDS );
33523366

3353-
// This may have not worked if the file was opened in read-only mode,
3354-
// so retry in update mode
3367+
// If the file was opened in read-only mode, or if the above failed,
3368+
// we need to reopen it in update mode
33553369
if ( !bSuccess )
33563370
{
3357-
QgsDebugMsg( "GPKG: Trying again" );
3371+
if ( openedAsUpdate )
3372+
QgsDebugMsg( "GPKG: Trying again" );
3373+
else
3374+
QgsDebugMsg( "GPKG: Trying to return to delete mode" );
33583375
CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", "DELETE" );
33593376
hDS = GDALOpenEx( datasetName.toUtf8().constData(), GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr );
33603377
CPLSetThreadLocalConfigOption( "OGR_SQLITE_JOURNAL", nullptr );

src/providers/ogr/qgsogrprovider.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,12 @@ class QgsOgrProviderUtils
308308
//! Map dataset identification to a list of corresponding DatasetWithLayers*
309309
static QMap< DatasetIdentification, QList<DatasetWithLayers *> > mapSharedDS;
310310

311-
//! Map a dataset name to the number of opened GDAL dataset objects on it (if opened with GDALOpenWrapper)
311+
//! Map a dataset name to the number of opened GDAL dataset objects on it (if opened with GDALOpenWrapper, only for GPKG)
312312
static QMap< QString, int > mapCountOpenedDS;
313313

314+
//! Map a dataset handle to its update open mode (if opened with GDALOpenWrapper, only for GPKG)
315+
static QMap< GDALDatasetH, bool> mapDSHandleToUpdateMode;
316+
314317
//! Map a dataset name to its last modified data
315318
static QMap< QString, QDateTime > mapDSNameToLastModifiedDate;
316319

0 commit comments

Comments
 (0)