Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgstransaction.h 3 : : ---------------- 4 : : begin : May 5, 2014 5 : : copyright : (C) 2014 by Marco Hugentobler 6 : : email : marco dot hugentobler at sourcepole dot ch 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #ifndef QGSTRANSACTION_H 19 : : #define QGSTRANSACTION_H 20 : : 21 : : #include <QSet> 22 : : #include "qgis_sip.h" 23 : : #include <QString> 24 : : #include <QObject> 25 : : #include <QStack> 26 : : 27 : : #include "qgis_core.h" 28 : : #include "qgis_sip.h" 29 : : 30 : : class QgsVectorDataProvider; 31 : : class QgsVectorLayer; 32 : : 33 : : /** 34 : : * \ingroup core 35 : : * \brief This class allows including a set of layers in a database-side transaction, 36 : : * provided the layer data providers support transactions and are compatible 37 : : * with each other. 38 : : * 39 : : * Only layers which are not in edit mode can be included in a transaction, 40 : : * and all layers need to be in read-only mode for a transaction to be committed 41 : : * or rolled back. 42 : : * 43 : : * Layers can only be included in one transaction at a time. 44 : : * 45 : : * When editing layers which are part of a transaction group, all changes are 46 : : * sent directly to the data provider (bypassing the undo/redo stack), and the 47 : : * changes can either be committed or rolled back on the database side via the 48 : : * QgsTransaction::commit and QgsTransaction::rollback methods. 49 : : * 50 : : * As long as the transaction is active, the state of all layer features reflects 51 : : * the current state in the transaction. 52 : : * 53 : : * Edits on features can get rejected if another conflicting transaction is active. 54 : : */ 55 : : 56 : : class CORE_EXPORT QgsTransaction : public QObject SIP_ABSTRACT 57 : : { 58 : 0 : Q_OBJECT 59 : : 60 : : public: 61 : : 62 : : /** 63 : : * Create a transaction for the specified connection string \a connString 64 : : * and provider with \a providerKey. 65 : : */ 66 : : static QgsTransaction *create( const QString &connString, const QString &providerKey ) SIP_FACTORY; 67 : : 68 : : /** 69 : : * Create a transaction which includes the \a layers. 70 : : * All layers are expected to have the same connection string and data 71 : : * provider. 72 : : */ 73 : : static QgsTransaction *create( const QSet<QgsVectorLayer *> &layers ) SIP_FACTORY; 74 : : 75 : : ~QgsTransaction() override; 76 : : 77 : : /** 78 : : * Add the \a layer to the transaction. The layer must not be 79 : : * in edit mode and the connection string must match. 80 : : */ 81 : : bool addLayer( QgsVectorLayer *layer ); 82 : : 83 : : /** 84 : : * Begin transaction 85 : : * The \a statementTimeout (in seconds) specifies how long an sql statement 86 : : * is allowed to block QGIS before it is aborted. 87 : : * Statements can block, if multiple transactions are active and a 88 : : * statement would produce a conflicting state. In these cases, the 89 : : * statements block until the conflicting transaction is committed or 90 : : * rolled back. 91 : : * Some providers might not honour the statement timeout. 92 : : */ 93 : : bool begin( QString &errorMsg SIP_OUT, int statementTimeout = 20 ); 94 : : 95 : : /** 96 : : * Commit transaction. 97 : : */ 98 : : bool commit( QString &errorMsg SIP_OUT ); 99 : : 100 : : /** 101 : : * Roll back transaction. 102 : : */ 103 : : bool rollback( QString &errorMsg SIP_OUT ); 104 : : 105 : : /** 106 : : * Execute the \a sql string. 107 : : * 108 : : * \param sql The sql query to execute 109 : : * \param error The error message 110 : : * \param isDirty Flag to indicate if the underlying data will be modified 111 : : * \param name Name of the transaction ( only used if `isDirty` is TRUE) 112 : : * 113 : : * \returns TRUE if everything is OK, FALSE otherwise 114 : : */ 115 : : virtual bool executeSql( const QString &sql, QString &error SIP_OUT, bool isDirty = false, const QString &name = QString() ) = 0; 116 : : 117 : : /** 118 : : * Checks if the provider of a given \a layer supports transactions. 119 : : */ 120 : : static bool supportsTransaction( const QgsVectorLayer *layer ); 121 : : 122 : : /** 123 : : * creates a save point 124 : : * returns empty string on error 125 : : * returns the last created savepoint if it's not dirty 126 : : * \since QGIS 3.0 127 : : */ 128 : : QString createSavepoint( QString &error SIP_OUT ); 129 : : 130 : : /** 131 : : * creates a save point 132 : : * returns empty string on error 133 : : * \since QGIS 3.0 134 : : */ 135 : : QString createSavepoint( const QString &savePointId, QString &error SIP_OUT ); 136 : : 137 : : /** 138 : : * rollback to save point, the save point is maintained and is "undertied" 139 : : * \since QGIS 3.0 140 : : */ 141 : : bool rollbackToSavepoint( const QString &name, QString &error SIP_OUT ); 142 : : 143 : : /** 144 : : * dirty save point such that next call to createSavepoint will create a new one 145 : : * \since QGIS 3.0 146 : : */ 147 : : void dirtyLastSavePoint(); 148 : : 149 : : /** 150 : : * returns savepoints 151 : : * \since QGIS 3.0 152 : : */ 153 : 0 : QList< QString > savePoints() const { return QList< QString >::fromVector( mSavepoints ); } 154 : : 155 : : /** 156 : : * returns the last created savepoint 157 : : * \since QGIS 3.0 158 : : */ 159 : 0 : bool lastSavePointIsDirty() const { return mLastSavePointIsDirty; } 160 : : 161 : : ///@cond PRIVATE 162 : : // For internal use only, or by QgsTransactionGroup 163 : : static QString connectionString( const QString &layerUri ) SIP_SKIP; 164 : : ///@endcond 165 : : 166 : : signals: 167 : : 168 : : /** 169 : : * Emitted after a rollback 170 : : */ 171 : : void afterRollback(); 172 : : 173 : : /** 174 : : * Emitted if a sql query is executed and the underlying data is modified 175 : : */ 176 : : void dirtied( const QString &sql, const QString &name ); 177 : : 178 : : protected: 179 : : QgsTransaction( const QString &connString ) SIP_SKIP; 180 : : 181 : : QString mConnString; 182 : : 183 : : private slots: 184 : : void onLayerDeleted(); 185 : : 186 : : private: 187 : : 188 : : bool mTransactionActive; 189 : : QSet<QgsVectorLayer *> mLayers; 190 : : 191 : : QStack< QString > mSavepoints; 192 : : bool mLastSavePointIsDirty; 193 : : 194 : : void setLayerTransactionIds( QgsTransaction *transaction ); 195 : : 196 : : static QString removeLayerIdOrName( const QString &str ); 197 : : 198 : : virtual bool beginTransaction( QString &error, int statementTimeout ) = 0; 199 : : virtual bool commitTransaction( QString &error ) = 0; 200 : : virtual bool rollbackTransaction( QString &error ) = 0; 201 : : }; 202 : : 203 : : #endif // QGSTRANSACTION_H