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