1 /******************************************************************************
2  *
3  * Project:  OpenGIS Simple Features Reference Implementation
4  * Purpose:  Implement OGRDataSourceWithTransaction class
5  * Author:   Even Rouault, even dot rouault at spatialys dot com
6  *
7  ******************************************************************************
8  * Copyright (c) 2015, Even Rouault <even dot rouault at spatialys dot com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28 
29 #include "ogremulatedtransaction.h"
30 #include "ogrlayerdecorator.h"
31 #include <map>
32 #include <set>
33 
34 CPL_CVSID("$Id: ogremulatedtransaction.cpp 25a31153bd3d94e8497c6df1148b9befac96bd89 2021-10-15 11:46:07 +0200 Even Rouault $")
35 
36 class OGRDataSourceWithTransaction;
37 
38 class OGRLayerWithTransaction final: public OGRLayerDecorator
39 {
40         CPL_DISALLOW_COPY_ASSIGN(OGRLayerWithTransaction)
41 
42     protected:
43         friend class OGRDataSourceWithTransaction;
44 
45         OGRDataSourceWithTransaction* m_poDS;
46         OGRFeatureDefn* m_poFeatureDefn;
47 
48     public:
49 
50         OGRLayerWithTransaction(OGRDataSourceWithTransaction* poDS,
51                                 OGRLayer* poBaseLayer);
52     virtual ~OGRLayerWithTransaction();
53 
GetName()54     virtual const char *GetName() override { return GetDescription(); }
55     virtual OGRFeatureDefn *GetLayerDefn() override;
56 
57     virtual OGRErr      CreateField( OGRFieldDefn *poField,
58                                      int bApproxOK = TRUE ) override;
59     virtual OGRErr      DeleteField( int iField ) override;
60     virtual OGRErr      ReorderFields( int* panMap ) override;
61     virtual OGRErr      AlterFieldDefn( int iField, OGRFieldDefn* poNewFieldDefn, int nFlags ) override;
62 
63     virtual OGRErr      CreateGeomField( OGRGeomFieldDefn *poField,
64                                      int bApproxOK = TRUE ) override;
65 
66     virtual OGRFeature *GetNextFeature() override;
67     virtual OGRFeature *GetFeature( GIntBig nFID ) override;
68     virtual OGRErr      ISetFeature( OGRFeature *poFeature ) override;
69     virtual OGRErr      ICreateFeature( OGRFeature *poFeature ) override;
70 };
71 
72 class OGRDataSourceWithTransaction final: public OGRDataSource
73 {
74         CPL_DISALLOW_COPY_ASSIGN(OGRDataSourceWithTransaction)
75 
76   protected:
77     OGRDataSource *m_poBaseDataSource;
78     IOGRTransactionBehaviour* m_poTransactionBehavior;
79     int            m_bHasOwnershipDataSource;
80     int            m_bHasOwnershipTransactionBehavior;
81     int            m_bInTransaction;
82 
83     std::map<CPLString, OGRLayerWithTransaction* > m_oMapLayers{};
84     std::set<OGRLayerWithTransaction*> m_oSetLayers{};
85     std::set<OGRLayer*> m_oSetExecuteSQLLayers{};
86 
87     OGRLayer*     WrapLayer(OGRLayer* poLayer);
88     void          RemapLayers();
89 
90   public:
91 
92                  OGRDataSourceWithTransaction(OGRDataSource* poBaseDataSource,
93                                           IOGRTransactionBehaviour* poTransactionBehaviour,
94                                           int bTakeOwnershipDataSource,
95                                           int bTakeOwnershipTransactionBehavior);
96 
97     virtual     ~OGRDataSourceWithTransaction();
98 
IsInTransaction() const99     int                 IsInTransaction() const { return m_bInTransaction; }
100 
101     virtual const char  *GetName() override;
102 
103     virtual int         GetLayerCount() override ;
104     virtual OGRLayer    *GetLayer(int) override;
105     virtual OGRLayer    *GetLayerByName(const char *) override;
106     virtual OGRErr      DeleteLayer(int) override;
107 
108     virtual int         TestCapability( const char * ) override;
109 
110     virtual OGRLayer   *ICreateLayer( const char *pszName,
111                                      OGRSpatialReference *poSpatialRef = nullptr,
112                                      OGRwkbGeometryType eGType = wkbUnknown,
113                                      char ** papszOptions = nullptr ) override;
114     virtual OGRLayer   *CopyLayer( OGRLayer *poSrcLayer,
115                                    const char *pszNewName,
116                                    char **papszOptions = nullptr ) override;
117 
118     virtual OGRStyleTable *GetStyleTable() override;
119     virtual void        SetStyleTableDirectly( OGRStyleTable *poStyleTable ) override;
120 
121     virtual void        SetStyleTable(OGRStyleTable *poStyleTable) override;
122 
123     virtual OGRLayer *  ExecuteSQL( const char *pszStatement,
124                                     OGRGeometry *poSpatialFilter,
125                                     const char *pszDialect ) override;
126     virtual void        ReleaseResultSet( OGRLayer * poResultsSet ) override;
127 
128     virtual void        FlushCache() override;
129 
130     virtual OGRErr      StartTransaction(int bForce=FALSE) override;
131     virtual OGRErr      CommitTransaction() override;
132     virtual OGRErr      RollbackTransaction() override;
133 
134     virtual const OGRFieldDomain* GetFieldDomain(const std::string& name) const override;
135     virtual bool        AddFieldDomain(std::unique_ptr<OGRFieldDomain>&& domain,
136                                        std::string& failureReason) override;
137 
138     virtual std::shared_ptr<GDALGroup> GetRootGroup() const override;
139 
140     virtual char      **GetMetadata( const char * pszDomain = "" ) override;
141     virtual CPLErr      SetMetadata( char ** papszMetadata,
142                                      const char * pszDomain = "" ) override;
143     virtual const char *GetMetadataItem( const char * pszName,
144                                          const char * pszDomain = "" ) override;
145     virtual CPLErr      SetMetadataItem( const char * pszName,
146                                          const char * pszValue,
147                                          const char * pszDomain = "" ) override;
148 };
149 
150 /************************************************************************/
151 /*                         ~IOGRTransactionBehaviour                    */
152 /************************************************************************/
153 
~IOGRTransactionBehaviour()154 IOGRTransactionBehaviour::~IOGRTransactionBehaviour()
155 {
156 }
157 
158 /************************************************************************/
159 /*              OGRCreateEmulatedTransactionDataSourceWrapper()         */
160 /************************************************************************/
161 
OGRCreateEmulatedTransactionDataSourceWrapper(OGRDataSource * poBaseDataSource,IOGRTransactionBehaviour * poTransactionBehaviour,int bTakeOwnershipDataSource,int bTakeOwnershipTransactionBehavior)162 OGRDataSource* OGRCreateEmulatedTransactionDataSourceWrapper(
163                                 OGRDataSource* poBaseDataSource,
164                                 IOGRTransactionBehaviour* poTransactionBehaviour,
165                                 int bTakeOwnershipDataSource,
166                                 int bTakeOwnershipTransactionBehavior)
167 {
168     return new OGRDataSourceWithTransaction(poBaseDataSource,
169                                             poTransactionBehaviour,
170                                             bTakeOwnershipDataSource,
171                                             bTakeOwnershipTransactionBehavior);
172 }
173 
174 /************************************************************************/
175 /*                      OGRDataSourceWithTransaction                    */
176 /************************************************************************/
177 
OGRDataSourceWithTransaction(OGRDataSource * poBaseDataSource,IOGRTransactionBehaviour * poTransactionBehaviour,int bTakeOwnershipDataSource,int bTakeOwnershipTransactionBehavior)178 OGRDataSourceWithTransaction::OGRDataSourceWithTransaction(
179     OGRDataSource* poBaseDataSource,
180     IOGRTransactionBehaviour* poTransactionBehaviour,
181     int bTakeOwnershipDataSource,
182     int bTakeOwnershipTransactionBehavior) :
183     m_poBaseDataSource(poBaseDataSource),
184     m_poTransactionBehavior(poTransactionBehaviour),
185     m_bHasOwnershipDataSource(bTakeOwnershipDataSource),
186     m_bHasOwnershipTransactionBehavior(bTakeOwnershipTransactionBehavior),
187     m_bInTransaction(FALSE)
188 {}
189 
~OGRDataSourceWithTransaction()190 OGRDataSourceWithTransaction::~OGRDataSourceWithTransaction()
191 {
192     std::set<OGRLayerWithTransaction*>::iterator oIter = m_oSetLayers.begin();
193     for(; oIter != m_oSetLayers.end(); ++oIter )
194         delete *oIter;
195 
196     if( m_bHasOwnershipDataSource )
197         delete m_poBaseDataSource;
198     if( m_bHasOwnershipTransactionBehavior )
199         delete m_poTransactionBehavior;
200 }
201 
WrapLayer(OGRLayer * poLayer)202 OGRLayer* OGRDataSourceWithTransaction::WrapLayer(OGRLayer* poLayer)
203 {
204     if( poLayer )
205     {
206         OGRLayer* poWrappedLayer = m_oMapLayers[poLayer->GetName()];
207         if( poWrappedLayer )
208             poLayer = poWrappedLayer;
209         else
210         {
211             OGRLayerWithTransaction* poMutexedLayer = new OGRLayerWithTransaction(this,poLayer);
212             m_oMapLayers[poLayer->GetName()] = poMutexedLayer;
213             m_oSetLayers.insert(poMutexedLayer);
214             poLayer = poMutexedLayer;
215         }
216     }
217     return poLayer;
218 }
219 
RemapLayers()220 void OGRDataSourceWithTransaction::RemapLayers()
221 {
222     std::set<OGRLayerWithTransaction*>::iterator oIter = m_oSetLayers.begin();
223     for(; oIter != m_oSetLayers.end(); ++oIter )
224     {
225         OGRLayerWithTransaction* poWrappedLayer = *oIter;
226         if( m_poBaseDataSource == nullptr )
227             poWrappedLayer->m_poDecoratedLayer = nullptr;
228         else
229         {
230             poWrappedLayer->m_poDecoratedLayer =
231                 m_poBaseDataSource->GetLayerByName(poWrappedLayer->GetName());
232         }
233     }
234     m_oMapLayers.clear();
235 }
236 
GetName()237 const char  *OGRDataSourceWithTransaction::GetName()
238 {
239     if( !m_poBaseDataSource ) return "";
240     return m_poBaseDataSource->GetName();
241 }
242 
GetLayerCount()243 int         OGRDataSourceWithTransaction::GetLayerCount()
244 {
245     if( !m_poBaseDataSource ) return 0;
246     return m_poBaseDataSource->GetLayerCount();
247 }
248 
GetLayer(int iIndex)249 OGRLayer    *OGRDataSourceWithTransaction::GetLayer(int iIndex)
250 {
251     if( !m_poBaseDataSource ) return nullptr;
252     return WrapLayer(m_poBaseDataSource->GetLayer(iIndex));
253 }
254 
GetLayerByName(const char * pszName)255 OGRLayer    *OGRDataSourceWithTransaction::GetLayerByName(const char *pszName)
256 {
257     if( !m_poBaseDataSource ) return nullptr;
258     return WrapLayer(m_poBaseDataSource->GetLayerByName(pszName));
259 }
260 
DeleteLayer(int iIndex)261 OGRErr      OGRDataSourceWithTransaction::DeleteLayer(int iIndex)
262 {
263     if( !m_poBaseDataSource ) return OGRERR_FAILURE;
264     OGRLayer* poLayer = GetLayer(iIndex);
265     CPLString osName;
266     if( poLayer )
267         osName = poLayer->GetName();
268     OGRErr eErr = m_poBaseDataSource->DeleteLayer(iIndex);
269     if( eErr == OGRERR_NONE && !osName.empty() )
270     {
271         std::map<CPLString, OGRLayerWithTransaction*>::iterator oIter = m_oMapLayers.find(osName);
272         if(oIter != m_oMapLayers.end())
273         {
274             delete oIter->second;
275             m_oSetLayers.erase(oIter->second);
276             m_oMapLayers.erase(oIter);
277         }
278     }
279     return eErr;
280 }
281 
TestCapability(const char * pszCap)282 int         OGRDataSourceWithTransaction::TestCapability( const char * pszCap )
283 {
284     if( !m_poBaseDataSource ) return FALSE;
285 
286     if( EQUAL(pszCap,ODsCEmulatedTransactions) )
287         return TRUE;
288 
289     return m_poBaseDataSource->TestCapability(pszCap);
290 }
291 
ICreateLayer(const char * pszName,OGRSpatialReference * poSpatialRef,OGRwkbGeometryType eGType,char ** papszOptions)292 OGRLayer   *OGRDataSourceWithTransaction::ICreateLayer( const char *pszName,
293                                      OGRSpatialReference *poSpatialRef,
294                                      OGRwkbGeometryType eGType,
295                                      char ** papszOptions)
296 {
297     if( !m_poBaseDataSource ) return nullptr;
298     return WrapLayer(m_poBaseDataSource->CreateLayer(pszName, poSpatialRef, eGType, papszOptions));
299 }
300 
CopyLayer(OGRLayer * poSrcLayer,const char * pszNewName,char ** papszOptions)301 OGRLayer   *OGRDataSourceWithTransaction::CopyLayer( OGRLayer *poSrcLayer,
302                                    const char *pszNewName,
303                                    char **papszOptions )
304 {
305     if( !m_poBaseDataSource ) return nullptr;
306     return WrapLayer(m_poBaseDataSource->CopyLayer(poSrcLayer, pszNewName, papszOptions ));
307 }
308 
GetStyleTable()309 OGRStyleTable *OGRDataSourceWithTransaction::GetStyleTable()
310 {
311     if( !m_poBaseDataSource ) return nullptr;
312     return m_poBaseDataSource->GetStyleTable();
313 }
314 
SetStyleTableDirectly(OGRStyleTable * poStyleTable)315 void        OGRDataSourceWithTransaction::SetStyleTableDirectly( OGRStyleTable *poStyleTable )
316 {
317     if( !m_poBaseDataSource ) return;
318     m_poBaseDataSource->SetStyleTableDirectly(poStyleTable);
319 }
320 
SetStyleTable(OGRStyleTable * poStyleTable)321 void        OGRDataSourceWithTransaction::SetStyleTable(OGRStyleTable *poStyleTable)
322 {
323     if( !m_poBaseDataSource ) return;
324     m_poBaseDataSource->SetStyleTable(poStyleTable);
325 }
326 
ExecuteSQL(const char * pszStatement,OGRGeometry * poSpatialFilter,const char * pszDialect)327 OGRLayer *  OGRDataSourceWithTransaction::ExecuteSQL( const char *pszStatement,
328                                     OGRGeometry *poSpatialFilter,
329                                     const char *pszDialect )
330 {
331     if( !m_poBaseDataSource ) return nullptr;
332     OGRLayer* poLayer = m_poBaseDataSource->ExecuteSQL(pszStatement, poSpatialFilter,
333                                                        pszDialect);
334     if( poLayer != nullptr )
335         m_oSetExecuteSQLLayers.insert(poLayer);
336     return poLayer;
337 }
338 
ReleaseResultSet(OGRLayer * poResultsSet)339 void        OGRDataSourceWithTransaction::ReleaseResultSet( OGRLayer * poResultsSet )
340 {
341     if( !m_poBaseDataSource ) return;
342     m_oSetExecuteSQLLayers.erase(poResultsSet);
343     m_poBaseDataSource->ReleaseResultSet(poResultsSet);
344 }
345 
FlushCache()346 void      OGRDataSourceWithTransaction::FlushCache()
347 {
348     if( !m_poBaseDataSource ) return;
349     return m_poBaseDataSource->FlushCache();
350 }
351 
StartTransaction(int bForce)352 OGRErr OGRDataSourceWithTransaction::StartTransaction(int bForce)
353 {
354     if( !m_poBaseDataSource ) return OGRERR_FAILURE;
355     if( !bForce )
356     {
357         CPLError(CE_Failure, CPLE_NotSupported,
358                  "Transactions only supported in forced mode");
359         return OGRERR_UNSUPPORTED_OPERATION;
360     }
361     if( !m_oSetExecuteSQLLayers.empty() )
362     {
363         CPLError(CE_Failure, CPLE_NotSupported,
364                  "Cannot start transaction while a layer returned by "
365                  "ExecuteSQL() hasn't been released.");
366         return OGRERR_FAILURE;
367     }
368     if( m_bInTransaction )
369     {
370         CPLError(CE_Failure, CPLE_AppDefined,
371                  "Transaction is already in progress");
372         return OGRERR_FAILURE;
373     }
374     int bHasReopenedDS = FALSE;
375     OGRErr eErr =
376         m_poTransactionBehavior->StartTransaction(m_poBaseDataSource, bHasReopenedDS);
377     if( bHasReopenedDS )
378         RemapLayers();
379     if( eErr == OGRERR_NONE )
380         m_bInTransaction = TRUE;
381     return eErr;
382 }
383 
CommitTransaction()384 OGRErr OGRDataSourceWithTransaction::CommitTransaction()
385 {
386     if( !m_poBaseDataSource ) return OGRERR_FAILURE;
387     if( !m_bInTransaction )
388     {
389         CPLError(CE_Failure, CPLE_AppDefined,
390                  "No transaction in progress");
391         return OGRERR_FAILURE;
392     }
393     if( !m_oSetExecuteSQLLayers.empty() )
394     {
395         CPLError(CE_Failure, CPLE_NotSupported,
396                  "Cannot interrupt transaction while a layer returned by "
397                  "ExecuteSQL() hasn't been released.");
398         return OGRERR_FAILURE;
399     }
400     m_bInTransaction = FALSE;
401     int bHasReopenedDS = FALSE;
402     OGRErr eErr =
403         m_poTransactionBehavior->CommitTransaction(m_poBaseDataSource, bHasReopenedDS);
404     if( bHasReopenedDS )
405         RemapLayers();
406     return eErr;
407 }
408 
RollbackTransaction()409 OGRErr OGRDataSourceWithTransaction::RollbackTransaction()
410 {
411     if( !m_poBaseDataSource ) return OGRERR_FAILURE;
412     if( !m_bInTransaction )
413     {
414         CPLError(CE_Failure, CPLE_AppDefined,
415                  "No transaction in progress");
416         return OGRERR_FAILURE;
417     }
418     if( !m_oSetExecuteSQLLayers.empty() )
419     {
420         CPLError(CE_Failure, CPLE_NotSupported,
421                  "Cannot interrupt transaction while a layer returned by "
422                  "ExecuteSQL() hasn't been released.");
423         return OGRERR_FAILURE;
424     }
425     m_bInTransaction = FALSE;
426     int bHasReopenedDS = FALSE;
427     OGRErr eErr =
428         m_poTransactionBehavior->RollbackTransaction(m_poBaseDataSource, bHasReopenedDS);
429     if( bHasReopenedDS )
430         RemapLayers();
431     return eErr;
432 }
433 
GetFieldDomain(const std::string & name) const434 const OGRFieldDomain* OGRDataSourceWithTransaction::GetFieldDomain(const std::string& name) const
435 {
436     if( !m_poBaseDataSource ) return nullptr;
437     return m_poBaseDataSource->GetFieldDomain(name);
438 }
439 
AddFieldDomain(std::unique_ptr<OGRFieldDomain> && domain,std::string & failureReason)440 bool OGRDataSourceWithTransaction::AddFieldDomain(std::unique_ptr<OGRFieldDomain>&& domain, std::string& failureReason)
441 {
442     if( !m_poBaseDataSource ) return false;
443     return m_poBaseDataSource->AddFieldDomain(std::move(domain), failureReason);
444 }
445 
GetRootGroup() const446 std::shared_ptr<GDALGroup> OGRDataSourceWithTransaction::GetRootGroup() const
447 {
448     if( !m_poBaseDataSource ) return nullptr;
449     return m_poBaseDataSource->GetRootGroup();
450 }
451 
GetMetadata(const char * pszDomain)452 char      **OGRDataSourceWithTransaction::GetMetadata( const char * pszDomain )
453 {
454     if( !m_poBaseDataSource ) return nullptr;
455     return m_poBaseDataSource->GetMetadata(pszDomain);
456 }
457 
SetMetadata(char ** papszMetadata,const char * pszDomain)458 CPLErr      OGRDataSourceWithTransaction::SetMetadata( char ** papszMetadata,
459                                           const char * pszDomain )
460 {
461     if( !m_poBaseDataSource ) return CE_Failure;
462     return m_poBaseDataSource->SetMetadata(papszMetadata, pszDomain);
463 }
464 
GetMetadataItem(const char * pszName,const char * pszDomain)465 const char *OGRDataSourceWithTransaction::GetMetadataItem( const char * pszName,
466                                               const char * pszDomain )
467 {
468     if( !m_poBaseDataSource ) return nullptr;
469     return m_poBaseDataSource->GetMetadataItem(pszName, pszDomain);
470 }
471 
SetMetadataItem(const char * pszName,const char * pszValue,const char * pszDomain)472 CPLErr      OGRDataSourceWithTransaction::SetMetadataItem( const char * pszName,
473                                               const char * pszValue,
474                                               const char * pszDomain )
475 {
476     if( !m_poBaseDataSource ) return CE_Failure;
477     return m_poBaseDataSource->SetMetadataItem(pszName, pszValue, pszDomain);
478 }
479 
480 /************************************************************************/
481 /*                       OGRLayerWithTransaction                        */
482 /************************************************************************/
483 
OGRLayerWithTransaction(OGRDataSourceWithTransaction * poDS,OGRLayer * poBaseLayer)484 OGRLayerWithTransaction::OGRLayerWithTransaction(
485     OGRDataSourceWithTransaction* poDS, OGRLayer* poBaseLayer) :
486     OGRLayerDecorator(poBaseLayer, FALSE),
487     m_poDS(poDS),
488     m_poFeatureDefn(nullptr)
489 {}
490 
~OGRLayerWithTransaction()491 OGRLayerWithTransaction::~OGRLayerWithTransaction()
492 {
493     if( m_poFeatureDefn )
494         m_poFeatureDefn->Release();
495 }
496 
GetLayerDefn()497 OGRFeatureDefn *OGRLayerWithTransaction::GetLayerDefn()
498 {
499     if( !m_poDecoratedLayer )
500     {
501         if( m_poFeatureDefn == nullptr )
502         {
503             m_poFeatureDefn = new OGRFeatureDefn(GetDescription());
504             m_poFeatureDefn->Reference();
505         }
506         return m_poFeatureDefn;
507     }
508     else if( m_poFeatureDefn == nullptr )
509     {
510         OGRFeatureDefn* poSrcFeatureDefn = m_poDecoratedLayer->GetLayerDefn();
511         m_poFeatureDefn = poSrcFeatureDefn->Clone();
512         m_poFeatureDefn->Reference();
513     }
514     return m_poFeatureDefn;
515 }
516 
CreateField(OGRFieldDefn * poField,int bApproxOK)517 OGRErr      OGRLayerWithTransaction::CreateField( OGRFieldDefn *poField,
518                                             int bApproxOK )
519 {
520     if( !m_poDecoratedLayer ) return OGRERR_FAILURE;
521     int nFields = m_poDecoratedLayer->GetLayerDefn()->GetFieldCount();
522     OGRErr eErr = m_poDecoratedLayer->CreateField(poField, bApproxOK);
523     if( m_poFeatureDefn && eErr == OGRERR_NONE && m_poDecoratedLayer->GetLayerDefn()->GetFieldCount() == nFields + 1 )
524     {
525         m_poFeatureDefn->AddFieldDefn( m_poDecoratedLayer->GetLayerDefn()->GetFieldDefn(nFields) );
526     }
527     return eErr;
528 }
529 
CreateGeomField(OGRGeomFieldDefn * poField,int bApproxOK)530 OGRErr      OGRLayerWithTransaction::CreateGeomField( OGRGeomFieldDefn *poField,
531                                             int bApproxOK )
532 {
533     if( !m_poDecoratedLayer ) return OGRERR_FAILURE;
534     int nFields = m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldCount();
535     OGRErr eErr = m_poDecoratedLayer->CreateGeomField(poField, bApproxOK);
536     if( m_poFeatureDefn && eErr == OGRERR_NONE && m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldCount() == nFields + 1 )
537     {
538         m_poFeatureDefn->AddGeomFieldDefn( m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldDefn(nFields) );
539     }
540     return eErr;
541 }
542 
DeleteField(int iField)543 OGRErr      OGRLayerWithTransaction::DeleteField( int iField )
544 {
545     if( !m_poDecoratedLayer ) return OGRERR_FAILURE;
546     OGRErr eErr = m_poDecoratedLayer->DeleteField(iField);
547     if( m_poFeatureDefn && eErr == OGRERR_NONE )
548         m_poFeatureDefn->DeleteFieldDefn(iField);
549     return eErr;
550 }
551 
ReorderFields(int * panMap)552 OGRErr      OGRLayerWithTransaction::ReorderFields( int* panMap )
553 {
554     if( !m_poDecoratedLayer ) return OGRERR_FAILURE;
555     OGRErr eErr = m_poDecoratedLayer->ReorderFields(panMap);
556     if( m_poFeatureDefn && eErr == OGRERR_NONE )
557         m_poFeatureDefn->ReorderFieldDefns(panMap);
558     return eErr;
559 }
560 
AlterFieldDefn(int iField,OGRFieldDefn * poNewFieldDefn,int nFlagsIn)561 OGRErr      OGRLayerWithTransaction::AlterFieldDefn( int iField,
562                                                      OGRFieldDefn* poNewFieldDefn,
563                                                      int nFlagsIn )
564 {
565     if( !m_poDecoratedLayer ) return OGRERR_FAILURE;
566     OGRErr eErr = m_poDecoratedLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
567     if( m_poFeatureDefn && eErr == OGRERR_NONE )
568     {
569         OGRFieldDefn* poSrcFieldDefn = m_poDecoratedLayer->GetLayerDefn()->GetFieldDefn(iField);
570         OGRFieldDefn* poDstFieldDefn = m_poFeatureDefn->GetFieldDefn(iField);
571         poDstFieldDefn->SetName(poSrcFieldDefn->GetNameRef());
572         poDstFieldDefn->SetType(poSrcFieldDefn->GetType());
573         poDstFieldDefn->SetSubType(poSrcFieldDefn->GetSubType());
574         poDstFieldDefn->SetWidth(poSrcFieldDefn->GetWidth());
575         poDstFieldDefn->SetPrecision(poSrcFieldDefn->GetPrecision());
576         poDstFieldDefn->SetDefault(poSrcFieldDefn->GetDefault());
577         poDstFieldDefn->SetNullable(poSrcFieldDefn->IsNullable());
578     }
579     return eErr;
580 }
581 
GetNextFeature()582 OGRFeature * OGRLayerWithTransaction::GetNextFeature()
583 {
584     if( !m_poDecoratedLayer ) return nullptr;
585     OGRFeature* poSrcFeature = m_poDecoratedLayer->GetNextFeature();
586     if( !poSrcFeature )
587         return nullptr;
588     OGRFeature* poFeature = new OGRFeature(GetLayerDefn());
589     poFeature->SetFrom(poSrcFeature);
590     poFeature->SetFID(poSrcFeature->GetFID());
591     delete poSrcFeature;
592     return poFeature;
593 }
594 
GetFeature(GIntBig nFID)595 OGRFeature * OGRLayerWithTransaction::GetFeature( GIntBig nFID )
596 {
597     if( !m_poDecoratedLayer ) return nullptr;
598     OGRFeature* poSrcFeature = m_poDecoratedLayer->GetFeature(nFID);
599     if( !poSrcFeature )
600         return nullptr;
601     OGRFeature* poFeature = new OGRFeature(GetLayerDefn());
602     poFeature->SetFrom(poSrcFeature);
603     poFeature->SetFID(poSrcFeature->GetFID());
604     delete poSrcFeature;
605     return poFeature;
606 }
607 
ISetFeature(OGRFeature * poFeature)608 OGRErr       OGRLayerWithTransaction::ISetFeature( OGRFeature *poFeature )
609 {
610     if( !m_poDecoratedLayer ) return OGRERR_FAILURE;
611     OGRFeature* poSrcFeature = new OGRFeature(m_poDecoratedLayer->GetLayerDefn());
612     poSrcFeature->SetFrom(poFeature);
613     poSrcFeature->SetFID(poFeature->GetFID());
614     OGRErr eErr = m_poDecoratedLayer->SetFeature(poSrcFeature);
615     delete poSrcFeature;
616     return eErr;
617 }
618 
ICreateFeature(OGRFeature * poFeature)619 OGRErr       OGRLayerWithTransaction::ICreateFeature( OGRFeature *poFeature )
620 {
621     if( !m_poDecoratedLayer ) return OGRERR_FAILURE;
622     OGRFeature* poSrcFeature = new OGRFeature(m_poDecoratedLayer->GetLayerDefn());
623     poSrcFeature->SetFrom(poFeature);
624     poSrcFeature->SetFID(poFeature->GetFID());
625     OGRErr eErr = m_poDecoratedLayer->CreateFeature(poSrcFeature);
626     poFeature->SetFID(poSrcFeature->GetFID());
627     delete poSrcFeature;
628     return eErr;
629 }
630