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