Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogrsf_frmts/generic/ogrlayerpool.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  Defines OGRLayerPool and OGRProxiedLayer class
5
 * Author:   Even Rouault, even dot rouault at spatialys.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2012-2013, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef DOXYGEN_SKIP
14
15
#include "ogrlayerpool.h"
16
#include "ogr_recordbatch.h"
17
18
/************************************************************************/
19
/*                      OGRAbstractProxiedLayer()                       */
20
/************************************************************************/
21
22
OGRAbstractProxiedLayer::OGRAbstractProxiedLayer(OGRLayerPool *poPoolIn)
23
0
    : poPrevLayer(nullptr), poNextLayer(nullptr), poPool(poPoolIn)
24
0
{
25
0
    CPLAssert(poPoolIn != nullptr);
26
0
}
27
28
/************************************************************************/
29
/*                     ~OGRAbstractProxiedLayer()                       */
30
/************************************************************************/
31
32
OGRAbstractProxiedLayer::~OGRAbstractProxiedLayer()
33
0
{
34
    /* Remove us from the list of LRU layers if necessary */
35
0
    poPool->UnchainLayer(this);
36
0
}
37
38
/************************************************************************/
39
/*                            OGRLayerPool()                            */
40
/************************************************************************/
41
42
OGRLayerPool::OGRLayerPool(int nMaxSimultaneouslyOpenedIn)
43
0
    : poMRULayer(nullptr), poLRULayer(nullptr), nMRUListSize(0),
44
0
      nMaxSimultaneouslyOpened(nMaxSimultaneouslyOpenedIn)
45
0
{
46
0
}
47
48
/************************************************************************/
49
/*                           ~OGRLayerPool()                            */
50
/************************************************************************/
51
52
OGRLayerPool::~OGRLayerPool()
53
0
{
54
0
    CPLAssert(poMRULayer == nullptr);
55
0
    CPLAssert(poLRULayer == nullptr);
56
0
    CPLAssert(nMRUListSize == 0);
57
0
}
58
59
/************************************************************************/
60
/*                          SetLastUsedLayer()                          */
61
/************************************************************************/
62
63
void OGRLayerPool::SetLastUsedLayer(OGRAbstractProxiedLayer *poLayer)
64
0
{
65
    /* If we are already the MRU layer, nothing to do */
66
0
    if (poLayer == poMRULayer)
67
0
        return;
68
69
    // CPLDebug("OGR", "SetLastUsedLayer(%s)", poLayer->GetName());
70
71
0
    if (poLayer->poPrevLayer != nullptr || poLayer->poNextLayer != nullptr)
72
0
    {
73
        /* Remove current layer from its current place in the list */
74
0
        UnchainLayer(poLayer);
75
0
    }
76
0
    else if (nMRUListSize == nMaxSimultaneouslyOpened)
77
0
    {
78
        /* If we have reached the maximum allowed number of layers */
79
        /* simultaneously opened, then close the LRU one that */
80
        /* was still active until now */
81
0
        CPLAssert(poLRULayer != nullptr);
82
83
0
        poLRULayer->CloseUnderlyingLayer();
84
0
        UnchainLayer(poLRULayer);
85
0
    }
86
87
    /* Put current layer on top of MRU list */
88
0
    CPLAssert(poLayer->poPrevLayer == nullptr);
89
0
    CPLAssert(poLayer->poNextLayer == nullptr);
90
0
    poLayer->poNextLayer = poMRULayer;
91
0
    if (poMRULayer != nullptr)
92
0
    {
93
0
        CPLAssert(poMRULayer->poPrevLayer == nullptr);
94
0
        poMRULayer->poPrevLayer = poLayer;
95
0
    }
96
0
    poMRULayer = poLayer;
97
0
    if (poLRULayer == nullptr)
98
0
        poLRULayer = poLayer;
99
0
    nMRUListSize++;
100
0
}
101
102
/************************************************************************/
103
/*                           UnchainLayer()                             */
104
/************************************************************************/
105
106
void OGRLayerPool::UnchainLayer(OGRAbstractProxiedLayer *poLayer)
107
0
{
108
0
    OGRAbstractProxiedLayer *poPrevLayer = poLayer->poPrevLayer;
109
0
    OGRAbstractProxiedLayer *poNextLayer = poLayer->poNextLayer;
110
111
0
    CPLAssert(poPrevLayer == nullptr || poPrevLayer->poNextLayer == poLayer);
112
0
    CPLAssert(poNextLayer == nullptr || poNextLayer->poPrevLayer == poLayer);
113
114
0
    if (poPrevLayer != nullptr || poNextLayer != nullptr ||
115
0
        poLayer == poMRULayer)
116
0
        nMRUListSize--;
117
118
0
    if (poLayer == poMRULayer)
119
0
        poMRULayer = poNextLayer;
120
0
    if (poLayer == poLRULayer)
121
0
        poLRULayer = poPrevLayer;
122
0
    if (poPrevLayer != nullptr)
123
0
        poPrevLayer->poNextLayer = poNextLayer;
124
0
    if (poNextLayer != nullptr)
125
0
        poNextLayer->poPrevLayer = poPrevLayer;
126
0
    poLayer->poPrevLayer = nullptr;
127
0
    poLayer->poNextLayer = nullptr;
128
0
}
129
130
/************************************************************************/
131
/*                          OGRProxiedLayer()                           */
132
/************************************************************************/
133
134
static void ReleaseDelete(OGRLayer *poLayer, void *)
135
0
{
136
0
    delete poLayer;
137
0
}
138
139
OGRProxiedLayer::OGRProxiedLayer(OGRLayerPool *poPoolIn,
140
                                 OpenLayerFunc pfnOpenLayerIn,
141
                                 FreeUserDataFunc pfnFreeUserDataIn,
142
                                 void *pUserDataIn)
