Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: CARTO Translator
4 : * Purpose: Definition of classes for OGR Carto driver.
5 : * Author: Even Rouault, even dot rouault at spatialys.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #ifndef OGR_CARTO_H_INCLUDED
14 : #define OGR_CARTO_H_INCLUDED
15 :
16 : #include "ogrsf_frmts.h"
17 :
18 : #include "cpl_http.h"
19 : #include "cpl_json_header.h"
20 :
21 : #include <vector>
22 :
23 : json_object *OGRCARTOGetSingleRow(json_object *poObj);
24 : CPLString OGRCARTOEscapeIdentifier(const char *pszStr);
25 : CPLString OGRCARTOEscapeLiteral(const char *pszStr);
26 : CPLString OGRCARTOEscapeLiteralCopy(const char *pszStr);
27 :
28 : /************************************************************************/
29 : /* OGRCartoGeomFieldDefn */
30 : /************************************************************************/
31 :
32 : class OGRCartoGeomFieldDefn final : public OGRGeomFieldDefn
33 : {
34 : public:
35 : int nSRID;
36 :
37 13 : OGRCartoGeomFieldDefn(const char *pszNameIn, OGRwkbGeometryType eType)
38 13 : : OGRGeomFieldDefn(pszNameIn, eType), nSRID(0)
39 : {
40 13 : }
41 : };
42 :
43 : /************************************************************************/
44 : /* OGRCARTOLayer */
45 : /************************************************************************/
46 : class OGRCARTODataSource;
47 :
48 : class OGRCARTOLayer CPL_NON_FINAL : public OGRLayer
49 : {
50 : protected:
51 : OGRCARTODataSource *poDS;
52 :
53 : OGRFeatureDefn *poFeatureDefn;
54 : CPLString osBaseSQL;
55 : CPLString osFIDColName;
56 :
57 : bool bEOF;
58 : int nFetchedObjects;
59 : int iNextInFetchedObjects;
60 : GIntBig m_nNextFID;
61 : GIntBig m_nNextOffset;
62 : json_object *poCachedObj;
63 :
64 : virtual OGRFeature *GetNextRawFeature();
65 : OGRFeature *BuildFeature(json_object *poRowObj);
66 :
67 : void EstablishLayerDefn(const char *pszLayerName, json_object *poObjIn);
68 : OGRSpatialReference *GetSRS(const char *pszGeomCol, int *pnSRID);
69 : virtual CPLString GetSRS_SQL(const char *pszGeomCol) = 0;
70 :
71 : public:
72 : explicit OGRCARTOLayer(OGRCARTODataSource *poDS);
73 : virtual ~OGRCARTOLayer();
74 :
75 : virtual void ResetReading() override;
76 : virtual OGRFeature *GetNextFeature() override;
77 :
78 : virtual OGRFeatureDefn *GetLayerDefn() override;
79 : virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) = 0;
80 : virtual json_object *FetchNewFeatures();
81 :
82 0 : virtual const char *GetFIDColumn() override
83 : {
84 0 : return osFIDColName.c_str();
85 : }
86 :
87 : virtual int TestCapability(const char *) override;
88 :
89 : GDALDataset *GetDataset() override;
90 :
91 132 : static int GetFeaturesToFetch()
92 : {
93 132 : return atoi(CPLGetConfigOption(
94 132 : "CARTO_PAGE_SIZE", CPLGetConfigOption("CARTODB_PAGE_SIZE", "500")));
95 : }
96 : };
97 :
98 : typedef enum
99 : {
100 : INSERT_UNINIT,
101 : INSERT_SINGLE_FEATURE,
102 : INSERT_MULTIPLE_FEATURE
103 : } InsertState;
104 :
105 : /************************************************************************/
106 : /* OGRCARTOTableLayer */
107 : /************************************************************************/
108 :
109 : class OGRCARTOTableLayer final : public OGRCARTOLayer
110 : {
111 : CPLString osName;
112 : CPLString osQuery;
113 : CPLString osWHERE;
114 : CPLString osSELECTWithoutWHERE;
115 :
116 : bool bLaunderColumnNames;
117 :
118 : bool bInDeferredInsert;
119 : bool bCopyMode;
120 : InsertState eDeferredInsertState;
121 : CPLString osDeferredBuffer;
122 : CPLString osCopySQL;
123 : GIntBig m_nNextFIDWrite;
124 :
125 : bool bDeferredCreation;
126 : bool bCartodbfy;
127 : int nMaxChunkSize;
128 :
129 : bool bDropOnCreation;
130 :
131 : void BuildWhere();
132 : std::vector<bool> m_abFieldSetForInsert;
133 :
134 : virtual CPLString GetSRS_SQL(const char *pszGeomCol) override;
135 :
136 : public:
137 : OGRCARTOTableLayer(OGRCARTODataSource *poDS, const char *pszName);
138 : virtual ~OGRCARTOTableLayer();
139 :
140 8 : virtual const char *GetName() override
141 : {
142 8 : return osName.c_str();
143 : }
144 :
145 : virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) override;
146 : virtual json_object *FetchNewFeatures() override;
147 :
148 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
149 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
150 :
151 : virtual int TestCapability(const char *) override;
152 :
153 : virtual OGRErr CreateGeomField(const OGRGeomFieldDefn *poGeomFieldIn,
154 : int bApproxOK = TRUE) override;
155 :
156 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
157 : int bApproxOK = TRUE) override;
158 :
159 : virtual OGRErr DeleteField(int iField) override;
160 :
161 : virtual OGRFeature *GetNextRawFeature() override;
162 :
163 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
164 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
165 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
166 :
167 1 : virtual void SetSpatialFilter(OGRGeometry *poGeom) override
168 : {
169 1 : SetSpatialFilter(0, poGeom);
170 1 : }
171 :
172 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override;
173 : virtual OGRErr SetAttributeFilter(const char *) override;
174 :
175 0 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override
176 : {
177 0 : return GetExtent(0, psExtent, bForce);
178 : }
179 :
180 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
181 : int bForce) override;
182 :
183 4 : void SetLaunderFlag(bool bFlag)
184 : {
185 4 : bLaunderColumnNames = bFlag;
186 4 : }
187 :
188 : void SetDeferredCreation(OGRwkbGeometryType eGType,
189 : OGRSpatialReference *poSRS, bool bGeomNullable,
190 : bool bCartodbfy);
191 : OGRErr RunDeferredCreationIfNecessary();
192 :
193 4 : bool GetDeferredCreation() const
194 : {
195 4 : return bDeferredCreation;
196 : }
197 :
198 4 : void CancelDeferredCreation()
199 : {
200 4 : bDeferredCreation = false;
201 4 : bCartodbfy = false;
202 4 : }
203 :
204 : OGRErr FlushDeferredBuffer(bool bReset = true);
205 : void RunDeferredCartofy();
206 :
207 : OGRErr FlushDeferredInsert(bool bReset = true);
208 : OGRErr FlushDeferredCopy(bool bReset = true);
209 : OGRErr ICreateFeatureInsert(OGRFeature *poFeature,
210 : bool bHasUserFieldMatchingFID,
211 : bool bHasJustGotNextFID);
212 : OGRErr ICreateFeatureCopy(OGRFeature *poFeature,
213 : bool bHasUserFieldMatchingFID,
214 : bool bHasJustGotNextFID);
215 : char *OGRCARTOGetHexGeometry(OGRGeometry *poGeom, int i);
216 :
217 4 : void SetDropOnCreation(bool bFlag)
218 : {
219 4 : bDropOnCreation = bFlag;
220 4 : }
221 :
222 4 : bool GetDropOnCreation() const
223 : {
224 4 : return bDropOnCreation;
225 : }
226 : };
227 :
228 : /************************************************************************/
229 : /* OGRCARTOResultLayer */
230 : /************************************************************************/
231 :
232 : class OGRCARTOResultLayer final : public OGRCARTOLayer
233 : {
234 : OGRFeature *poFirstFeature;
235 :
236 : virtual CPLString GetSRS_SQL(const char *pszGeomCol) override;
237 :
238 : public:
239 : OGRCARTOResultLayer(OGRCARTODataSource *poDS, const char *pszRawStatement);
240 : virtual ~OGRCARTOResultLayer();
241 :
242 : virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) override;
243 : virtual OGRFeature *GetNextRawFeature() override;
244 :
245 : bool IsOK();
246 : };
247 :
248 : /************************************************************************/
249 : /* OGRCARTODataSource */
250 : /************************************************************************/
251 :
252 : class OGRCARTODataSource final : public GDALDataset
253 : {
254 : char *pszAccount;
255 :
256 : OGRCARTOTableLayer **papoLayers;
257 : int nLayers;
258 :
259 : bool bReadWrite;
260 : bool bBatchInsert;
261 : bool bCopyMode;
262 :
263 : bool bUseHTTPS;
264 :
265 : CPLString osAPIKey;
266 :
267 : bool bMustCleanPersistent;
268 :
269 : CPLString osCurrentSchema;
270 :
271 : int bHasOGRMetadataFunction;
272 :
273 : int nPostGISMajor;
274 : int nPostGISMinor;
275 :
276 : public:
277 : OGRCARTODataSource();
278 : virtual ~OGRCARTODataSource();
279 :
280 : int Open(const char *pszFilename, char **papszOpenOptions, int bUpdate);
281 :
282 5 : virtual int GetLayerCount() override
283 : {
284 5 : return nLayers;
285 : }
286 :
287 : virtual OGRLayer *GetLayer(int) override;
288 :
289 : virtual int TestCapability(const char *) override;
290 :
291 : OGRLayer *ICreateLayer(const char *pszName,
292 : const OGRGeomFieldDefn *poGeomFieldDefn,
293 : CSLConstList papszOptions) override;
294 : virtual OGRErr DeleteLayer(int) override;
295 :
296 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
297 : OGRGeometry *poSpatialFilter,
298 : const char *pszDialect) override;
299 : virtual void ReleaseResultSet(OGRLayer *poLayer) override;
300 :
301 : const char *GetAPIURL() const;
302 :
303 34 : bool IsReadWrite() const
304 : {
305 34 : return bReadWrite;
306 : }
307 :
308 22 : bool DoBatchInsert() const
309 : {
310 22 : return bBatchInsert;
311 : }
312 :
313 22 : bool DoCopyMode() const
314 : {
315 22 : return bCopyMode;
316 : }
317 :
318 : char **AddHTTPOptions();
319 : json_object *RunSQL(const char *pszUnescapedSQL);
320 : json_object *RunCopyFrom(const char *pszSQL, const char *pszCopyFile);
321 :
322 16 : const CPLString &GetCurrentSchema()
323 : {
324 16 : return osCurrentSchema;
325 : }
326 :
327 : static int FetchSRSId(const OGRSpatialReference *poSRS);
328 :
329 45 : int IsAuthenticatedConnection()
330 : {
331 45 : return !osAPIKey.empty();
332 : }
333 :
334 9 : int HasOGRMetadataFunction()
335 : {
336 9 : return bHasOGRMetadataFunction;
337 : }
338 :
339 3 : void SetOGRMetadataFunction(int bFlag)
340 : {
341 3 : bHasOGRMetadataFunction = bFlag;
342 3 : }
343 :
344 : OGRLayer *ExecuteSQLInternal(const char *pszSQLCommand,
345 : OGRGeometry *poSpatialFilter = nullptr,
346 : const char *pszDialect = nullptr,
347 : bool bRunDeferredActions = false);
348 :
349 7 : int GetPostGISMajor() const
350 : {
351 7 : return nPostGISMajor;
352 : }
353 :
354 7 : int GetPostGISMinor() const
355 : {
356 7 : return nPostGISMinor;
357 : }
358 : };
359 :
360 : #endif /* ndef OGR_CARTO_H_INCLUDED */
|