Skip to content

Commit 16a421c

Browse files
landamm-kuhn
authored andcommitted
OGR data provider: use transactions when changing attributes and geometries (if possible) (fixes #16216)
1 parent 04508fc commit 16a421c

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/providers/ogr/qgsogrprovider.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,31 @@ bool QgsOgrProvider::renameAttributes( const QgsFieldNameMap &renamedAttributes
15201520
return result;
15211521
}
15221522

1523+
bool QgsOgrProvider::startTransaction()
1524+
{
1525+
bool inTransaction = false;
1526+
if ( OGR_L_TestCapability( ogrLayer, OLCTransactions ) )
1527+
{
1528+
// A transaction might already be active, so be robust on failed
1529+
// StartTransaction.
1530+
CPLPushErrorHandler( CPLQuietErrorHandler );
1531+
inTransaction = ( OGR_L_StartTransaction( ogrLayer ) == OGRERR_NONE );
1532+
CPLPopErrorHandler();
1533+
}
1534+
return inTransaction;
1535+
}
1536+
1537+
1538+
bool QgsOgrProvider::commitTransaction()
1539+
{
1540+
if ( OGR_L_CommitTransaction( ogrLayer ) != OGRERR_NONE )
1541+
{
1542+
pushError( tr( "OGR error committing transaction: %1" ).arg( CPLGetLastErrorMsg() ) );
1543+
return false;
1544+
}
1545+
return true;
1546+
}
1547+
15231548

15241549
bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map )
15251550
{
@@ -1533,6 +1558,8 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
15331558

15341559
setRelevantFields( ogrLayer, true, attributeIndexes() );
15351560

1561+
const bool inTransaction = startTransaction();
1562+
15361563
for ( QgsChangedAttributesMap::const_iterator it = attr_map.begin(); it != attr_map.end(); ++it )
15371564
{
15381565
QgsFeatureId fid = it.key();
@@ -1646,6 +1673,11 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
16461673
OGR_F_Destroy( of );
16471674
}
16481675

1676+
if ( inTransaction )
1677+
{
1678+
commitTransaction();
1679+
}
1680+
16491681
if ( OGR_L_SyncToDisk( ogrLayer ) != OGRERR_NONE )
16501682
{
16511683
pushError( tr( "OGR error syncing to disk: %1" ).arg( CPLGetLastErrorMsg() ) );
@@ -1661,6 +1693,8 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
16611693

16621694
setRelevantFields( ogrLayer, true, attributeIndexes() );
16631695

1696+
const bool inTransaction = startTransaction();
1697+
16641698
for ( QgsGeometryMap::const_iterator it = geometry_map.constBegin(); it != geometry_map.constEnd(); ++it )
16651699
{
16661700
if ( FID_TO_NUMBER( it.key() ) > std::numeric_limits<long>::max() )
@@ -1729,6 +1763,12 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
17291763

17301764
OGR_F_Destroy( theOGRFeature );
17311765
}
1766+
1767+
if ( inTransaction )
1768+
{
1769+
commitTransaction();
1770+
}
1771+
17321772
QgsOgrConnPool::instance()->invalidateConnections( dataSourceUri() );
17331773
return syncToDisc();
17341774
}

src/providers/ogr/qgsogrprovider.h

+6
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ class QgsOgrProvider : public QgsVectorDataProvider
167167
unsigned char *getGeometryPointer( OGRFeatureH fet );
168168
QString ogrWkbGeometryTypeName( OGRwkbGeometryType type ) const;
169169

170+
//! Starts a transaction if possible and return true in that case
171+
bool startTransaction();
172+
173+
//! Commits a transaction
174+
bool commitTransaction();
175+
170176
QgsFields mAttributeFields;
171177

172178
//! Map of field index to default value

0 commit comments

Comments
 (0)