Skip to content

Commit

Permalink
Merge pull request #1830 from manisandro/transaction
Browse files Browse the repository at this point in the history
[FEATURE] Transactional editing for postgres layers
  • Loading branch information
mhugent committed Jan 20, 2015
2 parents cae4eb3 + 7b31a17 commit a2a82d2
Show file tree
Hide file tree
Showing 26 changed files with 1,074 additions and 201 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -12,6 +12,7 @@

%Include qgis.sip

%Include qgstransaction.sip
%Include qgsapplication.sip
%Include qgsattributeaction.sip
%Include qgsbrowsermodel.sip
Expand Down
51 changes: 51 additions & 0 deletions python/core/qgstransaction.sip
@@ -0,0 +1,51 @@
/**
* This class allows to include a set of layers in a database-side transaction,
* provided the layer data providers support transactions and are compatible
* with each other.
*
* Only layers which are not in edit mode can be included in a transaction,
* and all layers need to be in read-only mode for a transaction to be committed
* or rolled back.
*
* Layers cannot only be included in one transaction at a time.
*
* When editing layers which are part of a transaction group, all changes are
* sent directly to the data provider (bypassing the undo/redo stack), and the
* changes can either be committed or rolled back on the database side via the
* QgsTransaction::commit and QgsTransaction::rollback methods.
*
* As long as the transaction is active, the state of all layer features reflects
* the current state in the transaction.
*
* Edits on features can get rejected if another conflicting transaction is active.
*/
class QgsTransaction /Abstract/
{
%TypeHeaderCode
#include <qgstransaction.h>
%End
public:
/** Creates a transaction for the specified connection string and provider */
static QgsTransaction* create( const QString& connString, const QString& providerKey ) /Factory/;

/** Creates a transaction which includes the specified layers. Connection string
* and data provider are taken from the first layer */
static QgsTransaction* create( const QStringList& layerIds ) /Factory/;

virtual ~QgsTransaction();

/** Add layer to the transaction. The layer must not be in edit mode. The transaction must not be active. */
bool addLayer( const QString& layerId );

/** Begin transaction */
bool begin( QString& errorMsg );

/** Commit transaction. All layers need to be in read-only mode. */
bool commit( QString& errorMsg );

/** Roll back transaction. All layers need to be in read-only mode. */
bool rollback( QString& errorMsg );

/** Executes sql */
virtual bool executeSql( const QString& sql, QString& error ) = 0;
};
2 changes: 2 additions & 0 deletions python/core/qgsvectordataprovider.sip
Expand Up @@ -313,6 +313,8 @@ class QgsVectorDataProvider : QgsDataProvider

static QVariant convertValue( QVariant::Type type, QString value );

virtual QgsTransaction* transaction() const;

protected:
void clearMinMaxCache();
void fillMinMaxCache();
Expand Down
2 changes: 1 addition & 1 deletion python/core/qgsvectorlayer.sip
Expand Up @@ -578,7 +578,7 @@ class QgsVectorLayer : QgsMapLayer
/** Deletes the selected features
* @return true in case of success and false otherwise
*/
bool deleteSelectedFeatures();
bool deleteSelectedFeatures(int* deletedCount = 0);

