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