Coverage Report

Created: 2025-06-13 06:29

/src/gdal/ogr/ogrsf_frmts/generic/ogrlayerpool.cpp
Line
Count
Source (jump to first uncovered line)
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()
191
0
{
192
0
    CPLDebug("OGR", "OpenUnderlyingLayer(%p)", this);
193
0
    CPLAssert(poUnderlyingLayer == nullptr);
194
0
    poPool->SetLastUsedLayer(this);
195
0
    poUnderlyingLayer = pfnOpenLayer(pUserData);
196
0
    if (poUnderlyingLayer == nullptr)
197
0
    {
198
0
        CPLError(CE_Failure, CPLE_FileIO, "Cannot open underlying layer");
199
0
    }
200
0
    return poUnderlyingLayer != nullptr;
201
0
}
202
203
/************************************************************************/
204
/*                         CloseUnderlyingLayer()                       */
205
/************************************************************************/
206
207
void OGRProxiedLayer::CloseUnderlyingLayer()
208
0
{
209
0
    CPLDebug("OGR", "CloseUnderlyingLayer(%p)", this);
210
0
    if (poUnderlyingLayer)
211
0
    {
212
0
        pfnReleaseLayer(poUnderlyingLayer, pUserData);
213
0
    }
214
0
    poUnderlyingLayer = nullptr;
215
0
}
216
217
/************************************************************************/
218
/*                          GetUnderlyingLayer()                        */
219
/************************************************************************/
220
221
OGRLayer *OGRProxiedLayer::GetUnderlyingLayer()
222
0
{
223
0
    if (poUnderlyingLayer == nullptr)
224
0
    {
225
        //  If the open fails, poUnderlyingLayer will still be a nullptr
226
        // and the user will be warned by the open call.
227
0
        CPL_IGNORE_RET_VAL(OpenUnderlyingLayer());
228
0
    }
229
0
    return poUnderlyingLayer;
230
0
}
231
232
/************************************************************************/
233
/*                          GetSpatialFilter()                          */
234
/************************************************************************/
235
236
OGRGeometry *OGRProxiedLayer::GetSpatialFilter()
237
0
{
238
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
239
0
        return nullptr;
240
0
    return poUnderlyingLayer->GetSpatialFilter();
241
0
}
242
243
/************************************************************************/
244
/*                         ISetSpatialFilter()                          */
245
/************************************************************************/
246
247
OGRErr OGRProxiedLayer::ISetSpatialFilter(int iGeomField,
248
                                          const OGRGeometry *poGeom)
249
0
{
250
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
251
0
        return OGRERR_FAILURE;
252
0
    return poUnderlyingLayer->SetSpatialFilter(iGeomField, poGeom);
253
0
}
254
255
/************************************************************************/
256
/*                          SetAttributeFilter()                        */
257
/************************************************************************/
258
259
OGRErr OGRProxiedLayer::SetAttributeFilter(const char *poAttrFilter)
260
0
{
261
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
262
0
        return OGRERR_FAILURE;
263
0
    return poUnderlyingLayer->SetAttributeFilter(poAttrFilter);
264
0
}
265
266
/************************************************************************/
267
/*                            ResetReading()                            */
268
/************************************************************************/
269
270
void OGRProxiedLayer::ResetReading()
271
0
{
272
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
273
0
        return;
274
0
    poUnderlyingLayer->ResetReading();
275
0
}
276
277
/************************************************************************/
278
/*                           GetNextFeature()                           */
279
/************************************************************************/
280
281
OGRFeature *OGRProxiedLayer::GetNextFeature()
282
0
{
283
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
284
0
        return nullptr;
285
0
    return poUnderlyingLayer->GetNextFeature();
286
0
}
287
288
/************************************************************************/
289
/*                            GDALDataset()                             */
290
/************************************************************************/
291
292
GDALDataset *OGRProxiedLayer::GetDataset()
293
0
{
294
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
295
0
        return nullptr;
296
0
    return poUnderlyingLayer->GetDataset();
297
0
}
298
299
/************************************************************************/
300
/*                          GetArrowStream()                            */
301
/************************************************************************/
302
303
bool OGRProxiedLayer::GetArrowStream(struct ArrowArrayStream *out_stream,
304
                                     CSLConstList papszOptions)
