LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/generic - ogreditablelayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 351 392 89.5 %
Date: 2025-02-20 10:14:44 Functions: 37 43 86.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGREditableLayer class
       5             :  * Author:   Even Rouault <even.rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2015, Even Rouault <even.rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "ogreditablelayer.h"
      14             : #include "../mem/ogr_mem.h"
      15             : 
      16             : #include <map>
      17             : 
      18             : //! @cond Doxygen_Suppress
      19             : 
      20             : /************************************************************************/
      21             : /*                  ~IOGREditableLayerSynchronizer()                    */
      22             : /************************************************************************/
      23             : 
      24         371 : IOGREditableLayerSynchronizer::~IOGREditableLayerSynchronizer()
      25             : {
      26         371 : }
      27             : 
      28             : /************************************************************************/
      29             : /*                          OGREditableLayer()                          */
      30             : /************************************************************************/
      31             : 
      32         371 : OGREditableLayer::OGREditableLayer(
      33             :     OGRLayer *poDecoratedLayer, bool bTakeOwnershipDecoratedLayer,
      34             :     IOGREditableLayerSynchronizer *poSynchronizer,
      35           0 :     bool bTakeOwnershipSynchronizer)
      36             :     : OGRLayerDecorator(poDecoratedLayer, bTakeOwnershipDecoratedLayer),
      37             :       m_poSynchronizer(poSynchronizer),
      38             :       m_bTakeOwnershipSynchronizer(bTakeOwnershipSynchronizer),
      39         371 :       m_poEditableFeatureDefn(poDecoratedLayer->GetLayerDefn()->Clone()),
      40         371 :       m_nNextFID(0), m_poMemLayer(new OGRMemLayer("", nullptr, wkbNone)),
      41             :       m_bStructureModified(false), m_bSupportsCreateGeomField(false),
      42        1113 :       m_bSupportsCurveGeometries(false)
      43             : {
      44         371 :     m_poEditableFeatureDefn->Reference();
      45             : 
      46        1348 :     for (int i = 0; i < m_poEditableFeatureDefn->GetFieldCount(); i++)
      47         977 :         m_poMemLayer->CreateField(m_poEditableFeatureDefn->GetFieldDefn(i));
      48             : 
      49         549 :     for (int i = 0; i < m_poEditableFeatureDefn->GetGeomFieldCount(); i++)
      50         356 :         m_poMemLayer->CreateGeomField(
      51         178 :             m_poEditableFeatureDefn->GetGeomFieldDefn(i));
      52             : 
      53         371 :     m_oIter = m_oSetCreated.begin();
      54         371 : }
      55             : 
      56             : /************************************************************************/
      57             : /*                         ~OGREditableLayer()                          */
      58             : /************************************************************************/
      59             : 
      60         371 : OGREditableLayer::~OGREditableLayer()
      61             : {
      62         371 :     OGREditableLayer::SyncToDisk();
      63             : 
      64         371 :     m_poEditableFeatureDefn->Release();
      65         371 :     delete m_poMemLayer;
      66         371 :     if (m_bTakeOwnershipSynchronizer)
      67         371 :         delete m_poSynchronizer;
      68         371 : }
      69             : 
      70             : /************************************************************************/
      71             : /*                           SetNextFID()                               */
      72             : /************************************************************************/
      73             : 
      74           3 : void OGREditableLayer::SetNextFID(GIntBig nNextFID)
      75             : {
      76           3 :     m_nNextFID = nNextFID;
      77           3 : }
      78             : 
      79             : /************************************************************************/
      80             : /*                       SetSupportsCurveGeometries()                   */
      81             : /************************************************************************/
      82             : 
      83         208 : void OGREditableLayer::SetSupportsCurveGeometries(bool bSupportsCurveGeometries)
      84             : {
      85         208 :     m_bSupportsCurveGeometries = bSupportsCurveGeometries;
      86         208 : }
      87             : 
      88             : /************************************************************************/
      89             : /*                       SetSupportsCreateGeomField()                   */
      90             : /************************************************************************/
      91             : 
      92         208 : void OGREditableLayer::SetSupportsCreateGeomField(bool bSupportsCreateGeomField)
      93             : {
      94         208 :     m_bSupportsCreateGeomField = bSupportsCreateGeomField;
      95         208 : }
      96             : 
      97             : /************************************************************************/
      98             : /*                           DetectNextFID()                            */
      99             : /************************************************************************/
     100             : 
     101           6 : void OGREditableLayer::DetectNextFID()
     102             : {
     103           6 :     if (m_nNextFID > 0)
     104           1 :         return;
     105           5 :     m_nNextFID = 0;
     106           5 :     m_poDecoratedLayer->ResetReading();
     107           5 :     OGRFeature *poFeat = nullptr;
     108          26 :     while ((poFeat = m_poDecoratedLayer->GetNextFeature()) != nullptr)
     109             :     {
     110          21 :         if (poFeat->GetFID() > m_nNextFID)
     111          20 :             m_nNextFID = poFeat->GetFID();
     112          21 :         delete poFeat;
     113             :     }
     114           5 :     m_nNextFID++;
     115             : }
     116             : 
     117             : /************************************************************************/
     118             : /*                         GetSrcGeomFieldIndex()                       */
     119             : /************************************************************************/
     120             : 
     121         168 : int OGREditableLayer::GetSrcGeomFieldIndex(int iGeomField)
     122             : {
     123         336 :     if (m_poDecoratedLayer == nullptr || iGeomField < 0 ||
     124         168 :         iGeomField >= m_poEditableFeatureDefn->GetGeomFieldCount())
     125             :     {
     126          12 :         return -1;
     127             :     }
     128             :     OGRGeomFieldDefn *poGeomFieldDefn =
     129         156 :         m_poEditableFeatureDefn->GetGeomFieldDefn(iGeomField);
     130         312 :     return m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldIndex(
     131         156 :         poGeomFieldDefn->GetNameRef());
     132             : }
     133             : 
     134             : /************************************************************************/
     135             : /*                            ResetReading()                            */
     136             : /************************************************************************/
     137             : 
     138         548 : void OGREditableLayer::ResetReading()
     139             : {
     140         548 :     if (!m_poDecoratedLayer)
     141           0 :         return;
     142         548 :     m_poDecoratedLayer->ResetReading();
     143         548 :     m_oIter = m_oSetCreated.begin();
     144             : }
     145             : 
     146             : /************************************************************************/
     147             : /*                             Translate()                              */
     148             : /************************************************************************/
     149             : 
     150        1235 : OGRFeature *OGREditableLayer::Translate(OGRFeatureDefn *poTargetDefn,
     151             :                                         OGRFeature *poSrcFeature,
     152             :                                         bool bCanStealSrcFeature,
     153             :                                         bool bHideDeletedFields)
     154             : {
     155        1235 :     if (poSrcFeature == nullptr)
     156          20 :         return nullptr;
     157        1215 :     OGRFeature *poRet = new OGRFeature(poTargetDefn);
     158             : 
     159        1215 :     std::map<CPLString, int> oMapTargetFieldNameToIdx;
     160        1215 :     std::map<CPLString, int> *poMap = &oMapTargetFieldNameToIdx;
     161        2029 :     if (poTargetDefn == m_poEditableFeatureDefn &&
     162         814 :         !m_oMapEditableFDefnFieldNameToIdx.empty())
     163             :     {
     164         676 :         poMap = &m_oMapEditableFDefnFieldNameToIdx;
     165             :     }
     166             :     else
     167             :     {
     168        3448 :         for (int iField = 0; iField < poTargetDefn->GetFieldCount(); iField++)
     169             :         {
     170        2909 :             oMapTargetFieldNameToIdx[poTargetDefn->GetFieldDefn(iField)
     171        2909 :                                          ->GetNameRef()] = iField;
     172             :         }
     173         539 :         if (poTargetDefn == m_poEditableFeatureDefn)
     174             :         {
     175             :             m_oMapEditableFDefnFieldNameToIdx =
     176         138 :                 std::move(oMapTargetFieldNameToIdx);
     177         138 :             poMap = &m_oMapEditableFDefnFieldNameToIdx;
     178             :         }
     179             :     }
     180             : 
     181             :     int *panMap = static_cast<int *>(
     182        1215 :         CPLMalloc(sizeof(int) * poSrcFeature->GetFieldCount()));
     183       10846 :     for (int iField = 0; iField < poSrcFeature->GetFieldCount(); iField++)
     184             :     {
     185             :         const char *pszFieldName =
     186        9631 :             poSrcFeature->GetFieldDefnRef(iField)->GetNameRef();
     187       16648 :         if (bHideDeletedFields &&
     188       16648 :             m_oSetDeletedFields.find(pszFieldName) != m_oSetDeletedFields.end())
     189             :         {
     190           7 :             panMap[iField] = -1;
     191             :         }
     192             :         else
     193             :         {
     194        9624 :             auto oIter = poMap->find(pszFieldName);
     195        9624 :             panMap[iField] = (oIter == poMap->end()) ? -1 : oIter->second;
     196             :         }
     197             :     }
     198        1215 :     poRet->SetFieldsFrom(poSrcFeature, panMap, TRUE);
     199        1215 :     CPLFree(panMap);
     200             : 
     201        2153 :     for (int i = 0; i < poTargetDefn->GetGeomFieldCount(); i++)
     202             :     {
     203         938 :         OGRGeomFieldDefn *poGeomField = poTargetDefn->GetGeomFieldDefn(i);
     204             :         int iSrcGeomFieldIdx =
     205         938 :             poTargetDefn->GetGeomFieldIndex(poGeomField->GetNameRef());
     206         938 :         if (iSrcGeomFieldIdx >= 0)
     207             :         {
     208         938 :             if (bCanStealSrcFeature)
     209             :             {
     210         728 :                 poRet->SetGeomFieldDirectly(
     211             :                     i, poSrcFeature->StealGeometry(iSrcGeomFieldIdx));
     212             :             }
     213             :             else
     214             :             {
     215         210 :                 poRet->SetGeomField(
     216         210 :                     i, poSrcFeature->GetGeomFieldRef(iSrcGeomFieldIdx));
     217             :             }
     218         938 :             OGRGeometry *poGeom = poRet->GetGeomFieldRef(i);
     219         938 :             if (poGeom != nullptr)
     220         868 :                 poGeom->assignSpatialReference(poGeomField->GetSpatialRef());
     221             :         }
     222             :     }
     223        1215 :     poRet->SetStyleString(poSrcFeature->GetStyleString());
     224        1215 :     poRet->SetNativeData(poSrcFeature->GetNativeData());
     225        1215 :     poRet->SetNativeMediaType(poSrcFeature->GetNativeMediaType());
     226        1215 :     poRet->SetFID(poSrcFeature->GetFID());
     227             : 
     228        1215 :     return poRet;
     229             : }
     230             : 
     231             : /************************************************************************/
     232             : /*                           GetNextFeature()                           */
     233             : /************************************************************************/
     234             : 
     235         772 : OGRFeature *OGREditableLayer::GetNextFeature()
     236             : {
     237         772 :     if (!m_poDecoratedLayer)
     238           0 :         return nullptr;
     239             :     while (true)
     240             :     {
     241         925 :         OGRFeature *poSrcFeature = m_poDecoratedLayer->GetNextFeature();
     242         925 :         bool bHideDeletedFields = true;
     243         925 :         if (poSrcFeature != nullptr)
     244             :         {
     245         745 :             const GIntBig nFID = poSrcFeature->GetFID();
     246         745 :             if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
     247             :             {
     248           6 :                 delete poSrcFeature;
     249           6 :                 continue;
     250             :             }
     251        1467 :             else if (m_oSetCreated.find(nFID) != m_oSetCreated.end() ||
     252        1467 :                      m_oSetEdited.find(nFID) != m_oSetEdited.end())
     253             :             {
     254          48 :                 delete poSrcFeature;
     255          48 :                 poSrcFeature = m_poMemLayer->GetFeature(nFID);
     256          48 :                 bHideDeletedFields = false;
     257             :             }
     258             :         }
     259             :         else
     260             :         {
     261         180 :             if (m_oIter != m_oSetCreated.end())
     262             :             {
     263          17 :                 poSrcFeature = m_poMemLayer->GetFeature(*m_oIter);
     264          17 :                 bHideDeletedFields = false;
     265          17 :                 ++m_oIter;
     266             :             }
     267             :             else
     268             :             {
     269         163 :                 return nullptr;
     270             :             }
     271             :         }
     272         756 :         OGRFeature *poRet = Translate(m_poEditableFeatureDefn, poSrcFeature,
     273             :                                       true, bHideDeletedFields);
     274         756 :         delete poSrcFeature;
     275             : 
     276        1648 :         if ((m_poFilterGeom == nullptr ||
     277        1510 :              FilterGeometry(poRet->GetGeomFieldRef(m_iGeomFieldFilter))) &&
     278         754 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poRet)))
     279             :         {
     280         609 :             return poRet;
     281             :         }
     282         147 :         delete poRet;
     283         153 :     }
     284             : }
     285             : 
     286             : /************************************************************************/
     287             : /*                          SetNextByIndex()                            */
     288             : /************************************************************************/
     289             : 
     290          18 : OGRErr OGREditableLayer::SetNextByIndex(GIntBig nIndex)
     291             : {
     292          31 :     if (m_poDecoratedLayer != nullptr && m_oSetCreated.empty() &&
     293          49 :         m_oSetDeleted.empty() && m_oSetEdited.empty())
     294             :     {
     295          13 :         return m_poDecoratedLayer->SetNextByIndex(nIndex);
     296             :     }
     297             : 
     298           5 :     return OGRLayer::SetNextByIndex(nIndex);
     299             : }
     300             : 
     301             : /************************************************************************/
     302             : /*                              GetFeature()                            */
     303             : /************************************************************************/
     304             : 
     305          78 : OGRFeature *OGREditableLayer::GetFeature(GIntBig nFID)
     306             : {
     307          78 :     if (!m_poDecoratedLayer)
     308           0 :         return nullptr;
     309             : 
     310          78 :     OGRFeature *poSrcFeature = nullptr;
     311          78 :     bool bHideDeletedFields = true;
     312         151 :     if (m_oSetCreated.find(nFID) != m_oSetCreated.end() ||
     313         151 :         m_oSetEdited.find(nFID) != m_oSetEdited.end())
     314             :     {
     315          20 :         poSrcFeature = m_poMemLayer->GetFeature(nFID);
     316          20 :         bHideDeletedFields = false;
     317             :     }
     318          58 :     else if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
     319             :     {
     320           4 :         poSrcFeature = nullptr;
     321             :     }
     322             :     else
     323             :     {
     324          54 :         poSrcFeature = m_poDecoratedLayer->GetFeature(nFID);
     325             :     }
     326          78 :     OGRFeature *poRet = Translate(m_poEditableFeatureDefn, poSrcFeature, true,
     327             :                                   bHideDeletedFields);
     328          78 :     delete poSrcFeature;
     329          78 :     return poRet;
     330             : }
     331             : 
     332             : /************************************************************************/
     333             : /*                            ISetFeature()                             */
     334             : /************************************************************************/
     335             : 
     336          27 : OGRErr OGREditableLayer::ISetFeature(OGRFeature *poFeature)
     337             : {
     338          27 :     if (!m_poDecoratedLayer)
     339           0 :         return OGRERR_FAILURE;
     340             : 
     341          40 :     if (!m_bStructureModified && m_oSetDeleted.empty() &&
     342          74 :         m_oSetEdited.empty() && m_oSetCreated.empty() &&
     343           7 :         m_poDecoratedLayer->TestCapability(OLCRandomWrite))
     344             :     {
     345           0 :         OGRFeature *poTargetFeature = Translate(
     346           0 :             m_poDecoratedLayer->GetLayerDefn(), poFeature, false, false);
     347           0 :         OGRErr eErr = m_poDecoratedLayer->SetFeature(poTargetFeature);
     348           0 :         delete poTargetFeature;
     349           0 :         return eErr;
     350             :     }
     351             : 
     352             :     OGRFeature *poMemFeature =
     353          27 :         Translate(m_poMemLayer->GetLayerDefn(), poFeature, false, false);
     354          27 :     OGRErr eErr = m_poMemLayer->SetFeature(poMemFeature);
     355          27 :     if (eErr == OGRERR_NONE)
     356             :     {
     357          23 :         const GIntBig nFID = poMemFeature->GetFID();
     358          23 :         m_oSetDeleted.erase(nFID);
     359             :         // If the feature isn't in the created list, insert it in the edited
     360             :         // list
     361          23 :         if (m_oSetCreated.find(nFID) == m_oSetCreated.end())
     362             :         {
     363          21 :             m_oSetEdited.insert(nFID);
     364             :         }
     365          23 :         poFeature->SetFID(nFID);
     366             :     }
     367          27 :     delete poMemFeature;
     368             : 
     369          27 :     return eErr;
     370             : }
     371             : 
     372             : /************************************************************************/
     373             : /*                          ICreateFeature()                            */
     374             : /************************************************************************/
     375             : 
     376         374 : OGRErr OGREditableLayer::ICreateFeature(OGRFeature *poFeature)
     377             : {
     378         374 :     if (!m_poDecoratedLayer)
     379           0 :         return OGRERR_FAILURE;
     380             : 
     381         740 :     if (!m_bStructureModified && m_oSetDeleted.empty() &&
     382        1114 :         m_oSetCreated.empty() &&
     383         369 :         m_poDecoratedLayer->TestCapability(OLCSequentialWrite))
     384             :     {
     385         368 :         OGRFeature *poTargetFeature = Translate(
     386         368 :             m_poDecoratedLayer->GetLayerDefn(), poFeature, false, false);
     387         368 :         OGRErr eErr = m_poDecoratedLayer->CreateFeature(poTargetFeature);
     388         368 :         if (poFeature->GetFID() < 0)
     389         358 :             poFeature->SetFID(poTargetFeature->GetFID());
     390         368 :         delete poTargetFeature;
     391         368 :         return eErr;
     392             :     }
     393             : 
     394             :     OGRFeature *poMemFeature =
     395           6 :         Translate(m_poMemLayer->GetLayerDefn(), poFeature, false, false);
     396           6 :     DetectNextFID();
     397           6 :     if (poMemFeature->GetFID() < 0)
     398           4 :         poMemFeature->SetFID(m_nNextFID++);
     399           6 :     OGRErr eErr = m_poMemLayer->CreateFeature(poMemFeature);
     400           6 :     if (eErr == OGRERR_NONE)
     401             :     {
     402           6 :         const GIntBig nFID = poMemFeature->GetFID();
     403           6 :         m_oSetDeleted.erase(nFID);
     404           6 :         m_oSetEdited.erase(nFID);
     405           6 :         m_oSetCreated.insert(nFID);
     406           6 :         poFeature->SetFID(nFID);
     407             :     }
     408           6 :     delete poMemFeature;
     409             : 
     410           6 :     ResetReading();
     411             : 
     412           6 :     return eErr;
     413             : }
     414             : 
     415             : /************************************************************************/
     416             : /*                          IUpsertFeature()                            */
     417             : /************************************************************************/
     418             : 
     419           0 : OGRErr OGREditableLayer::IUpsertFeature(OGRFeature *poFeature)
     420             : {
     421             :     auto poFeatureExisting =
     422           0 :         std::unique_ptr<OGRFeature>(GetFeature(poFeature->GetFID()));
     423           0 :     if (poFeatureExisting)
     424             :     {
     425           0 :         return ISetFeature(poFeature);
     426             :     }
     427             :     else
     428             :     {
     429           0 :         return ICreateFeature(poFeature);
     430             :     }
     431             : }
     432             : 
     433             : /************************************************************************/
     434             : /*                            IUpdateFeature()                          */
     435             : /************************************************************************/
     436             : 
     437           6 : OGRErr OGREditableLayer::IUpdateFeature(OGRFeature *poFeature,
     438             :                                         int nUpdatedFieldsCount,
     439             :                                         const int *panUpdatedFieldsIdx,
     440             :                                         int nUpdatedGeomFieldsCount,
     441             :                                         const int *panUpdatedGeomFieldsIdx,
     442             :                                         bool bUpdateStyleString)
     443             : {
     444             :     // Do not use OGRLayerDecorator::IUpdateFeature() which will forward
     445             :     // to the decorated layer
     446           6 :     return OGRLayer::IUpdateFeature(
     447             :         poFeature, nUpdatedFieldsCount, panUpdatedFieldsIdx,
     448           6 :         nUpdatedGeomFieldsCount, panUpdatedGeomFieldsIdx, bUpdateStyleString);
     449             : }
     450             : 
     451             : /************************************************************************/
     452             : /*                          DeleteFeature()                             */
     453             : /************************************************************************/
     454             : 
     455          19 : OGRErr OGREditableLayer::DeleteFeature(GIntBig nFID)
     456             : {
     457          19 :     if (!m_poDecoratedLayer)
     458           0 :         return OGRERR_FAILURE;
     459             : 
     460             :     OGRErr eErr;
     461          19 :     if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
     462             :     {
     463           3 :         eErr = OGRERR_NON_EXISTING_FEATURE;
     464             :     }
     465             :     // cppcheck-suppress redundantIfRemove
     466          16 :     else if (m_oSetCreated.find(nFID) != m_oSetCreated.end())
     467             :     {
     468           1 :         m_oSetCreated.erase(nFID);
     469           1 :         eErr = m_poMemLayer->DeleteFeature(nFID);
     470             :     }
     471             :     // cppcheck-suppress redundantIfRemove
     472          15 :     else if (m_oSetEdited.find(nFID) != m_oSetEdited.end())
     473             :     {
     474           1 :         m_oSetEdited.erase(nFID);
     475           1 :         m_oSetDeleted.insert(nFID);
     476           1 :         eErr = m_poMemLayer->DeleteFeature(nFID);
     477             :     }
     478             :     else
     479             :     {
     480          14 :         OGRFeature *poFeature = m_poDecoratedLayer->GetFeature(nFID);
     481          14 :         if (poFeature != nullptr)
     482             :         {
     483           5 :             m_oSetDeleted.insert(nFID);
     484           5 :             eErr = OGRERR_NONE;
     485           5 :             delete poFeature;
     486             :         }
     487             :         else
     488             :         {
     489           9 :             eErr = OGRERR_NON_EXISTING_FEATURE;
     490             :         }
     491             :     }
     492             : 
     493          19 :     ResetReading();
     494             : 
     495          19 :     return eErr;
     496             : }
     497             : 
     498             : /************************************************************************/
     499             : /*                             GetGeomType()                            */
     500             : /************************************************************************/
     501             : 
     502         244 : OGRwkbGeometryType OGREditableLayer::GetGeomType()
     503             : {
     504         244 :     return OGRLayer::GetGeomType();
     505             : }
     506             : 
     507             : /************************************************************************/
     508             : /*                             GetLayerDefn()                           */
     509             : /************************************************************************/
     510             : 
     511        3057 : OGRFeatureDefn *OGREditableLayer::GetLayerDefn()
     512             : {
     513        3057 :     return m_poEditableFeatureDefn;
     514             : }
     515             : 
     516             : /************************************************************************/
     517             : /*                             GetSpatialRef()                          */
     518             : /************************************************************************/
     519             : 
     520          73 : OGRSpatialReference *OGREditableLayer::GetSpatialRef()
     521             : {
     522          73 :     return OGRLayer::GetSpatialRef();
     523             : }
     524             : 
     525             : /************************************************************************/
     526             : /*                           GetSpatialFilter()                         */
     527             : /************************************************************************/
     528             : 
     529          19 : OGRGeometry *OGREditableLayer::GetSpatialFilter()
     530             : {
     531          19 :     return OGRLayer::GetSpatialFilter();
     532             : }
     533             : 
     534             : /************************************************************************/
     535             : /*                           SetAttributeFilter()                       */
     536             : /************************************************************************/
     537             : 
     538         219 : OGRErr OGREditableLayer::SetAttributeFilter(const char *poAttrFilter)
     539             : {
     540         219 :     return OGRLayer::SetAttributeFilter(poAttrFilter);
     541             : }
     542             : 
     543             : /************************************************************************/
     544             : /*                           GetArrowStream()                           */
     545             : /************************************************************************/
     546             : 
     547          24 : bool OGREditableLayer::GetArrowStream(struct ArrowArrayStream *out_stream,
     548             :                                       CSLConstList papszOptions)
     549             : {
     550          24 :     return OGRLayer::GetArrowStream(out_stream, papszOptions);
     551             : }
     552             : 
     553             : /************************************************************************/
     554             : /*                          ISetSpatialFilter()                         */
     555             : /************************************************************************/
     556             : 
     557         149 : OGRErr OGREditableLayer::ISetSpatialFilter(int iGeomField,
     558             :                                            const OGRGeometry *poGeom)
     559             : {
     560         149 :     m_iGeomFieldFilter = iGeomField;
     561         149 :     if (InstallFilter(poGeom))
     562          50 :         ResetReading();
     563             : 
     564         149 :     OGRErr eErr = OGRERR_NONE;
     565         149 :     const int iSrcGeomFieldIdx = GetSrcGeomFieldIndex(iGeomField);
     566         149 :     if (iSrcGeomFieldIdx >= 0)
     567             :     {
     568         137 :         eErr = m_poDecoratedLayer->SetSpatialFilter(iSrcGeomFieldIdx, poGeom);
     569             :     }
     570         149 :     if (eErr == OGRERR_NONE)
     571         149 :         eErr = m_poMemLayer->SetSpatialFilter(iGeomField, poGeom);
     572         149 :     return eErr;
     573             : }
     574             : 
     575             : /************************************************************************/
     576             : /*                          GetFeatureCount()                           */
     577             : /************************************************************************/
     578             : 
     579         149 : GIntBig OGREditableLayer::GetFeatureCount(int bForce)
     580             : {
     581         149 :     if (!m_poDecoratedLayer)
     582           0 :         return 0;
     583         250 :     if (m_poAttrQuery == nullptr && m_poFilterGeom == nullptr &&
     584         399 :         m_oSetDeleted.empty() && m_oSetEdited.empty())
     585             :     {
     586         114 :         GIntBig nFC = m_poDecoratedLayer->GetFeatureCount(bForce);
     587         114 :         if (nFC >= 0)
     588             :         {
     589         114 :             nFC += m_oSetCreated.size();
     590             :         }
     591         114 :         return nFC;
     592             :     }
     593          35 :     return OGRLayer::GetFeatureCount(bForce);
     594             : }
     595             : 
     596             : /************************************************************************/
     597             : /*                              IGetExtent()                            */
     598             : /************************************************************************/
     599             : 
     600          19 : OGRErr OGREditableLayer::IGetExtent(int iGeomField, OGREnvelope *psExtent,
     601             :                                     bool bForce)
     602             : {
     603          19 :     if (!m_poDecoratedLayer)
     604           0 :         return OGRERR_FAILURE;
     605          19 :     int iSrcGeomFieldIdx = GetSrcGeomFieldIndex(iGeomField);
     606          19 :     if (iSrcGeomFieldIdx >= 0 && m_oSetEdited.empty() && m_oSetDeleted.empty())
     607             :     {
     608             :         OGRErr eErr =
     609          19 :             m_poDecoratedLayer->GetExtent(iSrcGeomFieldIdx, psExtent, bForce);
     610          19 :         if (eErr == OGRERR_NONE)
     611             :         {
     612          18 :             OGREnvelope sExtentMemLayer;
     613          18 :             if (m_poMemLayer->GetExtent(iGeomField, &sExtentMemLayer, bForce) ==
     614             :                 OGRERR_NONE)
     615             :             {
     616           1 :                 psExtent->Merge(sExtentMemLayer);
     617             :             }
     618             :         }
     619          19 :         return eErr;
     620             :     }
     621           0 :     return OGRLayer::IGetExtent(iGeomField, psExtent, bForce);
     622             : }
     623             : 
     624             : /************************************************************************/
     625             : /*                            TestCapability()                          */
     626             : /************************************************************************/
     627             : 
     628         690 : int OGREditableLayer::TestCapability(const char *pszCap)
     629             : {
     630         690 :     if (!m_poDecoratedLayer)
     631           0 :         return FALSE;
     632         690 :     if (EQUAL(pszCap, OLCSequentialWrite) || EQUAL(pszCap, OLCRandomWrite) ||
     633         641 :         EQUAL(pszCap, OLCCreateField) || EQUAL(pszCap, OLCDeleteField) ||
     634         592 :         EQUAL(pszCap, OLCReorderFields) || EQUAL(pszCap, OLCAlterFieldDefn) ||
     635         576 :         EQUAL(pszCap, OLCAlterGeomFieldDefn) || EQUAL(pszCap, OLCDeleteFeature))
     636             :     {
     637         176 :         return m_poDecoratedLayer->TestCapability(OLCCreateField) == TRUE ||
     638         176 :                m_poDecoratedLayer->TestCapability(OLCSequentialWrite) == TRUE;
     639             :     }
     640         570 :     if (EQUAL(pszCap, OLCCreateGeomField))
     641           1 :         return m_bSupportsCreateGeomField;
     642         569 :     if (EQUAL(pszCap, OLCCurveGeometries))
     643         226 :         return m_bSupportsCurveGeometries;
     644         343 :     if (EQUAL(pszCap, OLCTransactions))
     645           8 :         return FALSE;
     646             : 
     647         335 :     return m_poDecoratedLayer->TestCapability(pszCap);
     648             : }
     649             : 
     650             : /************************************************************************/
     651             : /*                            CreateField()                             */
     652             : /************************************************************************/
     653             : 
     654         605 : OGRErr OGREditableLayer::CreateField(const OGRFieldDefn *poField, int bApproxOK)
     655             : {
     656         605 :     if (!m_poDecoratedLayer)
     657           0 :         return OGRERR_FAILURE;
     658             : 
     659         605 :     m_oMapEditableFDefnFieldNameToIdx.clear();
     660             : 
     661        1209 :     if (!m_bStructureModified &&
     662         604 :         m_poDecoratedLayer->TestCapability(OLCCreateField))
     663             :     {
     664         602 :         OGRErr eErr = m_poDecoratedLayer->CreateField(poField, bApproxOK);
     665         602 :         if (eErr == OGRERR_NONE)
     666             :         {
     667         602 :             eErr = m_poMemLayer->CreateField(poField, bApproxOK);
     668         602 :             if (eErr == OGRERR_NONE)
     669             :             {
     670         602 :                 m_poEditableFeatureDefn->AddFieldDefn(poField);
     671             :             }
     672             :         }
     673         602 :         return eErr;
     674             :     }
     675             : 
     676           3 :     OGRErr eErr = m_poMemLayer->CreateField(poField, bApproxOK);
     677           3 :     if (eErr == OGRERR_NONE)
     678             :     {
     679           3 :         m_poEditableFeatureDefn->AddFieldDefn(poField);
     680           3 :         m_bStructureModified = true;
     681             :     }
     682           3 :     return eErr;
     683             : }
     684             : 
     685             : /************************************************************************/
     686             : /*                             DeleteField()                            */
     687             : /************************************************************************/
     688             : 
     689           4 : OGRErr OGREditableLayer::DeleteField(int iField)
     690             : {
     691           4 :     if (!m_poDecoratedLayer)
     692           0 :         return OGRERR_FAILURE;
     693             : 
     694           4 :     m_oMapEditableFDefnFieldNameToIdx.clear();
     695             : 
     696           4 :     CPLString osDeletedField;
     697           4 :     if (iField >= 0 && iField < m_poEditableFeatureDefn->GetFieldCount())
     698             :     {
     699             :         osDeletedField =
     700           3 :             m_poEditableFeatureDefn->GetFieldDefn(iField)->GetNameRef();
     701             :     }
     702             : 
     703           4 :     OGRErr eErr = m_poMemLayer->DeleteField(iField);
     704           4 :     if (eErr == OGRERR_NONE)
     705             :     {
     706           3 :         m_poEditableFeatureDefn->DeleteFieldDefn(iField);
     707           3 :         m_bStructureModified = true;
     708           3 :         m_oSetDeletedFields.insert(osDeletedField);
     709             :     }
     710           4 :     return eErr;
     711             : }
     712             : 
     713             : /************************************************************************/
     714             : /*                             ReorderFields()                          */
     715             : /************************************************************************/
     716             : 
     717           2 : OGRErr OGREditableLayer::ReorderFields(int *panMap)
     718             : {
     719           2 :     if (!m_poDecoratedLayer)
     720           0 :         return OGRERR_FAILURE;
     721             : 
     722           2 :     m_oMapEditableFDefnFieldNameToIdx.clear();
     723             : 
     724           2 :     OGRErr eErr = m_poMemLayer->ReorderFields(panMap);
     725           2 :     if (eErr == OGRERR_NONE)
     726             :     {
     727           1 :         m_poEditableFeatureDefn->ReorderFieldDefns(panMap);
     728           1 :         m_bStructureModified = true;
     729             :     }
     730           2 :     return eErr;
     731             : }
     732             : 
     733             : /************************************************************************/
     734             : /*                            AlterFieldDefn()                          */
     735             : /************************************************************************/
     736             : 
     737           2 : OGRErr OGREditableLayer::AlterFieldDefn(int iField,
     738             :                                         OGRFieldDefn *poNewFieldDefn,
     739             :                                         int nFlagsIn)
     740             : {
     741           2 :     if (!m_poDecoratedLayer)
     742           0 :         return OGRERR_FAILURE;
     743             : 
     744           2 :     m_oMapEditableFDefnFieldNameToIdx.clear();
     745             : 
     746             :     OGRErr eErr =
     747           2 :         m_poMemLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
     748           2 :     if (eErr == OGRERR_NONE)
     749             :     {
     750             :         OGRFieldDefn *poFieldDefn =
     751           1 :             m_poEditableFeatureDefn->GetFieldDefn(iField);
     752             :         OGRFieldDefn *poMemFieldDefn =
     753           1 :             m_poMemLayer->GetLayerDefn()->GetFieldDefn(iField);
     754           1 :         poFieldDefn->SetName(poMemFieldDefn->GetNameRef());
     755           1 :         poFieldDefn->SetType(poMemFieldDefn->GetType());
     756           1 :         poFieldDefn->SetSubType(poMemFieldDefn->GetSubType());
     757           1 :         poFieldDefn->SetWidth(poMemFieldDefn->GetWidth());
     758           1 :         poFieldDefn->SetPrecision(poMemFieldDefn->GetPrecision());
     759           1 :         poFieldDefn->SetDefault(poMemFieldDefn->GetDefault());
     760           1 :         poFieldDefn->SetNullable(poMemFieldDefn->IsNullable());
     761           1 :         poFieldDefn->SetUnique(poMemFieldDefn->IsUnique());
     762           1 :         poFieldDefn->SetDomainName(poMemFieldDefn->GetDomainName());
     763           1 :         poFieldDefn->SetComment(poMemFieldDefn->GetComment());
     764           1 :         m_bStructureModified = true;
     765             :     }
     766           2 :     return eErr;
     767             : }
     768             : 
     769             : /************************************************************************/
     770             : /*                         AlterGeomFieldDefn()                         */
     771             : /************************************************************************/
     772             : 
     773           0 : OGRErr OGREditableLayer::AlterGeomFieldDefn(
     774             :     int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
     775             : {
     776           0 :     if (!m_poDecoratedLayer)
     777           0 :         return OGRERR_FAILURE;
     778             : 
     779           0 :     OGRErr eErr = m_poMemLayer->AlterGeomFieldDefn(
     780           0 :         iGeomField, poNewGeomFieldDefn, nFlagsIn);
     781           0 :     if (eErr == OGRERR_NONE)
     782             :     {
     783             :         OGRGeomFieldDefn *poFieldDefn =
     784           0 :             m_poEditableFeatureDefn->GetGeomFieldDefn(iGeomField);
     785             :         OGRGeomFieldDefn *poMemFieldDefn =
     786           0 :             m_poMemLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomField);
     787           0 :         poFieldDefn->SetName(poMemFieldDefn->GetNameRef());
     788           0 :         poFieldDefn->SetType(poMemFieldDefn->GetType());
     789           0 :         poFieldDefn->SetNullable(poMemFieldDefn->IsNullable());
     790           0 :         poFieldDefn->SetSpatialRef(poMemFieldDefn->GetSpatialRef());
     791           0 :         m_bStructureModified = true;
     792             :     }
     793           0 :     return eErr;
     794             : }
     795             : 
     796             : /************************************************************************/
     797             : /*                          CreateGeomField()                          */
     798             : /************************************************************************/
     799             : 
     800          16 : OGRErr OGREditableLayer::CreateGeomField(const OGRGeomFieldDefn *poField,
     801             :                                          int bApproxOK)
     802             : {
     803          16 :     if (!m_poDecoratedLayer || !m_bSupportsCreateGeomField)
     804           0 :         return OGRERR_FAILURE;
     805             : 
     806          31 :     if (!m_bStructureModified &&
     807          15 :         m_poDecoratedLayer->TestCapability(OLCCreateGeomField))
     808             :     {
     809          15 :         OGRErr eErr = m_poDecoratedLayer->CreateGeomField(poField, bApproxOK);
     810          15 :         if (eErr == OGRERR_NONE)
     811             :         {
     812          14 :             eErr = m_poMemLayer->CreateGeomField(poField, bApproxOK);
     813          14 :             if (eErr == OGRERR_NONE)
     814             :             {
     815          14 :                 m_poEditableFeatureDefn->AddGeomFieldDefn(poField);
     816             :             }
     817             :         }
     818          15 :         return eErr;
     819             :     }
     820             : 
     821           1 :     OGRErr eErr = m_poMemLayer->CreateGeomField(poField, bApproxOK);
     822           1 :     if (eErr == OGRERR_NONE)
     823             :     {
     824           1 :         m_poEditableFeatureDefn->AddGeomFieldDefn(poField);
     825           1 :         m_bStructureModified = true;
     826             :     }
     827           1 :     return eErr;
     828             : }
     829             : 
     830             : /************************************************************************/
     831             : /*                             SyncToDisk()                             */
     832             : /************************************************************************/
     833             : 
     834         569 : OGRErr OGREditableLayer::SyncToDisk()
     835             : {
     836         569 :     if (!m_poDecoratedLayer || m_poSynchronizer == nullptr)
     837           0 :         return OGRERR_FAILURE;
     838         569 :     OGRErr eErr = m_poDecoratedLayer->SyncToDisk();
     839         569 :     if (eErr == OGRERR_NONE)
     840             :     {
     841        1692 :         if (m_oSetCreated.empty() && m_oSetEdited.empty() &&
     842        1692 :             m_oSetDeleted.empty() && !m_bStructureModified)
     843             :         {
     844         556 :             return OGRERR_NONE;
     845             :         }
     846          13 :         eErr = m_poSynchronizer->EditableSyncToDisk(this, &m_poDecoratedLayer);
     847             :     }
     848          13 :     m_oSetCreated.clear();
     849          13 :     m_oSetEdited.clear();
     850          13 :     m_oSetDeleted.clear();
     851          13 :     m_oSetDeletedFields.clear();
     852          13 :     m_bStructureModified = false;
     853          13 :     return eErr;
     854             : }
     855             : 
     856             : /************************************************************************/
     857             : /*                          StartTransaction()                          */
     858             : /************************************************************************/
     859             : 
     860          36 : OGRErr OGREditableLayer::StartTransaction()
     861             : 
     862             : {
     863          36 :     return OGRLayer::StartTransaction();
     864             : }
     865             : 
     866             : /************************************************************************/
     867             : /*                         CommitTransaction()                          */
     868             : /************************************************************************/
     869             : 
     870          33 : OGRErr OGREditableLayer::CommitTransaction()
     871             : 
     872             : {
     873          33 :     return OGRLayer::CommitTransaction();
     874             : }
     875             : 
     876             : /************************************************************************/
     877             : /*                        RollbackTransaction()                         */
     878             : /************************************************************************/
     879             : 
     880           4 : OGRErr OGREditableLayer::RollbackTransaction()
     881             : 
     882             : {
     883           4 :     return OGRLayer::RollbackTransaction();
     884             : }
     885             : 
     886             : /************************************************************************/
     887             : /*                         GetGeometryColumn()                          */
     888             : /************************************************************************/
     889             : 
     890           9 : const char *OGREditableLayer::GetGeometryColumn()
     891             : 
     892             : {
     893           9 :     return OGRLayer::GetGeometryColumn();
     894             : }
     895             : 
     896             : //! @endcond

Generated by: LCOV version 1.14