143
0
    : OGRAbstractProxiedLayer(poPoolIn), pfnOpenLayer(pfnOpenLayerIn),
144
0
      pfnReleaseLayer(ReleaseDelete), pfnFreeUserData(pfnFreeUserDataIn),
145
0
      pUserData(pUserDataIn), poUnderlyingLayer(nullptr),
146
0
      poFeatureDefn(nullptr), poSRS(nullptr)
147
0
{
148
0
    CPLAssert(pfnOpenLayerIn != nullptr);
149
0
}
150
151
/************************************************************************/
152
/*                          OGRProxiedLayer()                           */
153
/************************************************************************/
154
155
OGRProxiedLayer::OGRProxiedLayer(OGRLayerPool *poPoolIn,
156
                                 OpenLayerFunc pfnOpenLayerIn,
157
                                 ReleaseLayerFunc pfnReleaseLayerIn,
158
                                 FreeUserDataFunc pfnFreeUserDataIn,
159
                                 void *pUserDataIn)
160
0
    : OGRAbstractProxiedLayer(poPoolIn), pfnOpenLayer(pfnOpenLayerIn),
161
0
      pfnReleaseLayer(pfnReleaseLayerIn), pfnFreeUserData(pfnFreeUserDataIn),
162
0
      pUserData(pUserDataIn), poUnderlyingLayer(nullptr),
163
0
      poFeatureDefn(nullptr), poSRS(nullptr)