305
0
{
306
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
307
0
    {
308
0
        memset(out_stream, 0, sizeof(*out_stream));
309
0
        return false;
310
0
    }
311
0
    return poUnderlyingLayer->GetArrowStream(out_stream, papszOptions);
312
0
}
313
314
/************************************************************************/
315
/*                           SetNextByIndex()                           */
316
/************************************************************************/
317
318
OGRErr OGRProxiedLayer::SetNextByIndex(GIntBig nIndex)
319
0
{
320
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
321
0
        return OGRERR_FAILURE;
322
0
    return poUnderlyingLayer->SetNextByIndex(nIndex);
323
0
}
324
325
/************************************************************************/
326
/*                             GetFeature()                             */
327
/************************************************************************/
328
329
OGRFeature *OGRProxiedLayer::GetFeature(GIntBig nFID)
330
0
{
331
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
332
0
        return nullptr;
333
0
    return poUnderlyingLayer->GetFeature(nFID);
334
0
}
335
336
/************************************************************************/
337
/*                             ISetFeature()                             */
338
/************************************************************************/
339
340
OGRErr OGRProxiedLayer::ISetFeature(OGRFeature *poFeature)
341
0
{
342
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
343
0
        return OGRERR_FAILURE;
344
0
    return poUnderlyingLayer->SetFeature(poFeature);
345
0
}
346
347
/************************************************************************/
348
/*                            ICreateFeature()                           */
349
/************************************************************************/
350
351
OGRErr OGRProxiedLayer::ICreateFeature(OGRFeature *poFeature)
352
0
{
353
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
354
0
        return OGRERR_FAILURE;
355
0
    return poUnderlyingLayer->CreateFeature(poFeature);
356
0
}
357
358
/************************************************************************/
359
/*                            IUpsertFeature()                          */
360
/************************************************************************/
361
362
OGRErr OGRProxiedLayer::IUpsertFeature(OGRFeature *poFeature)
363
0
{
364
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
365
0
        return OGRERR_FAILURE;
366
0
    return poUnderlyingLayer->UpsertFeature(poFeature);
367
0
}
368
369
/************************************************************************/
370
/*                            IUpdateFeature()                          */
371
/************************************************************************/
372
373
OGRErr OGRProxiedLayer::IUpdateFeature(OGRFeature *poFeature,
374
                                       int nUpdatedFieldsCount,
375
                                       const int *panUpdatedFieldsIdx,
376
                                       int nUpdatedGeomFieldsCount,
377
                                       const int *panUpdatedGeomFieldsIdx,
378
                                       bool bUpdateStyleString)
