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 : virtual OGRErr ISetSpatialFilter(int iGeomField, 185 : const OGRGeometry *poGeom) override; 186 : virtual OGRErr SetAttributeFilter(const char *) override; 187 : 188 : virtual OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent, 189 : bool bForce) override; 190 : 191 : void SetDeferredCreation(OGRwkbGeometryType eGType, 192 : OGRSpatialReference *poSRS, int bGeomNullable); 193 : 194 : static CPLString GetAmigoCloudType(const OGRFieldDefn &oField); 195 : 196 : OGRErr RunDeferredCreationIfNecessary(); 197 : 198 0 : int GetDeferredCreation() const 199 : { 200 0 : return bDeferredCreation; 201 : } 202 : 203 0 : void CancelDeferredCreation() 204 : { 205 0 : bDeferredCreation = FALSE; 206 0 : } 207 : 208 : void FlushDeferredInsert(); 209 : bool IsDatasetExists(); 210 : }; 211 : 212 : /************************************************************************/ 213 : /* OGRAmigoCloudResultLayer */ 214 : /************************************************************************/ 215 : 216 : class OGRAmigoCloudResultLayer final : public OGRAmigoCloudLayer 217 : { 218 : OGRFeature *poFirstFeature; 219 : 220 : virtual CPLString GetSRS_SQL(const char *pszGeomCol) override; 221 : 222 : public: 223 : OGRAmigoCloudResultLayer(OGRAmigoCloudDataSource *poDS, 224 : const char *pszRawStatement); 225 : virtual ~OGRAmigoCloudResultLayer(); 226 : 227 : virtual OGRFeatureDefn *GetLayerDefnInternal(json_object *poObjIn) override; 228 : virtual OGRFeature *GetNextRawFeature() override; 229 : 230 : int IsOK(); 231 : }; 232 : 233 : /************************************************************************/ 234 : /* OGRAmigoCloudDataSource */ 235 : /************************************************************************/ 236 : 237 : class OGRAmigoCloudDataSource final : public GDALDataset 238 : { 239 : char *pszProjectId; 240 : 241 : OGRAmigoCloudTableLayer **papoLayers; 242 : int nLayers; 243 : bool bReadWrite; 244 : 245 : bool bUseHTTPS; 246 : 247 : CPLString osAPIKey; 248 : 249 : bool bMustCleanPersistent; 250 : 251 : CPLString osCurrentSchema; 252 : // TODO(schwehr): Can bHasOGRMetadataFunction be a bool? 253 : int bHasOGRMetadataFunction; 254 : 255 : public: 256 : OGRAmigoCloudDataSource(); 257 : virtual ~OGRAmigoCloudDataSource(); 258 : 259 : int Open(const char *pszFilename, char **papszOpenOptions, int bUpdate); 260 : 261 0 : virtual int GetLayerCount() override 262 : { 263 0 : return nLayers; 264 : } 265 : 266 : virtual OGRLayer *GetLayer(int) override; 267 : virtual OGRLayer *GetLayerByName(const char *) override; 268 : 269 : virtual int TestCapability(const char *) override; 270 : 271 : virtual OGRLayer *ICreateLayer(const char *pszName, 272 : const OGRGeomFieldDefn *poGeomFieldDefn, 273 : CSLConstList papszOptions) override; 274 : virtual OGRErr DeleteLayer(int) override; 275 : 276 : virtual OGRLayer *ExecuteSQL(const char *pszSQLCommand, 277 : OGRGeometry *poSpatialFilter, 278 : const char *pszDialect) override; 279 : virtual void ReleaseResultSet(OGRLayer *poLayer) override; 280 : 281 : const char *GetAPIURL() const; 282 : 283 0 : bool IsReadWrite() const 284 : { 285 0 : return bReadWrite; 286 : } 287 : 288 0 : const char *GetProjectId() 289 : { 290 0 : return pszProjectId; 291 : } 292 : 293 : char **AddHTTPOptions(); 294 : json_object * 295 : RunPOST(const char *pszURL, const char *pszPostData, 296 : const char *pszHeaders = "HEADERS=Content-Type: application/json"); 297 : json_object *RunGET(const char *pszURL); 298 : bool RunDELETE(const char *pszURL); 299 : json_object *RunSQL(const char *pszUnescapedSQL); 300 : 301 0 : const CPLString &GetCurrentSchema() 302 : { 303 0 : return osCurrentSchema; 304 : } 305 : 306 : static int FetchSRSId(OGRSpatialReference *poSRS); 307 : 308 : static std::string GetUserAgentOption(); 309 : 310 : int IsAuthenticatedConnection() 311 : { 312 : return !osAPIKey.empty(); 313 : } 314 : 315 : int HasOGRMetadataFunction() 316 : { 317 : return bHasOGRMetadataFunction; 318 : } 319 : 320 : void SetOGRMetadataFunction(int bFlag) 321 : { 322 : bHasOGRMetadataFunction = bFlag; 323 : } 324 : 325 : OGRLayer *ExecuteSQLInternal(const char *pszSQLCommand, 326 : OGRGeometry *poSpatialFilter = nullptr, 327 : const char *pszDialect = nullptr, 328 : bool bRunDeferredActions = false); 329 : 330 : bool ListDatasets(); 331 : bool waitForJobToFinish(const char *jobId); 332 : bool TruncateDataset(const CPLString &tableName); 333 : void SubmitChangeset(const CPLString &json); 334 : }; 335 : 336 : #endif /* ndef OGR_AMIGOCLOUD_H_INCLUDED */