164
0
{
165
0
    CPLAssert(pfnOpenLayerIn != nullptr);
166
0
}
167
168
/************************************************************************/
169
/*                         ~OGRProxiedLayer()                           */
170
/************************************************************************/
171
172
OGRProxiedLayer::~OGRProxiedLayer()
173
0
{
174
0
    OGRProxiedLayer::CloseUnderlyingLayer();
175
176
0
    if (poSRS)
177
0
        poSRS->Release();
178
179
0
    if (poFeatureDefn)
180
0
        poFeatureDefn->Release();
181
182
0
    if (pfnFreeUserData != nullptr)
183
0
        pfnFreeUserData(pUserData);
184
0
}
185
186
/************************************************************************/
187
/*                       OpenUnderlyingLayer()                          */
188
/************************************************************************/
189
190
int OGRProxiedLayer::OpenUnderlyingLayer() const
191
0
{
192
0
    std::lock_guard oLock(m_oMutex);
193
0
    if (poUnderlyingLayer == nullptr)
194
0
    {
195
0
        CPLDebug("OGR", "OpenUnderlyingLayer(%p)", this);
196
0
        poPool->SetLastUsedLayer(const_cast<OGRProxiedLayer *>(this));
197
0
        poUnderlyingLayer = pfnOpenLayer(pUserData);
198
0
        if (poUnderlyingLayer == nullptr)
199
0
        {
200
0
            CPLError(CE_Failure, CPLE_FileIO, "Cannot open underlying layer");
201
0
        }
202
0
    }
203
0
    return poUnderlyingLayer != nullptr;
204
0
}
205
206
/************************************************************************/
207
/*                         CloseUnderlyingLayer()                       */
208
/************************************************************************/
209
210
void OGRProxiedLayer::CloseUnderlyingLayer()
211
0
{
212
0
    CPLDebug("OGR", "CloseUnderlyingLayer(%p)", this);
213
0
    if (poUnderlyingLayer)
214
0
    {
215
0
        pfnReleaseLayer(poUnderlyingLayer, pUserData);
216
0
    }
217
0
    poUnderlyingLayer = nullptr;
218
0
}
219
220
/************************************************************************/
221
/*                          GetUnderlyingLayer()                        */
222
/************************************************************************/
223
224
OGRLayer *OGRProxiedLayer::GetUnderlyingLayer()
225
0
{
226
0
    if (poUnderlyingLayer == nullptr)
227
0
    {
228
        //  If the open fails, poUnderlyingLayer will still be a nullptr
229
        // and the user will be warned by the open call.
230
0
        CPL_IGNORE_RET_VAL(OpenUnderlyingLayer());
231
0
    }
232
0
    return poUnderlyingLayer;
233
0
}
234
235
/************************************************************************/
236
/*                          GetSpatialFilter()                          */
237
/************************************************************************/
238
239
OGRGeometry *OGRProxiedLayer::GetSpatialFilter()
240
0
{
241
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
242
0
        return nullptr;
243
0
    return poUnderlyingLayer->GetSpatialFilter();
244
0
}
245
246
/************************************************************************/
247
/*                         ISetSpatialFilter()                          */
248
/************************************************************************/
249
250
OGRErr OGRProxiedLayer::ISetSpatialFilter(int iGeomField,
251
                                          const OGRGeometry *poGeom)
252
0
{
253
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
254
0
        return OGRERR_FAILURE;
255
0
    return poUnderlyingLayer->SetSpatialFilter(iGeomField, poGeom);
256
0
}
257
258
/************************************************************************/
259
/*                          SetAttributeFilter()                        */
260
/************************************************************************/
261
262
OGRErr OGRProxiedLayer::SetAttributeFilter(const char *poAttrFilter)
263
0
{
264
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
265
0
        return OGRERR_FAILURE;
266
0
    return poUnderlyingLayer->SetAttributeFilter(poAttrFilter);
267
0
}
268
269
/************************************************************************/
270
/*                            ResetReading()                            */
271
/************************************************************************/
272
273
void OGRProxiedLayer::ResetReading()
274
0
{
275
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
276
0
        return;
277
0
    poUnderlyingLayer->ResetReading();
278
0
}
279
280
/************************************************************************/
281
/*                           GetNextFeature()                           */
282
/************************************************************************/
283
284
OGRFeature *OGRProxiedLayer::GetNextFeature()
285
0
{
286
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
287
0
        return nullptr;
288
0
    return poUnderlyingLayer->GetNextFeature();
289
0
}
290
291
/************************************************************************/
292
/*                            GDALDataset()                             */
293
/************************************************************************/
294
295
GDALDataset *OGRProxiedLayer::GetDataset()
296
0
{
297
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
298
0
        return nullptr;
299
0
    return poUnderlyingLayer->GetDataset();
300
0
}
301
302
/************************************************************************/
303
/*                          GetArrowStream()                            */
304
/************************************************************************/
305
306
bool OGRProxiedLayer::GetArrowStream(struct ArrowArrayStream *out_stream,
307
                                     CSLConstList papszOptions)