379
0
{
380
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
381
0
        return OGRERR_FAILURE;
382
0
    return poUnderlyingLayer->UpdateFeature(
383
0
        poFeature, nUpdatedFieldsCount, panUpdatedFieldsIdx,
384
0
        nUpdatedGeomFieldsCount, panUpdatedGeomFieldsIdx, bUpdateStyleString);
385
0
}
386
387
/************************************************************************/
388
/*                           DeleteFeature()                            */
389
/************************************************************************/
390
391
OGRErr OGRProxiedLayer::DeleteFeature(GIntBig nFID)
392
0
{
393
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
394
0
        return OGRERR_FAILURE;
395
0
    return poUnderlyingLayer->DeleteFeature(nFID);
396
0
}
397
398
/************************************************************************/
399
/*                             GetName()                                */
400
/************************************************************************/
401
402
const char *OGRProxiedLayer::GetName()
403
0
{
404
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
405
0
        return "";
406
0
    return poUnderlyingLayer->GetName();
407
0
}
408
409
/************************************************************************/
410
/*                            GetGeomType()                             */
411
/************************************************************************/
412
413
OGRwkbGeometryType OGRProxiedLayer::GetGeomType()
414
0
{
415
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
416
0
        return wkbUnknown;
417
0
    return poUnderlyingLayer->GetGeomType();
418
0
}
419
420
/************************************************************************/
421
/*                            GetLayerDefn()                            */
422
/************************************************************************/
423
424
OGRFeatureDefn *OGRProxiedLayer::GetLayerDefn()
425
0
{
426
0
    if (poFeatureDefn != nullptr)
427
0
        return poFeatureDefn;
428
429
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
430
0
    {
431
0
        poFeatureDefn = new OGRFeatureDefn("");
432
0
    }
433
0
    else
434
0
    {
435
0
        poFeatureDefn = poUnderlyingLayer->GetLayerDefn();
436
0
    }
437
438
0
    poFeatureDefn->Reference();
439
440
0
    return poFeatureDefn;
441
0
}
442
443
/************************************************************************/
444
/*                            GetSpatialRef()                           */
445
/************************************************************************/
446
447
OGRSpatialReference *OGRProxiedLayer::GetSpatialRef()
448
0
{
449
0
    if (poSRS != nullptr)
450
0
        return poSRS;
451
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
452
0
        return nullptr;
453
0
    OGRSpatialReference *poRet = poUnderlyingLayer->GetSpatialRef();
454
0
    if (poRet != nullptr)
455
0
    {
456
0
        poSRS = poRet;
457
0
        poSRS->Reference();
458
0
    }
459
0
    return poRet;
460
0
}
461
462
/************************************************************************/
463
/*                          GetFeatureCount()                           */
464
/************************************************************************/
465
466
GIntBig OGRProxiedLayer::GetFeatureCount(int bForce)
467
0
{
468
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
469
0
        return 0;
470
0
    return poUnderlyingLayer->GetFeatureCount(bForce);
471
0
}
472
473
/************************************************************************/
474
/*                            IGetExtent()                              */
475
/************************************************************************/
476
477
OGRErr OGRProxiedLayer::IGetExtent(int iGeomField, OGREnvelope *psExtent,
478
                                   bool bForce)
479
0
{
480
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
481
0
        return OGRERR_FAILURE;
482
0
    return poUnderlyingLayer->GetExtent(iGeomField, psExtent, bForce);
483
0
}
484
485
/************************************************************************/
486
/*                           TestCapability()                           */
487
/************************************************************************/
488
489
int OGRProxiedLayer::TestCapability(const char *pszCapability)
490
0
{
491
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
492
0
        return FALSE;
493
0
    return poUnderlyingLayer->TestCapability(pszCapability);
494
0
}
495
496
/************************************************************************/
497
/*                            CreateField()                             */
498
/************************************************************************/
499
500
OGRErr OGRProxiedLayer::CreateField(const OGRFieldDefn *poField, int bApproxOK)
501
0
{
502
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
503
0
        return OGRERR_FAILURE;
504
0
    return poUnderlyingLayer->CreateField(poField, bApproxOK);
505
0
}
506
507
/************************************************************************/
508
/*                            DeleteField()                             */
509
/************************************************************************/
510
511
OGRErr OGRProxiedLayer::DeleteField(int iField)
512
0
{
513
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
514
0
        return OGRERR_FAILURE;
515
0
    return poUnderlyingLayer->DeleteField(iField);
516
0
}
517
518
/************************************************************************/
519
/*                            ReorderFields()                           */
520
/************************************************************************/
521
522
OGRErr OGRProxiedLayer::ReorderFields(int *panMap)
523
0
{
524
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
525
0
        return OGRERR_FAILURE;
526
0
    return poUnderlyingLayer->ReorderFields(panMap);
527
0
}
528
529
/************************************************************************/
530
/*                           AlterFieldDefn()                           */
531
/************************************************************************/
532
533
OGRErr OGRProxiedLayer::AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
534
                                       int nFlagsIn)
