Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/ogr/ogr_schema_override.h
Line
Count
Source
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
0
    OGRFieldDefnOverride() = default;
31
32
    void SetFieldName(const std::string &osName)
33
0
    {
34
0
        m_osName = osName;
35
0
    }
36
37
    void SetSrcFieldType(OGRFieldType eType)
38
0
    {
39
0
        m_eSrcType = eType;
40
0
    }
41
42
    void SetSrcFieldSubType(OGRFieldSubType eSubType)
43
0
    {
44
0
        m_eSrcSubType = eSubType;
45
0
    }
46
47
    void SetFieldType(OGRFieldType eType)
48
0
    {
49
0
        m_eType = eType;
50
0
    }
51
52
    void SetFieldSubType(OGRFieldSubType eSubType)
53
0
    {
54
0
        m_eSubType = eSubType;
55
0
    }
56
57
    void SetFieldWidth(int nWidth)
58
0
    {
59
0
        m_nWidth = nWidth;
60
0
    }
61
62
    void SetFieldPrecision(int nPrecision)
63
0
    {
64
0
        m_nPrecision = nPrecision;
65
0
    }
66
67
    std::optional<std::string> GetFieldName() const
68
0
    {
69
0
        return m_osName;
70
0
    }
71
72
    std::optional<OGRFieldType> GetSrcFieldType() const
73
0
    {
74
0
        return m_eSrcType;
75
0
    }
76
77
    std::optional<OGRFieldSubType> GetSrcFieldSubType() const
78
0
    {
79
0
        return m_eSrcSubType;
80
0
    }
81
82
    std::optional<OGRFieldType> GetFieldType() const
83
0
    {
84
0
        return m_eType;
85
0
    }
86
87
    std::optional<OGRFieldSubType> GetFieldSubType() const
88
0
    {
89
0
        return m_eSubType;
90
0
    }
91
92
    std::optional<int> GetFieldWidth() const
93
0
    {
94
0
        return m_nWidth;
95
0
    }
96
97
    std::optional<int> GetFieldPrecision() const
98
0
    {
99
0
        return m_nPrecision;
100
0
    }
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
0
    OGRLayerSchemaOverride() = default;
120
121
    void SetLayerName(const std::string &osLayerName)
122
0
    {
123
0
        m_osLayerName = osLayerName;
124
0
    }
125
126
    void AddNamedFieldOverride(const std::string &osFieldName,
127
                               const OGRFieldDefnOverride &oFieldOverride)
128
0
    {
129
0
        m_oNamedFieldOverrides[osFieldName] = oFieldOverride;
130
0
    }
131
132
    void AddUnnamedFieldOverride(const OGRFieldDefnOverride &oFieldOverride)
133
0
    {
134
0
        m_aoUnnamedFieldOverrides.push_back(oFieldOverride);
135
0
    }
136
137
    const std::string &GetLayerName() const
138
0
    {
139
0
        return m_osLayerName;
140
0
    }
141
142
    const std::map<std::string, OGRFieldDefnOverride> &
143
    GetNamedFieldOverrides() const
144
0
    {
145
0
        return m_oNamedFieldOverrides;
146
0
    }
147
148
    const std::vector<OGRFieldDefnOverride> &GetUnnamedFieldOverrides() const
149
0
    {
150
0
        return m_aoUnnamedFieldOverrides;
151
0
    }
152
153
    bool IsFullOverride() const
154
0
    {
155
0
        return m_bIsFullOverride;
156
0
    }
157
158
    void SetFullOverride(bool bIsFullOverride)
159
0
    {
160
0
        m_bIsFullOverride = bIsFullOverride;
161
0
    }
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
0
    OGRSchemaOverride() = default;
179
180
    void AddLayerOverride(const OGRLayerSchemaOverride &oLayerOverride)
181
0
    {
182
0
        m_aoLayerOverrides.push_back(oLayerOverride);
183
0
    }
184
185
    bool LoadFromJSON(const std::string &osJSON);
186
187
    const std::vector<OGRLayerSchemaOverride> &GetLayerOverrides() const
188
0
    {
189
0
        return m_aoLayerOverrides;
190
0
    }
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
0
            [](OGRLayer *, int) {}) const;
199
200
  private:
201
    std::vector<OGRLayerSchemaOverride> m_aoLayerOverrides{};
202
};
203
204
//! @endcond
205
206
#endif /* ndef OGR_FEATURE_H_INCLUDED */