Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: AMIGOCLOUD Translator
5 : * Purpose: Definition of classes for OGR AmigoCloud driver.
6 : * Author: Victor Chernetsky, <victor at amigocloud dot com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2015, Victor Chernetsky, <victor at amigocloud dot com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #ifndef OGR_AMIGOCLOUD_H_INCLUDED
31 : #define OGR_AMIGOCLOUD_H_INCLUDED
32 :
33 : #include "ogrsf_frmts.h"
34 :
35 : #include "cpl_json_header.h"
36 : #include "cpl_hash_set.h"
37 : #include "cpl_http.h"
38 :
39 : #include <vector>
40 : #include <string>
41 :
42 : #include <cstdlib>
43 :
44 : json_object *OGRAMIGOCLOUDGetSingleRow(json_object *poObj);
45 : CPLString OGRAMIGOCLOUDEscapeIdentifier(const char *pszStr);
46 : std::string OGRAMIGOCLOUDJsonEncode(const std::string &value);
47 :
48 : /************************************************************************/
49 : /* OGRAmigoCloudGeomFieldDefn */
50 : /************************************************************************/
51 :
52 : class OGRAmigoCloudGeomFieldDefn final : public OGRGeomFieldDefn
53 : {
54 : public:
55 : int nSRID;
56 :
57 0 : OGRAmigoCloudGeomFieldDefn(const char *pszNameIn, OGRwkbGeometryType eType)
58 0 : : OGRGeomFieldDefn(pszNameIn, eType), nSRID(0)
59 : {
60 0 : }
61 : };
62 :
63 0 : class OGRAmigoCloudFID
64 : {
65 : public:
66 : GIntBig iIndex;
67 : GIntBig iFID;
68 : std::string osAmigoId;
69 :
70 0 : OGRAmigoCloudFID(const std::string &amigo_id, GIntBig index)
71 0 : : iIndex(index),
72 0 : iFID(std::abs((long)CPLHashSetHashStr(amigo_id.c_str()))),
73 0 : osAmigoId(amigo_id)
74 : {
75 0 : }
76 :
77 0 : OGRAmigoCloudFID()
78 0 : {
79 0 : iIndex = 0;
80 0 : iFID = 0;
81 0 : }
82 :
83 : OGRAmigoCloudFID(const OGRAmigoCloudFID &fid) = default;
84 : OGRAmigoCloudFID &operator=(const OGRAmigoCloudFID &fid) = default;
85 : };
86 :
87 : /************************************************************************/
88 : /* OGRAmigoCloudLayer */
89 : /************************************************************************/
90 : class OGRAmigoCloudDataSource;
91 :
92 : class OGRAmigoCloudLayer CPL_NON_FINAL : public OGRLayer
93 : {
94 : protected:
95 : OGRAmigoCloudDataSource *poDS;
96 :
97 : OGRFeatureDefn *poFeatureDefn;
98 : CPLString osBaseSQL;
99 : CPLString osFIDColName;
100 :
101 : int bEOF;
102 : int nFetchedObjects;
103 : int iNextInFetchedObjects;
104 : GIntBig iNext;
105 : json_object *poCachedObj;
106 :
107 : std::map<GIntBig, OGRAmigoCloudFID> mFIDs;
108 :
109 : virtual OGRFeature *GetNextRawFeature();
110 : OGRFeature *BuildFeature(json_object *poRowObj);
111 :
112 : void EstablishLayerDefn(const char *pszLayerName, json_object *poObjIn);
113 : OGRSpatialReference *GetSRS(const char *pszGeomCol, int *pnSRID);
114 : virtual CPLString GetSRS_SQL(const char *pszGeomCol) = 0;
115 :
116 : public:
117 : explicit OGRAmigoCloudLayer(OGRAmigoCloudDataSource *poDS);
118 : virtual ~OGRAmigoCloudLayer();
119 :
120 : virtual void ResetReading() override;
121 : virtual OGRFeature *GetNextFeature() override;
122 :
123 : virtual OGRFeatureDefn *GetLayerDefn() override;
124 : virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) = 0;
125 : virtual json_object *FetchNewFeatures(GIntBig iNext);
126 :
127 0 : virtual const char *GetFIDColumn() override
128 : {
129 0 : return osFIDColName.c_str();
130 : }
131 :
132 : virtual int TestCapability(const char *) override;
133 :
134 : GDALDataset *GetDataset() override;
135 :
136 0 : static int GetFeaturesToFetch()
137 : {
138 0 : return 100;
139 : }
140 : };
141 :
142 : /************************************************************************/
143 : /* OGRAmigoCloudTableLayer */
144 : /************************************************************************/
145 :
146 : class OGRAmigoCloudTableLayer final : public OGRAmigoCloudLayer
147 : {
148 : CPLString osTableName;
149 : CPLString osName;
150 : CPLString osDatasetId;
151 : CPLString osQuery;
152 : CPLString osWHERE;
153 : CPLString osSELECTWithoutWHERE;
154 :
155 : std::vector<std::string> vsDeferredInsertChangesets;
156 : GIntBig nNextFID;
157 :
158 : int bDeferredCreation;
159 : int nMaxChunkSize;
160 :
161 : void BuildWhere();
162 :
163 : virtual CPLString GetSRS_SQL(const char *pszGeomCol) override;
164 :
165 : public:
166 : OGRAmigoCloudTableLayer(OGRAmigoCloudDataSource *poDS, const char *pszName);
167 : virtual ~OGRAmigoCloudTableLayer();
168 :
169 0 : virtual const char *GetName() override
170 : {
171 0 : return osName.c_str();
172 : }
173 :
174 0 : const char *GetTableName()
175 : {
176 0 : return osTableName.c_str();
177 : }
178 :
179 0 : const char *GetDatasetId()
180 : {
181 0 : return osDatasetId.c_str();
182 : }
183 :
184 : virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) override;
185 : virtual json_object *FetchNewFeatures(GIntBig iNext) override;
186 :
187 : virtual GIntBig GetFeatureCount(int bForce = TRUE) override;
188 : virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
189 :
190 : virtual int TestCapability(const char *) override;
191 :
192 : virtual OGRErr CreateField(const OGRFieldDefn *poField,
193 : int bApproxOK = TRUE) override;
194 :
195 : virtual OGRFeature *GetNextRawFeature() override;
196 :
197 : virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
198 : virtual OGRErr ISetFeature(OGRFeature *poFeature) override;
199 : virtual OGRErr DeleteFeature(GIntBig nFID) override;
200 :
201 0 : virtual void SetSpatialFilter(OGRGeometry *poGeom) override
202 : {
203 0 : SetSpatialFilter(0, poGeom);
204 0 : }
205 :
206 : virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override;
207 : virtual OGRErr SetAttributeFilter(const char *) override;
208 :
209 0 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override
210 : {
211 0 : return GetExtent(0, psExtent, bForce);
212 : }
213 :
214 : virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
215 : int bForce) override;
216 :
217 : void SetDeferredCreation(OGRwkbGeometryType eGType,
218 : OGRSpatialReference *poSRS, int bGeomNullable);
219 :
220 : static CPLString GetAmigoCloudType(const OGRFieldDefn &oField);
221 :
222 : OGRErr RunDeferredCreationIfNecessary();
223 :
224 0 : int GetDeferredCreation() const
225 : {
226 0 : return bDeferredCreation;
227 : }
228 :
229 0 : void CancelDeferredCreation()
230 : {
231 0 : bDeferredCreation = FALSE;
232 0 : }
233 :
234 : void FlushDeferredInsert();
235 : bool IsDatasetExists();
236 : };
237 :
238 : /************************************************************************/
239 : /* OGRAmigoCloudResultLayer */
240 : /************************************************************************/
241 :
242 : class OGRAmigoCloudResultLayer final : public OGRAmigoCloudLayer
243 : {
244 : OGRFeature *poFirstFeature;
245 :
246 : virtual CPLString GetSRS_SQL(const char *pszGeomCol) override;
247 :
248 : public:
249 : OGRAmigoCloudResultLayer(OGRAmigoCloudDataSource *poDS,
250 : const char *pszRawStatement);
251 : virtual ~OGRAmigoCloudResultLayer();
252 :
253 : virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) override;
254 : virtual OGRFeature *GetNextRawFeature() override;
255 :
256 : int IsOK();
257 : };
258 :
259 : /************************************************************************/
260 : /* OGRAmigoCloudDataSource */
261 : /************************************************************************/
262 :
263 : class OGRAmigoCloudDataSource final : public OGRDataSource
264 : {
265 : char *pszName;
266 : char *pszProjectId;
267 :
268 : OGRAmigoCloudTableLayer **papoLayers;
269 : int nLayers;
270 : bool bReadWrite;
271 :
272 : bool bUseHTTPS;
273 :
274 : CPLString osAPIKey;
275 :
276 : bool bMustCleanPersistent;
277 :
278 : CPLString osCurrentSchema;
279 : // TODO(schwehr): Can bHasOGRMetadataFunction be a bool?
280 : int bHasOGRMetadataFunction;
281 :
282 : public:
283 : OGRAmigoCloudDataSource();
284 : virtual ~OGRAmigoCloudDataSource();
285 :
286 : int Open(const char *pszFilename, char **papszOpenOptions, int bUpdate);
287 :
288 0 : virtual const char *GetName() override
289 : {
290 0 : return pszName;
291 : }
292 :
293 0 : virtual int GetLayerCount() override
294 : {
295 0 : return nLayers;
296 : }
297 :
298 : virtual OGRLayer *GetLayer(int) override;
299 : virtual OGRLayer *GetLayerByName(const char *) override;
300 :
301 : virtual int TestCapability(const char *) override;
302 :
303 : virtual OGRLayer *ICreateLayer(const char *pszName,
304 : const OGRGeomFieldDefn *poGeomFieldDefn,
305 : CSLConstList papszOptions) override;
306 : virtual OGRErr DeleteLayer(int) override;
307 :
308 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand,
309 : OGRGeometry *poSpatialFilter,
310 : const char *pszDialect) override;
311 : virtual void ReleaseResultSet(OGRLayer *poLayer) override;
312 :
313 : const char *GetAPIURL() const;
314 :
315 0 : bool IsReadWrite() const
316 : {
317 0 : return bReadWrite;
318 : }
319 :
320 0 : const char *GetProjectId()
321 : {
322 0 : return pszProjectId;
323 : }
324 :
325 : char **AddHTTPOptions();
326 : json_object *
327 : RunPOST(const char *pszURL, const char *pszPostData,
328 : const char *pszHeaders = "HEADERS=Content-Type: application/json");
329 : json_object *RunGET(const char *pszURL);
330 : bool RunDELETE(const char *pszURL);
331 : json_object *RunSQL(const char *pszUnescapedSQL);
332 :
333 0 : const CPLString &GetCurrentSchema()
334 : {
335 0 : return osCurrentSchema;
336 : }
337 :
338 : static int FetchSRSId(OGRSpatialReference *poSRS);
339 :
340 : static std::string GetUserAgentOption();
341 :
342 : int IsAuthenticatedConnection()
343 : {
344 : return !osAPIKey.empty();
345 : }
346 :
347 : int HasOGRMetadataFunction()
348 : {
349 : return bHasOGRMetadataFunction;
350 : }
351 :
352 : void SetOGRMetadataFunction(int bFlag)
353 : {
354 : bHasOGRMetadataFunction = bFlag;
355 : }
356 :
357 : OGRLayer *ExecuteSQLInternal(const char *pszSQLCommand,
358 : OGRGeometry *poSpatialFilter = nullptr,
359 : const char *pszDialect = nullptr,
360 : bool bRunDeferredActions = false);
361 :
362 : bool ListDatasets();
363 : bool waitForJobToFinish(const char *jobId);
364 : bool TruncateDataset(const CPLString &tableName);
365 : void SubmitChangeset(const CPLString &json);
366 : };
367 :
368 : #endif /* ndef OGR_AMIGOCLOUD_H_INCLUDED */
|