@@ -99,6 +99,8 @@ QMap< QgsOgrProviderUtils::DatasetIdentification,
99
99
100
100
QMap< QString, int > QgsOgrProviderUtils::mapCountOpenedDS;
101
101
102
+ QMap< GDALDatasetH, bool> QgsOgrProviderUtils::mapDSHandleToUpdateMode;
103
+
102
104
QMap< QString, QDateTime > QgsOgrProviderUtils::mapDSNameToLastModifiedDate;
103
105
104
106
bool QgsOgrProvider::convertField( QgsField &field, const QTextCodec &encoding )
@@ -3222,6 +3224,7 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp
3222
3224
}
3223
3225
3224
3226
QString filePath ( QString::fromUtf8 ( pszPath ) );
3227
+ bool bIsLocalGpkg = false ;
3225
3228
if ( QFileInfo ( filePath ).suffix ().compare ( QLatin1String ( " gpkg" ), Qt::CaseInsensitive ) == 0 &&
3226
3229
IsLocalFile ( filePath ) &&
3227
3230
!CPLGetConfigOption ( " OGR_SQLITE_JOURNAL" , nullptr ) &&
@@ -3233,6 +3236,7 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp
3233
3236
// But only do that on a local file since WAL is advertized not to work
3234
3237
// on network shares
3235
3238
CPLSetThreadLocalConfigOption ( " OGR_SQLITE_JOURNAL" , " WAL" );
3239
+ bIsLocalGpkg = true ;
3236
3240
}
3237
3241
3238
3242
const int nOpenFlags = GDAL_OF_VECTOR | ( bUpdate ? GDAL_OF_UPDATE : 0 );
@@ -3248,10 +3252,11 @@ GDALDatasetH QgsOgrProviderUtils::GDALOpenWrapper( const char *pszPath, bool bUp
3248
3252
return nullptr ;
3249
3253
}
3250
3254
GDALDriverH hDrv = GDALGetDatasetDriver ( hDS );
3251
- if ( strcmp ( GDALGetDriverShortName ( hDrv ), " GPKG" ) == 0 )
3255
+ if ( bIsLocalGpkg && strcmp ( GDALGetDriverShortName ( hDrv ), " GPKG" ) == 0 )
3252
3256
{
3253
3257
QMutexLocker locker ( &globalMutex );
3254
3258
mapCountOpenedDS[ filePath ]++;
3259
+ mapDSHandleToUpdateMode[ hDS ] = bUpdate;
3255
3260
}
3256
3261
if ( phDriver )
3257
3262
*phDriver = hDrv;
@@ -3308,53 +3313,65 @@ void QgsOgrProviderUtils::GDALCloseWrapper( GDALDatasetH hDS )
3308
3313
IsLocalFile ( datasetName ) &&
3309
3314
!CPLGetConfigOption ( " OGR_SQLITE_JOURNAL" , nullptr ) )
3310
3315
{
3316
+ bool openedAsUpdate = false ;
3311
3317
bool tryReturnToWall = false ;
3312
3318
{
3313
3319
QMutexLocker locker ( &globalMutex );
3314
3320
mapCountOpenedDS[ datasetName ] --;
3315
3321
if ( mapCountOpenedDS[ datasetName ] == 0 )
3322
+ {
3323
+ mapCountOpenedDS.remove ( datasetName );
3324
+ openedAsUpdate = mapDSHandleToUpdateMode[hDS];
3316
3325
tryReturnToWall = true ;
3326
+ }
3327
+ mapDSHandleToUpdateMode.remove ( hDS );
3317
3328
}
3318
3329
if ( tryReturnToWall )
3319
3330
{
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" );
3330
3331
bool bSuccess = false ;
3331
- OGRLayerH hSqlLyr = GDALDatasetExecuteSQL ( hDS,
3332
- " PRAGMA journal_mode = delete" ,
3333
- nullptr , nullptr );
3334
- if ( hSqlLyr )
3332
+ if ( openedAsUpdate )
3335
3333
{
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 ++ )
3338
3338
{
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 ) );
3343
3340
}
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 ();
3344
3364
}
3345
- else if ( CPLGetLastErrorType () != CE_None )
3346
- {
3347
- QgsDebugMsg ( QString ( " Return: %1" ).arg ( CPLGetLastErrorMsg () ) );
3348
- }
3349
- GDALDatasetReleaseResultSet ( hDS, hSqlLyr );
3350
- CPLPopErrorHandler ();
3351
3365
GDALClose ( hDS );
3352
3366
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
3355
3369
if ( !bSuccess )
3356
3370
{
3357
- QgsDebugMsg ( " GPKG: Trying again" );
3371
+ if ( openedAsUpdate )
3372
+ QgsDebugMsg ( " GPKG: Trying again" );
3373
+ else
3374
+ QgsDebugMsg ( " GPKG: Trying to return to delete mode" );
3358
3375
CPLSetThreadLocalConfigOption ( " OGR_SQLITE_JOURNAL" , " DELETE" );
3359
3376
hDS = GDALOpenEx ( datasetName.toUtf8 ().constData (), GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr , nullptr , nullptr );
3360
3377
CPLSetThreadLocalConfigOption ( " OGR_SQLITE_JOURNAL" , nullptr );
0 commit comments