Fix QgsVectorFileWriter use of transactions while writing

Previously the writer was only using transactions in some
cases (when calling the static writeAsVectorFormat method).

This changes the writer to always use a transaction when
possible.

Fixes the map renderer job test using gpkg from timing out after
taking forever to running twice the speed of the shapefile
version. Similar benefits across other parts of qgis,
which are writing files without using the static method, e.g.
processing.
This commit is contained in:
Nyall Dawson 2017-10-22 14:22:50 +10:00
parent 10a2867cab
commit 51fb66541d
3 changed files with 19 additions and 18 deletions

View File

@ -630,6 +630,13 @@ void QgsVectorFileWriter::init( QString vectorFileName,
if ( newFilename )
*newFilename = vectorFileName;
// enabling transaction on databases that support it
mUsingTransaction = true;
if ( OGRERR_NONE != OGR_L_StartTransaction( mLayer ) )
{
mUsingTransaction = false;
}
}
OGRGeometryH QgsVectorFileWriter::createEmptyGeometry( QgsWkbTypes::Type wkbType )
@ -2219,6 +2226,15 @@ bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
QgsVectorFileWriter::~QgsVectorFileWriter()
{
if ( mUsingTransaction )
{
if ( OGRERR_NONE != OGR_L_CommitTransaction( mLayer ) )
{
QgsDebugMsg( "Error while committing transaction on OGRLayer." );
}
}
if ( mDS )
{
OGR_DS_Destroy( mDS );
@ -2545,15 +2561,6 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer *layer,
writer->startRender( layer );
// enabling transaction on databases that support it
bool transactionsEnabled = true;
if ( OGRERR_NONE != OGR_L_StartTransaction( writer->mLayer ) )
{
QgsDebugMsg( "Error when trying to enable transactions on OGRLayer." );
transactionsEnabled = false;
}
writer->resetMap( attributes );
// Reset mFields to layer fields, and not just exported fields
writer->mFields = layer->fields();
@ -2641,14 +2648,6 @@ QgsVectorFileWriter::writeAsVectorFormat( QgsVectorLayer *layer,
n++;
}
if ( transactionsEnabled )
{
if ( OGRERR_NONE != OGR_L_CommitTransaction( writer->mLayer ) )
{
QgsDebugMsg( "Error while committing transaction on OGRLayer." );
}
}
writer->stopRender( layer );
delete writer;

View File

@ -676,6 +676,8 @@ class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
QgsRenderContext mRenderContext;
bool mUsingTransaction = false;
static QMap<QString, MetaData> initMetaData();
void createSymbolLayerTable( QgsVectorLayer *vl, const QgsCoordinateTransform &ct, OGRDataSourceH ds );
OGRFeatureH createFeature( const QgsFeature &feature );

View File

@ -109,7 +109,7 @@ void TestQgsMapRendererJob::initTestCase()
QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
QString myTestDataDir = myDataDir + '/';
QString myTmpDir = QDir::tempPath() + '/';
QString myFileName = myTmpDir + "maprender_testdata.shp";
QString myFileName = myTmpDir + "maprender_testdata.gpkg";
//copy over the default qml for our generated layer
QString myQmlFileName = myTestDataDir + "maprender_testdata.qml";
QFile::remove( myTmpDir + "maprender_testdata.qml" );