Skip to content

Commit

Permalink
Dirty save points so that undo/redo works correctly + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed Sep 9, 2021
1 parent f55c705 commit 176a35e
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/providers/mssql/qgsmssqlprovider.cpp
Expand Up @@ -1378,6 +1378,9 @@ bool QgsMssqlProvider::addFeatures( QgsFeatureList &flist, Flags flags )
}
}

if ( mTransaction )
mTransaction->dirtyLastSavePoint();

return true;
}

Expand Down Expand Up @@ -1422,6 +1425,10 @@ bool QgsMssqlProvider::addAttributes( const QList<QgsField> &attributes )
}

loadFields();

if ( mTransaction )
mTransaction->dirtyLastSavePoint();

return true;
}

Expand Down Expand Up @@ -1452,6 +1459,10 @@ bool QgsMssqlProvider::deleteAttributes( const QgsAttributeIds &attributes )

query.finish();
loadFields();

if ( mTransaction )
mTransaction->dirtyLastSavePoint();

return true;
}

Expand Down Expand Up @@ -1607,6 +1618,9 @@ bool QgsMssqlProvider::changeAttributeValues( const QgsChangedAttributesMap &att
}
}

if ( mTransaction )
mTransaction->dirtyLastSavePoint();

return true;
}

Expand Down Expand Up @@ -1677,6 +1691,9 @@ bool QgsMssqlProvider::changeGeometryValues( const QgsGeometryMap &geometry_map
}
}

if ( mTransaction )
mTransaction->dirtyLastSavePoint();

return true;
}

Expand Down Expand Up @@ -1704,7 +1721,11 @@ bool QgsMssqlProvider::deleteFeatures( const QgsFeatureIds &ids )
if ( query.exec( statement ) )
{
if ( query.numRowsAffected() == ids.size() )
{
if ( mTransaction )
mTransaction->dirtyLastSavePoint();
return true;
}

pushError( tr( "Only %1 of %2 features deleted" ).arg( query.numRowsAffected() ).arg( ids.size() ) );
}
Expand Down Expand Up @@ -1735,7 +1756,11 @@ bool QgsMssqlProvider::deleteFeatures( const QgsFeatureIds &ids )
}

if ( i == ids.size() )
{
if ( mTransaction )
mTransaction->dirtyLastSavePoint();
return true;
}

if ( i > 0 )
pushError( tr( "Only %1 of %2 features deleted" ).arg( i ).arg( ids.size() ) );
Expand Down
98 changes: 98 additions & 0 deletions tests/src/providers/testqgsmssqlprovider.cpp
Expand Up @@ -47,6 +47,9 @@ class TestQgsMssqlProvider : public QObject

void projectTransaction();

void transactionTwoLayers();
void transactionUndoRedo();

private:

QString mDbConn;
Expand Down Expand Up @@ -189,5 +192,100 @@ void TestQgsMssqlProvider::projectTransaction()
QCOMPARE( vectorLayerPoint->featureCount(), 5 );
}

void TestQgsMssqlProvider::transactionTwoLayers()
{
QString uriPoint( mDbConn + QStringLiteral( " key = \"pk\" srid=4326 type=POINT schema=\"qgis_test\" table=\"someData\" (geom) sql=" ) );
QgsVectorLayer *vectorLayerPoint1 = new QgsVectorLayer( uriPoint, QStringLiteral( "point_layer_1" ), QStringLiteral( "mssql" ) );
QgsVectorLayer *vectorLayerPoint2 = new QgsVectorLayer( uriPoint, QStringLiteral( "point_layer_2" ), QStringLiteral( "mssql" ) );

QgsProject project;
project.addMapLayer( vectorLayerPoint1 );
project.addMapLayer( vectorLayerPoint2 );

// point to be added to the point layer
QgsFeature feat;
feat.setFields( vectorLayerPoint1->fields(), true );
feat.setAttribute( 0, 123 );
feat.setGeometry( QgsGeometry( new QgsPoint( -123, 123 ) ) );

// 1. without transaction, try to add a feature to the first layer -> the other layer is not affected

QVERIFY( vectorLayerPoint1->startEditing() );

vectorLayerPoint1->addFeature( feat );

QCOMPARE( vectorLayerPoint1->featureCount(), 6 );
QCOMPARE( vectorLayerPoint2->featureCount(), 5 );

vectorLayerPoint1->rollBack();

// 2. with transaction, try to add a feature to the first layer -> both layers are affected

project.setAutoTransaction( true );

QVERIFY( vectorLayerPoint1->startEditing() );

vectorLayerPoint1->addFeature( feat );

QCOMPARE( vectorLayerPoint1->featureCount(), 6 );
QCOMPARE( vectorLayerPoint2->featureCount(), 6 );

vectorLayerPoint1->rollBack();

QCOMPARE( vectorLayerPoint1->featureCount(), 5 );
QCOMPARE( vectorLayerPoint2->featureCount(), 5 );
}

void TestQgsMssqlProvider::transactionUndoRedo()
{
QString uriPoint( mDbConn + QStringLiteral( " key = \"pk\" srid=4326 type=POINT schema=\"qgis_test\" table=\"someData\" (geom) sql=" ) );
QgsVectorLayer *vectorLayerPoint1 = new QgsVectorLayer( uriPoint, QStringLiteral( "point_layer_1" ), QStringLiteral( "mssql" ) );
//QgsVectorLayer *vectorLayerPoint2 = new QgsVectorLayer( uriPoint, QStringLiteral( "point_layer_2" ), QStringLiteral( "mssql" ) );

QgsProject project;
project.addMapLayer( vectorLayerPoint1 );
//project.addMapLayer( vectorLayerPoint2 );

// point to be added to the point layer
QgsFeature feat1;
feat1.setFields( vectorLayerPoint1->fields(), true );
feat1.setAttribute( 0, 111 );
feat1.setGeometry( QgsGeometry( new QgsPoint( -111, 111 ) ) );

QgsFeature feat2;
feat2.setFields( vectorLayerPoint1->fields(), true );
feat2.setAttribute( 0, 222 );
feat2.setGeometry( QgsGeometry( new QgsPoint( -222, 222 ) ) );

// 1. without transaction

project.setAutoTransaction( true );

QVERIFY( vectorLayerPoint1->startEditing() );

QCOMPARE( vectorLayerPoint1->undoStack()->count(), 0 );

vectorLayerPoint1->addFeature( feat1 );

vectorLayerPoint1->addFeature( feat2 );

QCOMPARE( vectorLayerPoint1->undoStack()->count(), 2 );

QCOMPARE( vectorLayerPoint1->featureCount(), 7 );
vectorLayerPoint1->undoStack()->undo();
QCOMPARE( vectorLayerPoint1->featureCount(), 6 );
vectorLayerPoint1->undoStack()->undo();
QCOMPARE( vectorLayerPoint1->featureCount(), 5 );
vectorLayerPoint1->undoStack()->redo();
QCOMPARE( vectorLayerPoint1->featureCount(), 6 );
vectorLayerPoint1->undoStack()->redo();
QCOMPARE( vectorLayerPoint1->featureCount(), 7 );

vectorLayerPoint1->rollBack();

// 2. with transaction, try to add a feature to the first layer -> both layers are affected

}

QGSTEST_MAIN( TestQgsMssqlProvider )
#include "testqgsmssqlprovider.moc"

0 comments on commit 176a35e

Please sign in to comment.