308
0
{
309
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
310
0
    {
311
0
        memset(out_stream, 0, sizeof(*out_stream));
312
0
        return false;
313
0
    }
314
0
    return poUnderlyingLayer->GetArrowStream(out_stream, papszOptions);
315
0
}
316
317
/************************************************************************/
318
/*                           SetNextByIndex()                           */
319
/************************************************************************/
320
321
OGRErr OGRProxiedLayer::SetNextByIndex(GIntBig nIndex)
322
0
{
323
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
324
0
        return OGRERR_FAILURE;
325
0
    return poUnderlyingLayer->SetNextByIndex(nIndex);
326
0
}
327
328
/************************************************************************/
329
/*                             GetFeature()                             */
330
/************************************************************************/
331
332
OGRFeature *OGRProxiedLayer::GetFeature(GIntBig nFID)
333
0
{
334
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
335
0
        return nullptr;
336
0
    return poUnderlyingLayer->GetFeature(nFID);
337
0
}
338
339
/************************************************************************/
340
/*                             ISetFeature()                             */
341
/************************************************************************/
342
343
OGRErr OGRProxiedLayer::ISetFeature(OGRFeature *poFeature)
344
0
{
345
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
346
0
        return OGRERR_FAILURE;
347
0
    return poUnderlyingLayer->SetFeature(poFeature);
348
0
}
349
350
/************************************************************************/
351
/*                            ICreateFeature()                           */
352
/************************************************************************/
353
354
OGRErr OGRProxiedLayer::ICreateFeature(OGRFeature *poFeature)
355
0
{
356
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
357
0
        return OGRERR_FAILURE;
358
0
    return poUnderlyingLayer->CreateFeature(poFeature);
359
0
}
360
361
/************************************************************************/
362
/*                            IUpsertFeature()                          */
363
/************************************************************************/
364
365
OGRErr OGRProxiedLayer::IUpsertFeature(OGRFeature *poFeature)
366
0
{
367
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
368
0
        return OGRERR_FAILURE;
369
0
    return poUnderlyingLayer->UpsertFeature(poFeature);
370
0
}
371
372
/************************************************************************/
373
/*                            IUpdateFeature()                          */
374
/************************************************************************/
375
376
OGRErr OGRProxiedLayer::IUpdateFeature(OGRFeature *poFeature,
377
                                       int nUpdatedFieldsCount,
378
                                       const int *panUpdatedFieldsIdx,
379
                                       int nUpdatedGeomFieldsCount,
380
                                       const int *panUpdatedGeomFieldsIdx,
381
                                       bool bUpdateStyleString)
