Coverage Report

Created: 2025-06-09 08:44

/src/gdal/ogr/ogrsf_frmts/amigocloud/ogr_amigocloud.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  AMIGOCLOUD Translator
4
 * Purpose:  Definition of classes for OGR AmigoCloud driver.
5
 * Author:   Victor Chernetsky, <victor at amigocloud dot com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2015, Victor Chernetsky, <victor at amigocloud dot com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef OGR_AMIGOCLOUD_H_INCLUDED
14
#define OGR_AMIGOCLOUD_H_INCLUDED
15
16
#include "ogrsf_frmts.h"
17
18
#include "cpl_json_header.h"
19
#include "cpl_hash_set.h"
20
#include "cpl_http.h"
21
22
#include <vector>
23
#include <string>
24
25
#include <cstdlib>
26
27
json_object *OGRAMIGOCLOUDGetSingleRow(json_object *poObj);
28
CPLString OGRAMIGOCLOUDEscapeIdentifier(const char *pszStr);
29
std::string OGRAMIGOCLOUDJsonEncode(const std::string &value);
30
31
/************************************************************************/
32
/*                      OGRAmigoCloudGeomFieldDefn                      */
33
/************************************************************************/
34
35
class OGRAmigoCloudGeomFieldDefn final : public OGRGeomFieldDefn
36
{
37
  public:
38
    int nSRID;
39
40
    OGRAmigoCloudGeomFieldDefn(const char *pszNameIn, OGRwkbGeometryType eType)
41
0
        : OGRGeomFieldDefn(pszNameIn, eType), nSRID(0)
42
0
    {
43
0
    }
44
45
    ~OGRAmigoCloudGeomFieldDefn() override;
46
};
47
48
class OGRAmigoCloudFID
49
{
50
  public:
51
    GIntBig iIndex;
52
    GIntBig iFID;
53
    std::string osAmigoId;
54
55
    OGRAmigoCloudFID(const std::string &amigo_id, GIntBig index)
56
0
        : iIndex(index),
57
0
          iFID(std::abs((long)CPLHashSetHashStr(amigo_id.c_str()))),
58
0
          osAmigoId(amigo_id)
59
0
    {
60
0
    }
61
62
    OGRAmigoCloudFID()
63
0
    {
64
0
        iIndex = 0;
65
0
        iFID = 0;
66
0
    }
67
68
    OGRAmigoCloudFID(const OGRAmigoCloudFID &fid) = default;
69
0
    OGRAmigoCloudFID &operator=(const OGRAmigoCloudFID &fid) = default;
70
};
71
72
/************************************************************************/
73
/*                           OGRAmigoCloudLayer                            */
74
/************************************************************************/
75
class OGRAmigoCloudDataSource;
76
77
class OGRAmigoCloudLayer CPL_NON_FINAL : public OGRLayer
78
{
79
  protected:
80
    OGRAmigoCloudDataSource *poDS;
81
82
    OGRFeatureDefn *poFeatureDefn;
83
    CPLString osBaseSQL;
84
    CPLString osFIDColName;
85
86
    int bEOF;
87
    int nFetchedObjects;
88
    int iNextInFetchedObjects;
89
    GIntBig iNext;
90
    json_object *poCachedObj;
91
92
    std::map<GIntBig, OGRAmigoCloudFID> mFIDs;
93
94
    virtual OGRFeature *GetNextRawFeature();
95
    OGRFeature *BuildFeature(json_object *poRowObj);
96
97
    void EstablishLayerDefn(const char *pszLayerName, json_object *poObjIn);
98
    OGRSpatialReference *GetSRS(const char *pszGeomCol, int *pnSRID);
99
    virtual CPLString GetSRS_SQL(const char *pszGeomCol) = 0;
100
101
  public:
102
    explicit OGRAmigoCloudLayer(OGRAmigoCloudDataSource *poDS);
103
    virtual ~OGRAmigoCloudLayer();
104
105
    virtual void ResetReading() override;
106
    virtual OGRFeature *GetNextFeature() override;
107
108
    virtual OGRFeatureDefn *GetLayerDefn() override;
109
    virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) = 0;
