LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/elastic - ogr_elastic.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 40 44 90.9 %
Date: 2024-11-21 22:18:42 Functions: 16 18 88.9 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  Elasticsearch Translator
       5             :  * Purpose:
       6             :  * Author:
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2011, Adam Estrada
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #ifndef OGR_ELASTIC_H_INCLUDED
      15             : #define OGR_ELASTIC_H_INCLUDED
      16             : 
      17             : #include "ogrsf_frmts.h"
      18             : 
      19             : #include "cpl_json_header.h"
      20             : #include "cpl_hash_set.h"
      21             : #include "ogr_p.h"
      22             : #include "cpl_http.h"
      23             : #include "cpl_json.h"
      24             : 
      25             : #include <map>
      26             : #include <memory>
      27             : #include <set>
      28             : #include <vector>
      29             : 
      30             : typedef enum
      31             : {
      32             :     ES_GEOMTYPE_AUTO,
      33             :     ES_GEOMTYPE_GEO_POINT,
      34             :     ES_GEOMTYPE_GEO_SHAPE
      35             : } ESGeometryTypeMapping;
      36             : 
      37             : class OGRElasticDataSource;
      38             : 
      39             : class OGRESSortDesc
      40             : {
      41             :   public:
      42             :     CPLString osColumn;
      43             :     bool bAsc;
      44             : 
      45           5 :     OGRESSortDesc(const CPLString &osColumnIn, bool bAscIn)
      46           5 :         : osColumn(osColumnIn), bAsc(bAscIn)
      47             :     {
      48           5 :     }
      49             : };
      50             : 
      51             : /************************************************************************/
      52             : /*                          OGRElasticLayer                             */
      53             : /************************************************************************/
      54             : 
      55             : class OGRElasticLayer final : public OGRLayer
      56             : {
      57             :     OGRElasticDataSource *m_poDS = nullptr;
      58             : 
      59             :     CPLString m_osIndexName{};
      60             :     CPLString m_osMappingName{};
      61             : 
      62             :     OGRFeatureDefn *m_poFeatureDefn = nullptr;
      63             :     bool m_bFeatureDefnFinalized = false;
      64             :     bool m_bAddSourceIndexName = false;
      65             : 
      66             :     bool m_bManualMapping = false;
      67             :     bool m_bSerializeMapping = false;
      68             :     CPLString m_osWriteMapFilename{};
      69             :     bool m_bStoreFields = false;
      70             :     char **m_papszStoredFields = nullptr;
      71             :     char **m_papszNotAnalyzedFields = nullptr;
      72             :     char **m_papszNotIndexedFields = nullptr;
      73             :     char **m_papszFieldsWithRawValue = nullptr;
      74             : 
      75             :     CPLString m_osESSearch{};
      76             :     std::vector<OGRESSortDesc> m_aoSortColumns{};
      77             : 
      78             :     CPLString m_osBulkContent{};
      79             :     int m_nBulkUpload{};
      80             : 
      81             :     CPLString m_osFID{};
      82             : 
      83             :     std::vector<std::vector<CPLString>> m_aaosFieldPaths{};
      84             :     std::map<CPLString, int> m_aosMapToFieldIndex{};
      85             : 
      86             :     std::vector<std::vector<CPLString>> m_aaosGeomFieldPaths{};
      87             :     std::map<CPLString, int> m_aosMapToGeomFieldIndex{};
      88             :     std::vector<OGRCoordinateTransformation *> m_apoCT{};
      89             :     std::vector<int> m_abIsGeoPoint{};
      90             :     ESGeometryTypeMapping m_eGeomTypeMapping = ES_GEOMTYPE_AUTO;
      91             :     CPLString m_osPrecision{};
      92             : 
      93             :     CPLString m_osScrollID{};
      94             :     GIntBig m_iCurID = 0;
      95             :     GIntBig m_nNextFID = -1;  // for creation
      96             :     int m_iCurFeatureInPage = 0;
      97             :     std::vector<OGRFeature *> m_apoCachedFeatures{};
      98             :     bool m_bEOF = false;
      99             : 
     100             :     json_object *m_poSpatialFilter = nullptr;
     101             :     CPLString m_osJSONFilter{};
     102             :     bool m_bFilterMustBeClientSideEvaluated = false;
     103             :     json_object *m_poJSONFilter = nullptr;
     104             : 
     105             :     bool m_bIgnoreSourceID = false;
     106             :     bool m_bDotAsNestedField = true;
     107             : 
     108             :     bool m_bAddPretty = false;
     109             :     bool m_bGeoShapeAsGeoJSON = false;
     110             : 
     111             :     CPLString m_osSingleQueryTimeout{};
     112             :     double m_dfSingleQueryTimeout = 0;
     113             :     double m_dfFeatureIterationTimeout = 0;
     114             :     //! Timestamp after which the query must be terminated
     115             :     double m_dfEndTimeStamp = 0;
     116             : 
     117             :     GIntBig m_nReadFeaturesSinceResetReading = 0;
     118             :     GIntBig m_nSingleQueryTerminateAfter = 0;
     119             :     GIntBig m_nFeatureIterationTerminateAfter = 0;
     120             :     CPLString m_osSingleQueryTerminateAfter;
     121             : 
     122             :     bool m_bUseSingleQueryParams = false;
     123             : 
     124             :     void CopyMembersTo(OGRElasticLayer *poNew);
     125             : 
     126             :     bool PushIndex();
     127             :     CPLString BuildMap();
     128             : 
     129             :     OGRErr WriteMapIfNecessary();
     130             :     OGRFeature *GetNextRawFeature();
     131             :     void BuildFeature(OGRFeature *poFeature, json_object *poSource,
     132             :                       CPLString osPath);
     133             :     void CreateFieldFromSchema(const char *pszName, const char *pszPrefix,
     134             :                                std::vector<CPLString> aosPath,
     135             :                                json_object *poObj);
     136             :     void AddOrUpdateField(const char *pszAttrName, const char *pszKey,
     137             :                           json_object *poObj, char chNestedAttributeSeparator,
     138             :                           std::vector<CPLString> &aosPath);
     139             : 
     140             :     CPLString BuildMappingURL(bool bMappingApi);
     141             : 
     142             :     CPLString BuildJSonFromFeature(OGRFeature *poFeature);
     143             : 
     144             :     static CPLString BuildPathFromArray(const std::vector<CPLString> &aosPath);
     145             : 
     146             :     void AddFieldDefn(const char *pszName, OGRFieldType eType,
     147             :                       const std::vector<CPLString> &aosPath,
     148             :                       OGRFieldSubType eSubType = OFSTNone);
     149             :     void AddGeomFieldDefn(const char *pszName, OGRwkbGeometryType eType,
     150             :                           const std::vector<CPLString> &aosPath,
     151             :                           int bIsGeoPoint);
     152             : 
     153             :     CPLString BuildQuery(bool bCountOnly);
     154             :     json_object *GetValue(int nFieldIdx, swq_expr_node *poValNode);
     155             :     json_object *TranslateSQLToFilter(swq_expr_node *poNode);
     156             :     json_object *BuildSort();
     157             : 
     158             :     void AddTimeoutTerminateAfterToURL(CPLString &osURL);
     159             : 
     160             :   public:
     161             :     OGRElasticLayer(const char *pszLayerName, const char *pszIndexName,
     162             :                     const char *pszMappingName, OGRElasticDataSource *poDS,
     163             :                     CSLConstList papszOptions,
     164             :                     const char *pszESSearch = nullptr);
     165             :     OGRElasticLayer(const char *pszLayerName,
     166             :                     OGRElasticLayer *poReferenceLayer);
     167             :     virtual ~OGRElasticLayer();
     168             : 
     169             :     virtual void ResetReading() override;
     170             :     virtual OGRFeature *GetNextFeature() override;
     171             : 
     172             :     virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
     173             :     virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
     174             :     OGRErr IUpsertFeature(OGRFeature *poFeature) override;
     175             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     176             :                                int bApproxOK) override;
     177             :     virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poField,
     178             :                                    int bApproxOK) override;
     179             : 
     180          45 :     virtual const char *GetName() override
     181             :     {
     182          45 :         return m_poFeatureDefn->GetName();
     183             :     }
     184             : 
     185             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     186             :     virtual const char *GetFIDColumn() override;
     187             : 
     188             :     virtual int TestCapability(const char *) override;
     189             : 
     190             :     virtual GIntBig GetFeatureCount(int bForce) override;
     191             : 
     192           9 :     virtual void SetSpatialFilter(OGRGeometry *poGeom) override
     193             :     {
     194           9 :         SetSpatialFilter(0, poGeom);
     195           9 :     }
     196             : 
     197             :     virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override;
     198             :     virtual OGRErr SetAttributeFilter(const char *pszFilter) override;
     199             : 
     200           0 :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE) override
     201             :     {
     202           0 :         return GetExtent(0, psExtent, bForce);
     203             :     }
     204             : 
     205             :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     206             :                              int bForce = TRUE) override;
     207             : 
     208             :     virtual OGRErr SyncToDisk() override;
     209             : 
     210             :     GDALDataset *GetDataset() override;
     211             : 
     212             :     void FinalizeFeatureDefn(bool bReadFeatures = true);
     213             :     void InitFeatureDefnFromMapping(json_object *poSchema,
     214             :                                     const char *pszPrefix,
     215             :                                     const std::vector<CPLString> &aosPath);
     216             : 
     217           7 :     const CPLString &GetIndexName() const
     218             :     {
     219           7 :         return m_osIndexName;
     220             :     }
     221             : 
     222           1 :     const CPLString &GetMappingName() const
     223             :     {
     224           1 :         return m_osMappingName;
     225             :     }
     226             : 
     227          21 :     void SetIgnoreSourceID(bool bFlag)
     228             :     {
     229          21 :         m_bIgnoreSourceID = bFlag;
     230          21 :     }
     231             : 
     232           6 :     void SetManualMapping()
     233             :     {
     234           6 :         m_bManualMapping = true;
     235           6 :     }
     236             : 
     237          21 :     void SetDotAsNestedField(bool bFlag)
     238             :     {
     239          21 :         m_bDotAsNestedField = bFlag;
     240          21 :     }
     241             : 
     242          21 :     void SetFID(const CPLString &m_osFIDIn)
     243             :     {
     244          21 :         m_osFID = m_osFIDIn;
     245          21 :     }
     246             : 
     247          21 :     void SetNextFID(GIntBig nNextFID)
     248             :     {
     249          21 :         m_nNextFID = nNextFID;
     250          21 :     }
     251             : 
     252             :     OGRElasticLayer *Clone();
     253             : 
     254           3 :     void SetOrderBy(const std::vector<OGRESSortDesc> &v)
     255             :     {
     256           3 :         m_aoSortColumns = v;
     257           3 :     }
     258             : 
     259           3 :     void SetFeatureDefnFinalized()
     260             :     {
     261           3 :         m_bFeatureDefnFinalized = true;
     262           3 :     }
     263             : 
     264             :     void GetGeomFieldProperties(int iGeomField, std::vector<CPLString> &aosPath,
     265             :                                 bool &bIsGeoPoint);
     266             : 
     267             :     static void ClampEnvelope(OGREnvelope &sEnvelope);
     268             : };
     269             : 
     270             : /************************************************************************/
     271             : /*                      OGRElasticAggregationLayer                      */
     272             : /************************************************************************/
     273             : 
     274             : class OGRElasticAggregationLayer final
     275             :     : public OGRLayer,
     276             :       public OGRGetNextFeatureThroughRaw<OGRElasticAggregationLayer>
     277             : {
     278             : 
     279             :     OGRElasticDataSource *m_poDS = nullptr;
     280             :     std::string m_osIndexName{};
     281             :     std::string m_osGeometryField{};
     282             :     OGRFeatureDefn *m_poFeatureDefn = nullptr;
     283             :     bool m_bFeaturesRequested = false;
     284             :     int m_iCurFeature = 0;
     285             :     bool m_bRequestHasSpatialFilter = false;
     286             :     int m_nGeohashGridMaxSize = 10000;
     287             :     int m_nGeohashGridPrecision = -1;
     288             :     CPLJSONObject m_oFieldDef{};
     289             :     CPLJSONObject m_oAggregatedFieldsRequest{};
     290             :     std::vector<std::unique_ptr<OGRFeature>> m_apoCachedFeatures{};
     291             : 
     292             :     explicit OGRElasticAggregationLayer(OGRElasticDataSource *poDS);
     293             :     std::string BuildRequest();
     294             :     void IssueAggregationRequest();
     295             :     OGRFeature *GetNextRawFeature();
     296             : 
     297             :   public:
     298             :     ~OGRElasticAggregationLayer() override;
     299             : 
     300           3 :     OGRFeatureDefn *GetLayerDefn() override
     301             :     {
     302           3 :         return m_poFeatureDefn;
     303             :     }
     304             : 
     305             :     void ResetReading() override;
     306           7 :     DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(OGRElasticAggregationLayer)
     307             :     GIntBig GetFeatureCount(int bForce) override;
     308             :     int TestCapability(const char *) override;
     309             : 
     310             :     using OGRLayer::SetSpatialFilter;
     311             :     void SetSpatialFilter(OGRGeometry *poGeom) override;
     312             : 
     313             :     GDALDataset *GetDataset() override;
     314             : 
     315             :     static std::unique_ptr<OGRElasticAggregationLayer>
     316             :     Build(OGRElasticDataSource *poDS, const char *pszAggregation);
     317             : };
     318             : 
     319             : /************************************************************************/
     320             : /*                         OGRElasticDataSource                         */
     321             : /************************************************************************/
     322             : 
     323             : class OGRElasticDataSource final : public GDALDataset
     324             : {
     325             :     char *m_pszName;
     326             :     CPLString m_osURL;
     327             :     CPLString m_osUserPwd;
     328             :     CPLString m_osFID;
     329             : 
     330             :     std::set<CPLString> m_oSetLayers;
     331             :     std::vector<std::unique_ptr<OGRElasticLayer>> m_apoLayers;
     332             :     std::unique_ptr<OGRElasticAggregationLayer> m_poAggregationLayer{};
     333             :     bool m_bAllLayersListed = false;
     334             :     std::map<OGRLayer *, OGRLayer *> m_oMapResultSet;
     335             :     std::map<std::string, std::string> m_oMapHeadersFromEnv{};
     336             : 
     337             :     bool CheckVersion();
     338             :     int GetLayerIndex(const char *pszName);
     339             :     void FetchMapping(const char *pszIndexName);
     340             :     bool OpenAggregation(const char *pszAggregation);
     341             :     std::vector<std::string> GetIndexList(const char *pszQueriedIndexName);
     342             : 
     343             :   public:
     344             :     OGRElasticDataSource();
     345             :     virtual ~OGRElasticDataSource();
     346             : 
     347             :     bool m_bOverwrite;
     348             :     int m_nBulkUpload;
     349             :     char *m_pszWriteMap;
     350             :     char *m_pszMapping;
     351             :     int m_nBatchSize;
     352             :     int m_nFeatureCountToEstablishFeatureDefn;
     353             :     bool m_bJSonField;
     354             :     bool m_bFlattenNestedAttributes;
     355             :     bool m_bAddSourceIndexName = false;  // Only used for wildcard layers
     356             :     int m_nMajorVersion = 0;
     357             :     int m_nMinorVersion = 0;
     358             : 
     359             :     bool Open(GDALOpenInfo *poOpenInfo);
     360             : 
     361             :     int Create(const char *pszFilename, char **papszOptions);
     362             : 
     363             :     CPLHTTPResult *HTTPFetch(const char *pszURL, CSLConstList papszOptions);
     364             : 
     365         237 :     const char *GetURL()
     366             :     {
     367         237 :         return m_osURL.c_str();
     368             :     }
     369             : 
     370           0 :     virtual const char *GetName()
     371             :     {
     372           0 :         return m_pszName;
     373             :     }
     374             : 
     375             :     virtual int GetLayerCount() override;
     376             :     virtual OGRLayer *GetLayer(int) override;
     377             :     virtual OGRLayer *GetLayerByName(const char *pszName) override;
     378             : 
     379             :     OGRLayer *ICreateLayer(const char *pszName,
     380             :                            const OGRGeomFieldDefn *poGeomFieldDefn,
     381             :                            CSLConstList papszOptions) override;
     382             :     virtual OGRErr DeleteLayer(int iLayer) override;
     383             : 
     384             :     virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
     385             :                                  OGRGeometry *poSpatialFilter,
     386             :                                  const char *pszDialect) override;
     387             :     virtual void ReleaseResultSet(OGRLayer *poLayer) override;
     388             : 
     389             :     virtual int TestCapability(const char *) override;
     390             : 
     391             :     bool UploadFile(const CPLString &url, const CPLString &data,
     392             :                     const CPLString &osVerb = CPLString());
     393             :     void Delete(const CPLString &url);
     394             : 
     395             :     json_object *RunRequest(
     396             :         const char *pszURL, const char *pszPostContent = nullptr,
     397             :         const std::vector<int> &anSilentedHTTPErrors = std::vector<int>());
     398             : 
     399          90 :     const CPLString &GetFID() const
     400             :     {
     401          90 :         return m_osFID;
     402             :     }
     403             : 
     404             :     void FetchMapping(const char *pszIndexName, std::set<CPLString> &oSetLayers,
     405             :                       std::vector<std::unique_ptr<OGRElasticLayer>> &apoLayers);
     406             : };
     407             : 
     408             : #endif /* ndef _OGR_Elastic_H_INCLUDED */

Generated by: LCOV version 1.14