1 : /******************************************************************************
2 : * $Id: ogr_couchdb.h 23324 2011-11-05 16:17:33Z rouault $
3 : *
4 : * Project: CouchDB Translator
5 : * Purpose: Definition of classes for OGR CouchDB / GeoCouch driver.
6 : * Author: Even Rouault, even dot rouault at mines dash paris dot org
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2011, Even Rouault <even dot rouault at mines dash paris dot org>
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_COUCHDB_H_INCLUDED
31 : #define _OGR_COUCHDB_H_INCLUDED
32 :
33 : #include "ogrsf_frmts.h"
34 : #include "cpl_http.h"
35 : #include "json.h"
36 :
37 : #include <vector>
38 : #include <map>
39 :
40 : #define _ID_FIELD 0
41 : #define _REV_FIELD 1
42 : #define FIRST_FIELD 2
43 :
44 : typedef enum
45 : {
46 : COUCHDB_TABLE_LAYER,
47 : COUCHDB_ROWS_LAYER
48 : } CouchDBLayerType;
49 :
50 : /************************************************************************/
51 : /* OGRCouchDBLayer */
52 : /************************************************************************/
53 : class OGRCouchDBDataSource;
54 :
55 : class OGRCouchDBLayer : public OGRLayer
56 : {
57 : protected:
58 : OGRCouchDBDataSource* poDS;
59 :
60 : OGRFeatureDefn* poFeatureDefn;
61 : OGRSpatialReference* poSRS;
62 :
63 : int nNextInSeq;
64 : int nOffset;
65 : int bEOF;
66 :
67 : json_object* poFeatures;
68 : std::vector<json_object*> aoFeatures;
69 :
70 : OGRFeature* GetNextRawFeature();
71 : OGRFeature* TranslateFeature( json_object* poObj );
72 : void ParseFieldValue(OGRFeature* poFeature,
73 : const char* pszKey,
74 : json_object* poValue);
75 :
76 : int FetchNextRowsAnalyseDocs(json_object* poAnswerObj);
77 : virtual int FetchNextRows() = 0;
78 :
79 : int bGeoJSONDocument;
80 :
81 : void BuildFeatureDefnFromDoc(json_object* poDoc);
82 : int BuildFeatureDefnFromRows(json_object* poAnswerObj);
83 :
84 22 : int GetFeaturesToFetch() { return atoi(CPLGetConfigOption("COUCHDB_PAGE_SIZE", "500")); }
85 :
86 : public:
87 : OGRCouchDBLayer(OGRCouchDBDataSource* poDS);
88 : ~OGRCouchDBLayer();
89 :
90 : virtual void ResetReading();
91 : virtual OGRFeature * GetNextFeature();
92 :
93 : virtual OGRFeatureDefn * GetLayerDefn();
94 :
95 : virtual int TestCapability( const char * );
96 :
97 : virtual OGRSpatialReference*GetSpatialRef();
98 :
99 : virtual CouchDBLayerType GetLayerType() = 0;
100 :
101 : virtual OGRErr SetNextByIndex( long nIndex );
102 : };
103 :
104 : /************************************************************************/
105 : /* OGRCouchDBTableLayer */
106 : /************************************************************************/
107 :
108 : class OGRCouchDBTableLayer : public OGRCouchDBLayer
109 : {
110 : CPLString osName;
111 : CPLString osEscapedName;
112 :
113 : int nNextFIDForCreate;
114 : int bInTransaction;
115 : std::vector<json_object*> aoTransactionFeatures;
116 :
117 : OGRwkbGeometryType eGeomType;
118 :
119 : int bHasLoadedMetadata;
120 : int bMustWriteMetadata;
121 : CPLString osMetadataRev;
122 : void LoadMetadata();
123 : void WriteMetadata();
124 :
125 : virtual int FetchNextRows();
126 :
127 : int bHasOGRSpatial;
128 : int bHasGeocouchUtilsMinimalSpatialView;
129 : int bServerSideSpatialFilteringWorks;
130 : int bMustRunSpatialFilter;
131 : std::vector<CPLString> aosIdsToFetch;
132 : int RunSpatialFilterQueryIfNecessary();
133 : int FetchNextRowsSpatialFilter();
134 :
135 : int bHasInstalledAttributeFilter;
136 : int bServerSideAttributeFilteringWorks;
137 : CPLString osURIAttributeFilter;
138 : std::map<CPLString, int> oMapFilterFields;
139 : CPLString BuildAttrQueryURI(int& bOutHasStrictComparisons);
140 : int FetchNextRowsAttributeFilter();
141 :
142 : int GetTotalFeatureCount();
143 : int GetMaximumId();
144 :
145 : int nUpdateSeq;
146 : int bAlwaysValid;
147 : int FetchUpdateSeq();
148 :
149 : int bExtentValid;
150 : int bExtentSet;
151 : double dfMinX;
152 : double dfMinY;
153 : double dfMaxX;
154 : double dfMaxY;
155 :
156 : int nCoordPrecision;
157 :
158 : OGRFeature* GetFeature( const char* pszId );
159 : OGRErr DeleteFeature( OGRFeature* poFeature );
160 :
161 : public:
162 : OGRCouchDBTableLayer(OGRCouchDBDataSource* poDS,
163 : const char* pszName);
164 : ~OGRCouchDBTableLayer();
165 :
166 : virtual void ResetReading();
167 :
168 : virtual OGRFeatureDefn * GetLayerDefn();
169 :
170 4 : virtual const char * GetName() { return osName.c_str(); }
171 :
172 : virtual int GetFeatureCount( int bForce = TRUE );
173 : virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce = TRUE);
174 :
175 : virtual OGRFeature * GetFeature( long nFID );
176 :
177 : virtual void SetSpatialFilter( OGRGeometry * );
178 : virtual OGRErr SetAttributeFilter( const char * );
179 :
180 : virtual OGRErr CreateField( OGRFieldDefn *poField,
181 : int bApproxOK = TRUE );
182 : virtual OGRErr CreateFeature( OGRFeature *poFeature );
183 : virtual OGRErr SetFeature( OGRFeature *poFeature );
184 : virtual OGRErr DeleteFeature( long nFID );
185 :
186 : virtual OGRErr StartTransaction();
187 : virtual OGRErr CommitTransaction();
188 : virtual OGRErr RollbackTransaction();
189 :
190 : virtual int TestCapability( const char * );
191 :
192 : virtual OGRSpatialReference*GetSpatialRef();
193 :
194 : void SetInfoAfterCreation(OGRwkbGeometryType eGType,
195 : OGRSpatialReference* poSRSIn,
196 : int nUpdateSeqIn,
197 : int bGeoJSONDocumentIn);
198 :
199 15 : void SetUpdateSeq(int nUpdateSeqIn) { nUpdateSeq = nUpdateSeqIn; };
200 :
201 : int HasFilterOnFieldOrCreateIfNecessary(const char* pszFieldName);
202 :
203 0 : void SetCoordinatePrecision(int nCoordPrecision) { this->nCoordPrecision = nCoordPrecision; }
204 :
205 1 : virtual CouchDBLayerType GetLayerType() { return COUCHDB_TABLE_LAYER; }
206 :
207 : OGRErr DeleteFeature( const char* pszId );
208 : };
209 :
210 : /************************************************************************/
211 : /* OGRCouchDBRowsLayer */
212 : /************************************************************************/
213 :
214 : class OGRCouchDBRowsLayer : public OGRCouchDBLayer
215 : {
216 : int bAllInOne;
217 :
218 : virtual int FetchNextRows();
219 :
220 : public:
221 : OGRCouchDBRowsLayer(OGRCouchDBDataSource* poDS);
222 : ~OGRCouchDBRowsLayer();
223 :
224 : virtual void ResetReading();
225 :
226 : int BuildFeatureDefn();
227 :
228 0 : virtual CouchDBLayerType GetLayerType() { return COUCHDB_TABLE_LAYER; }
229 : };
230 :
231 : /************************************************************************/
232 : /* OGRCouchDBDataSource */
233 : /************************************************************************/
234 :
235 : class OGRCouchDBDataSource : public OGRDataSource
236 : {
237 : char* pszName;
238 :
239 : OGRLayer** papoLayers;
240 : int nLayers;
241 :
242 : int bReadWrite;
243 :
244 : int bMustCleanPersistant;
245 :
246 : CPLString osURL;
247 : CPLString osUserPwd;
248 :
249 : json_object* REQUEST(const char* pszVerb,
250 : const char* pszURI,
251 : const char* pszData);
252 :
253 : OGRLayer* OpenDatabase(const char* pszLayerName = NULL);
254 : OGRLayer* OpenView();
255 : void DeleteLayer( const char *pszLayerName );
256 :
257 : OGRLayer * ExecuteSQLStats( const char *pszSQLCommand );
258 :
259 : public:
260 : OGRCouchDBDataSource();
261 : ~OGRCouchDBDataSource();
262 :
263 : int Open( const char * pszFilename,
264 : int bUpdate );
265 :
266 16 : virtual const char* GetName() { return pszName; }
267 :
268 3 : virtual int GetLayerCount() { return nLayers; }
269 : virtual OGRLayer* GetLayer( int );
270 : virtual OGRLayer *GetLayerByName(const char *);
271 :
272 : virtual int TestCapability( const char * );
273 :
274 : virtual OGRLayer *CreateLayer( const char *pszName,
275 : OGRSpatialReference *poSpatialRef = NULL,
276 : OGRwkbGeometryType eGType = wkbUnknown,
277 : char ** papszOptions = NULL );
278 : virtual OGRErr DeleteLayer(int);
279 :
280 : virtual OGRLayer* ExecuteSQL( const char *pszSQLCommand,
281 : OGRGeometry *poSpatialFilter,
282 : const char *pszDialect );
283 : virtual void ReleaseResultSet( OGRLayer * poLayer );
284 :
285 0 : int IsReadWrite() const { return bReadWrite; }
286 :
287 : json_object* GET(const char* pszURI);
288 : json_object* PUT(const char* pszURI, const char* pszData);
289 : json_object* POST(const char* pszURI, const char* pszData);
290 : json_object* DELETE(const char* pszURI);
291 :
292 4 : const CPLString& GetURL() const { return osURL; }
293 :
294 : static int IsError(json_object* poAnswerObj,
295 : const char* pszErrorMsg);
296 : static int IsOK (json_object* poAnswerObj,
297 : const char* pszErrorMsg);
298 : };
299 :
300 : /************************************************************************/
301 : /* OGRCouchDBDriver */
302 : /************************************************************************/
303 :
304 : class OGRCouchDBDriver : public OGRSFDriver
305 226 : {
306 : public:
307 : ~OGRCouchDBDriver();
308 :
309 : virtual const char* GetName();
310 : virtual OGRDataSource* Open( const char *, int );
311 : virtual OGRDataSource* CreateDataSource( const char * pszName,
312 : char **papszOptions );
313 : virtual int TestCapability( const char * );
314 : };
315 :
316 : #endif /* ndef _OGR_COUCHDB_H_INCLUDED */
|