LCOV - code coverage report
Current view: top level - ogr - ogr_schema_override.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 58 70 82.9 %
Date: 2026-04-09 00:01:40 Functions: 25 29 86.2 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * Project:  OGR_SCHEMA open options handling
       3             :  * Purpose:  Class for representing a layer schema override.
       4             :  * Author:   Alessandro Pasotti, elpaso@itopen.it
       5             :  *
       6             :  ******************************************************************************
       7             :  * Copyright (c) 2024, Alessandro Pasotti <elpaso at itopen dot it>
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  ****************************************************************************/
      11             : 
      12             : #ifndef OGR_SCHEMA_OVERRIDE_H_INCLUDED
      13             : #define OGR_SCHEMA_OVERRIDE_H_INCLUDED
      14             : 
      15             : //! @cond Doxygen_Suppress
      16             : 
      17             : #include <functional>
      18             : #include <string>
      19             : #include <map>
      20             : #include <optional>
      21             : #include <ogr_api.h>
      22             : #include <ogr_feature.h>
      23             : #include <cpl_vsi.h>
      24             : #include <cpl_json.h>
      25             : 
      26             : /** Class that holds the schema override options for a single field */
      27             : class CPL_DLL OGRFieldDefnOverride
      28             : {
      29             :   public:
      30         169 :     OGRFieldDefnOverride() = default;
      31             : 
      32           9 :     void SetFieldName(const std::string &osName)
      33             :     {
      34           9 :         m_osName = osName;
      35           9 :     }
      36             : 
      37           2 :     void SetSrcFieldType(OGRFieldType eType)
      38             :     {
      39           2 :         m_eSrcType = eType;
      40           2 :     }
      41             : 
      42           1 :     void SetSrcFieldSubType(OGRFieldSubType eSubType)
      43             :     {
      44           1 :         m_eSrcSubType = eSubType;
      45           1 :     }
      46             : 
      47          59 :     void SetFieldType(OGRFieldType eType)
      48             :     {
      49          59 :         m_eType = eType;
      50          59 :     }
      51             : 
      52          23 :     void SetFieldSubType(OGRFieldSubType eSubType)
      53             :     {
      54          23 :         m_eSubType = eSubType;
      55          23 :     }
      56             : 
      57           5 :     void SetFieldWidth(int nWidth)
      58             :     {
      59           5 :         m_nWidth = nWidth;
      60           5 :     }
      61             : 
      62           5 :     void SetFieldPrecision(int nPrecision)
      63             :     {
      64           5 :         m_nPrecision = nPrecision;
      65           5 :     }
      66             : 
      67          13 :     void SetNullable(bool bNullable)
      68             :     {
      69          13 :         m_bNullable = bNullable;
      70          13 :     }
      71             : 
      72          13 :     void SetUnique(bool bUnique)
      73             :     {
      74          13 :         m_bUnique = bUnique;
      75          13 :     }
      76             : 
      77           0 :     void SetComment(const std::string &osComment)
      78             :     {
      79           0 :         m_osComment = osComment;
      80           0 :     }
      81             : 
      82           0 :     void SetAlias(const std::string &osAlias)
      83             :     {
      84           0 :         m_osAlias = osAlias;
      85           0 :     }
      86             : 
      87           2 :     void SetTimezone(const std::string &osTimezone)
      88             :     {
      89           2 :         m_osTimezone = osTimezone;
      90           2 :     }
      91             : 
      92           0 :     void SetDomainName(const std::string &osDomainName)
      93             :     {
      94           0 :         m_osDomainName = osDomainName;
      95           0 :     }
      96             : 
      97           0 :     void SetDefaultValue(const std::string &osDefaultValue)
      98             :     {
      99           0 :         m_osDefaultValue = osDefaultValue;
     100           0 :     }
     101             : 
     102          61 :     std::optional<std::string> GetFieldName() const
     103             :     {
     104          61 :         return m_osName;
     105             :     }
     106             : 
     107          22 :     std::optional<OGRFieldType> GetSrcFieldType() const
     108             :     {
     109          22 :         return m_eSrcType;
     110             :     }
     111             : 
     112           7 :     std::optional<OGRFieldSubType> GetSrcFieldSubType() const
     113             :     {
     114           7 :         return m_eSrcSubType;
     115             :     }
     116             : 
     117          84 :     std::optional<OGRFieldType> GetFieldType() const
     118             :     {
     119          84 :         return m_eType;
     120             :     }
     121             : 
     122          89 :     std::optional<OGRFieldSubType> GetFieldSubType() const
     123             :     {
     124          89 :         return m_eSubType;
     125             :     }
     126             : 
     127          59 :     std::optional<int> GetFieldWidth() const
     128             :     {
     129          59 :         return m_nWidth;
     130             :     }
     131             : 
     132          59 :     std::optional<int> GetFieldPrecision() const
     133             :     {
     134          59 :         return m_nPrecision;
     135             :     }
     136             : 
     137             :     std::optional<int> GetNullable() const
     138             :     {
     139             :         return m_bNullable;
     140             :     }
     141             : 
     142             :     std::optional<int> GetUnique() const
     143             :     {
     144             :         return m_bUnique;
     145             :     }
     146             : 
     147             :     std::optional<std::string> GetComment() const
     148             :     {
     149             :         return m_osComment;
     150             :     }
     151             : 
     152             :     std::optional<std::string> GetAlias() const
     153             :     {
     154             :         return m_osAlias;
     155             :     }
     156             : 
     157             :     std::optional<std::string> GetTimezone() const
     158             :     {
     159             :         return m_osTimezone;
     160             :     }
     161             : 
     162             :     std::optional<std::string> GetDomainName() const
     163             :     {
     164             :         return m_osDomainName;
     165             :     }
     166             : 
     167             :     // Considered valid if it carries any change information, otherwise it's considered a no-op
     168             :     bool IsValid() const;
     169             : 
     170             :     /**
     171             :      *  Build an OGRFieldDefn based on the override information.
     172             :      *  \a osDefaultName is used as field name if the override doesn't specify one.
     173             :      */
     174             :     OGRFieldDefn ToFieldDefn(const std::string &osDefaultName) const;
     175             : 
     176             :   private:
     177             :     std::optional<std::string> m_osName{};
     178             :     std::optional<OGRFieldType> m_eSrcType{};
     179             :     std::optional<OGRFieldSubType> m_eSrcSubType{};
     180             :     std::optional<OGRFieldType> m_eType{};
     181             :     std::optional<OGRFieldSubType> m_eSubType{};
     182             :     std::optional<int> m_nWidth{};
     183             :     std::optional<int> m_nPrecision{};
     184             :     std::optional<bool> m_bUnique{};
     185             :     std::optional<bool> m_bNullable{};
     186             :     std::optional<std::string> m_osComment{};
     187             :     std::optional<std::string> m_osAlias{};
     188             :     std::optional<std::string> m_osTimezone{};
     189             :     std::optional<std::string> m_osDomainName{};
     190             :     std::optional<std::string> m_osDefaultValue{};
     191             : };
     192             : 
     193             : /**
     194             :  *  Class that holds the schema override options for a single geometry field
     195             :  */
     196             : class CPL_DLL OGRGeomFieldDefnOverride
     197             : {
     198             :   public:
     199          16 :     OGRGeomFieldDefnOverride() = default;
     200             : 
     201          16 :     void SetFieldName(const std::string &osName)
     202             :     {
     203          16 :         m_osName = osName;
     204          16 :     }
     205             : 
     206          16 :     void SetGeometryType(OGRwkbGeometryType eType)
     207             :     {
     208          16 :         m_eType = eType;
     209          16 :     }
     210             : 
     211          15 :     void SetSRS(const OGRSpatialReference &oSRS)
     212             :     {
     213          15 :         m_oSRS = oSRS;
     214          15 :     }
     215             : 
     216             :     void SetNullable(bool bNullable)
     217             :     {
     218             :         m_bNullable = bNullable;
     219             :     }
     220             : 
     221             :     std::optional<std::string> GetFieldName() const
     222             :     {
     223             :         return m_osName;
     224             :     }
     225             : 
     226             :     std::optional<OGRwkbGeometryType> GetGeometryType() const
     227             :     {
     228             :         return m_eType;
     229             :     }
     230             : 
     231             :     std::optional<OGRSpatialReference> GetSRS() const
     232             :     {
     233             :         return m_oSRS;
     234             :     }
     235             : 
     236             :     std::optional<bool> GetNullable() const
     237             :     {
     238             :         return m_bNullable;
     239             :     }
     240             : 
     241             :     /**
     242             :      *  Build an OGRGeometryFieldDefn based on the override information.
     243             :      *  \a osDefaultName is used as field name if the override doesn't specify one.
     244             :      *  If the override doesn't specify a type, wkbUnknown is used as default type.
     245             :      */
     246             :     OGRGeomFieldDefn
     247             :     ToGeometryFieldDefn(const std::string &osDefaultName) const;
     248             : 
     249             :   private:
     250             :     std::optional<bool> m_bNullable{};
     251             :     std::optional<std::string> m_osName{};
     252             :     std::optional<OGRwkbGeometryType> m_eType{};
     253             :     std::optional<OGRSpatialReference> m_oSRS{};
     254             : };
     255             : 
     256             : /** Class that holds the schema override options for a single layer */
     257             : class CPL_DLL OGRLayerSchemaOverride
     258             : {
     259             :   public:
     260          77 :     OGRLayerSchemaOverride() = default;
     261             : 
     262             :     void SetLayerName(const std::string &osLayerName);
     263             : 
     264             :     void SetFIDColumnName(const std::string &osFIDColumnName);
     265             : 
     266             :     void AddNamedFieldOverride(const std::string &osFieldName,
     267             :                                const OGRFieldDefnOverride &oFieldOverride);
     268             : 
     269             :     void AddUnnamedFieldOverride(const OGRFieldDefnOverride &oFieldOverride);
     270             : 
     271             :     const std::string &GetLayerName() const;
     272             : 
     273             :     const std::string &GetFIDColumnName() const;
     274             : 
     275             :     const std::map<std::string, OGRFieldDefnOverride> &
     276             :     GetNamedFieldOverrides() const;
     277             : 
     278             :     const std::vector<OGRFieldDefnOverride> &GetUnnamedFieldOverrides() const;
     279             : 
     280             :     void AddGeometryFieldOverride(
     281             :         const OGRGeomFieldDefnOverride &oGeomFieldOverride);
     282             : 
     283             :     const std::vector<OGRGeomFieldDefnOverride> &
     284             :     GetGeometryFieldOverrides() const;
     285             : 
     286             :     std::vector<OGRFieldDefn> GetFieldDefinitions() const;
     287             : 
     288             :     std::vector<OGRGeomFieldDefn> GetGeomFieldDefinitions() const;
     289             : 
     290             :     bool IsFullOverride() const;
     291             : 
     292             :     void SetFullOverride(bool bIsFullOverride);
     293             : 
     294             :     bool IsValid() const;
     295             : 
     296             :     bool empty() const;
     297             : 
     298             :   private:
     299             :     std::string m_osLayerName{};
     300             :     std::string m_osFIDColumnName{};
     301             :     std::map<std::string, OGRFieldDefnOverride> m_oNamedFieldOverrides{};
     302             :     std::vector<OGRFieldDefnOverride> m_aoUnnamedFieldOverrides{};
     303             :     std::vector<OGRGeomFieldDefnOverride> m_aoGeomFieldOverrides{};
     304             :     bool m_bIsFullOverride = false;
     305             : };
     306             : 
     307             : class GDALDataset;
     308             : 
     309             : /** Class that holds the schema override options for a datasource */
     310             : class CPL_DLL OGRSchemaOverride
     311             : {
     312             :   public:
     313          92 :     OGRSchemaOverride() = default;
     314             : 
     315             :     void AddLayerOverride(const OGRLayerSchemaOverride &oLayerOverride);
     316             : 
     317             :     /**
     318             :      * Load an override schema from JSON string that follows OGR_SCHEMA specification.
     319             :      * @param osJSON JSON string
     320             :      * @param bAllowGeometryFields Whether to allow a geometry fields in the JSON (normally not overridable but allowed if the schema is applied to a dataset that doesn't have any geometry field, so that it can be used to create a geometry field in that case)
     321             :      * @return TRUE if the JSON was successfully parsed and the schema override is valid, FALSE otherwise
     322             :      */
     323             :     bool LoadFromJSON(const std::string &osJSON,
     324             :                       bool bAllowGeometryFields = false);
     325             : 
     326             :     const std::vector<OGRLayerSchemaOverride> &GetLayerOverrides() const;
     327             : 
     328             :     bool IsValid() const;
     329             : 
     330             :     /**
     331             :      *  Default implementation to apply the overrides to a dataset
     332             :      *  \note geometry fields are ignored (not overridable)
     333             :      */
     334             :     bool DefaultApply(
     335             :         GDALDataset *poDS, const char *pszDebugKey,
     336             :         std::function<void(OGRLayer *, int)> callbackWhenRemovingField =
     337          12 :             [](OGRLayer *, int) {}) const;
     338             : 
     339             :     const OGRLayerSchemaOverride &
     340             :     GetLayerOverride(const std::string &osLayerName) const;
     341             : 
     342             :   private:
     343             :     std::vector<OGRLayerSchemaOverride> m_aoLayerOverrides{};
     344             : };
     345             : 
     346             : //! @endcond
     347             : 
     348             : #endif /* ndef OGR_FEATURE_H_INCLUDED */

Generated by: LCOV version 1.14