LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/generic - ogremulatedtransaction.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 174 360 48.3 %
Date: 2024-11-21 22:18:42 Functions: 35 54 64.8 %

          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             : }

Generated by: LCOV version 1.14