LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/filegdb - ogr_fgdb.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 46 57 80.7 %
Date: 2024-11-25 13:07:18 Functions: 21 25 84.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  OpenGIS Simple Features Reference Implementation
       5             :  * Purpose:  Standard includes and class definitions ArcObjects OGR driver.
       6             :  * Author:   Ragi Yaser Burhum, ragi@burhum.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2009, Ragi Yaser Burhum
      10             :  * Copyright (c) 2011-2014, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef OGR_FGDB_H_INCLUDED
      16             : #define OGR_FGDB_H_INCLUDED
      17             : 
      18             : #include <vector>
      19             : #include <set>
      20             : #include "ogrsf_frmts.h"
      21             : #include "ogremulatedtransaction.h"
      22             : 
      23             : /* GDAL string utilities */
      24             : #include "cpl_string.h"
      25             : 
      26             : /* GDAL XML handler */
      27             : #include "cpl_minixml.h"
      28             : 
      29             : /* FGDB API headers through our own inclusion file */
      30             : #include "filegdbsdk_headers.h"
      31             : 
      32             : /* Workaround needed for Linux, at least for FileGDB API 1.1 (#4455) */
      33             : #if defined(__linux__)
      34             : #define EXTENT_WORKAROUND
      35             : #endif
      36             : 
      37             : /************************************************************************
      38             :  * Default layer creation options
      39             :  */
      40             : 
      41             : #define FGDB_FEATURE_DATASET "";
      42             : #define FGDB_GEOMETRY_NAME "SHAPE"
      43             : #define FGDB_OID_NAME "OBJECTID"
      44             : constexpr const char *pszRelationshipTypeUUID =
      45             :     "{B606A7E1-FA5B-439C-849C-6E9C2481537B}";
      46             : 
      47             : /* The ESRI FGDB API namespace */
      48             : using namespace FileGDBAPI;
      49             : 
      50             : class FGdbDriver;
      51             : 
      52             : /************************************************************************/
      53             : /*                           FGdbBaseLayer                              */
      54             : /************************************************************************/
      55             : 
      56             : class FGdbBaseLayer CPL_NON_FINAL : public OGRLayer
      57             : {
      58             :   protected:
      59             :     FGdbBaseLayer();
      60             :     virtual ~FGdbBaseLayer();
      61             : 
      62             :     OGRFeatureDefn *m_pFeatureDefn;
      63             :     OGRSpatialReference *m_pSRS;
      64             : 
      65             :     EnumRows *m_pEnumRows;
      66             : 
      67             :     std::vector<std::wstring>
      68             :         m_vOGRFieldToESRIField;  // OGR Field Index to ESRI Field Name Mapping
      69             :     std::vector<std::string>
      70             :         m_vOGRFieldToESRIFieldType;  // OGR Field Index to ESRI Field Type
      71             :                                      // Mapping
      72             : 
      73             :     bool m_suppressColumnMappingError;
      74             :     bool m_forceMulti;
      75             :     bool m_bTimeInUTC = false;
      76             : 
      77             :     bool OGRFeatureFromGdbRow(Row *pRow, OGRFeature **ppFeature);
      78             : 
      79             :     virtual void CloseGDBObjects();
      80             : 
      81             :   public:
      82             :     virtual OGRFeature *GetNextFeature() override;
      83             : };
      84             : 
      85             : /************************************************************************/
      86             : /*                            FGdbLayer                                 */
      87             : /************************************************************************/
      88             : 
      89             : class FGdbDataSource;
      90             : 
      91             : class FGdbLayer final : public FGdbBaseLayer
      92             : {
      93             :     friend class FGdbDataSource;
      94             : 
      95             :     bool m_bWorkaroundCrashOnCDFWithBinaryField = false;
      96             : 
      97             :     int m_bBulkLoadAllowed;
      98             :     int m_bBulkLoadInProgress;
      99             : 
     100             :     virtual void CloseGDBObjects() override;
     101             :     int EditIndexesForFIDHack(const char *pszRadixTablename);
     102             :     int EditGDBTablX(const CPLString &osGDBTablX,
     103             :                      const CPLString &osNewGDBTablX);
     104             :     int EditATXOrSPX(const CPLString &osIndex);
     105             :     int EditATXOrSPX(VSILFILE *fp, int nThisPage, int &nLastPageVisited,
     106             :                      int nDepth, int nSizeIndexedValue,
     107             :                      GByte *pabyLastIndexedValue, int &bIndexedValueIsValid,
     108             :                      int &nFirstIndexAtThisValue,
     109             :                      std::vector<int> &anPagesAtThisValue, int &bSortThisValue,
     110             :                      int &bInvalidateIndex);
     111             : 
     112             :     void StartBulkLoad();
     113             :     void EndBulkLoad();
     114             : 
     115             : #ifdef EXTENT_WORKAROUND
     116             :     bool m_bLayerJustCreated;
     117             :     OGREnvelope sLayerEnvelope;
     118             :     bool m_bLayerEnvelopeValid;
     119             :     void WorkAroundExtentProblem();
     120             :     bool UpdateRowWithGeometry(Row &row, OGRGeometry *poGeom);
     121             : #endif
     122             : 
     123             :     std::vector<ByteArray *> m_apoByteArrays;
     124             :     OGRErr PopulateRowWithFeature(Row &row, OGRFeature *poFeature);
     125             :     OGRErr GetRow(EnumRows &enumRows, Row &row, GIntBig nFID);
     126             : 
     127             :     char **m_papszOptions;
     128             : 
     129             :     int m_bCreateMultipatch;
     130             : 
     131             :     std::map<int, int> m_oMapOGRFIDToFGDBFID;
     132             :     std::map<int, int> m_oMapFGDBFIDToOGRFID;
     133             :     int m_nResyncThreshold;
     134             :     void ResyncIDs();
     135             : 
     136             :     int m_bSymlinkFlag;
     137             :     int CreateRealCopy();
     138             : 
     139             :     char *CreateFieldDefn(OGRFieldDefn &oField, int bApproxOK,
     140             :                           std::string &fieldname_clean,
     141             :                           std::string &gdbFieldType);
     142             : 
     143             :   public:
     144             :     FGdbLayer();
     145             :     virtual ~FGdbLayer();
     146             : 
     147             :     // Internal used by FGDB driver */
     148             :     bool Initialize(FGdbDataSource *pParentDataSource, Table *pTable,
     149             :                     const std::wstring &wstrTablePath,
     150             :                     const std::wstring &wstrType);
     151             :     bool Create(FGdbDataSource *pParentDataSource, const char *pszLayerName,
     152             :                 const OGRGeomFieldDefn *poSrcGeomFieldDefn,
     153             :                 CSLConstList papszOptions);
     154             :     static bool CreateFeatureDataset(FGdbDataSource *pParentDataSource,
     155             :                                      const std::string &feature_dataset_name,
     156             :                                      const OGRGeomFieldDefn *poSrcGeomFieldDefn,
     157             :                                      CSLConstList papszOptions);
     158             : 
     159             :     // virtual const char *GetName();
     160         683 :     virtual const char *GetFIDColumn() override
     161             :     {
     162         683 :         return m_strOIDFieldName.c_str();
     163             :     }
     164             : 
     165             :     virtual void ResetReading() override;
     166             :     virtual OGRFeature *GetNextFeature() override;
     167             :     virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
     168             : 
     169             :     Table *GetTable()
     170             :     {
     171             :         return m_pTable;
     172             :     }
     173             : 
     174           2 :     std::wstring GetTablePath() const
     175             :     {
     176           2 :         return m_wstrTablePath;
     177             :     }
     178             : 
     179           2 :     std::wstring GetType() const
     180             :     {
     181           2 :         return m_wstrType;
     182             :     }
     183             : 
     184             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     185             :                                int bApproxOK) override;
     186             :     virtual OGRErr DeleteField(int iFieldToDelete) override;
     187             : #ifdef AlterFieldDefn_implemented_but_not_working
     188             :     virtual OGRErr AlterFieldDefn(int iFieldToAlter,
     189             :                                   OGRFieldDefn *poNewFieldDefn, int nFlags);
     190             : #endif
     191             : 
     192             :     virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
     193             :     virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
     194             :     virtual OGRErr DeleteFeature(GIntBig nFID) override;
     195             : 
     196             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     197             : 
     198          68 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     199             :                              int bForce) override
     200             :     {
     201          68 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     202             :     }
     203             : 
     204             :     virtual GIntBig GetFeatureCount(int bForce) override;
     205             :     virtual OGRErr SetAttributeFilter(const char *pszQuery) override;
     206             : 
     207             :     virtual void SetSpatialFilter(OGRGeometry *) override;
     208             : 
     209         213 :     virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
     210             :     {
     211         213 :         OGRLayer::SetSpatialFilter(iGeomField, poGeom);
     212         213 :     }
     213             : 
     214             :     //  virtual OGRErr        StartTransaction( );
     215             :     //  virtual OGRErr        CommitTransaction( );
     216             :     //  virtual OGRErr        RollbackTransaction( );
     217             : 
     218       21702 :     OGRFeatureDefn *GetLayerDefn() override
     219             :     {
     220       21702 :         return m_pFeatureDefn;
     221             :     }
     222             : 
     223             :     virtual int TestCapability(const char *) override;
     224             : 
     225             :     // Access the XML directly. The 2 following methods are not currently used
     226             :     // by the driver, but can be used by external code for specific purposes.
     227             :     OGRErr GetLayerXML(char **poXml);
     228             :     OGRErr GetLayerMetadataXML(char **poXmlMeta);
     229             : 
     230           0 :     void SetSymlinkFlag()
     231             :     {
     232           0 :         m_bSymlinkFlag = TRUE;
     233           0 :     }
     234             : 
     235             :     virtual const char *GetMetadataItem(const char *pszName,
     236             :                                         const char *pszDomain) override;
     237             : 
     238             :     virtual OGRErr Rename(const char *pszNewName) override;
     239             : 
     240             :     GDALDataset *GetDataset() override;
     241             : 
     242             :   protected:
     243             :     bool GDBToOGRFields(CPLXMLNode *psFields);
     244             :     bool ParseGeometryDef(const CPLXMLNode *psGeometryDef);
     245             : 
     246             :     static bool ParseSpatialReference(const CPLXMLNode *psSpatialRefNode,
     247             :                                       std::string *pOutWkt,
     248             :                                       std::string *pOutWKID,
     249             :                                       std::string *pOutLatestWKID);
     250             : 
     251             :     FGdbDataSource *m_pDS;
     252             :     Table *m_pTable;
     253             : 
     254             :     std::string
     255             :         m_strName;  // contains underlying FGDB table name (not catalog name)
     256             : 
     257             :     std::string m_strOIDFieldName;
     258             :     std::string m_strShapeFieldName;
     259             : 
     260             :     std::wstring m_wstrTablePath;
     261             :     std::wstring m_wstrType;  // the type: "Table" or "Feature Class"
     262             : 
     263             :     std::wstring m_wstrSubfields;
     264             :     std::wstring m_wstrWhereClause;
     265             : 
     266             :     bool m_bFilterDirty;  // optimization to avoid multiple calls to search
     267             :                           // until necessary
     268             : 
     269             :     bool m_bLaunderReservedKeywords;
     270             : };
     271             : 
     272             : /************************************************************************/
     273             : /*                         FGdbResultLayer                              */
     274             : /************************************************************************/
     275             : 
     276             : class FGdbResultLayer final : public FGdbBaseLayer
     277             : {
     278             :   public:
     279             :     FGdbResultLayer(FGdbDataSource *pParentDataSource, const char *pszStatement,
     280             :                     EnumRows *pEnumRows);
     281             :     virtual ~FGdbResultLayer();
     282             : 
     283             :     virtual void ResetReading() override;
     284             : 
     285           0 :     OGRFeatureDefn *GetLayerDefn() override
     286             :     {
     287           0 :         return m_pFeatureDefn;
     288             :     }
     289             : 
     290             :     virtual int TestCapability(const char *) override;
     291             : 
     292             :   protected:
     293             :     FGdbDataSource *m_pDS;
     294             :     CPLString osSQL;
     295             : };
     296             : 
     297             : /************************************************************************/
     298             : /*                           FGdbDataSource                            */
     299             : /************************************************************************/
     300             : 
     301             : class FGdbDatabaseConnection;
     302             : class OGRFileGDBGroup;
     303             : 
     304             : class FGdbDataSource final : public GDALDataset
     305             : {
     306             :     CPLString m_osFSName;
     307             :     CPLString m_osPublicName;
     308             :     std::set<OGRLayer *> m_oSetSelectLayers;
     309             :     std::shared_ptr<GDALGroup> m_poRootGroup{};
     310             :     std::map<std::string, std::unique_ptr<GDALRelationship>>
     311             :         m_osMapRelationships{};
     312             : 
     313             :     int FixIndexes();
     314             :     int bPerLayerCopyingForTransaction;
     315             : 
     316             :   public:
     317             :     FGdbDataSource(bool bUseDriverMutex, FGdbDatabaseConnection *pConnection,
     318             :                    bool bUseOpenFileGDB);
     319             :     virtual ~FGdbDataSource();
     320             : 
     321             :     int Open(const char *pszFSName, int bUpdate, const char *pszPublicName);
     322             : 
     323         406 :     const char *GetFSName()
     324             :     {
     325         406 :         return m_osFSName.c_str();
     326             :     }
     327             : 
     328        9029 :     int GetLayerCount() override
     329             :     {
     330        9029 :         return static_cast<int>(m_layers.size());
     331             :     }
     332             : 
     333             :     OGRLayer *GetLayer(int) override;
     334             : 
     335             :     OGRLayer *ICreateLayer(const char *pszName,
     336             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     337             :                            CSLConstList papszOptions) override;
     338             : 
     339             :     virtual OGRErr DeleteLayer(int) override;
     340             : 
     341             :     virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
     342             :                                  OGRGeometry *poSpatialFilter,
     343             :                                  const char *pszDialect) override;
     344             :     virtual void ReleaseResultSet(OGRLayer *poResultsSet) override;
     345             : 
     346             :     int TestCapability(const char *) override;
     347             : 
     348             :     const OGRFieldDomain *
     349             :     GetFieldDomain(const std::string &name) const override;
     350             :     std::vector<std::string>
     351             :     GetFieldDomainNames(CSLConstList papszOptions = nullptr) const override;
     352             : 
     353             :     bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
     354             :                         std::string &failureReason) override;
     355             : 
     356             :     bool DeleteFieldDomain(const std::string &name,
     357             :                            std::string &failureReason) override;
     358             : 
     359             :     bool UpdateFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
     360             :                            std::string &failureReason) override;
     361             : 
     362             :     std::vector<std::string>
     363             :     GetRelationshipNames(CSLConstList papszOptions = nullptr) const override;
     364             : 
     365             :     const GDALRelationship *
     366             :     GetRelationship(const std::string &name) const override;
     367             : 
     368           1 :     std::shared_ptr<GDALGroup> GetRootGroup() const override
     369             :     {
     370           1 :         return m_poRootGroup;
     371             :     }
     372             : 
     373         567 :     Geodatabase *GetGDB()
     374             :     {
     375         567 :         return m_pGeodatabase;
     376             :     }
     377             : 
     378        3129 :     bool GetUpdate()
     379             :     {
     380        3129 :         return m_bUpdate;
     381             :     }
     382             : 
     383           2 :     FGdbDatabaseConnection *GetConnection()
     384             :     {
     385           2 :         return m_pConnection;
     386             :     }
     387             : 
     388           1 :     GDALDriver *GetOpenFileGDBDrv()
     389             :     {
     390           1 :         return m_poOpenFileGDBDrv;
     391             :     }
     392             : 
     393           1 :     int HasSelectLayers()
     394             :     {
     395           1 :         return !m_oSetSelectLayers.empty();
     396             :     }
     397             : 
     398             :     int CloseInternal(int bCloseGeodatabase = FALSE);
     399             :     int ReOpen();
     400             : 
     401             :     int HasPerLayerCopyingForTransaction();
     402             : 
     403           0 :     void SetPerLayerCopyingForTransaction(int bFlag)
     404             :     {
     405           0 :         bPerLayerCopyingForTransaction = bFlag;
     406           0 :     }
     407             : 
     408             :     void SetSymlinkFlagOnAllLayers();
     409             : 
     410         408 :     bool UseOpenFileGDB() const
     411             :     {
     412         408 :         return m_bUseOpenFileGDB;
     413             :     }
     414             : 
     415             :     /*
     416             :     protected:
     417             : 
     418             :     void EnumerateSpatialTables();
     419             :     void OpenSpatialTable( const char* pszTableName );
     420             :     */
     421             :   protected:
     422             :     bool LoadLayers(const std::wstring &parent);
     423             :     bool OpenFGDBTables(OGRFileGDBGroup *group, const std::wstring &type,
     424             :                         const std::vector<std::wstring> &layers);
     425             : 
     426             :     bool m_bUseDriverMutex = true;
     427             :     FGdbDatabaseConnection *m_pConnection;
     428             :     std::vector<OGRLayer *> m_layers;
     429             :     Geodatabase *m_pGeodatabase;
     430             :     bool m_bUpdate;
     431             :     GDALDriver *m_poOpenFileGDBDrv;
     432             :     std::unique_ptr<GDALDataset> m_poOpenFileGDBDS;
     433             :     bool m_bUseOpenFileGDB = false;
     434             : };
     435             : 
     436             : /************************************************************************/
     437             : /*                              FGdbDriver                                */
     438             : /************************************************************************/
     439             : 
     440             : class FGdbDatabaseConnection
     441             : {
     442             :   public:
     443          76 :     FGdbDatabaseConnection(const std::string &osName, Geodatabase *pGeodatabase)
     444          76 :         : m_osName(osName), m_pGeodatabase(pGeodatabase), m_nRefCount(1),
     445          76 :           m_bLocked(FALSE), m_bFIDHackInProgress(FALSE)
     446             :     {
     447          76 :     }
     448             : 
     449             :     std::string m_osName;
     450             :     Geodatabase *m_pGeodatabase;
     451             :     int m_nRefCount;
     452             :     int m_bLocked;
     453             :     int m_bFIDHackInProgress;
     454             : 
     455          88 :     Geodatabase *GetGDB()
     456             :     {
     457          88 :         return m_pGeodatabase;
     458             :     }
     459             : 
     460           0 :     void SetLocked(int bLockedIn)
     461             :     {
     462           0 :         m_bLocked = bLockedIn;
     463           0 :     }
     464             : 
     465           1 :     int GetRefCount() const
     466             :     {
     467           1 :         return m_nRefCount;
     468             :     }
     469             : 
     470          87 :     int IsLocked() const
     471             :     {
     472          87 :         return m_bLocked;
     473             :     }
     474             : 
     475         231 :     int IsFIDHackInProgress() const
     476             :     {
     477         231 :         return m_bFIDHackInProgress;
     478             :     }
     479             : 
     480           2 :     void SetFIDHackInProgress(int bFlag)
     481             :     {
     482           2 :         m_bFIDHackInProgress = bFlag;
     483           2 :     }
     484             : 
     485             :     int OpenGeodatabase(const char *pszOverriddenName);
     486             :     void CloseGeodatabase();
     487             : };
     488             : 
     489             : class FGdbTransactionManager final : public IOGRTransactionBehaviour
     490             : {
     491             :   public:
     492             :     virtual OGRErr StartTransaction(GDALDataset *&poDSInOut,
     493             :                                     int &bOutHasReopenedDS) override;
     494             :     virtual OGRErr CommitTransaction(GDALDataset *&poDSInOut,
     495             :                                      int &bOutHasReopenedDS) override;
     496             :     virtual OGRErr RollbackTransaction(GDALDataset *&poDSInOut,
     497             :                                        int &bOutHasReopenedDS) override;
     498             : };
     499             : 
     500             : class FGdbDriver final : public GDALDriver
     501             : {
     502             :   public:
     503             :     static void Release(const char *pszName);
     504             : 
     505             :     static FGdbTransactionManager *GetTransactionManager();
     506             : 
     507             :     static CPLMutex *hMutex;
     508             :     static FGdbTransactionManager *m_poTransactionManager;
     509             : };
     510             : 
     511             : CPL_C_START
     512             : void CPL_DLL RegisterOGRFileGDB();
     513             : CPL_C_END
     514             : 
     515             : #endif /* ndef _OGR_PG_H_INCLUDED */

Generated by: LCOV version 1.14