Skip to content
Permalink
Browse files
OGR data provider: use transactions when changing attributes and geom…
…etries (if possible) (fixes #16216)
  • Loading branch information
landam authored and m-kuhn committed Mar 15, 2017
1 parent 04508fc commit 16a421c7a8292b4e697363e5c57634ff57025e3a
Showing with 46 additions and 0 deletions.
  1. +40 −0 src/providers/ogr/qgsogrprovider.cpp
  2. +6 −0 src/providers/ogr/qgsogrprovider.h
@@ -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 )
{
@@ -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();
@@ -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() ) );
@@ -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() )
@@ -1729,6 +1763,12 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )

OGR_F_Destroy( theOGRFeature );
}

if ( inTransaction )
{
commitTransaction();
}

QgsOgrConnPool::instance()->invalidateConnections( dataSourceUri() );
return syncToDisc();
}
@@ -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

0 comments on commit 16a421c

Please sign in to comment.