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 59 78.0 %
Date: 2024-05-06 16:27:07 Functions: 21 26 80.8 %

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

Generated by: LCOV version 1.14