1 /******************************************************************************
2  * $Id: ogr_carto.h 842d122d2f23aaebb28362e083b52d6bc7dbcde2 2019-08-11 17:42:34 +0200 Even Rouault $
3  *
4  * Project:  CARTO Translator
5  * Purpose:  Definition of classes for OGR Carto driver.
6  * Author:   Even Rouault, even dot rouault at spatialys.com
7  *
8  ******************************************************************************
9  * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.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_CARTO_H_INCLUDED
31 #define OGR_CARTO_H_INCLUDED
32 
33 #include "ogrsf_frmts.h"
34 
35 #include "cpl_http.h"
36 #include "cpl_json_header.h"
37 
38 #include <vector>
39 
40 
41 json_object* OGRCARTOGetSingleRow(json_object* poObj);
42 CPLString OGRCARTOEscapeIdentifier(const char* pszStr);
43 CPLString OGRCARTOEscapeLiteral(const char* pszStr);
44 CPLString OGRCARTOEscapeLiteralCopy(const char* pszStr);
45 
46 /************************************************************************/
47 /*                      OGRCartoGeomFieldDefn                         */
48 /************************************************************************/
49 
50 class OGRCartoGeomFieldDefn final: public OGRGeomFieldDefn
51 {
52     public:
53         int nSRID;
54 
OGRCartoGeomFieldDefn(const char * pszNameIn,OGRwkbGeometryType eType)55         OGRCartoGeomFieldDefn(const char* pszNameIn, OGRwkbGeometryType eType) :
56                 OGRGeomFieldDefn(pszNameIn, eType), nSRID(0)
57         {
58         }
59 };
60 
61 /************************************************************************/
62 /*                           OGRCARTOLayer                            */
63 /************************************************************************/
64 class OGRCARTODataSource;
65 
66 class OGRCARTOLayer CPL_NON_FINAL: public OGRLayer
67 {
68 protected:
69     OGRCARTODataSource* poDS;
70 
71     OGRFeatureDefn      *poFeatureDefn;
72     CPLString            osBaseSQL;
73     CPLString            osFIDColName;
74 
75     bool                 bEOF;
76     int                  nFetchedObjects;
77     int                  iNextInFetchedObjects;
78     GIntBig              m_nNextFID;
79     GIntBig              m_nNextOffset;
80     json_object         *poCachedObj;
81 
82     virtual OGRFeature  *GetNextRawFeature();
83     OGRFeature          *BuildFeature(json_object* poRowObj);
84 
85     void                 EstablishLayerDefn(const char* pszLayerName,
86                                             json_object* poObjIn);
87     OGRSpatialReference *GetSRS(const char* pszGeomCol, int *pnSRID);
88     virtual CPLString    GetSRS_SQL(const char* pszGeomCol) = 0;
89 
90   public:
91     explicit OGRCARTOLayer(OGRCARTODataSource* poDS);
92     virtual ~OGRCARTOLayer();
93 
94     virtual void                ResetReading() override;
95     virtual OGRFeature *        GetNextFeature() override;
96 
97     virtual OGRFeatureDefn *    GetLayerDefn() override;
98     virtual OGRFeatureDefn *    GetLayerDefnInternal(json_object* poObjIn) = 0;
99     virtual json_object*        FetchNewFeatures();
100 
GetFIDColumn()101     virtual const char*         GetFIDColumn() override { return osFIDColName.c_str(); }
102 
103     virtual int                 TestCapability( const char * ) override;
104 
GetFeaturesToFetch()105     static int                         GetFeaturesToFetch() {
106         return atoi(CPLGetConfigOption("CARTO_PAGE_SIZE",
107                         CPLGetConfigOption("CARTODB_PAGE_SIZE", "500"))); }
108 };
109 
110 typedef enum
111 {
112     INSERT_UNINIT,
113     INSERT_SINGLE_FEATURE,
114     INSERT_MULTIPLE_FEATURE
115 } InsertState;
116 
117 /************************************************************************/
118 /*                        OGRCARTOTableLayer                          */
119 /************************************************************************/
120 
121 class OGRCARTOTableLayer final: public OGRCARTOLayer
122 {
123     CPLString           osName;
124     CPLString           osQuery;
125     CPLString           osWHERE;
126     CPLString           osSELECTWithoutWHERE;
127 
128     bool                bLaunderColumnNames;
129 
130     bool                bInDeferredInsert;
131     bool                bCopyMode;
132     InsertState         eDeferredInsertState;
133     CPLString           osDeferredBuffer;
134     CPLString           osCopySQL;
135     GIntBig             m_nNextFIDWrite;
136 
137     bool                bDeferredCreation;
138     bool                bCartodbfy;
139     int                 nMaxChunkSize;
140 
141     bool                bDropOnCreation;
142 
143     void                BuildWhere();
144     std::vector<bool>   m_abFieldSetForInsert;
145 
146     virtual CPLString    GetSRS_SQL(const char* pszGeomCol) override;
147 
148   public:
149                          OGRCARTOTableLayer(OGRCARTODataSource* poDS, const char* pszName);
150     virtual ~OGRCARTOTableLayer();
151 
GetName()152     virtual const char*         GetName() override { return osName.c_str(); }
153     virtual OGRFeatureDefn *    GetLayerDefnInternal(json_object* poObjIn) override;
154     virtual json_object*        FetchNewFeatures() override;
155 
156     virtual GIntBig             GetFeatureCount( int bForce = TRUE ) override;
157     virtual OGRFeature         *GetFeature( GIntBig nFeatureId ) override;
158 
159     virtual int                 TestCapability( const char * ) override;
160 
161     virtual OGRErr      CreateGeomField( OGRGeomFieldDefn *poGeomFieldIn,
162                                          int bApproxOK = TRUE ) override;
163 
164     virtual OGRErr      CreateField( OGRFieldDefn *poField,
165                                      int bApproxOK = TRUE ) override;
166 
167     virtual OGRErr      DeleteField( int iField ) override;
168 
169     virtual OGRFeature  *GetNextRawFeature() override;
170 
171     virtual OGRErr      ICreateFeature( OGRFeature *poFeature ) override;
172     virtual OGRErr      ISetFeature( OGRFeature *poFeature ) override;
173     virtual OGRErr      DeleteFeature( GIntBig nFID ) override;
174 
SetSpatialFilter(OGRGeometry * poGeom)175     virtual void        SetSpatialFilter( OGRGeometry *poGeom ) override { SetSpatialFilter(0, poGeom); }
176     virtual void        SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override;
177     virtual OGRErr      SetAttributeFilter( const char * ) override;
178 
GetExtent(OGREnvelope * psExtent,int bForce)179     virtual OGRErr      GetExtent( OGREnvelope *psExtent, int bForce ) override { return GetExtent(0, psExtent, bForce); }
180     virtual OGRErr      GetExtent( int iGeomField, OGREnvelope *psExtent, int bForce ) override;
181 
SetLaunderFlag(bool bFlag)182     void                SetLaunderFlag( bool bFlag )
183         { bLaunderColumnNames = bFlag; }
184     void                SetDeferredCreation( OGRwkbGeometryType eGType,
185                                              OGRSpatialReference* poSRS,
186                                              bool bGeomNullable,
187                                              bool bCartodbfy);
188     OGRErr              RunDeferredCreationIfNecessary();
GetDeferredCreation()189     bool                GetDeferredCreation() const
190         { return bDeferredCreation; }
CancelDeferredCreation()191     void                CancelDeferredCreation()
192         { bDeferredCreation = false; bCartodbfy = false; }
193 
194     OGRErr              FlushDeferredBuffer(bool bReset = true);
195     void                RunDeferredCartofy();
196 
197     OGRErr              FlushDeferredInsert( bool bReset = true );
198     OGRErr              FlushDeferredCopy( bool bReset = true );
199     OGRErr              ICreateFeatureInsert( OGRFeature *poFeature,
200                                               bool bHasUserFieldMatchingFID,
201                                               bool bHasJustGotNextFID );
202     OGRErr              ICreateFeatureCopy( OGRFeature *poFeature,
203                                             bool bHasUserFieldMatchingFID,
204                                             bool bHasJustGotNextFID );
205     char *              OGRCARTOGetHexGeometry( OGRGeometry* poGeom, int i );
206 
SetDropOnCreation(bool bFlag)207     void                SetDropOnCreation( bool bFlag )
208         { bDropOnCreation = bFlag; }
GetDropOnCreation()209     bool                GetDropOnCreation() const
210         { return bDropOnCreation; }
211 };
212 
213 /************************************************************************/
214 /*                       OGRCARTOResultLayer                            */
215 /************************************************************************/
216 
217 class OGRCARTOResultLayer final: public OGRCARTOLayer
218 {
219     OGRFeature          *poFirstFeature;
220 
221     virtual CPLString    GetSRS_SQL(const char* pszGeomCol) override;
222 
223   public:
224                         OGRCARTOResultLayer( OGRCARTODataSource* poDS,
225                                                const char * pszRawStatement );
226     virtual             ~OGRCARTOResultLayer();
227 
228     virtual OGRFeatureDefn *GetLayerDefnInternal(json_object* poObjIn) override;
229     virtual OGRFeature  *GetNextRawFeature() override;
230 
231     bool                IsOK();
232 };
233 
234 /************************************************************************/
235 /*                           OGRCARTODataSource                         */
236 /************************************************************************/
237 
238 class OGRCARTODataSource final: public OGRDataSource
239 {
240     char*               pszName;
241     char*               pszAccount;
242 
243     OGRCARTOTableLayer**  papoLayers;
244     int                 nLayers;
245 
246     bool                bReadWrite;
247     bool                bBatchInsert;
248     bool                bCopyMode;
249 
250     bool                bUseHTTPS;
251 
252     CPLString           osAPIKey;
253 
254     bool                bMustCleanPersistent;
255 
256     CPLString           osCurrentSchema;
257 
258     int                 bHasOGRMetadataFunction;
259 
260     int                 nPostGISMajor;
261     int                 nPostGISMinor;
262 
263   public:
264                         OGRCARTODataSource();
265     virtual ~OGRCARTODataSource();
266 
267     int                 Open( const char * pszFilename,
268                               char** papszOpenOptions,
269                               int bUpdate );
270 
GetName()271     virtual const char* GetName() override { return pszName; }
272 
GetLayerCount()273     virtual int         GetLayerCount() override { return nLayers; }
274     virtual OGRLayer*   GetLayer( int ) override;
275     virtual OGRLayer    *GetLayerByName(const char *) override;
276 
277     virtual int         TestCapability( const char * ) override;
278 
279     virtual OGRLayer   *ICreateLayer( const char *pszName,
280                                      OGRSpatialReference *poSpatialRef = nullptr,
281                                      OGRwkbGeometryType eGType = wkbUnknown,
282                                      char ** papszOptions = nullptr ) 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;
IsReadWrite()291     bool                        IsReadWrite() const { return bReadWrite; }
DoBatchInsert()292     bool                        DoBatchInsert() const { return bBatchInsert; }
DoCopyMode()293     bool                        DoCopyMode() const { return bCopyMode; }
294     char**                      AddHTTPOptions();
295     json_object*                RunSQL(const char* pszUnescapedSQL);
296     json_object*                RunCopyFrom(const char* pszSQL, const char* pszCopyFile);
GetCurrentSchema()297     const CPLString&            GetCurrentSchema() { return osCurrentSchema; }
298     static int                         FetchSRSId( OGRSpatialReference * poSRS );
299 
IsAuthenticatedConnection()300     int                         IsAuthenticatedConnection() { return !osAPIKey.empty(); }
HasOGRMetadataFunction()301     int                         HasOGRMetadataFunction() { return bHasOGRMetadataFunction; }
SetOGRMetadataFunction(int bFlag)302     void                        SetOGRMetadataFunction(int bFlag) { bHasOGRMetadataFunction = bFlag; }
303 
304     OGRLayer *                  ExecuteSQLInternal(
305         const char *pszSQLCommand,
306         OGRGeometry *poSpatialFilter = nullptr,
307         const char *pszDialect = nullptr,
308         bool bRunDeferredActions = false );
309 
GetPostGISMajor()310     int                         GetPostGISMajor() const { return nPostGISMajor; }
GetPostGISMinor()311     int                         GetPostGISMinor() const { return nPostGISMinor; }
312 };
313 
314 #endif /* ndef OGR_CARTO_H_INCLUDED */
315