110
    virtual json_object *FetchNewFeatures(GIntBig iNext);
111
112
    virtual const char *GetFIDColumn() override
113
0
    {
114
0
        return osFIDColName.c_str();
115
0
    }
116
117
    virtual int TestCapability(const char *) override;
118
119
    GDALDataset *GetDataset() override;
120
121
    static int GetFeaturesToFetch()
122
92
    {
123
92
        return 100;
124
92
    }
125
};
126
127
/************************************************************************/
128
/*                        OGRAmigoCloudTableLayer                          */
129
/************************************************************************/
130
131
class OGRAmigoCloudTableLayer final : public OGRAmigoCloudLayer
132
{
133
    CPLString osTableName;
134
    CPLString osName;
135
    CPLString osDatasetId;
136
    CPLString osQuery;
137
    CPLString osWHERE;
138
    CPLString osSELECTWithoutWHERE;
139
140
    std::vector<std::string> vsDeferredInsertChangesets;
141
    GIntBig nNextFID;
142
143
    int bDeferredCreation;
144
    int nMaxChunkSize;
145
146
    void BuildWhere();
147
148
    virtual CPLString GetSRS_SQL(const char *pszGeomCol) override;
149
150
  public:
151
    OGRAmigoCloudTableLayer(OGRAmigoCloudDataSource *poDS, const char *pszName);
152
    virtual ~OGRAmigoCloudTableLayer();
153
154
    virtual const char *GetName() override
155
0
    {
156
0
        return osName.c_str();
157
0
    }
158
159
    const char *GetTableName()
160
0
    {
161
0
        return osTableName.c_str();
162
0
    }
163
164
    const char *GetDatasetId()
165
0
    {
166
0
        return osDatasetId.c_str();
167
0
    }
168
169
    virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) override;
170
    virtual json_object *FetchNewFeatures(GIntBig iNext) override;
171
172
    virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
173
    virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
174
175
    virtual int TestCapability(const char *) override;
176
177
    virtual OGRErr CreateField(const OGRFieldDefn *poField,
178
                               int bApproxOK = TRUE) override;
179
180
    virtual OGRFeature *GetNextRawFeature() override;
181
182
    virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
183
    virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
184
    virtual OGRErr DeleteFeature(GIntBig nFID) override;
185
186
    virtual OGRErr ISetSpatialFilter(int iGeomField,
187
                                     const OGRGeometry *poGeom) override;
188
    virtual OGRErr SetAttributeFilter(const char *) override;
189
190
    virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
191
                              bool bForce) override;
192
193
    void SetDeferredCreation(OGRwkbGeometryType eGType,
194
                             OGRSpatialReference *poSRS, int bGeomNullable);
195
196
    static CPLString GetAmigoCloudType(const OGRFieldDefn &oField);
197
198
    OGRErr RunDeferredCreationIfNecessary();
199
200
    int GetDeferredCreation() const
201
0
    {
202
0
        return bDeferredCreation;
203
0
    }
204
205
    void CancelDeferredCreation()
206
0
    {
207
0
        bDeferredCreation = FALSE;
208
0
    }
209
210
    void FlushDeferredInsert();
211
    bool IsDatasetExists();
212
};
213
214
/************************************************************************/
215
/*                       OGRAmigoCloudResultLayer                          */
216
/************************************************************************/
217
218
class OGRAmigoCloudResultLayer final : public OGRAmigoCloudLayer
219
{
220
    OGRFeature *poFirstFeature;
221
222
    virtual CPLString GetSRS_SQL(const char *pszGeomCol) override;
223
224
  public:
225
    OGRAmigoCloudResultLayer(OGRAmigoCloudDataSource *poDS,
226
                             const char *pszRawStatement);
227
    virtual ~OGRAmigoCloudResultLayer();
228
229
    virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) override;
