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