535
0
{
536
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
537
0
        return OGRERR_FAILURE;
538
0
    return poUnderlyingLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
539
0
}
540
541
/************************************************************************/
542
/*                         AlterGeomFieldDefn()                         */
543
/************************************************************************/
544
545
OGRErr OGRProxiedLayer::AlterGeomFieldDefn(
546
    int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
547
0
{
548
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
549
0
        return OGRERR_FAILURE;
550
0
    return poUnderlyingLayer->AlterGeomFieldDefn(iGeomField, poNewGeomFieldDefn,
551
0
                                                 nFlagsIn);
552
0
}
553
554
/************************************************************************/
555
/*                            SyncToDisk()                              */
556
/************************************************************************/
557
558
OGRErr OGRProxiedLayer::SyncToDisk()
559
0
{
560
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
561
0
        return OGRERR_FAILURE;
562
0
    return poUnderlyingLayer->SyncToDisk();
563
0
}
564
565
/************************************************************************/
566
/*                           GetStyleTable()                            */
567
/************************************************************************/
568
569
OGRStyleTable *OGRProxiedLayer::GetStyleTable()
570
0
{
571
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
572
0
        return nullptr;
573
0
    return poUnderlyingLayer->GetStyleTable();
574
0
}
575
576
/************************************************************************/
577
/*                       SetStyleTableDirectly()                        */
578
/************************************************************************/
579
580
void OGRProxiedLayer::SetStyleTableDirectly(OGRStyleTable *poStyleTable)
581
0
{
582
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
583
0
        return;
584
0
    return poUnderlyingLayer->SetStyleTableDirectly(poStyleTable);
585
0
}
586
587
/************************************************************************/
588
/*                           SetStyleTable()                            */
589
/************************************************************************/
590
591
void OGRProxiedLayer::SetStyleTable(OGRStyleTable *poStyleTable)
592
0
{
593
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
594
0
        return;
595
0
    return poUnderlyingLayer->SetStyleTable(poStyleTable);
596
0
}
597
598
/************************************************************************/
599
/*                          StartTransaction()                          */
600
/************************************************************************/
601
602
OGRErr OGRProxiedLayer::StartTransaction()
603
0
{
604
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
605
0
        return OGRERR_FAILURE;
606
0
    return poUnderlyingLayer->StartTransaction();
607
0
}
608
609
/************************************************************************/
610
/*                          CommitTransaction()                         */
611
/************************************************************************/
612
613
OGRErr OGRProxiedLayer::CommitTransaction()
614
0
{
615
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
616
0
        return OGRERR_FAILURE;
617
0
    return poUnderlyingLayer->CommitTransaction();
618
0
}
619
620
/************************************************************************/
621
/*                        RollbackTransaction()                         */
622
/************************************************************************/
623
624
OGRErr OGRProxiedLayer::RollbackTransaction()
625
0
{
626
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
627
0
        return OGRERR_FAILURE;
628
0
    return poUnderlyingLayer->RollbackTransaction();
629
0
}
630
631
/************************************************************************/
632
/*                            GetFIDColumn()                            */
633
/************************************************************************/
634
635
const char *OGRProxiedLayer::GetFIDColumn()
636
0
{
637
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
638
0
        return "";
639
0
    return poUnderlyingLayer->GetFIDColumn();
640
0
}
641
642
/************************************************************************/
643
/*                          GetGeometryColumn()                         */
644
/************************************************************************/
645
646
const char *OGRProxiedLayer::GetGeometryColumn()
647
0
{
648
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
649
0
        return "";
650
0
    return poUnderlyingLayer->GetGeometryColumn();
651
0
}
652
653
/************************************************************************/
654
/*                          SetIgnoredFields()                          */
655
/************************************************************************/
656
657
OGRErr OGRProxiedLayer::SetIgnoredFields(CSLConstList papszFields)
658
0
{
659
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
660
0
        return OGRERR_FAILURE;
661
0
    return poUnderlyingLayer->SetIgnoredFields(papszFields);
662
0
}
663
664
/************************************************************************/
665
/*                              Rename()                                */
666
/************************************************************************/
667
668
OGRErr OGRProxiedLayer::Rename(const char *pszNewName)
669
0
{
670
0
    if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
671
0
        return OGRERR_FAILURE;
672
0
    return poUnderlyingLayer->Rename(pszNewName);
673
0
}
674
675
#endif /* #ifndef DOXYGEN_SKIP */