230
    virtual OGRFeature *GetNextRawFeature() override;
231
232
    int IsOK();
233
};
234
235
/************************************************************************/
236
/*                           OGRAmigoCloudDataSource                    */
237
/************************************************************************/
238
239
class OGRAmigoCloudDataSource final : public GDALDataset
240
{
241
    char *pszProjectId;
242
243
    OGRAmigoCloudTableLayer **papoLayers;
244
    int nLayers;
245
    bool bReadWrite;
246
247
    bool bUseHTTPS;
248
249
    CPLString osAPIKey;
250
251
    bool bMustCleanPersistent;
252
253
    CPLString osCurrentSchema;
254
    // TODO(schwehr): Can bHasOGRMetadataFunction be a bool?
255
    int bHasOGRMetadataFunction;
256
257
  public:
258
    OGRAmigoCloudDataSource();
259
    virtual ~OGRAmigoCloudDataSource();
260
261
    int Open(const char *pszFilename, char **papszOpenOptions, int bUpdate);
262
263
    virtual int GetLayerCount() override
264
0
    {
265
0
        return nLayers;
266
0
    }
267
268
    virtual OGRLayer *GetLayer(int) override;
269
    virtual OGRLayer *GetLayerByName(const char *) override;
270
271
    virtual int TestCapability(const char *) override;
272
273
    virtual OGRLayer *ICreateLayer(const char *pszName,
274
                                   const OGRGeomFieldDefn *poGeomFieldDefn,
275
                                   CSLConstList papszOptions) override;
276
    virtual OGRErr DeleteLayer(int) override;
277
278
    virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
279
                                 OGRGeometry *poSpatialFilter,
280
                                 const char *pszDialect) override;
281
    virtual void ReleaseResultSet(OGRLayer *poLayer) override;
282
283
    const char *GetAPIURL() const;
284
285
    bool IsReadWrite() const
286
0
    {
287
0
        return bReadWrite;
288
0
    }
289
290
    const char *GetProjectId()
291
0
    {
292
0
        return pszProjectId;
293
0
    }
294
295
    char **AddHTTPOptions();
296
    json_object *
297
    RunPOST(const char *pszURL, const char *pszPostData,
298
            const char *pszHeaders = "HEADERS=Content-Type: application/json");
299
    json_object *RunGET(const char *pszURL);
300
    bool RunDELETE(const char *pszURL);
301
    json_object *RunSQL(const char *pszUnescapedSQL);
302
303
    const CPLString &GetCurrentSchema()
304
0
    {
305
0
        return osCurrentSchema;
306
0
    }
307
308
    static int FetchSRSId(OGRSpatialReference *poSRS);
309
310
    static std::string GetUserAgentOption();
311
312
    int IsAuthenticatedConnection()
313
0
    {
314
0
        return !osAPIKey.empty();
315
0
    }
316
317
    int HasOGRMetadataFunction()
318
0
    {
319
0
        return bHasOGRMetadataFunction;
320
0
    }
321
322
    void SetOGRMetadataFunction(int bFlag)
323
0
    {
324
0
        bHasOGRMetadataFunction = bFlag;
325
0
    }
326
327
    OGRLayer *ExecuteSQLInternal(const char *pszSQLCommand,
328
                                 OGRGeometry *poSpatialFilter = nullptr,
329
                                 const char *pszDialect = nullptr,
330
                                 bool bRunDeferredActions = false);
331
332
    bool ListDatasets();
333
    bool waitForJobToFinish(const char *jobId);
334
    bool TruncateDataset(const CPLString &tableName);
335
    void SubmitChangeset(const CPLString &json);
336
};
337
338
#endif /* ndef OGR_AMIGOCLOUD_H_INCLUDED */