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