@@ -538,15 +538,15 @@ QgsOgrProvider::QgsOgrProvider( QString const &uri, const ProviderOptions &optio
538
538
539
539
setNativeTypes ( nativeTypes );
540
540
541
- QgsOgrConnPool::instance ()->ref( QgsOgrProviderUtils::connectionPoolId( dataSourceUri( true ) ) );
541
+ QgsOgrConnPool::instance ()->ref( QgsOgrProviderUtils::connectionPoolId( dataSourceUri( true ), mShareSameDatasetAmongLayers ) );
542
542
}
543
543
544
544
QgsOgrProvider::~QgsOgrProvider ()
545
545
{
546
- QgsOgrConnPool::instance ()->unref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
546
+ QgsOgrConnPool::instance ()->unref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
547
547
// We must also make sure to flush unusef cached connections so that
548
548
// the file can be removed (#15137)
549
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
549
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
550
550
551
551
// Do that as last step for final cleanup that might be prevented by
552
552
// still opened datasets.
@@ -948,7 +948,7 @@ OGRwkbGeometryType QgsOgrProvider::getOgrGeomType( OGRLayerH ogrLayer )
948
948
949
949
void QgsOgrProvider::loadFields ()
950
950
{
951
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
951
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
952
952
// the attribute fields need to be read again when the encoding changes
953
953
mAttributeFields .clear ();
954
954
mDefaultValues .clear ();
@@ -1642,7 +1642,7 @@ bool QgsOgrProvider::addAttributes( const QList<QgsField> &attributes )
1642
1642
{
1643
1643
// adding attributes in mapinfo requires to be able to delete the .dat file
1644
1644
// so drop any cached connections.
1645
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
1645
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
1646
1646
}
1647
1647
1648
1648
bool returnvalue = true ;
@@ -1885,10 +1885,10 @@ bool QgsOgrProvider::_setSubsetString( const QString &theSQL, bool updateFeature
1885
1885
if ( uri != dataSourceUri () )
1886
1886
{
1887
1887
if ( hasExistingRef )
1888
- QgsOgrConnPool::instance ()->unref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
1888
+ QgsOgrConnPool::instance ()->unref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
1889
1889
setDataSourceUri ( uri );
1890
1890
if ( hasExistingRef )
1891
- QgsOgrConnPool::instance ()->ref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
1891
+ QgsOgrConnPool::instance ()->ref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
1892
1892
}
1893
1893
1894
1894
mOgrLayer ->ResetReading ();
@@ -2061,7 +2061,7 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
2061
2061
{
2062
2062
pushError ( tr ( " OGR error syncing to disk: %1" ).arg ( CPLGetLastErrorMsg () ) );
2063
2063
}
2064
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
2064
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
2065
2065
return true ;
2066
2066
}
2067
2067
@@ -2140,7 +2140,7 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
2140
2140
if ( mTransaction )
2141
2141
mTransaction ->dirtyLastSavePoint ();
2142
2142
2143
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
2143
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
2144
2144
return syncToDisc ();
2145
2145
}
2146
2146
@@ -3595,21 +3595,24 @@ QByteArray QgsOgrProvider::quotedIdentifier( const QByteArray &field ) const
3595
3595
3596
3596
void QgsOgrProvider::forceReload ()
3597
3597
{
3598
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
3598
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
3599
3599
}
3600
3600
3601
- QString QgsOgrProviderUtils::connectionPoolId ( const QString &dataSourceURI )
3601
+ QString QgsOgrProviderUtils::connectionPoolId ( const QString &dataSourceURI, bool shareSameDatasetAmongLayers )
3602
3602
{
3603
- // If the file part of the URI is really a file, then use it as the
3604
- // connection pool id (for example, so that all layers of a .gpkg file can
3605
- // use the same GDAL dataset object)
3606
- // Otherwise use the datasourceURI
3607
- // Not completely sure about this logic. But at least, for GeoPackage this
3608
- // works fine with multi layer datasets.
3609
- QString filePath = dataSourceURI.left ( dataSourceURI.indexOf ( QLatin1String ( " |" ) ) );
3610
- QFileInfo fi ( filePath );
3611
- if ( fi.isFile () )
3612
- return filePath;
3603
+ if ( shareSameDatasetAmongLayers )
3604
+ {
3605
+ // If the file part of the URI is really a file, then use it as the
3606
+ // connection pool id (for example, so that all layers of a .gpkg file can
3607
+ // use the same GDAL dataset object)
3608
+ // Otherwise use the datasourceURI
3609
+ // Not completely sure about this logic. But at least, for GeoPackage this
3610
+ // works fine with multi layer datasets.
3611
+ QString filePath = dataSourceURI.left ( dataSourceURI.indexOf ( QLatin1String ( " |" ) ) );
3612
+ QFileInfo fi ( filePath );
3613
+ if ( fi.isFile () )
3614
+ return filePath;
3615
+ }
3613
3616
return dataSourceURI;
3614
3617
}
3615
3618
@@ -3877,7 +3880,7 @@ QString QgsOgrProviderUtils::quotedValue( const QVariant &value )
3877
3880
bool QgsOgrProvider::syncToDisc ()
3878
3881
{
3879
3882
// for shapefiles, remove spatial index files and create a new index
3880
- QgsOgrConnPool::instance ()->unref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
3883
+ QgsOgrConnPool::instance ()->unref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
3881
3884
bool shapeIndex = false ;
3882
3885
if ( mGDALDriverName == QLatin1String ( " ESRI Shapefile" ) )
3883
3886
{
@@ -3892,7 +3895,7 @@ bool QgsOgrProvider::syncToDisc()
3892
3895
{
3893
3896
shapeIndex = true ;
3894
3897
close ();
3895
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
3898
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
3896
3899
QFile::remove ( sbnIndexFile );
3897
3900
open ( OpenModeSameAsCurrent );
3898
3901
if ( !mValid )
@@ -3916,7 +3919,7 @@ bool QgsOgrProvider::syncToDisc()
3916
3919
}
3917
3920
#endif
3918
3921
3919
- QgsOgrConnPool::instance ()->ref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
3922
+ QgsOgrConnPool::instance ()->ref ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
3920
3923
if ( shapeIndex )
3921
3924
{
3922
3925
return createSpatialIndex ();
@@ -3978,7 +3981,7 @@ void QgsOgrProvider::recalculateFeatureCount()
3978
3981
mOgrLayer ->SetSpatialFilter ( filter );
3979
3982
}
3980
3983
3981
- QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ) ) );
3984
+ QgsOgrConnPool::instance ()->invalidateConnections ( QgsOgrProviderUtils::connectionPoolId ( dataSourceUri ( true ), mShareSameDatasetAmongLayers ) );
3982
3985
}
3983
3986
3984
3987
bool QgsOgrProvider::doesStrictFeatureTypeCheck () const
@@ -4010,13 +4013,13 @@ OGRwkbGeometryType QgsOgrProvider::ogrWkbSingleFlatten( OGRwkbGeometryType type
4010
4013
OGRLayerH QgsOgrProviderUtils::setSubsetString ( OGRLayerH layer, GDALDatasetH ds, QTextCodec *encoding, const QString &subsetString, bool addOriginalFid, bool *origFidAdded )
4011
4014
{
4012
4015
QByteArray layerName = OGR_FD_GetName ( OGR_L_GetLayerDefn ( layer ) );
4013
- GDALDriverH mGDALDriver = GDALGetDatasetDriver ( ds );
4014
- QString mGDALDriverName = GDALGetDriverShortName ( mGDALDriver );
4016
+ GDALDriverH driver = GDALGetDatasetDriver ( ds );
4017
+ QString driverName = GDALGetDriverShortName ( driver );
4015
4018
bool origFidAddAttempted = false ;
4016
4019
if ( origFidAdded )
4017
4020
*origFidAdded = false ;
4018
4021
4019
- if ( mGDALDriverName == QLatin1String ( " ODBC" ) ) // the odbc driver does not like schema names for subset
4022
+ if ( driverName == QLatin1String ( " ODBC" ) ) // the odbc driver does not like schema names for subset
4020
4023
{
4021
4024
QString layerNameString = encoding->toUnicode ( layerName );
4022
4025
int dotIndex = layerNameString.indexOf ( ' .' );
@@ -4037,7 +4040,7 @@ OGRLayerH QgsOgrProviderUtils::setSubsetString( OGRLayerH layer, GDALDatasetH ds
4037
4040
else
4038
4041
{
4039
4042
QByteArray sqlPart1 = " SELECT *" ;
4040
- QByteArray sqlPart3 = " FROM " + quotedIdentifier ( layerName, mGDALDriverName );
4043
+ QByteArray sqlPart3 = " FROM " + quotedIdentifier ( layerName, driverName );
4041
4044
if ( !subsetString.isEmpty () )
4042
4045
sqlPart3 += " WHERE " + encoding->fromUnicode ( subsetString );
4043
4046
@@ -4179,6 +4182,7 @@ void QgsOgrProvider::open( OpenMode mode )
4179
4182
if ( mOgrOrigLayer )
4180
4183
{
4181
4184
mGDALDriverName = mOgrOrigLayer ->driverName ();
4185
+ mShareSameDatasetAmongLayers = QgsOgrProviderUtils::canDriverShareSameDatasetAmongLayers ( mGDALDriverName );
4182
4186
4183
4187
QgsDebugMsg ( " OGR opened using Driver " + mGDALDriverName );
4184
4188
@@ -4493,6 +4497,8 @@ QgsOgrLayerUniquePtr QgsOgrProviderUtils::getLayer( const QString &dsName,
4493
4497
auto &datasetList = iter.value ();
4494
4498
Q_FOREACH ( QgsOgrProviderUtils::DatasetWithLayers *ds, datasetList )
4495
4499
{
4500
+ if ( !ds->canBeShared )
4501
+ continue ;
4496
4502
Q_ASSERT ( ds->refCount > 0 );
4497
4503
4498
4504
QString layerName;
@@ -4546,6 +4552,8 @@ QgsOgrLayerUniquePtr QgsOgrProviderUtils::getLayer( const QString &dsName,
4546
4552
auto datasetList = iter.value ();
4547
4553
Q_FOREACH ( QgsOgrProviderUtils::DatasetWithLayers *ds, datasetList )
4548
4554
{
4555
+ if ( !ds->canBeShared )
4556
+ continue ;
4549
4557
Q_ASSERT ( ds->refCount > 0 );
4550
4558
4551
4559
QString layerName;
@@ -4590,6 +4598,10 @@ QgsOgrLayerUniquePtr QgsOgrProviderUtils::getLayer( const QString &dsName,
4590
4598
new QgsOgrProviderUtils::DatasetWithLayers;
4591
4599
ds->hDS = hDS;
4592
4600
4601
+ GDALDriverH driver = GDALGetDatasetDriver ( hDS );
4602
+ QString driverName = GDALGetDriverShortName ( driver );
4603
+ ds->canBeShared = canDriverShareSameDatasetAmongLayers ( driverName );
4604
+
4593
4605
QgsOgrLayerUniquePtr layer = QgsOgrLayer::CreateForLayer (
4594
4606
ident, layerName, ds, hLayer );
4595
4607
ds->setLayers [layerName] = layer.get ();
@@ -4616,6 +4628,8 @@ QgsOgrLayerUniquePtr QgsOgrProviderUtils::getLayer( const QString &dsName,
4616
4628
auto &datasetList = iter.value ();
4617
4629
Q_FOREACH ( QgsOgrProviderUtils::DatasetWithLayers *ds, datasetList )
4618
4630
{
4631
+ if ( !ds->canBeShared )
4632
+ continue ;
4619
4633
Q_ASSERT ( ds->refCount > 0 );
4620
4634
4621
4635
auto iter2 = ds->setLayers .find ( layerName );
@@ -4979,6 +4993,45 @@ bool QgsOgrProviderUtils::canUseOpenedDatasets( const QString &dsName )
4979
4993
return getLastModified ( dsName ) <= iter.value ();
4980
4994
}
4981
4995
4996
+ QgsOgrProviderUtils::DatasetWithLayers *QgsOgrProviderUtils::createDatasetWithLayers (
4997
+ const QString &dsName,
4998
+ bool updateMode,
4999
+ const QStringList &options,
5000
+ const QString &layerName,
5001
+ const DatasetIdentification &ident,
5002
+ QgsOgrLayerUniquePtr &layer,
5003
+ QString &errCause )
5004
+ {
5005
+ GDALDatasetH hDS = OpenHelper ( dsName, updateMode, options );
5006
+ if ( !hDS )
5007
+ {
5008
+ errCause = QObject::tr ( " Cannot open %1." ).arg ( dsName );
5009
+ return nullptr ;
5010
+ }
5011
+ sMapDSNameToLastModifiedDate [dsName] = getLastModified ( dsName );
5012
+
5013
+ OGRLayerH hLayer = GDALDatasetGetLayerByName (
5014
+ hDS, layerName.toUtf8 ().constData () );
5015
+ if ( !hLayer )
5016
+ {
5017
+ errCause = QObject::tr ( " Cannot find layer %1." ).arg ( layerName );
5018
+ QgsOgrProviderUtils::GDALCloseWrapper ( hDS );
5019
+ return nullptr ;
5020
+ }
5021
+
5022
+ QgsOgrProviderUtils::DatasetWithLayers *ds =
5023
+ new QgsOgrProviderUtils::DatasetWithLayers;
5024
+ ds->hDS = hDS;
5025
+
5026
+ GDALDriverH driver = GDALGetDatasetDriver ( hDS );
5027
+ QString driverName = GDALGetDriverShortName ( driver );
5028
+ ds->canBeShared = canDriverShareSameDatasetAmongLayers ( driverName );
5029
+
5030
+ layer = QgsOgrLayer::CreateForLayer (
5031
+ ident, layerName, ds, hLayer );
5032
+ ds->setLayers [layerName] = layer.get ();
5033
+ return ds;
5034
+ }
4982
5035
4983
5036
QgsOgrLayerUniquePtr QgsOgrProviderUtils::getLayer ( const QString &dsName,
4984
5037
bool updateMode,
@@ -5018,6 +5071,8 @@ QgsOgrLayerUniquePtr QgsOgrProviderUtils::getLayer( const QString &dsName,
5018
5071
auto &datasetList = iter.value ();
5019
5072
Q_FOREACH ( QgsOgrProviderUtils::DatasetWithLayers *ds, datasetList )
5020
5073
{
5074
+ if ( !ds->canBeShared )
5075
+ continue ;
5021
5076
Q_ASSERT ( ds->refCount > 0 );
5022
5077
5023
5078
auto iter2 = ds->setLayers .find ( layerName );
@@ -5045,60 +5100,22 @@ QgsOgrLayerUniquePtr QgsOgrProviderUtils::getLayer( const QString &dsName,
5045
5100
5046
5101
// All existing DatasetWithLayers* already reference our layer of
5047
5102
// interest, so instantiate a new DatasetWithLayers*
5048
- GDALDatasetH hDS = OpenHelper ( dsName, updateMode, options );
5049
- if ( !hDS )
5050
- {
5051
- errCause = QObject::tr ( " Cannot open %1." ).arg ( dsName );
5052
- return nullptr ;
5053
- }
5054
- sMapDSNameToLastModifiedDate [dsName] = getLastModified ( dsName );
5055
-
5056
- OGRLayerH hLayer = GDALDatasetGetLayerByName (
5057
- hDS, layerName.toUtf8 ().constData () );
5058
- if ( !hLayer )
5059
- {
5060
- QgsOgrProviderUtils::GDALCloseWrapper ( hDS );
5061
- errCause = QObject::tr ( " Cannot find layer %1." ).arg ( layerName );
5062
- return nullptr ;
5063
- }
5064
-
5103
+ QgsOgrLayerUniquePtr layer;
5065
5104
QgsOgrProviderUtils::DatasetWithLayers *ds =
5066
- new QgsOgrProviderUtils::DatasetWithLayers;
5105
+ createDatasetWithLayers ( dsName, updateMode, options, layerName, ident, layer, errCause );
5106
+ if ( !ds )
5107
+ return nullptr ;
5067
5108
5068
5109
datasetList.push_back ( ds );
5069
5110
5070
- ds->hDS = hDS;
5071
-
5072
- QgsOgrLayerUniquePtr layer = QgsOgrLayer::CreateForLayer (
5073
- ident, layerName, ds, hLayer );
5074
- ds->setLayers [layerName] = layer.get ();
5075
5111
return layer;
5076
5112
}
5077
5113
5078
- GDALDatasetH hDS = OpenHelper ( dsName, updateMode, options );
5079
- if ( !hDS )
5080
- {
5081
- errCause = QObject::tr ( " Cannot open %1." ).arg ( dsName );
5082
- return nullptr ;
5083
- }
5084
- sMapDSNameToLastModifiedDate [dsName] = getLastModified ( dsName );
5085
-
5086
- OGRLayerH hLayer = GDALDatasetGetLayerByName (
5087
- hDS, layerName.toUtf8 ().constData () );
5088
- if ( !hLayer )
5089
- {
5090
- errCause = QObject::tr ( " Cannot find layer %1." ).arg ( layerName );
5091
- QgsOgrProviderUtils::GDALCloseWrapper ( hDS );
5092
- return nullptr ;
5093
- }
5094
-
5114
+ QgsOgrLayerUniquePtr layer;
5095
5115
QgsOgrProviderUtils::DatasetWithLayers *ds =
5096
- new QgsOgrProviderUtils::DatasetWithLayers;
5097
- ds->hDS = hDS;
5098
-
5099
- QgsOgrLayerUniquePtr layer = QgsOgrLayer::CreateForLayer (
5100
- ident, layerName, ds, hLayer );
5101
- ds->setLayers [layerName] = layer.get ();
5116
+ createDatasetWithLayers ( dsName, updateMode, options, layerName, ident, layer, errCause );
5117
+ if ( !ds )
5118
+ return nullptr ;
5102
5119
5103
5120
QList<DatasetWithLayers *> datasetList;
5104
5121
datasetList.push_back ( ds );
@@ -5192,6 +5209,11 @@ void QgsOgrProviderUtils::releaseDataset( QgsOgrDataset *&ds )
5192
5209
ds = nullptr ;
5193
5210
}
5194
5211
5212
+ bool QgsOgrProviderUtils::canDriverShareSameDatasetAmongLayers ( const QString &driverName )
5213
+ {
5214
+ return driverName != QStringLiteral ( " OSM" );
5215
+ }
5216
+
5195
5217
5196
5218
QgsOgrDatasetSharedPtr QgsOgrDataset::create ( const QgsOgrProviderUtils::DatasetIdentification &ident,
5197
5219
QgsOgrProviderUtils::DatasetWithLayers *ds )
0 commit comments