/**Adds a ring to polygon/multipolygon features
@return
Expand Down
13 changes: 7 additions & 6 deletions src/app/qgisapp.cpp
Expand Up @@ -5253,30 +5253,31 @@ void QgisApp::deleteSelected( QgsMapLayer *layer, QWidget* parent, bool promptCo
}

//validate selection
int numberOfDeletedFeatures = vlayer->selectedFeaturesIds().size();
if ( numberOfDeletedFeatures == 0 )
int numberOfSelectedFeatures = vlayer->selectedFeaturesIds().size();
if ( numberOfSelectedFeatures == 0 )
{
messageBar()->pushMessage( tr( "No Features Selected" ),
tr( "The current layer has no selected features" ),
QgsMessageBar::INFO, messageTimeout() );
return;
}
//display a warning
if ( promptConfirmation && QMessageBox::warning( parent, tr( "Delete features" ), tr( "Delete %n feature(s)?", "number of features to delete", numberOfDeletedFeatures ), QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
if ( promptConfirmation && QMessageBox::warning( parent, tr( "Delete features" ), tr( "Delete %n feature(s)?", "number of features to delete", numberOfSelectedFeatures ), QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Cancel )
{
return;
}

vlayer->beginEditCommand( tr( "Features deleted" ) );
if ( !vlayer->deleteSelectedFeatures() )
int deletedCount = 0;
if ( !vlayer->deleteSelectedFeatures( &deletedCount ) )
{
messageBar()->pushMessage( tr( "Problem deleting features" ),
tr( "A problem occured during deletion of features" ),
tr( "A problem occured during deletion of %1 feature(s)" ).arg( numberOfSelectedFeatures - deletedCount ),
QgsMessageBar::WARNING );
}
else
{
showStatusMessage( tr( "%n feature(s) deleted.", "number of features deleted", numberOfDeletedFeatures ) );
showStatusMessage( tr( "%n feature(s) deleted.", "number of features deleted", numberOfSelectedFeatures ) );
}

vlayer->endEditCommand();
Expand Down
20 changes: 14 additions & 6 deletions src/core/CMakeLists.txt
Expand Up @@ -155,12 +155,14 @@ SET(QGIS_CORE_SRCS
qgssnapper.cpp
qgssnappingutils.cpp
qgsspatialindex.cpp
qgstransaction.cpp
qgstolerance.cpp
qgsvectordataprovider.cpp
qgsvectorfilewriter.cpp
qgsvectorlayer.cpp
qgsvectorlayercache.cpp
qgsvectorlayereditbuffer.cpp
qgsvectorlayereditpassthrough.cpp
qgsvectorlayereditutils.cpp
qgsvectorlayerfeatureiterator.cpp
qgsvectorlayerimport.cpp
Expand Down Expand Up @@ -190,7 +192,7 @@ SET(QGIS_CORE_SRCS
composer/qgscomposermapoverview.cpp
composer/qgscomposertable.cpp
composer/qgscomposertablev2.cpp
composer/qgscomposertablecolumn.cpp
composer/qgscomposertablecolumn.cpp
composer/qgscomposerattributetable.cpp
composer/qgscomposerattributetablev2.cpp
composer/qgscomposerattributetablemodel.cpp
Expand All @@ -213,7 +215,7 @@ SET(QGIS_CORE_SRCS
composer/qgscomposermultiframe.cpp
composer/qgscomposermodel.cpp
composer/qgscomposition.cpp

dxf/qgsdxfexport.cpp
dxf/qgsdxfpaintdevice.cpp
dxf/qgsdxfpaintengine.cpp
Expand Down Expand Up @@ -271,7 +273,7 @@ SET(QGIS_CORE_SRCS
raster/qgssinglebandgrayrenderer.cpp
raster/qgssinglebandpseudocolorrenderer.cpp
raster/qgsbrightnesscontrastfilter.cpp
raster/qgshuesaturationfilter.cpp
raster/qgshuesaturationfilter.cpp
)

IF(ENABLE_MODELTEST)
Expand Down Expand Up @@ -364,6 +366,7 @@ SET(QGIS_CORE_MOC_HDRS
qgsrelationmanager.h
qgssnappingutils.h
qgsvectorlayer.h
qgsvectorlayereditpassthrough.h
qgsvectorlayereditbuffer.h
qgsnetworkaccessmanager.h
qgsvectordataprovider.h
Expand All @@ -382,14 +385,14 @@ SET(QGIS_CORE_MOC_HDRS
composer/qgscomposerobject.h
composer/qgscomposeritem.h
composer/qgscomposeritemgroup.h
composer/qgscomposermousehandles.h
composer/qgscomposermousehandles.h
composer/qgscomposerlabel.h
composer/qgscomposershape.h
composer/qgscomposerattributetable.h
composer/qgscomposerattributetablev2.h
composer/qgscomposerattributetablemodel.h
composer/qgscomposerattributetablemodelv2.h
composer/qgscomposertable.h
composer/qgscomposerattributetablemodelv2.h
composer/qgscomposertable.h
composer/qgscomposertablev2.h
composer/qgscomposertablecolumn.h
composer/qgscomposerhtml.h
Expand Down Expand Up @@ -463,6 +466,8 @@ SET(QGIS_CORE_HDRS
qgsclipper.h
qgscolorscheme.h
qgscolorschemeregistry.h
qgsconnectionpool.h
qgscontexthelp.h
qgscoordinatereferencesystem.h
qgscrscache.h
qgscsexception.h
Expand Down Expand Up @@ -533,6 +538,9 @@ SET(QGIS_CORE_HDRS
qgssnappingutils.h
qgsspatialindex.h
qgstolerance.h
qgstransaction.h
qgsvectordataprovider.h
qgsvectorlayercache.h
qgsvectorfilewriter.h
qgsvectorlayereditutils.h
qgsvectorlayerfeatureiterator.h
Expand Down

0 comments on commit a2a82d2

Please sign in to comment.