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