382
0
{
383
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
384
0
        return OGRERR_FAILURE;
385
0
    return poUnderlyingLayer->UpdateFeature(
386
0
        poFeature, nUpdatedFieldsCount, panUpdatedFieldsIdx,
387
0
        nUpdatedGeomFieldsCount, panUpdatedGeomFieldsIdx, bUpdateStyleString);
388
0
}
389
390
/************************************************************************/
391
/*                           DeleteFeature()                            */
392
/************************************************************************/
393
394
OGRErr OGRProxiedLayer::DeleteFeature(GIntBig nFID)
395
0
{
396
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
397
0
        return OGRERR_FAILURE;
398
0
    return poUnderlyingLayer->DeleteFeature(nFID);
399
0
}
400
401
/************************************************************************/
402
/*                             GetName()                                */
403
/************************************************************************/
404
405
const char *OGRProxiedLayer::GetName() const
406
0
{
407
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
408
0
        return "";
409
0
    return poUnderlyingLayer->GetName();
410
0
}
411
412
/************************************************************************/
413
/*                            GetGeomType()                             */
414
/************************************************************************/
415
416
OGRwkbGeometryType OGRProxiedLayer::GetGeomType() const
417
0
{
418
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
419
0
        return wkbUnknown;
420
0
    return poUnderlyingLayer->GetGeomType();
421
0
}
422
423
/************************************************************************/
424
/*                            GetLayerDefn()                            */
425
/************************************************************************/
426
427
const OGRFeatureDefn *OGRProxiedLayer::GetLayerDefn() const
428
0
{
429
0
    std::lock_guard oLock(m_oMutex);
430
0
    if (poFeatureDefn != nullptr)
431
0
        return poFeatureDefn;
432
433
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
434
0
    {
435
0
        poFeatureDefn = new OGRFeatureDefn("");
436
0
    }
437
0
    else
438
0
    {
439
0
        poFeatureDefn = poUnderlyingLayer->GetLayerDefn();
440
0
    }
441
442
0
    poFeatureDefn->Reference();
443
444
0
    return poFeatureDefn;
445
0
}
446
447
/************************************************************************/
448
/*                            GetSpatialRef()                           */
449
/************************************************************************/
450
451
const OGRSpatialReference *OGRProxiedLayer::GetSpatialRef() const
452
0
{
453
0
    std::lock_guard oLock(m_oMutex);
454
0
    if (poSRS != nullptr)
455
0
        return poSRS;
456
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
457
0
        return nullptr;
458
0
    OGRSpatialReference *l_poSRS =
459
0
        const_cast<OGRSpatialReference *>(poUnderlyingLayer->GetSpatialRef());
460
0
    if (l_poSRS != nullptr)
461
0
    {
462
0
        l_poSRS->Reference();
463
0
        poSRS = l_poSRS;
464
0
    }
465
0
    return poSRS;
466
0
}
467
468
/************************************************************************/
469
/*                          GetFeatureCount()                           */
470
/************************************************************************/
471
472
GIntBig OGRProxiedLayer::GetFeatureCount(int bForce)
473
0
{
474
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
475
0
        return 0;
476
0
    return poUnderlyingLayer->GetFeatureCount(bForce);
477
0
}
478
479
/************************************************************************/
480
/*                            IGetExtent()                              */
481
/************************************************************************/
482
483
OGRErr OGRProxiedLayer::IGetExtent(int iGeomField, OGREnvelope *psExtent,
484
                                   bool bForce)
485
0
{
486
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
487
0
        return OGRERR_FAILURE;
488
0
    return poUnderlyingLayer->GetExtent(iGeomField, psExtent, bForce);
489
0
}
490
491
/************************************************************************/
492
/*                           TestCapability()                           */
493
/************************************************************************/
494
495
int OGRProxiedLayer::TestCapability(const char *pszCapability) const
496
0
{
497
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
498
0
        return FALSE;
499
0
    return poUnderlyingLayer->TestCapability(pszCapability);
500
0
}
501
502
/************************************************************************/
503
/*                            CreateField()                             */
504
/************************************************************************/
505
506
OGRErr OGRProxiedLayer::CreateField(const OGRFieldDefn *poField, int bApproxOK)
507
0
{
508
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
509
0
        return OGRERR_FAILURE;
510
0
    return poUnderlyingLayer->CreateField(poField, bApproxOK);
511
0
}
512
513
/************************************************************************/
514
/*                            DeleteField()                             */
515
/************************************************************************/
516
517
OGRErr OGRProxiedLayer::DeleteField(int iField)
518
0
{
519
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
520
0
        return OGRERR_FAILURE;
521
0
    return poUnderlyingLayer->DeleteField(iField);
522
0
}
523
524
/************************************************************************/
525
/*                            ReorderFields()                           */
526
/************************************************************************/
527
528
OGRErr OGRProxiedLayer::ReorderFields(int *panMap)
529
0
{
530
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
531
0
        return OGRERR_FAILURE;
532
0
    return poUnderlyingLayer->ReorderFields(panMap);
533
0
}
534
535
/************************************************************************/
536
/*                           AlterFieldDefn()                           */
537
/************************************************************************/
538
539
OGRErr OGRProxiedLayer::AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
540
                                       int nFlagsIn)
