QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgstransaction.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgstransaction.cpp
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 #include <QLibrary>
19 
20 #include "qgstransaction.h"
21 #include "qgsdatasourceuri.h"
22 #include "qgsmaplayerregistry.h"
23 #include "qgsproviderregistry.h"
24 #include "qgsvectordataprovider.h"
25 #include "qgsvectorlayer.h"
26 
27 typedef QgsTransaction* createTransaction_t( const QString& connString );
28 
29 QgsTransaction* QgsTransaction::create( const QString& connString, const QString& providerKey )
30 {
31 
32  QLibrary* lib = QgsProviderRegistry::instance()->providerLibrary( providerKey );
33  if ( !lib )
34  {
35  return 0;
36  }
37 
38  createTransaction_t* createTransaction = ( createTransaction_t* ) cast_to_fptr( lib->resolve( "createTransaction" ) );
39  if ( !createTransaction )
40  {
41  return 0;
42  }
43 
44  QgsTransaction* ts = createTransaction( connString );
45 
46  delete lib;
47 
48  return ts;
49 }
50 
51 QgsTransaction* QgsTransaction::create( const QStringList& layerIds )
52 {
53  if ( layerIds.isEmpty() )
54  {
55  return 0;
56  }
57 
58  QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerIds.first() ) );
59  if ( !layer )
60  {
61  return 0;
62  }
63 
64  QString connStr = QgsDataSourceURI( layer->source() ).connectionInfo();
65  QString providerKey = layer->dataProvider()->name();
66  QgsTransaction* ts = QgsTransaction::create( connStr, providerKey );
67  if ( !ts )
68  {
69  return 0;
70  }
71 
72  foreach ( const QString& layerId, layerIds )
73  {
74  if ( !ts->addLayer( layerId ) )
75  {
76  delete ts;
77  return 0;
78  }
79  }
80  return ts;
81 }
82 
83 
84 QgsTransaction::QgsTransaction( const QString& connString )
85  : mConnString( connString ), mTransactionActive( false )
86 {
87 }
88 
90 {
91  setLayerTransactionIds( 0 );
92 }
93 
94 bool QgsTransaction::addLayer( const QString& layerId )
95 {
96  if ( mTransactionActive )
97  {
98  return false;
99  }
100 
101  QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) );
102  if ( !layer )
103  {
104  return false;
105  }
106 
107  if ( layer->isEditable() )
108  {
109  return false;
110  }
111 
112  //test if provider supports transactions
113  if ( !layer->dataProvider() || ( layer->dataProvider()->capabilities() & QgsVectorDataProvider::TransactionSupport ) == 0 )
114  {
115  return false;
116  }
117 
118  if ( layer->dataProvider()->transaction() != 0 )
119  {
120  return false;
121  }
122 
123  //connection string not compatible
124  if ( QgsDataSourceURI( layer->source() ).connectionInfo() != mConnString )
125  {
126  return false;
127  }
128 
129  mLayers.insert( layerId );
130  return true;
131 }
132 
133 bool QgsTransaction::begin( QString& errorMsg, int statementTimeout )
134 {
135  if ( mTransactionActive )
136  {
137  return false;
138  }
139 
140  //Set all layers to direct edit mode
141  if ( !beginTransaction( errorMsg, statementTimeout ) )
142  {
143  return false;
144  }
145 
146  setLayerTransactionIds( this );
147  mTransactionActive = true;
148  return true;
149 }
150 
151 bool QgsTransaction::commit( QString& errorMsg )
152 {
153  if ( !mTransactionActive )
154  {
155  return false;
156  }
157 
158  foreach ( const QString& layerid, mLayers )
159  {
161  if ( !l || l->isEditable() )
162  {
163  return false;
164  }
165  }
166 
167  if ( !commitTransaction( errorMsg ) )
168  {
169  return false;
170  }
171 
172  setLayerTransactionIds( 0 );
173  mTransactionActive = false;
174  return true;
175 }
176 
177 bool QgsTransaction::rollback( QString& errorMsg )
178 {
179  if ( !mTransactionActive )
180  {
181  return false;
182  }
183 
184  foreach ( const QString& layerid, mLayers )
185  {
187  if ( !l || l->isEditable() )
188  {
189  return false;
190  }
191  }
192 
193  if ( !rollbackTransaction( errorMsg ) )
194  {
195  return false;
196  }
197 
198  setLayerTransactionIds( 0 );
199  mTransactionActive = false;
200  return true;
201 }
202 
203 void QgsTransaction::setLayerTransactionIds( QgsTransaction* transaction )
204 {
205  foreach ( const QString& layerid, mLayers )
206  {
207  QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerid ) );
208  if ( vl && vl->dataProvider() )
209  {
210  vl->dataProvider()->setTransaction( transaction );
211  }
212  }
213 }