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