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