541
0
{
542
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
543
0
        return OGRERR_FAILURE;
544
0
    return poUnderlyingLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
545
0
}
546
547
/************************************************************************/
548
/*                         AlterGeomFieldDefn()                         */
549
/************************************************************************/
550
551
OGRErr OGRProxiedLayer::AlterGeomFieldDefn(
552
    int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
553
0
{
554
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
555
0
        return OGRERR_FAILURE;
556
0
    return poUnderlyingLayer->AlterGeomFieldDefn(iGeomField, poNewGeomFieldDefn,
557
0
                                                 nFlagsIn);
558
0
}
559
560
/************************************************************************/
561
/*                            SyncToDisk()                              */
562
/************************************************************************/
563
564
OGRErr OGRProxiedLayer::SyncToDisk()
565
0
{
566
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
567
0
        return OGRERR_FAILURE;
568
0
    return poUnderlyingLayer->SyncToDisk();
569
0
}
570
571
/************************************************************************/
572
/*                           GetStyleTable()                            */
573
/************************************************************************/
574
575
OGRStyleTable *OGRProxiedLayer::GetStyleTable()
576
0
{
577
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
578
0
        return nullptr;
579
0
    return poUnderlyingLayer->GetStyleTable();
580
0
}
581
582
/************************************************************************/
583
/*                       SetStyleTableDirectly()                        */
584
/************************************************************************/
585
586
void OGRProxiedLayer::SetStyleTableDirectly(OGRStyleTable *poStyleTable)
587
0
{
588
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
589
0
        return;
590
0
    return poUnderlyingLayer->SetStyleTableDirectly(poStyleTable);
591
0
}
592
593
/************************************************************************/
594
/*                           SetStyleTable()                            */
595
/************************************************************************/
596
597
void OGRProxiedLayer::SetStyleTable(OGRStyleTable *poStyleTable)
598
0
{
599
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
600
0
        return;
601
0
    return poUnderlyingLayer->SetStyleTable(poStyleTable);
602
0
}
603
604
/************************************************************************/
605
/*                          StartTransaction()                          */
606
/************************************************************************/
607
608
OGRErr OGRProxiedLayer::StartTransaction()
609
0
{
610
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
611
0
        return OGRERR_FAILURE;
612
0
    return poUnderlyingLayer->StartTransaction();
613
0
}
614
615
/************************************************************************/
616
/*                          CommitTransaction()                         */
617
/************************************************************************/
618
619
OGRErr OGRProxiedLayer::CommitTransaction()
620
0
{
621
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
622
0
        return OGRERR_FAILURE;
623
0
    return poUnderlyingLayer->CommitTransaction();
624
0
}
625
626
/************************************************************************/
627
/*                        RollbackTransaction()                         */
628
/************************************************************************/
629
630
OGRErr OGRProxiedLayer::RollbackTransaction()
631
0
{
632
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
633
0
        return OGRERR_FAILURE;
634
0
    return poUnderlyingLayer->RollbackTransaction();
635
0
}
636
637
/************************************************************************/
638
/*                            GetFIDColumn()                            */
639
/************************************************************************/
640
641
const char *OGRProxiedLayer::GetFIDColumn() const
642
0
{
643
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
644
0
        return "";
645
0
    return poUnderlyingLayer->GetFIDColumn();
646
0
}
647
648
/************************************************************************/
649
/*                          GetGeometryColumn()                         */
650
/************************************************************************/
651
652
const char *OGRProxiedLayer::GetGeometryColumn() const
653
0
{
654
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
655
0
        return "";
656
0
    return poUnderlyingLayer->GetGeometryColumn();
657
0
}
658
659
/************************************************************************/
660
/*                          SetIgnoredFields()                          */
661
/************************************************************************/
662
663
OGRErr OGRProxiedLayer::SetIgnoredFields(CSLConstList papszFields)
664
0
{
665
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
666
0
        return OGRERR_FAILURE;
667
0
    return poUnderlyingLayer->SetIgnoredFields(papszFields);
668
0
}
669
670
/************************************************************************/
671
/*                              Rename()                                */
672
/************************************************************************/
673
674
OGRErr OGRProxiedLayer::Rename(const char *pszNewName)
675
0
{
676
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
677
0
        return OGRERR_FAILURE;
678
0
    return poUnderlyingLayer->Rename(pszNewName);
679
0
}
680
681
#endif /* #ifndef DOXYGEN_SKIP */