Coverage Report

Created: 2025-06-09 08:44

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