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 5580 : OGRAbstractProxiedLayer::OGRAbstractProxiedLayer(OGRLayerPool *poPoolIn)
23 5580 : : poPrevLayer(nullptr), poNextLayer(nullptr), poPool(poPoolIn)
24 : {
25 5580 : CPLAssert(poPoolIn != nullptr);
26 5580 : }
27 :
28 : /************************************************************************/
29 : /* ~OGRAbstractProxiedLayer() */
30 : /************************************************************************/
31 :
32 5573 : OGRAbstractProxiedLayer::~OGRAbstractProxiedLayer()
33 : {
34 : /* Remove us from the list of LRU layers if necessary */
35 5573 : poPool->UnchainLayer(this);
36 5573 : }
37 :
38 : /************************************************************************/
39 : /* OGRLayerPool() */
40 : /************************************************************************/
41 :
42 3871 : OGRLayerPool::OGRLayerPool(int nMaxSimultaneouslyOpenedIn)
43 : : poMRULayer(nullptr), poLRULayer(nullptr), nMRUListSize(0),
44 3871 : nMaxSimultaneouslyOpened(nMaxSimultaneouslyOpenedIn)
45 : {
46 3871 : }
47 :
48 : /************************************************************************/
49 : /* ~OGRLayerPool() */
50 : /************************************************************************/
51 :
52 7728 : OGRLayerPool::~OGRLayerPool()
53 : {
54 3864 : CPLAssert(poMRULayer == nullptr);
55 3864 : CPLAssert(poLRULayer == nullptr);
56 3864 : CPLAssert(nMRUListSize == 0);
57 3864 : }
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 7714 : void OGRLayerPool::UnchainLayer(OGRAbstractProxiedLayer *poLayer)
107 : {
108 7714 : OGRAbstractProxiedLayer *poPrevLayer = poLayer->poPrevLayer;
109 7714 : OGRAbstractProxiedLayer *poNextLayer = poLayer->poNextLayer;
110 :
111 7714 : CPLAssert(poPrevLayer == nullptr || poPrevLayer->poNextLayer == poLayer);
112 7714 : CPLAssert(poNextLayer == nullptr || poNextLayer->poPrevLayer == poLayer);
113 :
114 7714 : if (poPrevLayer != nullptr || poNextLayer != nullptr ||
115 5187 : poLayer == poMRULayer)
116 2675 : nMRUListSize--;
117 :
118 7714 : if (poLayer == poMRULayer)
119 153 : poMRULayer = poNextLayer;
120 7714 : if (poLayer == poLRULayer)
121 2656 : poLRULayer = poPrevLayer;
122 7714 : if (poPrevLayer != nullptr)
123 2522 : poPrevLayer->poNextLayer = poNextLayer;
124 7714 : if (poNextLayer != nullptr)
125 19 : poNextLayer->poPrevLayer = poPrevLayer;
126 7714 : poLayer->poPrevLayer = nullptr;
127 7714 : poLayer->poNextLayer = nullptr;
128 7714 : }
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 0 : CPL_IGNORE_RET_VAL(OpenUnderlyingLayer());
228 : }
229 0 : return poUnderlyingLayer;
230 : }
231 :
232 : /************************************************************************/
233 : /* GetSpatialFilter() */
234 : /************************************************************************/
235 :
236 0 : OGRGeometry *OGRProxiedLayer::GetSpatialFilter()
237 : {
238 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
239 0 : return nullptr;
240 0 : return poUnderlyingLayer->GetSpatialFilter();
241 : }
242 :
243 : /************************************************************************/
244 : /* ISetSpatialFilter() */
245 : /************************************************************************/
246 :
247 184 : OGRErr OGRProxiedLayer::ISetSpatialFilter(int iGeomField,
248 : const OGRGeometry *poGeom)
249 : {
250 184 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
251 0 : return OGRERR_FAILURE;
252 184 : return poUnderlyingLayer->SetSpatialFilter(iGeomField, poGeom);
253 : }
254 :
255 : /************************************************************************/
256 : /* SetAttributeFilter() */
257 : /************************************************************************/
258 :
259 176 : OGRErr OGRProxiedLayer::SetAttributeFilter(const char *poAttrFilter)
260 : {
261 176 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
262 0 : return OGRERR_FAILURE;
263 176 : return poUnderlyingLayer->SetAttributeFilter(poAttrFilter);
264 : }
265 :
266 : /************************************************************************/
267 : /* ResetReading() */
268 : /************************************************************************/
269 :
270 133 : void OGRProxiedLayer::ResetReading()
271 : {
272 133 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
273 0 : return;
274 133 : poUnderlyingLayer->ResetReading();
275 : }
276 :
277 : /************************************************************************/
278 : /* GetNextFeature() */
279 : /************************************************************************/
280 :
281 1054 : OGRFeature *OGRProxiedLayer::GetNextFeature()
282 : {
283 1054 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
284 0 : return nullptr;
285 1054 : return poUnderlyingLayer->GetNextFeature();
286 : }
287 :
288 : /************************************************************************/
289 : /* GDALDataset() */
290 : /************************************************************************/
291 :
292 0 : GDALDataset *OGRProxiedLayer::GetDataset()
293 : {
294 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
295 0 : return nullptr;
296 0 : return poUnderlyingLayer->GetDataset();
297 : }
298 :
299 : /************************************************************************/
300 : /* GetArrowStream() */
301 : /************************************************************************/
302 :
303 0 : bool OGRProxiedLayer::GetArrowStream(struct ArrowArrayStream *out_stream,
304 : CSLConstList papszOptions)
305 : {
306 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
307 : {
308 0 : memset(out_stream, 0, sizeof(*out_stream));
309 0 : return false;
310 : }
311 0 : return poUnderlyingLayer->GetArrowStream(out_stream, papszOptions);
312 : }
313 :
314 : /************************************************************************/
315 : /* SetNextByIndex() */
316 : /************************************************************************/
317 :
318 0 : OGRErr OGRProxiedLayer::SetNextByIndex(GIntBig nIndex)
319 : {
320 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
321 0 : return OGRERR_FAILURE;
322 0 : return poUnderlyingLayer->SetNextByIndex(nIndex);
323 : }
324 :
325 : /************************************************************************/
326 : /* GetFeature() */
327 : /************************************************************************/
328 :
329 0 : OGRFeature *OGRProxiedLayer::GetFeature(GIntBig nFID)
330 : {
331 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
332 0 : return nullptr;
333 0 : return poUnderlyingLayer->GetFeature(nFID);
334 : }
335 :
336 : /************************************************************************/
337 : /* ISetFeature() */
338 : /************************************************************************/
339 :
340 0 : OGRErr OGRProxiedLayer::ISetFeature(OGRFeature *poFeature)
341 : {
342 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
343 0 : return OGRERR_FAILURE;
344 0 : return poUnderlyingLayer->SetFeature(poFeature);
345 : }
346 :
347 : /************************************************************************/
348 : /* ICreateFeature() */
349 : /************************************************************************/
350 :
351 0 : OGRErr OGRProxiedLayer::ICreateFeature(OGRFeature *poFeature)
352 : {
353 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
354 0 : return OGRERR_FAILURE;
355 0 : return poUnderlyingLayer->CreateFeature(poFeature);
356 : }
357 :
358 : /************************************************************************/
359 : /* IUpsertFeature() */
360 : /************************************************************************/
361 :
362 0 : OGRErr OGRProxiedLayer::IUpsertFeature(OGRFeature *poFeature)
363 : {
364 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
365 0 : return OGRERR_FAILURE;
366 0 : return poUnderlyingLayer->UpsertFeature(poFeature);
367 : }
368 :
369 : /************************************************************************/
370 : /* IUpdateFeature() */
371 : /************************************************************************/
372 :
373 0 : OGRErr OGRProxiedLayer::IUpdateFeature(OGRFeature *poFeature,
374 : int nUpdatedFieldsCount,
375 : const int *panUpdatedFieldsIdx,
376 : int nUpdatedGeomFieldsCount,
377 : const int *panUpdatedGeomFieldsIdx,
378 : bool bUpdateStyleString)
379 : {
380 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
381 0 : return OGRERR_FAILURE;
382 0 : return poUnderlyingLayer->UpdateFeature(
383 : poFeature, nUpdatedFieldsCount, panUpdatedFieldsIdx,
384 0 : nUpdatedGeomFieldsCount, panUpdatedGeomFieldsIdx, bUpdateStyleString);
385 : }
386 :
387 : /************************************************************************/
388 : /* DeleteFeature() */
389 : /************************************************************************/
390 :
391 0 : OGRErr OGRProxiedLayer::DeleteFeature(GIntBig nFID)
392 : {
393 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
394 0 : return OGRERR_FAILURE;
395 0 : return poUnderlyingLayer->DeleteFeature(nFID);
396 : }
397 :
398 : /************************************************************************/
399 : /* GetName() */
400 : /************************************************************************/
401 :
402 0 : const char *OGRProxiedLayer::GetName()
403 : {
404 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
405 0 : return "";
406 0 : return poUnderlyingLayer->GetName();
407 : }
408 :
409 : /************************************************************************/
410 : /* GetGeomType() */
411 : /************************************************************************/
412 :
413 0 : OGRwkbGeometryType OGRProxiedLayer::GetGeomType()
414 : {
415 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
416 0 : return wkbUnknown;
417 0 : return poUnderlyingLayer->GetGeomType();
418 : }
419 :
420 : /************************************************************************/
421 : /* GetLayerDefn() */
422 : /************************************************************************/
423 :
424 416 : OGRFeatureDefn *OGRProxiedLayer::GetLayerDefn()
425 : {
426 416 : if (poFeatureDefn != nullptr)
427 410 : return poFeatureDefn;
428 :
429 6 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
430 : {
431 0 : poFeatureDefn = new OGRFeatureDefn("");
432 : }
433 : else
434 : {
435 6 : poFeatureDefn = poUnderlyingLayer->GetLayerDefn();
436 : }
437 :
438 6 : poFeatureDefn->Reference();
439 :
440 6 : return poFeatureDefn;
441 : }
442 :
443 : /************************************************************************/
444 : /* GetSpatialRef() */
445 : /************************************************************************/
446 :
447 13 : OGRSpatialReference *OGRProxiedLayer::GetSpatialRef()
448 : {
449 13 : if (poSRS != nullptr)
450 8 : return poSRS;
451 5 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
452 0 : return nullptr;
453 5 : OGRSpatialReference *poRet = poUnderlyingLayer->GetSpatialRef();
454 5 : if (poRet != nullptr)
455 : {
456 5 : poSRS = poRet;
457 5 : poSRS->Reference();
458 : }
459 5 : return poRet;
460 : }
461 :
462 : /************************************************************************/
463 : /* GetFeatureCount() */
464 : /************************************************************************/
465 :
466 22 : GIntBig OGRProxiedLayer::GetFeatureCount(int bForce)
467 : {
468 22 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
469 0 : return 0;
470 22 : return poUnderlyingLayer->GetFeatureCount(bForce);
471 : }
472 :
473 : /************************************************************************/
474 : /* IGetExtent() */
475 : /************************************************************************/
476 :
477 8 : OGRErr OGRProxiedLayer::IGetExtent(int iGeomField, OGREnvelope *psExtent,
478 : bool bForce)
479 : {
480 8 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
481 0 : return OGRERR_FAILURE;
482 8 : return poUnderlyingLayer->GetExtent(iGeomField, psExtent, bForce);
483 : }
484 :
485 : /************************************************************************/
486 : /* TestCapability() */
487 : /************************************************************************/
488 :
489 161 : int OGRProxiedLayer::TestCapability(const char *pszCapability)
490 : {
491 161 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
492 0 : return FALSE;
493 161 : return poUnderlyingLayer->TestCapability(pszCapability);
494 : }
495 :
496 : /************************************************************************/
497 : /* CreateField() */
498 : /************************************************************************/
499 :
500 0 : OGRErr OGRProxiedLayer::CreateField(const OGRFieldDefn *poField, int bApproxOK)
501 : {
502 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
503 0 : return OGRERR_FAILURE;
504 0 : return poUnderlyingLayer->CreateField(poField, bApproxOK);
505 : }
506 :
507 : /************************************************************************/
508 : /* DeleteField() */
509 : /************************************************************************/
510 :
511 0 : OGRErr OGRProxiedLayer::DeleteField(int iField)
512 : {
513 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
514 0 : return OGRERR_FAILURE;
515 0 : return poUnderlyingLayer->DeleteField(iField);
516 : }
517 :
518 : /************************************************************************/
519 : /* ReorderFields() */
520 : /************************************************************************/
521 :
522 0 : OGRErr OGRProxiedLayer::ReorderFields(int *panMap)
523 : {
524 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
525 0 : return OGRERR_FAILURE;
526 0 : return poUnderlyingLayer->ReorderFields(panMap);
527 : }
528 :
529 : /************************************************************************/
530 : /* AlterFieldDefn() */
531 : /************************************************************************/
532 :
533 0 : OGRErr OGRProxiedLayer::AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
534 : int nFlagsIn)
535 : {
536 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
537 0 : return OGRERR_FAILURE;
538 0 : return poUnderlyingLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
539 : }
540 :
541 : /************************************************************************/
542 : /* AlterGeomFieldDefn() */
543 : /************************************************************************/
544 :
545 0 : OGRErr OGRProxiedLayer::AlterGeomFieldDefn(
546 : int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
547 : {
548 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
549 0 : return OGRERR_FAILURE;
550 0 : return poUnderlyingLayer->AlterGeomFieldDefn(iGeomField, poNewGeomFieldDefn,
551 0 : nFlagsIn);
552 : }
553 :
554 : /************************************************************************/
555 : /* SyncToDisk() */
556 : /************************************************************************/
557 :
558 0 : OGRErr OGRProxiedLayer::SyncToDisk()
559 : {
560 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
561 0 : return OGRERR_FAILURE;
562 0 : return poUnderlyingLayer->SyncToDisk();
563 : }
564 :
565 : /************************************************************************/
566 : /* GetStyleTable() */
567 : /************************************************************************/
568 :
569 4 : OGRStyleTable *OGRProxiedLayer::GetStyleTable()
570 : {
571 4 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
572 0 : return nullptr;
573 4 : return poUnderlyingLayer->GetStyleTable();
574 : }
575 :
576 : /************************************************************************/
577 : /* SetStyleTableDirectly() */
578 : /************************************************************************/
579 :
580 0 : void OGRProxiedLayer::SetStyleTableDirectly(OGRStyleTable *poStyleTable)
581 : {
582 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
583 0 : return;
584 0 : return poUnderlyingLayer->SetStyleTableDirectly(poStyleTable);
585 : }
586 :
587 : /************************************************************************/
588 : /* SetStyleTable() */
589 : /************************************************************************/
590 :
591 0 : void OGRProxiedLayer::SetStyleTable(OGRStyleTable *poStyleTable)
592 : {
593 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
594 0 : return;
595 0 : return poUnderlyingLayer->SetStyleTable(poStyleTable);
596 : }
597 :
598 : /************************************************************************/
599 : /* StartTransaction() */
600 : /************************************************************************/
601 :
602 0 : OGRErr OGRProxiedLayer::StartTransaction()
603 : {
604 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
605 0 : return OGRERR_FAILURE;
606 0 : return poUnderlyingLayer->StartTransaction();
607 : }
608 :
609 : /************************************************************************/
610 : /* CommitTransaction() */
611 : /************************************************************************/
612 :
613 0 : OGRErr OGRProxiedLayer::CommitTransaction()
614 : {
615 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
616 0 : return OGRERR_FAILURE;
617 0 : return poUnderlyingLayer->CommitTransaction();
618 : }
619 :
620 : /************************************************************************/
621 : /* RollbackTransaction() */
622 : /************************************************************************/
623 :
624 0 : OGRErr OGRProxiedLayer::RollbackTransaction()
625 : {
626 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
627 0 : return OGRERR_FAILURE;
628 0 : return poUnderlyingLayer->RollbackTransaction();
629 : }
630 :
631 : /************************************************************************/
632 : /* GetFIDColumn() */
633 : /************************************************************************/
634 :
635 8 : const char *OGRProxiedLayer::GetFIDColumn()
636 : {
637 8 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
638 0 : return "";
639 8 : return poUnderlyingLayer->GetFIDColumn();
640 : }
641 :
642 : /************************************************************************/
643 : /* GetGeometryColumn() */
644 : /************************************************************************/
645 :
646 0 : const char *OGRProxiedLayer::GetGeometryColumn()
647 : {
648 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
649 0 : return "";
650 0 : return poUnderlyingLayer->GetGeometryColumn();
651 : }
652 :
653 : /************************************************************************/
654 : /* SetIgnoredFields() */
655 : /************************************************************************/
656 :
657 129 : OGRErr OGRProxiedLayer::SetIgnoredFields(CSLConstList papszFields)
658 : {
659 129 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
660 0 : return OGRERR_FAILURE;
661 129 : return poUnderlyingLayer->SetIgnoredFields(papszFields);
662 : }
663 :
664 : /************************************************************************/
665 : /* Rename() */
666 : /************************************************************************/
667 :
668 0 : OGRErr OGRProxiedLayer::Rename(const char *pszNewName)
669 : {
670 0 : if (poUnderlyingLayer == nullptr && !OpenUnderlyingLayer())
671 0 : return OGRERR_FAILURE;
672 0 : return poUnderlyingLayer->Rename(pszNewName);
673 : }
674 :
675 : #endif /* #ifndef DOXYGEN_SKIP */
|