Skip to content

Commit

Permalink
OGR data provider: use transactions when changing attributes and geom…
Browse files Browse the repository at this point in the history
…etries (if possible) (fixes #16216)
  • Loading branch information
landam authored and m-kuhn committed Mar 15, 2017
1 parent 04508fc commit 16a421c
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -1520,6 +1520,31 @@ bool QgsOgrProvider::renameAttributes( const QgsFieldNameMap &renamedAttributes
return result;
}

bool QgsOgrProvider::startTransaction()
{
bool inTransaction = false;
if ( OGR_L_TestCapability( ogrLayer, OLCTransactions ) )
{
// A transaction might already be active, so be robust on failed
// StartTransaction.
CPLPushErrorHandler( CPLQuietErrorHandler );
inTransaction = ( OGR_L_StartTransaction( ogrLayer ) == OGRERR_NONE );
CPLPopErrorHandler();
}
return inTransaction;
}


bool QgsOgrProvider::commitTransaction()
{
if ( OGR_L_CommitTransaction( ogrLayer ) != OGRERR_NONE )
{
pushError( tr( "OGR error committing transaction: %1" ).arg( CPLGetLastErrorMsg() ) );
return false;
}
return true;
}


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

setRelevantFields( ogrLayer, true, attributeIndexes() );

const bool inTransaction = startTransaction();

for ( QgsChangedAttributesMap::const_iterator it = attr_map.begin(); it != attr_map.end(); ++it )
{
QgsFeatureId fid = it.key();
Expand Down Expand Up @@ -1646,6 +1673,11 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
OGR_F_Destroy( of );
}

if ( inTransaction )
{
commitTransaction();
}

if ( OGR_L_SyncToDisk( ogrLayer ) != OGRERR_NONE )
{
pushError( tr( "OGR error syncing to disk: %1" ).arg( CPLGetLastErrorMsg() ) );
Expand All @@ -1661,6 +1693,8 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )

setRelevantFields( ogrLayer, true, attributeIndexes() );

const bool inTransaction = startTransaction();

for ( QgsGeometryMap::const_iterator it = geometry_map.constBegin(); it != geometry_map.constEnd(); ++it )
{
if ( FID_TO_NUMBER( it.key() ) > std::numeric_limits<long>::max() )
Expand Down Expand Up @@ -1729,6 +1763,12 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )

OGR_F_Destroy( theOGRFeature );
}

if ( inTransaction )
{
commitTransaction();
}

QgsOgrConnPool::instance()->invalidateConnections( dataSourceUri() );
return syncToDisc();
}
Expand Down
6 changes: 6 additions & 0 deletions src/providers/ogr/qgsogrprovider.h
Expand Up @@ -167,6 +167,12 @@ class QgsOgrProvider : public QgsVectorDataProvider
unsigned char *getGeometryPointer( OGRFeatureH fet );
QString ogrWkbGeometryTypeName( OGRwkbGeometryType type ) const;

//! Starts a transaction if possible and return true in that case
bool startTransaction();

//! Commits a transaction
bool commitTransaction();

QgsFields mAttributeFields;

//! Map of field index to default value
Expand Down

0 comments on commit 16a421c

Please sign in to comment.