Line data Source code
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 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "ogremulatedtransaction.h"
14 : #include "ogrlayerdecorator.h"
15 : #include <map>
16 : #include <set>
17 :
18 : class OGRDataSourceWithTransaction;
19 :
20 : class OGRLayerWithTransaction final : public OGRLayerDecorator
21 : {
22 : CPL_DISALLOW_COPY_ASSIGN(OGRLayerWithTransaction)
23 :
24 : protected:
25 : friend class OGRDataSourceWithTransaction;
26 :
27 : OGRDataSourceWithTransaction *m_poDS;
28 : OGRFeatureDefn *m_poFeatureDefn;
29 :
30 : public:
31 : OGRLayerWithTransaction(OGRDataSourceWithTransaction *poDS,
32 : OGRLayer *poBaseLayer);
33 : virtual ~OGRLayerWithTransaction() override;
34 :
35 58 : virtual const char *GetName() override
36 : {
37 58 : return GetDescription();
38 : }
39 :
40 : virtual OGRFeatureDefn *GetLayerDefn() override;
41 :
42 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
43 : int bApproxOK = TRUE) override;
44 : virtual OGRErr DeleteField(int iField) override;
45 : virtual OGRErr ReorderFields(int *panMap) override;
46 : virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
47 : int nFlags) override;
48 : virtual OGRErr
49 : AlterGeomFieldDefn(int iField, const OGRGeomFieldDefn *poNewGeomFieldDefn,
50 : int nFlags) override;
51 :
52 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poField,
53 : int bApproxOK = TRUE) override;
54 :
55 : virtual OGRFeature *GetNextFeature() override;
56 : virtual OGRFeature *GetFeature(GIntBig nFID) override;
57 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
58 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
59 : virtual OGRErr IUpsertFeature(OGRFeature *poFeature) override;
60 :
61 : virtual OGRErr Rename(const char *pszNewName) override;
62 : };
63 :
64 : class OGRDataSourceWithTransaction final : public GDALDataset
65 : {
66 : CPL_DISALLOW_COPY_ASSIGN(OGRDataSourceWithTransaction)
67 :
68 : protected:
69 : GDALDataset *m_poBaseDataSource;
70 : IOGRTransactionBehaviour *m_poTransactionBehavior;
71 : int m_bHasOwnershipDataSource;
72 : int m_bHasOwnershipTransactionBehavior;
73 : int m_bInTransaction;
74 :
75 : std::map<CPLString, OGRLayerWithTransaction *> m_oMapLayers{};
76 : std::set<OGRLayerWithTransaction *> m_oSetLayers{};
77 : std::set<OGRLayer *> m_oSetExecuteSQLLayers{};
78 :
79 : OGRLayer *WrapLayer(OGRLayer *poLayer);
80 : void RemapLayers();
81 :
82 : public:
83 : OGRDataSourceWithTransaction(
84 : GDALDataset *poBaseDataSource,
85 : IOGRTransactionBehaviour *poTransactionBehaviour,
86 : int bTakeOwnershipDataSource, int bTakeOwnershipTransactionBehavior);
87 :
88 : virtual ~OGRDataSourceWithTransaction() override;
89 :
90 : int IsInTransaction() const
91 : {
92 : return m_bInTransaction;
93 : }
94 :
95 : virtual int GetLayerCount() override;
96 : virtual OGRLayer *GetLayer(int) override;
97 : virtual OGRLayer *GetLayerByName(const char *) override;
98 : virtual OGRErr DeleteLayer(int) override;
99 : virtual bool IsLayerPrivate(int iLayer) const override;
100 :
101 : virtual int TestCapability(const char *) override;
102 :
103 : OGRLayer *ICreateLayer(const char *pszName,
104 : const OGRGeomFieldDefn *poGeomFieldDefn,
105 : CSLConstList papszOptions) override;
106 :
107 : virtual OGRLayer *CopyLayer(OGRLayer *poSrcLayer, const char *pszNewName,
108 : char **papszOptions = nullptr) override;
109 :
110 : virtual OGRStyleTable *GetStyleTable() override;
111 : virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable) override;
112 :
113 : virtual void SetStyleTable(OGRStyleTable *poStyleTable) override;
114 :
115 : virtual OGRLayer *ExecuteSQL(const char *pszStatement,
116 : OGRGeometry *poSpatialFilter,
117 : const char *pszDialect) override;
118 : virtual void ReleaseResultSet(OGRLayer *poResultsSet) override;
119 :
120 : virtual CPLErr FlushCache(bool bAtClosing) override;
121 :
122 : virtual OGRErr StartTransaction(int bForce = FALSE) override;
123 : virtual OGRErr CommitTransaction() override;
124 : virtual OGRErr RollbackTransaction() override;
125 :
126 : virtual std::vector<std::string>
127 : GetFieldDomainNames(CSLConstList papszOptions = nullptr) const override;
128 : virtual const OGRFieldDomain *
129 : GetFieldDomain(const std::string &name) const override;
130 : virtual bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
131 : std::string &failureReason) override;
132 : virtual bool DeleteFieldDomain(const std::string &name,
133 : std::string &failureReason) override;
134 : virtual bool UpdateFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
135 : std::string &failureReason) override;
136 :
137 : std::vector<std::string>
138 : GetRelationshipNames(CSLConstList papszOptions = nullptr) const override;
139 :
140 : const GDALRelationship *
141 : GetRelationship(const std::string &name) const override;
142 :
143 : virtual std::shared_ptr<GDALGroup> GetRootGroup() const override;
144 :
145 : virtual char **GetMetadata(const char *pszDomain = "") override;
146 : virtual CPLErr SetMetadata(char **papszMetadata,
147 : const char *pszDomain = "") override;
148 : virtual const char *GetMetadataItem(const char *pszName,
149 : const char *pszDomain = "") override;
150 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
151 : const char *pszDomain = "") override;
152 : };
153 :
154 : /************************************************************************/
155 : /* ~IOGRTransactionBehaviour */
156 : /************************************************************************/
157 :
158 5 : IOGRTransactionBehaviour::~IOGRTransactionBehaviour()
159 : {
160 5 : }
161 :
162 : /************************************************************************/
163 : /* OGRCreateEmulatedTransactionDataSourceWrapper() */
164 : /************************************************************************/
165 :
166 42 : GDALDataset *OGRCreateEmulatedTransactionDataSourceWrapper(
167 : GDALDataset *poBaseDataSource,
168 : IOGRTransactionBehaviour *poTransactionBehaviour,
169 : int bTakeOwnershipDataSource, int bTakeOwnershipTransactionBehavior)
170 : {
171 : return new OGRDataSourceWithTransaction(
172 : poBaseDataSource, poTransactionBehaviour, bTakeOwnershipDataSource,
173 42 : bTakeOwnershipTransactionBehavior);
174 : }
175 :
176 : /************************************************************************/
177 : /* OGRDataSourceWithTransaction */
178 : /************************************************************************/
179 :
180 42 : OGRDataSourceWithTransaction::OGRDataSourceWithTransaction(
181 : GDALDataset *poBaseDataSource,
182 : IOGRTransactionBehaviour *poTransactionBehaviour,
183 42 : int bTakeOwnershipDataSource, int bTakeOwnershipTransactionBehavior)
184 : : m_poBaseDataSource(poBaseDataSource),
185 : m_poTransactionBehavior(poTransactionBehaviour),
186 : m_bHasOwnershipDataSource(bTakeOwnershipDataSource),
187 : m_bHasOwnershipTransactionBehavior(bTakeOwnershipTransactionBehavior),
188 42 : m_bInTransaction(FALSE)
189 : {
190 42 : }
191 :
192 84 : OGRDataSourceWithTransaction::~OGRDataSourceWithTransaction()
193 : {
194 42 : std::set<OGRLayerWithTransaction *>::iterator oIter = m_oSetLayers.begin();
195 230 : for (; oIter != m_oSetLayers.end(); ++oIter)
196 188 : delete *oIter;
197 :
198 42 : if (m_bHasOwnershipDataSource)
199 42 : delete m_poBaseDataSource;
200 42 : if (m_bHasOwnershipTransactionBehavior)
201 0 : delete m_poTransactionBehavior;
202 84 : }
203 :
204 213 : OGRLayer *OGRDataSourceWithTransaction::WrapLayer(OGRLayer *poLayer)
205 : {
206 213 : if (poLayer)
207 : {
208 201 : OGRLayer *poWrappedLayer = m_oMapLayers[poLayer->GetName()];
209 201 : if (poWrappedLayer)
210 11 : poLayer = poWrappedLayer;
211 : else
212 : {
213 : OGRLayerWithTransaction *poMutexedLayer =
214 190 : new OGRLayerWithTransaction(this, poLayer);
215 190 : m_oMapLayers[poLayer->GetName()] = poMutexedLayer;
216 190 : m_oSetLayers.insert(poMutexedLayer);
217 190 : poLayer = poMutexedLayer;
218 : }
219 : }
220 213 : return poLayer;
221 : }
222 :
223 0 : void OGRDataSourceWithTransaction::RemapLayers()
224 : {
225 0 : std::set<OGRLayerWithTransaction *>::iterator oIter = m_oSetLayers.begin();
226 0 : for (; oIter != m_oSetLayers.end(); ++oIter)
227 : {
228 0 : OGRLayerWithTransaction *poWrappedLayer = *oIter;
229 0 : if (m_poBaseDataSource == nullptr)
230 0 : poWrappedLayer->m_poDecoratedLayer = nullptr;
231 : else
232 : {
233 0 : poWrappedLayer->m_poDecoratedLayer =
234 0 : m_poBaseDataSource->GetLayerByName(poWrappedLayer->GetName());
235 : }
236 : }
237 0 : m_oMapLayers.clear();
238 0 : }
239 :
240 6 : int OGRDataSourceWithTransaction::GetLayerCount()
241 : {
242 6 : if (!m_poBaseDataSource)
243 0 : return 0;
244 6 : return m_poBaseDataSource->GetLayerCount();
245 : }
246 :
247 51 : OGRLayer *OGRDataSourceWithTransaction::GetLayer(int iIndex)
248 : {
249 51 : if (!m_poBaseDataSource)
250 0 : return nullptr;
251 51 : return WrapLayer(m_poBaseDataSource->GetLayer(iIndex));
252 : }
253 :
254 12 : OGRLayer *OGRDataSourceWithTransaction::GetLayerByName(const char *pszName)
255 : {
256 12 : if (!m_poBaseDataSource)
257 0 : return nullptr;
258 12 : return WrapLayer(m_poBaseDataSource->GetLayerByName(pszName));
259 : }
260 :
261 2 : OGRErr OGRDataSourceWithTransaction::DeleteLayer(int iIndex)
262 : {
263 2 : if (!m_poBaseDataSource)
264 0 : return OGRERR_FAILURE;
265 2 : OGRLayer *poLayer = GetLayer(iIndex);
266 2 : CPLString osName;
267 2 : if (poLayer)
268 2 : osName = poLayer->GetName();
269 2 : OGRErr eErr = m_poBaseDataSource->DeleteLayer(iIndex);
270 2 : if (eErr == OGRERR_NONE && !osName.empty())
271 : {
272 : std::map<CPLString, OGRLayerWithTransaction *>::iterator oIter =
273 2 : m_oMapLayers.find(osName);
274 2 : if (oIter != m_oMapLayers.end())
275 : {
276 2 : delete oIter->second;
277 2 : m_oSetLayers.erase(oIter->second);
278 2 : m_oMapLayers.erase(oIter);
279 : }
280 : }
281 2 : return eErr;
282 : }
283 :
284 0 : bool OGRDataSourceWithTransaction::IsLayerPrivate(int iLayer) const
285 : {
286 0 : if (!m_poBaseDataSource)
287 0 : return false;
288 0 : return m_poBaseDataSource->IsLayerPrivate(iLayer);
289 : }
290 :
291 36 : int OGRDataSourceWithTransaction::TestCapability(const char *pszCap)
292 : {
293 36 : if (!m_poBaseDataSource)
294 0 : return FALSE;
295 :
296 36 : if (EQUAL(pszCap, ODsCEmulatedTransactions))
297 0 : return TRUE;
298 :
299 36 : return m_poBaseDataSource->TestCapability(pszCap);
300 : }
301 :
302 150 : OGRLayer *OGRDataSourceWithTransaction::ICreateLayer(
303 : const char *pszName, const OGRGeomFieldDefn *poGeomFieldDefn,
304 : CSLConstList papszOptions)
305 : {
306 150 : if (!m_poBaseDataSource)
307 0 : return nullptr;
308 150 : return WrapLayer(m_poBaseDataSource->CreateLayer(pszName, poGeomFieldDefn,
309 150 : papszOptions));
310 : }
311 :
312 0 : OGRLayer *OGRDataSourceWithTransaction::CopyLayer(OGRLayer *poSrcLayer,
313 : const char *pszNewName,
314 : char **papszOptions)
315 : {
316 0 : if (!m_poBaseDataSource)
317 0 : return nullptr;
318 0 : return WrapLayer(
319 0 : m_poBaseDataSource->CopyLayer(poSrcLayer, pszNewName, papszOptions));
320 : }
321 :
322 0 : OGRStyleTable *OGRDataSourceWithTransaction::GetStyleTable()
323 : {
324 0 : if (!m_poBaseDataSource)
325 0 : return nullptr;
326 0 : return m_poBaseDataSource->GetStyleTable();
327 : }
328 :
329 0 : void OGRDataSourceWithTransaction::SetStyleTableDirectly(
330 : OGRStyleTable *poStyleTable)
331 : {
332 0 : if (!m_poBaseDataSource)
333 0 : return;
334 0 : m_poBaseDataSource->SetStyleTableDirectly(poStyleTable);
335 : }
336 :
337 7 : void OGRDataSourceWithTransaction::SetStyleTable(OGRStyleTable *poStyleTable)
338 : {
339 7 : if (!m_poBaseDataSource)
340 0 : return;
341 7 : m_poBaseDataSource->SetStyleTable(poStyleTable);
342 : }
343 :
344 7 : OGRLayer *OGRDataSourceWithTransaction::ExecuteSQL(const char *pszStatement,
345 : OGRGeometry *poSpatialFilter,
346 : const char *pszDialect)
347 : {
348 7 : if (!m_poBaseDataSource)
349 0 : return nullptr;
350 14 : OGRLayer *poLayer = m_poBaseDataSource->ExecuteSQL(
351 7 : pszStatement, poSpatialFilter, pszDialect);
352 7 : if (poLayer != nullptr)
353 6 : m_oSetExecuteSQLLayers.insert(poLayer);
354 7 : return poLayer;
355 : }
356 :
357 6 : void OGRDataSourceWithTransaction::ReleaseResultSet(OGRLayer *poResultsSet)
358 : {
359 6 : if (!m_poBaseDataSource)
360 0 : return;
361 6 : m_oSetExecuteSQLLayers.erase(poResultsSet);
362 6 : m_poBaseDataSource->ReleaseResultSet(poResultsSet);
363 : }
364 :
365 7 : CPLErr OGRDataSourceWithTransaction::FlushCache(bool bAtClosing)
366 : {
367 7 : if (!m_poBaseDataSource)
368 0 : return CE_None;
369 7 : return m_poBaseDataSource->FlushCache(bAtClosing);
370 : }
371 :
372 0 : OGRErr OGRDataSourceWithTransaction::StartTransaction(int bForce)
373 : {
374 0 : if (!m_poBaseDataSource)
375 0 : return OGRERR_FAILURE;
376 0 : if (!bForce)
377 : {
378 0 : CPLError(CE_Failure, CPLE_NotSupported,
379 : "Transactions only supported in forced mode");
380 0 : return OGRERR_UNSUPPORTED_OPERATION;
381 : }
382 0 : if (!m_oSetExecuteSQLLayers.empty())
383 : {
384 0 : CPLError(CE_Failure, CPLE_NotSupported,
385 : "Cannot start transaction while a layer returned by "
386 : "ExecuteSQL() hasn't been released.");
387 0 : return OGRERR_FAILURE;
388 : }
389 0 : if (m_bInTransaction)
390 : {
391 0 : CPLError(CE_Failure, CPLE_AppDefined,
392 : "Transaction is already in progress");
393 0 : return OGRERR_FAILURE;
394 : }
395 0 : int bHasReopenedDS = FALSE;
396 0 : OGRErr eErr = m_poTransactionBehavior->StartTransaction(m_poBaseDataSource,
397 0 : bHasReopenedDS);
398 0 : if (bHasReopenedDS)
399 0 : RemapLayers();
400 0 : if (eErr == OGRERR_NONE)
401 0 : m_bInTransaction = TRUE;
402 0 : return eErr;
403 : }
404 :
405 0 : OGRErr OGRDataSourceWithTransaction::CommitTransaction()
406 : {
407 0 : if (!m_poBaseDataSource)
408 0 : return OGRERR_FAILURE;
409 0 : if (!m_bInTransaction)
410 : {
411 0 : CPLError(CE_Failure, CPLE_AppDefined, "No transaction in progress");
412 0 : return OGRERR_FAILURE;
413 : }
414 0 : if (!m_oSetExecuteSQLLayers.empty())
415 : {
416 0 : CPLError(CE_Failure, CPLE_NotSupported,
417 : "Cannot interrupt transaction while a layer returned by "
418 : "ExecuteSQL() hasn't been released.");
419 0 : return OGRERR_FAILURE;
420 : }
421 0 : m_bInTransaction = FALSE;
422 0 : int bHasReopenedDS = FALSE;
423 0 : OGRErr eErr = m_poTransactionBehavior->CommitTransaction(m_poBaseDataSource,
424 0 : bHasReopenedDS);
425 0 : if (bHasReopenedDS)
426 0 : RemapLayers();
427 0 : return eErr;
428 : }
429 :
430 0 : OGRErr OGRDataSourceWithTransaction::RollbackTransaction()
431 : {
432 0 : if (!m_poBaseDataSource)
433 0 : return OGRERR_FAILURE;
434 0 : if (!m_bInTransaction)
435 : {
436 0 : CPLError(CE_Failure, CPLE_AppDefined, "No transaction in progress");
437 0 : return OGRERR_FAILURE;
438 : }
439 0 : if (!m_oSetExecuteSQLLayers.empty())
440 : {
441 0 : CPLError(CE_Failure, CPLE_NotSupported,
442 : "Cannot interrupt transaction while a layer returned by "
443 : "ExecuteSQL() hasn't been released.");
444 0 : return OGRERR_FAILURE;
445 : }
446 0 : m_bInTransaction = FALSE;
447 0 : int bHasReopenedDS = FALSE;
448 0 : OGRErr eErr = m_poTransactionBehavior->RollbackTransaction(
449 0 : m_poBaseDataSource, bHasReopenedDS);
450 0 : if (bHasReopenedDS)
451 0 : RemapLayers();
452 0 : return eErr;
453 : }
454 :
455 1 : std::vector<std::string> OGRDataSourceWithTransaction::GetFieldDomainNames(
456 : CSLConstList papszOptions) const
457 : {
458 1 : if (!m_poBaseDataSource)
459 0 : return std::vector<std::string>();
460 1 : return m_poBaseDataSource->GetFieldDomainNames(papszOptions);
461 : }
462 :
463 : const OGRFieldDomain *
464 10 : OGRDataSourceWithTransaction::GetFieldDomain(const std::string &name) const
465 : {
466 10 : if (!m_poBaseDataSource)
467 0 : return nullptr;
468 10 : return m_poBaseDataSource->GetFieldDomain(name);
469 : }
470 :
471 4 : bool OGRDataSourceWithTransaction::AddFieldDomain(
472 : std::unique_ptr<OGRFieldDomain> &&domain, std::string &failureReason)
473 : {
474 4 : if (!m_poBaseDataSource)
475 0 : return false;
476 4 : return m_poBaseDataSource->AddFieldDomain(std::move(domain), failureReason);
477 : }
478 :
479 2 : bool OGRDataSourceWithTransaction::DeleteFieldDomain(const std::string &name,
480 : std::string &failureReason)
481 : {
482 2 : if (!m_poBaseDataSource)
483 0 : return false;
484 2 : return m_poBaseDataSource->DeleteFieldDomain(name, failureReason);
485 : }
486 :
487 1 : bool OGRDataSourceWithTransaction::UpdateFieldDomain(
488 : std::unique_ptr<OGRFieldDomain> &&domain, std::string &failureReason)
489 : {
490 1 : if (!m_poBaseDataSource)
491 0 : return false;
492 1 : return m_poBaseDataSource->UpdateFieldDomain(std::move(domain),
493 1 : failureReason);
494 : }
495 :
496 0 : std::vector<std::string> OGRDataSourceWithTransaction::GetRelationshipNames(
497 : CSLConstList papszOptions) const
498 : {
499 0 : if (!m_poBaseDataSource)
500 0 : return {};
501 0 : return m_poBaseDataSource->GetRelationshipNames(papszOptions);
502 : }
503 :
504 : const GDALRelationship *
505 0 : OGRDataSourceWithTransaction::GetRelationship(const std::string &name) const
506 : {
507 0 : if (!m_poBaseDataSource)
508 0 : return nullptr;
509 0 : return m_poBaseDataSource->GetRelationship(name);
510 : }
511 :
512 0 : std::shared_ptr<GDALGroup> OGRDataSourceWithTransaction::GetRootGroup() const
513 : {
514 0 : if (!m_poBaseDataSource)
515 0 : return nullptr;
516 0 : return m_poBaseDataSource->GetRootGroup();
517 : }
518 :
519 1 : char **OGRDataSourceWithTransaction::GetMetadata(const char *pszDomain)
520 : {
521 1 : if (!m_poBaseDataSource)
522 0 : return nullptr;
523 1 : return m_poBaseDataSource->GetMetadata(pszDomain);
524 : }
525 :
526 0 : CPLErr OGRDataSourceWithTransaction::SetMetadata(char **papszMetadata,
527 : const char *pszDomain)
528 : {
529 0 : if (!m_poBaseDataSource)
530 0 : return CE_Failure;
531 0 : return m_poBaseDataSource->SetMetadata(papszMetadata, pszDomain);
532 : }
533 :
534 151 : const char *OGRDataSourceWithTransaction::GetMetadataItem(const char *pszName,
535 : const char *pszDomain)
536 : {
537 151 : if (!m_poBaseDataSource)
538 0 : return nullptr;
539 151 : return m_poBaseDataSource->GetMetadataItem(pszName, pszDomain);
540 : }
541 :
542 0 : CPLErr OGRDataSourceWithTransaction::SetMetadataItem(const char *pszName,
543 : const char *pszValue,
544 : const char *pszDomain)
545 : {
546 0 : if (!m_poBaseDataSource)
547 0 : return CE_Failure;
548 0 : return m_poBaseDataSource->SetMetadataItem(pszName, pszValue, pszDomain);
549 : }
550 :
551 : /************************************************************************/
552 : /* OGRLayerWithTransaction */
553 : /************************************************************************/
554 :
555 190 : OGRLayerWithTransaction::OGRLayerWithTransaction(
556 190 : OGRDataSourceWithTransaction *poDS, OGRLayer *poBaseLayer)
557 : : OGRLayerDecorator(poBaseLayer, FALSE), m_poDS(poDS),
558 190 : m_poFeatureDefn(nullptr)
559 : {
560 190 : }
561 :
562 380 : OGRLayerWithTransaction::~OGRLayerWithTransaction()
563 : {
564 190 : if (m_poFeatureDefn)
565 132 : m_poFeatureDefn->Release();
566 380 : }
567 :
568 3347 : OGRFeatureDefn *OGRLayerWithTransaction::GetLayerDefn()
569 : {
570 3347 : if (!m_poDecoratedLayer)
571 : {
572 0 : if (m_poFeatureDefn == nullptr)
573 : {
574 0 : m_poFeatureDefn = new OGRFeatureDefn(GetDescription());
575 0 : m_poFeatureDefn->Reference();
576 : }
577 0 : return m_poFeatureDefn;
578 : }
579 3347 : else if (m_poFeatureDefn == nullptr)
580 : {
581 132 : OGRFeatureDefn *poSrcFeatureDefn = m_poDecoratedLayer->GetLayerDefn();
582 132 : m_poFeatureDefn = poSrcFeatureDefn->Clone();
583 132 : m_poFeatureDefn->Reference();
584 : }
585 3347 : return m_poFeatureDefn;
586 : }
587 :
588 1369 : OGRErr OGRLayerWithTransaction::CreateField(const OGRFieldDefn *poField,
589 : int bApproxOK)
590 : {
591 1369 : if (!m_poDecoratedLayer)
592 0 : return OGRERR_FAILURE;
593 1369 : int nFields = m_poDecoratedLayer->GetLayerDefn()->GetFieldCount();
594 1369 : OGRErr eErr = m_poDecoratedLayer->CreateField(poField, bApproxOK);
595 1390 : if (m_poFeatureDefn && eErr == OGRERR_NONE &&
596 21 : m_poDecoratedLayer->GetLayerDefn()->GetFieldCount() == nFields + 1)
597 : {
598 42 : m_poFeatureDefn->AddFieldDefn(
599 21 : m_poDecoratedLayer->GetLayerDefn()->GetFieldDefn(nFields));
600 : }
601 1369 : return eErr;
602 : }
603 :
604 0 : OGRErr OGRLayerWithTransaction::CreateGeomField(const OGRGeomFieldDefn *poField,
605 : int bApproxOK)
606 : {
607 0 : if (!m_poDecoratedLayer)
608 0 : return OGRERR_FAILURE;
609 0 : int nFields = m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldCount();
610 0 : OGRErr eErr = m_poDecoratedLayer->CreateGeomField(poField, bApproxOK);
611 0 : if (m_poFeatureDefn && eErr == OGRERR_NONE &&
612 0 : m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldCount() == nFields + 1)
613 : {
614 0 : m_poFeatureDefn->AddGeomFieldDefn(
615 0 : m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldDefn(nFields));
616 : }
617 0 : return eErr;
618 : }
619 :
620 1 : OGRErr OGRLayerWithTransaction::DeleteField(int iField)
621 : {
622 1 : if (!m_poDecoratedLayer)
623 0 : return OGRERR_FAILURE;
624 1 : OGRErr eErr = m_poDecoratedLayer->DeleteField(iField);
625 1 : if (m_poFeatureDefn && eErr == OGRERR_NONE)
626 1 : m_poFeatureDefn->DeleteFieldDefn(iField);
627 1 : return eErr;
628 : }
629 :
630 0 : OGRErr OGRLayerWithTransaction::ReorderFields(int *panMap)
631 : {
632 0 : if (!m_poDecoratedLayer)
633 0 : return OGRERR_FAILURE;
634 0 : OGRErr eErr = m_poDecoratedLayer->ReorderFields(panMap);
635 0 : if (m_poFeatureDefn && eErr == OGRERR_NONE)
636 0 : m_poFeatureDefn->ReorderFieldDefns(panMap);
637 0 : return eErr;
638 : }
639 :
640 0 : OGRErr OGRLayerWithTransaction::AlterFieldDefn(int iField,
641 : OGRFieldDefn *poNewFieldDefn,
642 : int nFlagsIn)
643 : {
644 0 : if (!m_poDecoratedLayer)
645 0 : return OGRERR_FAILURE;
646 : OGRErr eErr =
647 0 : m_poDecoratedLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
648 0 : if (m_poFeatureDefn && eErr == OGRERR_NONE)
649 : {
650 : OGRFieldDefn *poSrcFieldDefn =
651 0 : m_poDecoratedLayer->GetLayerDefn()->GetFieldDefn(iField);
652 0 : OGRFieldDefn *poDstFieldDefn = m_poFeatureDefn->GetFieldDefn(iField);
653 0 : poDstFieldDefn->SetName(poSrcFieldDefn->GetNameRef());
654 0 : poDstFieldDefn->SetType(poSrcFieldDefn->GetType());
655 0 : poDstFieldDefn->SetSubType(poSrcFieldDefn->GetSubType());
656 0 : poDstFieldDefn->SetWidth(poSrcFieldDefn->GetWidth());
657 0 : poDstFieldDefn->SetPrecision(poSrcFieldDefn->GetPrecision());
658 0 : poDstFieldDefn->SetDefault(poSrcFieldDefn->GetDefault());
659 0 : poDstFieldDefn->SetNullable(poSrcFieldDefn->IsNullable());
660 0 : poDstFieldDefn->SetUnique(poSrcFieldDefn->IsUnique());
661 0 : poDstFieldDefn->SetDomainName(poSrcFieldDefn->GetDomainName());
662 0 : poDstFieldDefn->SetComment(poSrcFieldDefn->GetComment());
663 : }
664 0 : return eErr;
665 : }
666 :
667 0 : OGRErr OGRLayerWithTransaction::AlterGeomFieldDefn(
668 : int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
669 : {
670 0 : if (!m_poDecoratedLayer)
671 0 : return OGRERR_FAILURE;
672 0 : OGRErr eErr = m_poDecoratedLayer->AlterGeomFieldDefn(
673 0 : iGeomField, poNewGeomFieldDefn, nFlagsIn);
674 0 : if (m_poFeatureDefn && eErr == OGRERR_NONE)
675 : {
676 : const auto poSrcFieldDefn =
677 0 : m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomField);
678 0 : auto poDstFieldDefn = m_poFeatureDefn->GetGeomFieldDefn(iGeomField);
679 0 : poDstFieldDefn->SetName(poSrcFieldDefn->GetNameRef());
680 0 : poDstFieldDefn->SetType(poSrcFieldDefn->GetType());
681 0 : poDstFieldDefn->SetSpatialRef(poSrcFieldDefn->GetSpatialRef());
682 0 : poDstFieldDefn->SetNullable(poSrcFieldDefn->IsNullable());
683 : }
684 0 : return eErr;
685 : }
686 :
687 149 : OGRFeature *OGRLayerWithTransaction::GetNextFeature()
688 : {
689 149 : if (!m_poDecoratedLayer)
690 0 : return nullptr;
691 149 : OGRFeature *poSrcFeature = m_poDecoratedLayer->GetNextFeature();
692 149 : if (!poSrcFeature)
693 13 : return nullptr;
694 136 : OGRFeature *poFeature = new OGRFeature(GetLayerDefn());
695 136 : poFeature->SetFrom(poSrcFeature);
696 136 : poFeature->SetFID(poSrcFeature->GetFID());
697 136 : delete poSrcFeature;
698 136 : return poFeature;
699 : }
700 :
701 18 : OGRFeature *OGRLayerWithTransaction::GetFeature(GIntBig nFID)
702 : {
703 18 : if (!m_poDecoratedLayer)
704 0 : return nullptr;
705 18 : OGRFeature *poSrcFeature = m_poDecoratedLayer->GetFeature(nFID);
706 18 : if (!poSrcFeature)
707 4 : return nullptr;
708 14 : OGRFeature *poFeature = new OGRFeature(GetLayerDefn());
709 14 : poFeature->SetFrom(poSrcFeature);
710 14 : poFeature->SetFID(poSrcFeature->GetFID());
711 14 : delete poSrcFeature;
712 14 : return poFeature;
713 : }
714 :
715 7 : OGRErr OGRLayerWithTransaction::ISetFeature(OGRFeature *poFeature)
716 : {
717 7 : if (!m_poDecoratedLayer)
718 0 : return OGRERR_FAILURE;
719 : OGRFeature *poSrcFeature =
720 7 : new OGRFeature(m_poDecoratedLayer->GetLayerDefn());
721 7 : poSrcFeature->SetFrom(poFeature);
722 7 : poSrcFeature->SetFID(poFeature->GetFID());
723 7 : OGRErr eErr = m_poDecoratedLayer->SetFeature(poSrcFeature);
724 7 : delete poSrcFeature;
725 7 : return eErr;
726 : }
727 :
728 1568 : OGRErr OGRLayerWithTransaction::ICreateFeature(OGRFeature *poFeature)
729 : {
730 1568 : if (!m_poDecoratedLayer)
731 0 : return OGRERR_FAILURE;
732 : OGRFeature *poSrcFeature =
733 1568 : new OGRFeature(m_poDecoratedLayer->GetLayerDefn());
734 1568 : poSrcFeature->SetFrom(poFeature);
735 1568 : poSrcFeature->SetFID(poFeature->GetFID());
736 1568 : OGRErr eErr = m_poDecoratedLayer->CreateFeature(poSrcFeature);
737 1568 : poFeature->SetFID(poSrcFeature->GetFID());
738 1568 : delete poSrcFeature;
739 1568 : return eErr;
740 : }
741 :
742 0 : OGRErr OGRLayerWithTransaction::IUpsertFeature(OGRFeature *poFeature)
743 : {
744 0 : if (!m_poDecoratedLayer)
745 0 : return OGRERR_FAILURE;
746 : OGRFeature *poSrcFeature =
747 0 : new OGRFeature(m_poDecoratedLayer->GetLayerDefn());
748 0 : poSrcFeature->SetFrom(poFeature);
749 0 : poSrcFeature->SetFID(poFeature->GetFID());
750 0 : OGRErr eErr = m_poDecoratedLayer->UpsertFeature(poSrcFeature);
751 0 : delete poSrcFeature;
752 0 : return eErr;
753 : }
754 :
755 8 : OGRErr OGRLayerWithTransaction::Rename(const char *pszNewName)
756 : {
757 8 : if (!m_poDecoratedLayer)
758 0 : return OGRERR_FAILURE;
759 8 : OGRErr eErr = m_poDecoratedLayer->Rename(pszNewName);
760 8 : if (eErr == OGRERR_NONE)
761 : {
762 4 : SetDescription(m_poDecoratedLayer->GetDescription());
763 4 : if (m_poFeatureDefn)
764 4 : m_poFeatureDefn->SetName(
765 4 : m_poDecoratedLayer->GetLayerDefn()->GetName());
766 : }
767 8 : return eErr;
768 : }
|