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