Skip to content

Commit 06e336b

Browse files
authoredMar 20, 2017
Merge pull request #4285 from rouault/ogr_fast_changeattributes_2.18
[2.18] OGR data provider: use transactions when changing attributes and geometries (if possible) (#16216)
2 parents af74635 + 6becea7 commit 06e336b

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed
 

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,8 @@ bool QgsOgrProvider::addFeatures( QgsFeatureList & flist )
13061306

13071307
setRelevantFields( ogrLayer, true, attributeIndexes() );
13081308

1309+
const bool inTransaction = startTransaction();
1310+
13091311
bool returnvalue = true;
13101312
for ( QgsFeatureList::iterator it = flist.begin(); it != flist.end(); ++it )
13111313
{
@@ -1315,6 +1317,11 @@ bool QgsOgrProvider::addFeatures( QgsFeatureList & flist )
13151317
}
13161318
}
13171319

1320+
if ( inTransaction )
1321+
{
1322+
commitTransaction();
1323+
}
1324+
13181325
if ( !syncToDisc() )
13191326
{
13201327
returnvalue = false;
@@ -1521,6 +1528,31 @@ bool QgsOgrProvider::renameAttributes( const QgsFieldNameMap& renamedAttributes
15211528
#endif
15221529
}
15231530

1531+
bool QgsOgrProvider::startTransaction()
1532+
{
1533+
bool inTransaction = false;
1534+
if ( OGR_L_TestCapability( ogrLayer, OLCTransactions ) )
1535+
{
1536+
// A transaction might already be active, so be robust on failed
1537+
// StartTransaction.
1538+
CPLPushErrorHandler( CPLQuietErrorHandler );
1539+
inTransaction = ( OGR_L_StartTransaction( ogrLayer ) == OGRERR_NONE );
1540+
CPLPopErrorHandler();
1541+
}
1542+
return inTransaction;
1543+
}
1544+
1545+
1546+
bool QgsOgrProvider::commitTransaction()
1547+
{
1548+
if ( OGR_L_CommitTransaction( ogrLayer ) != OGRERR_NONE )
1549+
{
1550+
pushError( tr( "OGR error committing transaction: %1" ).arg( CPLGetLastErrorMsg() ) );
1551+
return false;
1552+
}
1553+
return true;
1554+
}
1555+
15241556

15251557
bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_map )
15261558
{
@@ -1534,6 +1566,8 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
15341566

15351567
setRelevantFields( ogrLayer, true, attributeIndexes() );
15361568

1569+
const bool inTransaction = startTransaction();
1570+
15371571
for ( QgsChangedAttributesMap::const_iterator it = attr_map.begin(); it != attr_map.end(); ++it )
15381572
{
15391573
QgsFeatureId fid = it.key();
@@ -1649,6 +1683,11 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
16491683
OGR_F_Destroy( of );
16501684
}
16511685

1686+
if ( inTransaction )
1687+
{
1688+
commitTransaction();
1689+
}
1690+
16521691
if ( OGR_L_SyncToDisk( ogrLayer ) != OGRERR_NONE )
16531692
{
16541693
pushError( tr( "OGR error syncing to disk: %1" ).arg( CPLGetLastErrorMsg() ) );
@@ -1664,6 +1703,8 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
16641703

16651704
setRelevantFields( ogrLayer, true, attributeIndexes() );
16661705

1706+
const bool inTransaction = startTransaction();
1707+
16671708
for ( QgsGeometryMap::const_iterator it = geometry_map.constBegin(); it != geometry_map.constEnd(); ++it )
16681709
{
16691710
if ( FID_TO_NUMBER( it.key() ) > std::numeric_limits<long>::max() )
@@ -1731,6 +1772,12 @@ bool QgsOgrProvider::changeGeometryValues( const QgsGeometryMap &geometry_map )
17311772

17321773
OGR_F_Destroy( theOGRFeature );
17331774
}
1775+
1776+
if ( inTransaction )
1777+
{
1778+
commitTransaction();
1779+
}
1780+
17341781
QgsOgrConnPool::instance()->invalidateConnections( dataSourceUri() );
17351782
return syncToDisc();
17361783
}
@@ -1780,6 +1827,8 @@ bool QgsOgrProvider::deleteFeatures( const QgsFeatureIds & id )
17801827
if ( !doInitialActionsForEdition() )
17811828
return false;
17821829

1830+
const bool inTransaction = startTransaction();
1831+
17831832
bool returnvalue = true;
17841833
for ( QgsFeatureIds::const_iterator it = id.begin(); it != id.end(); ++it )
17851834
{
@@ -1789,6 +1838,11 @@ bool QgsOgrProvider::deleteFeatures( const QgsFeatureIds & id )
17891838
}
17901839
}
17911840

1841+
if ( inTransaction )
1842+
{
1843+
commitTransaction();
1844+
}
1845+
17921846
if ( !syncToDisc() )
17931847
{
17941848
returnvalue = false;

‎src/providers/ogr/qgsogrprovider.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,13 @@ class QgsOgrProvider : public QgsVectorDataProvider
305305
private:
306306
unsigned char *getGeometryPointer( OGRFeatureH fet );
307307
QString ogrWkbGeometryTypeName( OGRwkbGeometryType type ) const;
308+
309+
//! Starts a transaction if possible and return true in that case
310+
bool startTransaction();
311+
312+
//! Commits a transaction
313+
bool commitTransaction();
314+
308315
QgsFields mAttributeFields;
309316
bool mFirstFieldIsFid;
310317
OGRDataSourceH ogrDataSource;

0 commit comments

Comments
 (0)
Please sign in to comment.