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