LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/generic - ogreditablelayer.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 352 392 89.8 %
Date: 2025-10-22 13:51:22 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 "memdataset.h"
      15             : 
      16             : #include <map>
      17             : 
      18             : //! @cond Doxygen_Suppress
      19             : 
      20             : /************************************************************************/
      21             : /*                  ~IOGREditableLayerSynchronizer()                    */
      22             : /************************************************************************/
      23             : 
      24         382 : IOGREditableLayerSynchronizer::~IOGREditableLayerSynchronizer()
      25             : {
      26         382 : }
      27             : 
      28             : /************************************************************************/
      29             : /*                          OGREditableLayer()                          */
      30             : /************************************************************************/
      31             : 
      32         382 : 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         382 :       m_poEditableFeatureDefn(poDecoratedLayer->GetLayerDefn()->Clone()),
      40         382 :       m_nNextFID(0), m_poMemLayer(new OGRMemLayer("", nullptr, wkbNone)),
      41             :       m_bStructureModified(false), m_bSupportsCreateGeomField(false),
      42        1146 :       m_bSupportsCurveGeometries(false)
      43             : {
      44         382 :     m_poEditableFeatureDefn->Reference();
      45             : 
      46        1370 :     for (int i = 0; i < m_poEditableFeatureDefn->GetFieldCount(); i++)
      47         988 :         CPL_IGNORE_RET_VAL(m_poMemLayer->CreateField(
      48         988 :             m_poEditableFeatureDefn->GetFieldDefn(i)));
      49             : 
      50         565 :     for (int i = 0; i < m_poEditableFeatureDefn->GetGeomFieldCount(); i++)
      51         366 :         m_poMemLayer->CreateGeomField(
      52         183 :             m_poEditableFeatureDefn->GetGeomFieldDefn(i));
      53             : 
      54         382 :     m_oIter = m_oSetCreated.begin();
      55         382 : }
      56             : 
      57             : /************************************************************************/
      58             : /*                         ~OGREditableLayer()                          */
      59             : /************************************************************************/
      60             : 
      61         382 : OGREditableLayer::~OGREditableLayer()
      62             : {
      63         382 :     OGREditableLayer::SyncToDisk();
      64             : 
      65         382 :     m_poEditableFeatureDefn->Release();
      66         382 :     delete m_poMemLayer;
      67         382 :     if (m_bTakeOwnershipSynchronizer)
      68         377 :         delete m_poSynchronizer;
      69         382 : }
      70             : 
      71             : /************************************************************************/
      72             : /*                           SetNextFID()                               */
      73             : /************************************************************************/
      74             : 
      75           3 : void OGREditableLayer::SetNextFID(GIntBig nNextFID)
      76             : {
      77           3 :     m_nNextFID = nNextFID;
      78           3 : }
      79             : 
      80             : /************************************************************************/
      81             : /*                       SetSupportsCurveGeometries()                   */
      82             : /************************************************************************/
      83             : 
      84         214 : void OGREditableLayer::SetSupportsCurveGeometries(bool bSupportsCurveGeometries)
      85             : {
      86         214 :     m_bSupportsCurveGeometries = bSupportsCurveGeometries;
      87         214 : }
      88             : 
      89             : /************************************************************************/
      90             : /*                       SetSupportsCreateGeomField()                   */
      91             : /************************************************************************/
      92             : 
      93         214 : void OGREditableLayer::SetSupportsCreateGeomField(bool bSupportsCreateGeomField)
      94             : {
      95         214 :     m_bSupportsCreateGeomField = bSupportsCreateGeomField;
      96         214 : }
      97             : 
      98             : /************************************************************************/
      99             : /*                           DetectNextFID()                            */
     100             : /************************************************************************/
     101             : 
     102          10 : void OGREditableLayer::DetectNextFID()
     103             : {
     104          10 :     if (m_nNextFID > 0)
     105           1 :         return;
     106           9 :     m_nNextFID = 0;
     107           9 :     m_poDecoratedLayer->ResetReading();
     108           9 :     OGRFeature *poFeat = nullptr;
     109          38 :     while ((poFeat = m_poDecoratedLayer->GetNextFeature()) != nullptr)
     110             :     {
     111          29 :         if (poFeat->GetFID() > m_nNextFID)
     112          25 :             m_nNextFID = poFeat->GetFID();
     113          29 :         delete poFeat;
     114             :     }
     115           9 :     m_nNextFID++;
     116             : }
     117             : 
     118             : /************************************************************************/
     119             : /*                         GetSrcGeomFieldIndex()                       */
     120             : /************************************************************************/
     121             : 
     122         210 : int OGREditableLayer::GetSrcGeomFieldIndex(int iGeomField)
     123             : {
     124         420 :     if (m_poDecoratedLayer == nullptr || iGeomField < 0 ||
     125         210 :         iGeomField >= m_poEditableFeatureDefn->GetGeomFieldCount())
     126             :     {
     127          12 :         return -1;
     128             :     }
     129             :     OGRGeomFieldDefn *poGeomFieldDefn =
     130         198 :         m_poEditableFeatureDefn->GetGeomFieldDefn(iGeomField);
     131         396 :     return m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldIndex(
     132         198 :         poGeomFieldDefn->GetNameRef());
     133             : }
     134             : 
     135             : /************************************************************************/
     136             : /*                            ResetReading()                            */
     137             : /************************************************************************/
     138             : 
     139         658 : void OGREditableLayer::ResetReading()
     140             : {
     141         658 :     if (!m_poDecoratedLayer)
     142           0 :         return;
     143         658 :     m_poDecoratedLayer->ResetReading();
     144         658 :     m_oIter = m_oSetCreated.begin();
     145             : }
     146             : 
     147             : /************************************************************************/
     148             : /*                             Translate()                              */
     149             : /************************************************************************/
     150             : 
     151        1412 : OGRFeature *OGREditableLayer::Translate(OGRFeatureDefn *poTargetDefn,
     152             :                                         OGRFeature *poSrcFeature,
     153             :                                         bool bCanStealSrcFeature,
     154             :                                         bool bHideDeletedFields)
     155             : {
     156        1412 :     if (poSrcFeature == nullptr)
     157          24 :         return nullptr;
     158        1388 :     OGRFeature *poRet = new OGRFeature(poTargetDefn);
     159             : 
     160        1388 :     std::map<CPLString, int> oMapTargetFieldNameToIdx;
     161        1388 :     std::map<CPLString, int> *poMap = &oMapTargetFieldNameToIdx;
     162        2314 :     if (poTargetDefn == m_poEditableFeatureDefn &&
     163         926 :         !m_oMapEditableFDefnFieldNameToIdx.empty())
     164             :     {
     165         783 :         poMap = &m_oMapEditableFDefnFieldNameToIdx;
     166             :     }
     167             :     else
     168             :     {
     169        3730 :         for (int iField = 0; iField < poTargetDefn->GetFieldCount(); iField++)
     170             :         {
     171        3125 :             oMapTargetFieldNameToIdx[poTargetDefn->GetFieldDefn(iField)
     172        3125 :                                          ->GetNameRef()] = iField;
     173             :         }
     174         605 :         if (poTargetDefn == m_poEditableFeatureDefn)
     175             :         {
     176             :             m_oMapEditableFDefnFieldNameToIdx =
     177         143 :                 std::move(oMapTargetFieldNameToIdx);
     178         143 :             poMap = &m_oMapEditableFDefnFieldNameToIdx;
     179             :         }
     180             :     }
     181             : 
     182             :     int *panMap = static_cast<int *>(
     183        1388 :         CPLMalloc(sizeof(int) * poSrcFeature->GetFieldCount()));
     184       12158 :     for (int iField = 0; iField < poSrcFeature->GetFieldCount(); iField++)
     185             :     {
     186             :         const char *pszFieldName =
     187       10770 :             poSrcFeature->GetFieldDefnRef(iField)->GetNameRef();
     188       18277 :         if (bHideDeletedFields &&
     189       18277 :             m_oSetDeletedFields.find(pszFieldName) != m_oSetDeletedFields.end())
     190             :         {
     191           7 :             panMap[iField] = -1;
     192             :         }
     193             :         else
     194             :         {
     195       10763 :             auto oIter = poMap->find(pszFieldName);
     196       10763 :             panMap[iField] = (oIter == poMap->end()) ? -1 : oIter->second;
     197             :         }
     198             :     }
     199        1388 :     poRet->SetFieldsFrom(poSrcFeature, panMap, TRUE);
     200        1388 :     CPLFree(panMap);
     201             : 
     202        2449 :     for (int i = 0; i < poTargetDefn->GetGeomFieldCount(); i++)
     203             :     {
     204        1061 :         OGRGeomFieldDefn *poGeomField = poTargetDefn->GetGeomFieldDefn(i);
     205             :         int iSrcGeomFieldIdx =
     206        1061 :             poTargetDefn->GetGeomFieldIndex(poGeomField->GetNameRef());
     207        1061 :         if (iSrcGeomFieldIdx >= 0)
     208             :         {
     209        1061 :             if (bCanStealSrcFeature)
     210             :             {
     211         841 :                 poRet->SetGeomFieldDirectly(
     212             :                     i, poSrcFeature->StealGeometry(iSrcGeomFieldIdx));
     213             :             }
     214             :             else
     215             :             {
     216         220 :                 poRet->SetGeomField(
     217         220 :                     i, poSrcFeature->GetGeomFieldRef(iSrcGeomFieldIdx));
     218             :             }
     219        1061 :             OGRGeometry *poGeom = poRet->GetGeomFieldRef(i);
     220        1061 :             if (poGeom != nullptr)
     221         989 :                 poGeom->assignSpatialReference(poGeomField->GetSpatialRef());
     222             :         }
     223             :     }
     224        1388 :     poRet->SetStyleString(poSrcFeature->GetStyleString());
     225        1388 :     poRet->SetNativeData(poSrcFeature->GetNativeData());
     226        1388 :     poRet->SetNativeMediaType(poSrcFeature->GetNativeMediaType());
     227        1388 :     poRet->SetFID(poSrcFeature->GetFID());
     228             : 
     229        1388 :     return poRet;
     230             : }
     231             : 
     232             : /************************************************************************/
     233             : /*                           GetNextFeature()                           */
     234             : /************************************************************************/
     235             : 
     236         913 : OGRFeature *OGREditableLayer::GetNextFeature()
     237             : {
     238         913 :     if (!m_poDecoratedLayer)
     239           0 :         return nullptr;
     240             :     while (true)
     241             :     {
     242        1079 :         OGRFeature *poSrcFeature = m_poDecoratedLayer->GetNextFeature();
     243        1079 :         bool bHideDeletedFields = true;
     244        1079 :         if (poSrcFeature != nullptr)
     245             :         {
     246         842 :             const GIntBig nFID = poSrcFeature->GetFID();
     247         842 :             if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
     248             :             {
     249           6 :                 delete poSrcFeature;
     250           6 :                 continue;
     251             :             }
     252        1653 :             else if (m_oSetCreated.find(nFID) != m_oSetCreated.end() ||
     253        1653 :                      m_oSetEdited.find(nFID) != m_oSetEdited.end())
     254             :             {
     255          67 :                 delete poSrcFeature;
     256          67 :                 poSrcFeature = m_poMemLayer->GetFeature(nFID);
     257          67 :                 bHideDeletedFields = false;
     258             :             }
     259             :         }
     260             :         else
     261             :         {
     262         237 :             if (m_oIter != m_oSetCreated.end())
     263             :             {
     264          28 :                 poSrcFeature = m_poMemLayer->GetFeature(*m_oIter);
     265          28 :                 bHideDeletedFields = false;
     266          28 :                 ++m_oIter;
     267             :             }
     268             :             else
     269             :             {
     270         209 :                 return nullptr;
     271             :             }
     272             :         }
     273         864 :         OGRFeature *poRet = Translate(m_poEditableFeatureDefn, poSrcFeature,
     274             :                                       true, bHideDeletedFields);
     275         864 :         delete poSrcFeature;
     276             : 
     277        1874 :         if ((m_poFilterGeom == nullptr ||
     278        1725 :              FilterGeometry(poRet->GetGeomFieldRef(m_iGeomFieldFilter))) &&
     279         861 :             (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poRet)))
     280             :         {
     281         704 :             return poRet;
     282             :         }
     283         160 :         delete poRet;
     284         166 :     }
     285             : }
     286             : 
     287             : /************************************************************************/
     288             : /*                          SetNextByIndex()                            */
     289             : /************************************************************************/
     290             : 
     291          21 : OGRErr OGREditableLayer::SetNextByIndex(GIntBig nIndex)
     292             : {
     293          35 :     if (m_poDecoratedLayer != nullptr && m_oSetCreated.empty() &&
     294          56 :         m_oSetDeleted.empty() && m_oSetEdited.empty())
     295             :     {
     296          14 :         return m_poDecoratedLayer->SetNextByIndex(nIndex);
     297             :     }
     298             : 
     299           7 :     return OGRLayer::SetNextByIndex(nIndex);
     300             : }
     301             : 
     302             : /************************************************************************/
     303             : /*                              GetFeature()                            */
     304             : /************************************************************************/
     305             : 
     306          86 : OGRFeature *OGREditableLayer::GetFeature(GIntBig nFID)
     307             : {
     308          86 :     if (!m_poDecoratedLayer)
     309           0 :         return nullptr;
     310             : 
     311          86 :     OGRFeature *poSrcFeature = nullptr;
     312          86 :     bool bHideDeletedFields = true;
     313         165 :     if (m_oSetCreated.find(nFID) != m_oSetCreated.end() ||
     314         165 :         m_oSetEdited.find(nFID) != m_oSetEdited.end())
     315             :     {
     316          22 :         poSrcFeature = m_poMemLayer->GetFeature(nFID);
     317          22 :         bHideDeletedFields = false;
     318             :     }
     319          64 :     else if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
     320             :     {
     321           5 :         poSrcFeature = nullptr;
     322             :     }
     323             :     else
     324             :     {
     325          59 :         poSrcFeature = m_poDecoratedLayer->GetFeature(nFID);
     326             :     }
     327          86 :     OGRFeature *poRet = Translate(m_poEditableFeatureDefn, poSrcFeature, true,
     328             :                                   bHideDeletedFields);
     329          86 :     delete poSrcFeature;
     330          86 :     return poRet;
     331             : }
     332             : 
     333             : /************************************************************************/
     334             : /*                            ISetFeature()                             */
     335             : /************************************************************************/
     336             : 
     337          33 : OGRErr OGREditableLayer::ISetFeature(OGRFeature *poFeature)
     338             : {
     339          33 :     if (!m_poDecoratedLayer)
     340           0 :         return OGRERR_FAILURE;
     341             : 
     342          50 :     if (!m_bStructureModified && m_oSetDeleted.empty() &&
     343          90 :         m_oSetEdited.empty() && m_oSetCreated.empty() &&
     344           7 :         m_poDecoratedLayer->TestCapability(OLCRandomWrite))
     345             :     {
     346           0 :         OGRFeature *poTargetFeature = Translate(
     347           0 :             m_poDecoratedLayer->GetLayerDefn(), poFeature, false, false);
     348           0 :         OGRErr eErr = m_poDecoratedLayer->SetFeature(poTargetFeature);
     349           0 :         delete poTargetFeature;
     350           0 :         return eErr;
     351             :     }
     352             : 
     353             :     OGRFeature *poMemFeature =
     354          33 :         Translate(m_poMemLayer->GetLayerDefn(), poFeature, false, false);
     355          33 :     OGRErr eErr = m_poMemLayer->SetFeature(poMemFeature);
     356          33 :     if (eErr == OGRERR_NONE)
     357             :     {
     358          28 :         const GIntBig nFID = poMemFeature->GetFID();
     359          28 :         m_oSetDeleted.erase(nFID);
     360             :         // If the feature isn't in the created list, insert it in the edited
     361             :         // list
     362          28 :         if (m_oSetCreated.find(nFID) == m_oSetCreated.end())
     363             :         {
     364          24 :             m_oSetEdited.insert(nFID);
     365             :         }
     366          28 :         poFeature->SetFID(nFID);
     367             :     }
     368          33 :     delete poMemFeature;
     369             : 
     370          33 :     return eErr;
     371             : }
     372             : 
     373             : /************************************************************************/
     374             : /*                          ICreateFeature()                            */
     375             : /************************************************************************/
     376             : 
     377         429 : OGRErr OGREditableLayer::ICreateFeature(OGRFeature *poFeature)
     378             : {
     379         429 :     if (!m_poDecoratedLayer)
     380           0 :         return OGRERR_FAILURE;
     381             : 
     382         849 :     if (!m_bStructureModified && m_oSetDeleted.empty() &&
     383        1278 :         m_oSetCreated.empty() &&
     384         423 :         m_poDecoratedLayer->TestCapability(OLCSequentialWrite))
     385             :     {
     386         419 :         OGRFeature *poTargetFeature = Translate(
     387         419 :             m_poDecoratedLayer->GetLayerDefn(), poFeature, false, false);
     388         419 :         OGRErr eErr = m_poDecoratedLayer->CreateFeature(poTargetFeature);
     389         419 :         if (poFeature->GetFID() < 0)
     390         409 :             poFeature->SetFID(poTargetFeature->GetFID());
     391         419 :         delete poTargetFeature;
     392         419 :         return eErr;
     393             :     }
     394             : 
     395             :     OGRFeature *poMemFeature =
     396          10 :         Translate(m_poMemLayer->GetLayerDefn(), poFeature, false, false);
     397          10 :     DetectNextFID();
     398          10 :     if (poMemFeature->GetFID() < 0)
     399           7 :         poMemFeature->SetFID(m_nNextFID++);
     400          10 :     OGRErr eErr = m_poMemLayer->CreateFeature(poMemFeature);
     401          10 :     if (eErr == OGRERR_NONE)
     402             :     {
     403          10 :         const GIntBig nFID = poMemFeature->GetFID();
     404          10 :         m_oSetDeleted.erase(nFID);
     405          10 :         m_oSetEdited.erase(nFID);
     406          10 :         m_oSetCreated.insert(nFID);
     407          10 :         poFeature->SetFID(nFID);
     408             :     }
     409          10 :     delete poMemFeature;
     410             : 
     411          10 :     ResetReading();
     412             : 
     413          10 :     return eErr;
     414             : }
     415             : 
     416             : /************************************************************************/
     417             : /*                          IUpsertFeature()                            */
     418             : /************************************************************************/
     419             : 
     420           0 : OGRErr OGREditableLayer::IUpsertFeature(OGRFeature *poFeature)
     421             : {
     422             :     auto poFeatureExisting =
     423           0 :         std::unique_ptr<OGRFeature>(GetFeature(poFeature->GetFID()));
     424           0 :     if (poFeatureExisting)
     425             :     {
     426           0 :         return ISetFeature(poFeature);
     427             :     }
     428             :     else
     429             :     {
     430           0 :         return ICreateFeature(poFeature);
     431             :     }
     432             : }
     433             : 
     434             : /************************************************************************/
     435             : /*                            IUpdateFeature()                          */
     436             : /************************************************************************/
     437             : 
     438           6 : OGRErr OGREditableLayer::IUpdateFeature(OGRFeature *poFeature,
     439             :                                         int nUpdatedFieldsCount,
     440             :                                         const int *panUpdatedFieldsIdx,
     441             :                                         int nUpdatedGeomFieldsCount,
     442             :                                         const int *panUpdatedGeomFieldsIdx,
     443             :                                         bool bUpdateStyleString)
     444             : {
     445             :     // Do not use OGRLayerDecorator::IUpdateFeature() which will forward
     446             :     // to the decorated layer
     447           6 :     return OGRLayer::IUpdateFeature(
     448             :         poFeature, nUpdatedFieldsCount, panUpdatedFieldsIdx,
     449           6 :         nUpdatedGeomFieldsCount, panUpdatedGeomFieldsIdx, bUpdateStyleString);
     450             : }
     451             : 
     452             : /************************************************************************/
     453             : /*                          DeleteFeature()                             */
     454             : /************************************************************************/
     455             : 
     456          22 : OGRErr OGREditableLayer::DeleteFeature(GIntBig nFID)
     457             : {
     458          22 :     if (!m_poDecoratedLayer)
     459           0 :         return OGRERR_FAILURE;
     460             : 
     461             :     OGRErr eErr;
     462          22 :     if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
     463             :     {
     464           3 :         eErr = OGRERR_NON_EXISTING_FEATURE;
     465             :     }
     466             :     // cppcheck-suppress redundantIfRemove
     467          19 :     else if (m_oSetCreated.find(nFID) != m_oSetCreated.end())
     468             :     {
     469           1 :         m_oSetCreated.erase(nFID);
     470           1 :         eErr = m_poMemLayer->DeleteFeature(nFID);
     471             :     }
     472             :     // cppcheck-suppress redundantIfRemove
     473          18 :     else if (m_oSetEdited.find(nFID) != m_oSetEdited.end())
     474             :     {
     475           1 :         m_oSetEdited.erase(nFID);
     476           1 :         m_oSetDeleted.insert(nFID);
     477           1 :         eErr = m_poMemLayer->DeleteFeature(nFID);
     478             :     }
     479             :     else
     480             :     {
     481          17 :         OGRFeature *poFeature = m_poDecoratedLayer->GetFeature(nFID);
     482          17 :         if (poFeature != nullptr)
     483             :         {
     484           6 :             m_oSetDeleted.insert(nFID);
     485           6 :             eErr = OGRERR_NONE;
     486           6 :             delete poFeature;
     487             :         }
     488             :         else
     489             :         {
     490          11 :             eErr = OGRERR_NON_EXISTING_FEATURE;
     491             :         }
     492             :     }
     493             : 
     494          22 :     ResetReading();
     495             : 
     496          22 :     return eErr;
     497             : }
     498             : 
     499             : /************************************************************************/
     500             : /*                             GetGeomType()                            */
     501             : /************************************************************************/
     502             : 
     503         253 : OGRwkbGeometryType OGREditableLayer::GetGeomType() const
     504             : {
     505         253 :     return OGRLayer::GetGeomType();
     506             : }
     507             : 
     508             : /************************************************************************/
     509             : /*                             GetLayerDefn()                           */
     510             : /************************************************************************/
     511             : 
     512        3511 : const OGRFeatureDefn *OGREditableLayer::GetLayerDefn() const
     513             : {
     514        3511 :     return m_poEditableFeatureDefn;
     515             : }
     516             : 
     517             : /************************************************************************/
     518             : /*                             GetSpatialRef()                          */
     519             : /************************************************************************/
     520             : 
     521          74 : const OGRSpatialReference *OGREditableLayer::GetSpatialRef() const
     522             : {
     523          74 :     return OGRLayer::GetSpatialRef();
     524             : }
     525             : 
     526             : /************************************************************************/
     527             : /*                           GetSpatialFilter()                         */
     528             : /************************************************************************/
     529             : 
     530          25 : OGRGeometry *OGREditableLayer::GetSpatialFilter()
     531             : {
     532          25 :     return OGRLayer::GetSpatialFilter();
     533             : }
     534             : 
     535             : /************************************************************************/
     536             : /*                           SetAttributeFilter()                       */
     537             : /************************************************************************/
     538             : 
     539         256 : OGRErr OGREditableLayer::SetAttributeFilter(const char *poAttrFilter)
     540             : {
     541         256 :     return OGRLayer::SetAttributeFilter(poAttrFilter);
     542             : }
     543             : 
     544             : /************************************************************************/
     545             : /*                           GetArrowStream()                           */
     546             : /************************************************************************/
     547             : 
     548          30 : bool OGREditableLayer::GetArrowStream(struct ArrowArrayStream *out_stream,
     549             :                                       CSLConstList papszOptions)
     550             : {
     551          30 :     return OGRLayer::GetArrowStream(out_stream, papszOptions);
     552             : }
     553             : 
     554             : /************************************************************************/
     555             : /*                          ISetSpatialFilter()                         */
     556             : /************************************************************************/
     557             : 
     558         187 : OGRErr OGREditableLayer::ISetSpatialFilter(int iGeomField,
     559             :                                            const OGRGeometry *poGeom)
     560             : {
     561         187 :     m_iGeomFieldFilter = iGeomField;
     562         187 :     if (InstallFilter(poGeom))
     563          60 :         ResetReading();
     564             : 
     565         187 :     OGRErr eErr = OGRERR_NONE;
     566         187 :     const int iSrcGeomFieldIdx = GetSrcGeomFieldIndex(iGeomField);
     567         187 :     if (iSrcGeomFieldIdx >= 0)
     568             :     {
     569         175 :         eErr = m_poDecoratedLayer->SetSpatialFilter(iSrcGeomFieldIdx, poGeom);
     570             :     }
     571         187 :     if (eErr == OGRERR_NONE)
     572         187 :         eErr = m_poMemLayer->SetSpatialFilter(iGeomField, poGeom);
     573         187 :     return eErr;
     574             : }
     575             : 
     576             : /************************************************************************/
     577             : /*                          GetFeatureCount()                           */
     578             : /************************************************************************/
     579             : 
     580         174 : GIntBig OGREditableLayer::GetFeatureCount(int bForce)
     581             : {
     582         174 :     if (!m_poDecoratedLayer)
     583           0 :         return 0;
     584         290 :     if (m_poAttrQuery == nullptr && m_poFilterGeom == nullptr &&
     585         464 :         m_oSetDeleted.empty() && m_oSetEdited.empty())
     586             :     {
     587         132 :         GIntBig nFC = m_poDecoratedLayer->GetFeatureCount(bForce);
     588         132 :         if (nFC >= 0)
     589             :         {
     590         132 :             nFC += m_oSetCreated.size();
     591             :         }
     592         132 :         return nFC;
     593             :     }
     594          42 :     return OGRLayer::GetFeatureCount(bForce);
     595             : }
     596             : 
     597             : /************************************************************************/
     598             : /*                              IGetExtent()                            */
     599             : /************************************************************************/
     600             : 
     601          23 : OGRErr OGREditableLayer::IGetExtent(int iGeomField, OGREnvelope *psExtent,
     602             :                                     bool bForce)
     603             : {
     604          23 :     if (!m_poDecoratedLayer)
     605           0 :         return OGRERR_FAILURE;
     606          23 :     int iSrcGeomFieldIdx = GetSrcGeomFieldIndex(iGeomField);
     607          23 :     if (iSrcGeomFieldIdx >= 0 && m_oSetEdited.empty() && m_oSetDeleted.empty())
     608             :     {
     609             :         OGRErr eErr =
     610          23 :             m_poDecoratedLayer->GetExtent(iSrcGeomFieldIdx, psExtent, bForce);
     611          23 :         if (eErr == OGRERR_NONE)
     612             :         {
     613          22 :             OGREnvelope sExtentMemLayer;
     614          22 :             if (m_poMemLayer->GetExtent(iGeomField, &sExtentMemLayer, bForce) ==
     615             :                 OGRERR_NONE)
     616             :             {
     617           1 :                 psExtent->Merge(sExtentMemLayer);
     618             :             }
     619             :         }
     620          23 :         return eErr;
     621             :     }
     622           0 :     return OGRLayer::IGetExtent(iGeomField, psExtent, bForce);
     623             : }
     624             : 
     625             : /************************************************************************/
     626             : /*                            TestCapability()                          */
     627             : /************************************************************************/
     628             : 
     629         766 : int OGREditableLayer::TestCapability(const char *pszCap) const
     630             : {
     631         766 :     if (!m_poDecoratedLayer)
     632           0 :         return FALSE;
     633         766 :     if (EQUAL(pszCap, OLCSequentialWrite) || EQUAL(pszCap, OLCRandomWrite) ||
     634         713 :         EQUAL(pszCap, OLCCreateField) || EQUAL(pszCap, OLCDeleteField) ||
     635         659 :         EQUAL(pszCap, OLCReorderFields) || EQUAL(pszCap, OLCAlterFieldDefn) ||
     636         639 :         EQUAL(pszCap, OLCAlterGeomFieldDefn) || EQUAL(pszCap, OLCDeleteFeature))
     637             :     {
     638         134 :         return TRUE;
     639             :     }
     640         632 :     if (EQUAL(pszCap, OLCCreateGeomField))
     641           1 :         return m_bSupportsCreateGeomField;
     642         631 :     if (EQUAL(pszCap, OLCCurveGeometries))
     643         243 :         return m_bSupportsCurveGeometries;
     644         388 :     if (EQUAL(pszCap, OLCTransactions))
     645          12 :         return FALSE;
     646             : 
     647         376 :     return m_poDecoratedLayer->TestCapability(pszCap);
     648             : }
     649             : 
     650             : /************************************************************************/
     651             : /*                            CreateField()                             */
     652             : /************************************************************************/
     653             : 
     654         622 : OGRErr OGREditableLayer::CreateField(const OGRFieldDefn *poField, int bApproxOK)
     655             : {
     656         622 :     if (!m_poDecoratedLayer)
     657           0 :         return OGRERR_FAILURE;
     658             : 
     659         622 :     m_oMapEditableFDefnFieldNameToIdx.clear();
     660             : 
     661        1243 :     if (!m_bStructureModified &&
     662         621 :         m_poDecoratedLayer->TestCapability(OLCCreateField))
     663             :     {
     664         618 :         OGRErr eErr = m_poDecoratedLayer->CreateField(poField, bApproxOK);
     665         618 :         if (eErr == OGRERR_NONE)
     666             :         {
     667         618 :             eErr = m_poMemLayer->CreateField(poField, bApproxOK);
     668         618 :             if (eErr == OGRERR_NONE)
     669             :             {
     670         618 :                 m_poEditableFeatureDefn->AddFieldDefn(poField);
     671             :             }
     672             :         }
     673         618 :         return eErr;
     674             :     }
     675             : 
     676           4 :     OGRErr eErr = m_poMemLayer->CreateField(poField, bApproxOK);
     677           4 :     if (eErr == OGRERR_NONE)
     678             :     {
     679           4 :         m_poEditableFeatureDefn->AddFieldDefn(poField);
     680           4 :         m_bStructureModified = true;
     681             :     }
     682           4 :     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(std::move(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         588 : OGRErr OGREditableLayer::SyncToDisk()
     835             : {
     836         588 :     if (!m_poDecoratedLayer || m_poSynchronizer == nullptr)
     837           5 :         return OGRERR_FAILURE;
     838         583 :     OGRErr eErr = m_poDecoratedLayer->SyncToDisk();
     839         583 :     if (eErr == OGRERR_NONE)
     840             :     {
     841        1725 :         if (m_oSetCreated.empty() && m_oSetEdited.empty() &&
     842        1725 :             m_oSetDeleted.empty() && !m_bStructureModified)
     843             :         {
     844         565 :             return OGRERR_NONE;
     845             :         }
     846          18 :         eErr = m_poSynchronizer->EditableSyncToDisk(this, &m_poDecoratedLayer);
     847             :     }
     848          18 :     m_oSetCreated.clear();
     849          18 :     m_oSetEdited.clear();
     850          18 :     m_oSetDeleted.clear();
     851          18 :     m_oSetDeletedFields.clear();
     852          18 :     m_bStructureModified = false;
     853          18 :     return eErr;
     854             : }
     855             : 
     856             : /************************************************************************/
     857             : /*                          StartTransaction()                          */
     858             : /************************************************************************/
     859             : 
     860          41 : OGRErr OGREditableLayer::StartTransaction()
     861             : 
     862             : {
     863          41 :     return OGRLayer::StartTransaction();
     864             : }
     865             : 
     866             : /************************************************************************/
     867             : /*                         CommitTransaction()                          */
     868             : /************************************************************************/
     869             : 
     870          36 : OGRErr OGREditableLayer::CommitTransaction()
     871             : 
     872             : {
     873          36 :     return OGRLayer::CommitTransaction();
     874             : }
     875             : 
     876             : /************************************************************************/
     877             : /*                        RollbackTransaction()                         */
     878             : /************************************************************************/
     879             : 
     880           6 : OGRErr OGREditableLayer::RollbackTransaction()
     881             : 
     882             : {
     883           6 :     return OGRLayer::RollbackTransaction();
     884             : }
     885             : 
     886             : /************************************************************************/
     887             : /*                         GetGeometryColumn()                          */
     888             : /************************************************************************/
     889             : 
     890          13 : const char *OGREditableLayer::GetGeometryColumn() const
     891             : 
     892             : {
     893          13 :     return OGRLayer::GetGeometryColumn();
     894             : }
     895             : 
     896             : //! @endcond

Generated by: LCOV version 1.14