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