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 129 : 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 39 : void SetFieldType(OGRFieldType eType) 48 : { 49 39 : m_eType = eType; 50 39 : } 51 : 52 21 : void SetFieldSubType(OGRFieldSubType eSubType) 53 : { 54 21 : m_eSubType = eSubType; 55 21 : } 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 61 : std::optional<std::string> GetFieldName() const 68 : { 69 61 : return m_osName; 70 : } 71 : 72 22 : std::optional<OGRFieldType> GetSrcFieldType() const 73 : { 74 22 : return m_eSrcType; 75 : } 76 : 77 7 : std::optional<OGRFieldSubType> GetSrcFieldSubType() const 78 : { 79 7 : return m_eSrcSubType; 80 : } 81 : 82 84 : std::optional<OGRFieldType> GetFieldType() const 83 : { 84 84 : return m_eType; 85 : } 86 : 87 89 : std::optional<OGRFieldSubType> GetFieldSubType() const 88 : { 89 89 : return m_eSubType; 90 : } 91 : 92 59 : std::optional<int> GetFieldWidth() const 93 : { 94 59 : return m_nWidth; 95 : } 96 : 97 59 : std::optional<int> GetFieldPrecision() const 98 : { 99 59 : return m_nPrecision; 100 : } 101 : 102 : // Considered valid if it carries any change information, otherwise it's considered a no-op 103 : bool IsValid() const; 104 : 105 : private: 106 : std::optional<std::string> m_osName{}; 107 : std::optional<OGRFieldType> m_eSrcType{}; 108 : std::optional<OGRFieldSubType> m_eSrcSubType{}; 109 : std::optional<OGRFieldType> m_eType{}; 110 : std::optional<OGRFieldSubType> m_eSubType{}; 111 : std::optional<int> m_nWidth{}; 112 : std::optional<int> m_nPrecision{}; 113 : }; 114 : 115 : /** Class that holds the schema override options for a single layer */ 116 : class CPL_DLL OGRLayerSchemaOverride 117 : { 118 : public: 119 56 : OGRLayerSchemaOverride() = default; 120 : 121 56 : void SetLayerName(const std::string &osLayerName) 122 : { 123 56 : m_osLayerName = osLayerName; 124 56 : } 125 : 126 61 : void AddNamedFieldOverride(const std::string &osFieldName, 127 : const OGRFieldDefnOverride &oFieldOverride) 128 : { 129 61 : m_oNamedFieldOverrides[osFieldName] = oFieldOverride; 130 61 : } 131 : 132 2 : void AddUnnamedFieldOverride(const OGRFieldDefnOverride &oFieldOverride) 133 : { 134 2 : m_aoUnnamedFieldOverrides.push_back(oFieldOverride); 135 2 : } 136 : 137 51 : const std::string &GetLayerName() const 138 : { 139 51 : return m_osLayerName; 140 : } 141 : 142 : const std::map<std::string, OGRFieldDefnOverride> & 143 51 : GetNamedFieldOverrides() const 144 : { 145 51 : return m_oNamedFieldOverrides; 146 : } 147 : 148 51 : const std::vector<OGRFieldDefnOverride> &GetUnnamedFieldOverrides() const 149 : { 150 51 : return m_aoUnnamedFieldOverrides; 151 : } 152 : 153 51 : bool IsFullOverride() const 154 : { 155 51 : return m_bIsFullOverride; 156 : } 157 : 158 56 : void SetFullOverride(bool bIsFullOverride) 159 : { 160 56 : m_bIsFullOverride = bIsFullOverride; 161 56 : } 162 : 163 : bool IsValid() const; 164 : 165 : private: 166 : std::string m_osLayerName{}; 167 : std::map<std::string, OGRFieldDefnOverride> m_oNamedFieldOverrides{}; 168 : std::vector<OGRFieldDefnOverride> m_aoUnnamedFieldOverrides{}; 169 : bool m_bIsFullOverride = false; 170 : }; 171 : 172 : class GDALDataset; 173 : 174 : /** Class that holds the schema override options for a datasource */ 175 : class CPL_DLL OGRSchemaOverride 176 : { 177 : public: 178 53 : OGRSchemaOverride() = default; 179 : 180 51 : void AddLayerOverride(const OGRLayerSchemaOverride &oLayerOverride) 181 : { 182 51 : m_aoLayerOverrides.push_back(oLayerOverride); 183 51 : } 184 : 185 : bool LoadFromJSON(const std::string &osJSON); 186 : 187 48 : const std::vector<OGRLayerSchemaOverride> &GetLayerOverrides() const 188 : { 189 48 : return m_aoLayerOverrides; 190 : } 191 : 192 : bool IsValid() const; 193 : 194 : // Default implementation to apply the overrides to a dataset 195 : bool DefaultApply( 196 : GDALDataset *poDS, const char *pszDebugKey, 197 : std::function<void(OGRLayer *, int)> callbackWhenRemovingField = 198 12 : [](OGRLayer *, int) {}) const; 199 : 200 : private: 201 : std::vector<OGRLayerSchemaOverride> m_aoLayerOverrides{}; 202 : }; 203 : 204 : //! @endcond 205 : 206 : #endif /* ndef OGR_FEATURE_H_INCLUDED */